使用Microsoft Solver Foundation 3.0进行团队建设优化

时间:2011-10-08 19:12:48

标签: optimization linear-programming ms-solver-foundation

我正在开发一个学生项目团队建设应用程序。我熟悉优化但之前没有使用Microsoft Solver Foundation。我已经解决了我的约束,但是在使用Solver语法识别我的目标时遇到了麻烦。以下是该应用程序的基本摘要:

  

教授为每个项目加重某些技能。学生列出哪个   技能是他们的优点和缺点,他们对项目进行排名   想干嘛。一个项目必须有3-5名学生分配到   它。必须为每个学生分配一个项目。

  • 主要目标是最大限度地满足技能要求
  • 次要目标是最大化学生的偏好

我一直在使用基于此SimplexSolver ClassMixed 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个问题。

  1. 我不相信所有的项目技能要求都会得到满足。这就是为什么我想设定一个目标,以最大化技能要求的数量,而不是将技能权重最小值设置为约束。即使一支球队在特定技能上只有1分,但仍然比所有将这项技能列为弱点的球员更好。
  2. 如果团队中有4名学生的编程技能权重为3,其中3人将编程列为强度(+1)并且其他学生将编程列为弱点(-1),然后我的模型会错误地显示编程要求未得到满足,因为(1 + 1 + 1-1)&lt ; 3
  3. 有人有什么想法吗? SimplexSolver是解决这个问题的最佳方法吗?看起来Solution Foundation有很多不同的求解器/工具。我有解决方案基金会的Express版本,但如果需要,可能会获得学术企业版本。

    谢谢,    - 格雷格

    *最终申请需要解决大约100名学生,20-30个项目和~30个潜在技能(每个项目约5个)的模型。

1 个答案:

答案 0 :(得分:1)

是的,您可以使用Simplex解决此问题。这是一个标准的“作业问题”,在偏好和技能权重方面有一些变化。

您可以通过引入一个或多个“虚拟变量”来解决'问题1 以解决'松弛'

而不是将技能限制写为:

每个项目p的

Sum for all students (X_sp) >= NumMin_pk,每个技能k。

你写了

每个p的

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编写两个约束,并避免弱点问题抵消另一个学生的技能。