开发者

Team Building Optimization Using Microsoft Solver Foundation 3.0

I'm working on a student project team building application. I'm familiar with optimization but haven't used Microsoft Solver Foundation before. I have my constraints worked out but am having trouble identifying my goals with the Solver syntax. Here's a basic summary of the application:

Professors weight certain skills for each project. Students list which skills are their strengths and weaknesses and they rank projects they would like to do. A project must have between 3-5 students assigned to it. Each student must be assigned a project.

  • Primary goal is开发者_开发技巧 to maximize number of satisfied skill requirements
  • Secondary goal is to maximize student preferences

I have been playing around with the SimplexSolver Class based on this Mixed Integer Problem tutorial and am able to maximize student preferences without any problem.

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>");

I see how I can add rows for each project skill requirement, and set coefficients for each student's strength/weakness for that skill and set a lower bound for that project's skill weight. This gives me 2 problems though.

  1. I don't believe that all project skill requirements are going to be met. That's why I would like to set a goal to maximize the number of skill requirements that are meant instead of setting the skill weight minimum as a constraint. Even if a team is 1 point short on a particular skill it is still better than all of them having that skill listed as a weakness.
  2. If there are 4 students on a team that has a programming skill weight of 3, and 3 of them have programming listed as a strength (+1) and the other student has programming listed as a weakness (-1) then my model would incorrectly show that the programming requirement is not met because (1+1+1-1)<3.

Anybody have any ideas? Is SimplexSolver the best way to go about this problem? It looks like Solution Foundation has a lot of different solvers/tools. I have the Express version of Solution Foundation but could probably get a hold of the Academic Enterprise version if needed.

Thanks, - Greg

*Final application will need to solve models with approximately 100 students, 20-30 projects, and ~30 potential skills (~5 per project).


Yes, you can solve this using Simplex. This is an standard "Assignment Problem" with a few variations in terms of preferences and skill weights.

You can address Issue 1 in your question by introducing one or more "dummy variables" to take up the 'slack'

Instead of writing the skill constraint as:

Sum for all students (X_sp) >= NumMin_pk for each project p, for each skill k.

you write

sum for all students (X_sp) > 0 + NumMin_pk * Dummy1_pk for each p, for each skill k

And in the objective function, you penalize Dummy_pk (by giving it a negative cost for the Maximization problem.) So, Simplex will assign a non-zero Dummy_pk only if it has no other alternative.

Further, let's say for one skill (programming) the project has a minimum skill weight of 3, but if 5 students have programming that is even better. You can achieve that by introducing a second Dummy Variable (Dummy2_pk).

Sum for all students (X_sp) > 0 + 3* Dummy_pk + 2 * Dummy_pk2 for each p, for each skill k

In the objective function, give a High negative cost to Dummy_pk and a smaller but negative cost to Dummy2_pk.The model will first try to make get Dummy1_pk 0, and if possible, if will drive Dummy2_pk zero. The result would be 5 students with programming skills getting assigned to that project.

To address issue 2 (negative skill weights): Split the skill vector into two vectors by separating the 1s and the -1's.

So [1,0,0,1,-1,0,1] becomes [1,0,0,1,0,0,1] and [0,0,0,0,-1,0,0]. Depending on what you want to do with skill weakness, you can write TWO constraints for each project p, skill k and avoid the problem of weakness canceling out another student's skill.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜