我正在开发一个学生项目团队建设应用程序。我熟悉优化但之前没有使用Microsoft Solver Foundation。我已经解决了我的约束,但是在使用Solver语法识别我的目标时遇到了麻烦。以下是该应用程序的基本摘要:
教授为每个项目加重某些技能。学生列出哪个 技能是他们的优点和缺点,他们对项目进行排名 想干嘛。一个项目必须有3-5名学生分配到 它。必须为每个学生分配一个项目。
我一直在使用基于此SimplexSolver Class的Mixed Integer Problem tutorial,并且能够最大限度地提高学生的偏好。
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>");
我看到如何为每个项目技能要求添加行,并为每个学生的技能强弱设置系数,并为该项目的技能权重设置下限。这给了我2个问题。
有人有什么想法吗? SimplexSolver是解决这个问题的最佳方法吗?看起来Solution Foundation有很多不同的求解器/工具。我有解决方案基金会的Express版本,但如果需要,可能会获得学术企业版本。
谢谢, - 格雷格
*最终申请需要解决大约100名学生,20-30个项目和~30个潜在技能(每个项目约5个)的模型。
答案 0 :(得分:1)
是的,您可以使用Simplex解决此问题。这是一个标准的“作业问题”,在偏好和技能权重方面有一些变化。
您可以通过引入一个或多个“虚拟变量”来解决'问题1 以解决'松弛'
而不是将技能限制写为:
每个项目p的 Sum for all students (X_sp) >= NumMin_pk
,每个技能k。
sum for all students (X_sp) > 0 + NumMin_pk * Dummy1_pk
,每个技能k
在目标函数中,你惩罚 Dummy_pk(通过给它一个最大化问题的负成本。)因此,只有在没有其他选择的情况下,Simplex才会分配非零Dummy_pk。
此外,假设对于一项技能(编程),该项目的最低技能权重为3,但如果5名学生的编程更好。你可以通过引入第二个虚拟变量(Dummy2_pk)来实现这一点。
每个p的 Sum for all students (X_sp) > 0 + 3* Dummy_pk + 2 * Dummy_pk2
,每个技能k
在目标函数中,给Dummy_pk一个高负成本,给Dummy2_pk一个较小但负成本。模型将首先尝试使得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编写两个约束,并避免弱点问题抵消另一个学生的技能。