2011-10-08 81 views
2

我正在研究學生項目團隊構建應用程序。我熟悉優化,但之前沒有使用Microsoft Solver Foundation。我有我的約束條件,但無法通過Solver語法確定我的目標。以下是該應用程序的基本概要:使用Microsoft Solver Foundation 3.0進行團隊建設優化

教授會爲每個項目加權某些技能。學生列出哪些技能是他們的優點和缺點,並將他們排列在 想要做的項目中。一個項目必須有3-5名學生分配到 它。每個學生都必須分配一個項目。

  • 主要目標是最大限度地滿足技術要求的數
  • 第二個目標是最大限度地提高學生的喜好

我一直在此基礎上Mixed Integer Problem tutorialSimplexSolver Class玩弄和我能夠沒有任何問題最大限度地提高學生的喜好

using Microsoft.SolverFoundation.Solvers; 

//This example has 2 projects and 6 students 
SimplexSolver solver = new SimplexSolver(); 
//Student A wants to be in project 1, Student B is indifferent to project 1, Student C does not want to be in project 1, etc... 
double[] studentprojectpref = new double[] { 1, 0, -1, 0, -1, 0, 0, 1, 0, 1, 0, 1 }; 
int[] choosestudentprojectPS = new int[12]; 

//GOAL - maximize student preferences 
int sumpreferences; 
solver.AddRow("sumpreferences", out sumpreferences); 
solver.AddGoal(sumpreferences, 1, false); 

//add a varaible (column) for each possible student/project pair 
for (int i = 0; i < choosestudentprojectPS.GetUpperBound(0)+1; i++) 
{ 
    solver.AddVariable(projectstudent[i], out choosestudentprojectPS[i]); 
    solver.SetBounds(choosestudentprojectPS[i], 0, 1); 
    solver.SetIntegrality(choosestudentprojectPS[i], true); 
    solver.SetCoefficient(sumpreferences, choosestudentprojectPS[i], studentprojectpref[i]); 
} 

solver.Solve(new SimplexSolverParams()); 

Response.Write(solver.MipResult + "<br>"); 
Response.Write("<br>Project 1<br>"); 
for (int i = 0; i < 6; i++) 
{ 
    if (solver.GetValue(choosestudentprojectPS[i]) == 1) Response.Write(projectstudent[i] + "<br>"); 
} 
Response.Write("<br>Project 2<br>"); 
for (int i = 6; i < 12; i++) 
{ 
    if (solver.GetValue(choosestudentprojectPS[i]) == 1) Response.Write(projectstudent[i] + "<br>"); 
} 
    Response.Write("<br>The total sumpreferences is: " + solver.GetValue(sumpreferences) + "<br>"); 

我知道怎樣才能爲每個項目技能要求添加行,併爲每個學生的強度係數爲技能/衰弱,並設置一個下限爲該項目的技能重量。儘管如此,這給了我兩個問題。

  1. 我不相信所有的項目技能要求都會得到滿足。這就是爲什麼我想設定一個目標來最大限度地提高技能要求的數量,而不是將技能權重設置爲最小限制。即使一支球隊在特定技能上短1分,但他們仍然比那些被列爲弱點的球員更好。
  2. 如果有4名學生對具有編程的3技能重量團隊,其中3有編程列爲強度(+1)和其他學生已經編程列爲弱點(-1),那麼我的模型會錯誤地顯示,編程要求沒有得到滿足,因爲(1 + 1 + 1-1)< 3.

任何人有什麼想法? SimplexSolver是解決這個問題的最好方法嗎?看起來解決方案基金會有很多不同的求解器/工具。我有Express版本的解決方案基礎,但如果需要,可能可能會獲得Academic Enterprise版本。

感謝, - 格雷格

*最終應用程序將需要大約100名學生,20-30工程,解決了模型,並〜30級潛在的技能(〜5%的項目)。

回答

1

是的,你可以使用Simplex來解決這個問題。這是一個標準的「分配問題」,在偏好和技能權重方面有一些變化。

可以通過引入一個或多個「虛擬變量」擔起「鬆弛」

而不是寫作技巧約束爲解決問題在你的問題1Sum for all students (X_sp) >= NumMin_pk爲每個項目p,爲每個技能k。

你寫

sum for all students (X_sp) > 0 + NumMin_pk * Dummy1_pk對於各個p,每個技能ķ

而且在目標函數,你懲罰 Dummy_pk(通過給它最大化問題負成本)。所以,單純只有在沒有其他選擇時纔會分配非零Dummy_pk。此外,假設一個技能(編程)該項目的最低技能權重爲3,但是如果5個學生的編程更好。您可以通過引入第二個虛擬變量(Dummy2_pk)來實現此目的。

Sum for all students (X_sp) > 0 + 3* Dummy_pk + 2 * Dummy_pk2對於各個p,每個技能ķ

目標函數,給Dummy_pk高負成本和更小,但負成本Dummy2_pk.The模型將首先嚐試讓拿到Dummy1_pk 0,如果可能的話,如果將Dummy2_pk驅動爲零。結果將是5名具有編程技能的學生被分配到該項目。

要解決問題2(負技能權重): 通過分離1和-1來將技能向量分解爲兩個向量。

因此[1,0,0,1,-1,0,1]變成[1,0,0,1,0,0,1]和[0,0,0,0,-1, 0,0]。根據你想要處理的技能弱點,你可以爲每個項目p,技能k寫兩個約束,並避免弱點取消另一個學生的技能。