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



我正在做一个学生项目团队建设应用程序。我熟悉优化,但之前没有使用过Microsoft Solver Foundation。我有我的约束,但我有麻烦确定我的目标与求解器语法。以下是该应用程序的基本摘要:

教授在每个项目中都重视某些技能。学生们列出了技能是他们的优势和劣势,他们对项目进行排名愿意做某事。一个项目必须有3-5名学生分配它。每个学生必须分配一个项目。

  • 主要目标是最大化满足技能要求的数量
  • 第二目标是最大化学生的偏好

我一直在玩基于这个混合整数问题教程的SimplexSolver类,并且能够最大限度地提高学生的偏好,没有任何问题。

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)<</ol>

    有人有什么想法吗?SimplexSolver是解决这个问题的最好方法吗?看起来解决方案基金会有很多不同的求解器/工具。我有解决方案基金会的快速版本,但如果需要的话,可能会得到学术企业版本。

    谢谢,——格雷格

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

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

您可以通过引入一个或多个"虚拟变量"来解决问题1,以占用"松弛"

而不是将技能约束写成:

每个项目p,每个技能k的Sum for all students (X_sp) >= NumMin_pk

你写

sum for all students (X_sp) > 0 + NumMin_pk * Dummy1_pk对于每个p,对于每个技能k

在目标函数中,你惩罚 Dummy_pk(通过给它一个负的最大化问题成本)。因此,Simplex只有在没有其他选择的情况下才会分配一个非零的Dummy_pk。

进一步,假设对于一项技能(编程),项目的最低技能权重为3,但如果有5名学生拥有编程,那就更好了。您可以通过引入第二个虚拟变量(Dummy2_pk)来实现这一点。

Sum for all students (X_sp) > 0 + 3* Dummy_pk + 2 * Dummy_pk2对于每个p,对于每个技能k

在目标函数中,给Dummy_pk一个较高的负代价,给Dummy2_pk一个较小的负代价。该模型将首先尝试使get Dummy1_pk为0,如果可能的话,它将使Dummy2_pk为0。结果是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写两个约束条件,以避免弱点抵消另一个学生的技能的问题。

最新更新