我在做一个学生项目团队建设应用程序。我熟悉优化,但以前没有使用过。我已经完成了我的约束,但是我很难用Solver语法来确定我的目标。下面是应用程序的基本摘要:
教授们对每个项目的某些技能进行了权衡。学生们列出哪些技能是他们的长处和弱点,并对他们想要做的项目进行排序。一个项目必须有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>");我知道如何为每个项目技能需求添加行,并为每个学生的强弱设置系数,并为该项目的技能权重设置一个下限。这给我带来了两个问题。
有人有什么想法吗?SimplexSolver是解决这个问题的最好方法吗?看起来解决方案基金会有很多不同的解决方案/工具。我有解决方案基金会的Express版本,但如果需要的话,我可能会获得学术企业版本。
谢谢,-格雷格
*最终申请将需要解决模型约100名学生,20-30个项目,和~30个潜在的技能(~5个项目)。
发布于 2012-02-05 14:18:55
是的,你可以用单纯形来解决这个问题。这是一个标准的“分配问题”,在偏好和技能权重方面有一些变化。
您可以通过引入一个或多个“虚拟变量”来处理问题中的问题1,以处理‘can’
而不是将技能约束写成:
Sum for all students (X_sp) >= NumMin_pk对每个项目p,对于每个技能k。
你写
sum for all students (X_sp) > 0 + NumMin_pk * Dummy1_pk对每个p,对于每个技能k
在目标函数中,你惩罚Dummy_pk (通过给它一个最大化问题的负代价)。因此,单纯形只有在没有其他选择的情况下才会分配一个非零的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.The模型一个较小但负的代价,先得到Dummy1_pk 0,如果可能的话,将Dummy2_pk变为零。结果将有5名具有编程技能的学生被分配到该项目中。
解决问题2(负技能权重):通过分离1s和-1将技能向量分成两个向量。
所以,1,0,0,1,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0。根据你想对技能弱点做些什么,你可以为每个项目写两个约束,技巧k,避免弱点抵消另一个学生的技能的问题。
https://stackoverflow.com/questions/7699157
复制相似问题