static void SolveDual3(GRBEnv env, HashSet <string> nodes_set, List <Arc> arcs) { GRBModel dual = new GRBModel(env); Dictionary <string, GRBConstr> flow_balance = new Dictionary <string, GRBConstr>(); Dictionary <Arc, GRBVar> arc_traversed = new Dictionary <Arc, GRBVar>(); GRBConstr[] constrs = dual.AddConstrs(nodes_set.Count); dual.Update(); int i = 0; foreach (string s in nodes_set) { GRBConstr con = constrs[i]; con.Set(GRB.StringAttr.ConstrName, "flow_balance." + s); con.Set(GRB.CharAttr.Sense, GRB.EQUAL); flow_balance[s] = con; ++i; } flow_balance[ORIGIN].Set(GRB.DoubleAttr.RHS, -1); flow_balance[DESTINATION].Set(GRB.DoubleAttr.RHS, 1); foreach (Arc a in arcs) { GRBColumn col = new GRBColumn(); col.AddTerm(1, flow_balance[a.dest]); col.AddTerm(-1, flow_balance[a.source]); arc_traversed[a] = dual.AddVar(0, 1, a.length, GRB.CONTINUOUS, col, "arc_traversed." + a.source + "." + a.dest); } dual.Optimize(); dual.Write("dual3.lp"); dual.Write("dual3.sol"); dual.Dispose(); }
public Schedule Run() { Schedule schedule = new Schedule(100); try { GRBEnv env = new GRBEnv(true); env.Set("LogFile", "mip1.log"); env.Start(); GRBModel model = new GRBModel(env); // Create variables GRBVar[,] varInstructors = new GRBVar[ctx.Instructors.Length, 100]; GRBVar[,] varStudents = new GRBVar[ctx.Students.Length, 100]; GRBVar[,] varPresidentsSessions = new GRBVar[ctx.Presidents.Length, 20]; GRBVar[,] varSecretariesSessions = new GRBVar[ctx.Secretaries.Length, 20]; GRBVar[] varPresidentsTempP = new GRBVar[ctx.Presidents.Length]; GRBVar[] varPresidentsTempQ = new GRBVar[ctx.Presidents.Length]; GRBVar[] varSecretariesTempP = new GRBVar[ctx.Secretaries.Length]; GRBVar[] varSecretariesTempQ = new GRBVar[ctx.Secretaries.Length]; GRBVar[] varMembersTempP = new GRBVar[ctx.Members.Length]; GRBVar[] varMembersTempQ = new GRBVar[ctx.Members.Length]; for (int ts = 0; ts < 100; ts++) { for (int i = 0; i < ctx.Instructors.Length; i++) { varInstructors[i, ts] = model.AddVar(0.0, 1.0, 0.0, GRB.BINARY, ctx.Instructors[i].Name + " " + ts); } for (int s = 0; s < ctx.Students.Length; s++) { varStudents[s, ts] = model.AddVar(0.0, 1.0, 0.0, GRB.BINARY, ctx.Students[s].Name + " " + ts); } } for (int session = 0; session < 20; session++) { for (int president = 0; president < ctx.Presidents.Length; president++) { varPresidentsSessions[president, session] = model.AddVar(0.0, 1.0, 0.0, GRB.BINARY, ctx.Presidents[president].Name + "_session_" + session); } for (int secretary = 0; secretary < ctx.Secretaries.Length; secretary++) { varSecretariesSessions[secretary, session] = model.AddVar(0.0, 1.0, 0.0, GRB.BINARY, ctx.Secretaries[secretary].Name + "_session_" + session); } } for (int president = 0; president < ctx.Presidents.Length; president++) { varPresidentsTempP[president] = model.AddVar(0.0, GRB.INFINITY, 0.0, GRB.INTEGER, ctx.Presidents[president].Name + "_workload_P"); varPresidentsTempQ[president] = model.AddVar(0.0, GRB.INFINITY, 0.0, GRB.INTEGER, ctx.Presidents[president].Name + "_workload_Q"); } for (int secretary = 0; secretary < ctx.Secretaries.Length; secretary++) { varSecretariesTempP[secretary] = model.AddVar(0.0, GRB.INFINITY, 0.0, GRB.INTEGER, ctx.Secretaries[secretary].Name + "_workload_P"); varSecretariesTempQ[secretary] = model.AddVar(0.0, GRB.INFINITY, 0.0, GRB.INTEGER, ctx.Secretaries[secretary].Name + "_workload_Q"); } for (int member = 0; member < ctx.Members.Length; member++) { varMembersTempP[member] = model.AddVar(0.0, GRB.INFINITY, 0.0, GRB.INTEGER, ctx.Members[member].Name + "workload_P"); varMembersTempQ[member] = model.AddVar(0.0, GRB.INFINITY, 0.0, GRB.INTEGER, ctx.Members[member].Name + "workload_Q"); } // Set objective model.SetObjective(SumProduct(varInstructors, ctx.Instructors) + SumOfVars(varPresidentsTempP) + SumOfVars(varPresidentsTempQ) + SumOfVars(varSecretariesTempP) + SumOfVars(varSecretariesTempQ) + SumOfVars(varMembersTempP) + SumOfVars(varMembersTempQ) , GRB.MINIMIZE); char[] equalArray = Enumerable.Range(0, 100).Select(x => GRB.EQUAL).ToArray(); char[] greaterArray = Enumerable.Range(0, 100).Select(x => GRB.GREATER_EQUAL).ToArray(); char[] lessArray = Enumerable.Range(0, 100).Select(x => GRB.LESS_EQUAL).ToArray(); // Add constraint: max 5 instructors string[] nameOfMaxNrInstructorsConstrs = Enumerable.Range(0, 100).Select(x => "MaxInstructorsNr" + x).ToArray(); model.AddConstrs(SumOfPersonVarsPerTs(varInstructors), lessArray, NrArray(5.0), nameOfMaxNrInstructorsConstrs); // Add constraint: be min a president in every ts (enélkül több elnök is lehet 1 ts-ban) string[] nameOfPresidentsConstrs = Enumerable.Range(0, 100).Select(x => "President" + x).ToArray(); model.AddConstrs(SumOfPersonVarsPerTs(GetPresidentsVars(varInstructors)), equalArray, NrArray(1.0), nameOfPresidentsConstrs); // Add constraint: be min a secretary in every ts string[] nameOfSecretariesConstrs = Enumerable.Range(0, 100).Select(x => "Secretary" + x).ToArray(); model.AddConstrs(SumOfPersonVarsPerTs(GetSecretariesVars(varInstructors)), equalArray, NrArray(1.0), nameOfSecretariesConstrs); // Add constraint: be min a member in every ts string[] nameOfMembersConstrs = Enumerable.Range(0, 100).Select(x => "Member" + x).ToArray(); model.AddConstrs(SumOfPersonVarsPerTs(GetMembersVars(varInstructors)), greaterArray, NrArray(1.0), nameOfMembersConstrs); string[] nameOfMembersMaxConstrs = Enumerable.Range(0, 100).Select(x => "MemberMax" + x).ToArray(); model.AddConstrs(SumOfPersonVarsPerTs(GetMembersVars(varInstructors)), lessArray, NrArray(2.0), nameOfMembersMaxConstrs); // Add constraint: be a student in every ts string[] nameOfStudentsPerTsConstrs = Enumerable.Range(0, 100).Select(x => "Student" + x).ToArray(); model.AddConstrs(SumOfPersonVarsPerTs(varStudents), equalArray, NrArray(1.0), nameOfStudentsPerTsConstrs); string[] nameOfStudentsConstrs = Enumerable.Range(0, 100).Select(x => "Student" + x).ToArray(); model.AddConstrs(SumOfPersonVarsPerPerson(varStudents), equalArray, NrArray(1.0), nameOfStudentsConstrs); // Add constraint: be the supervisor of student there for (int ts = 0; ts < varStudents.GetLength(1); ts++) { for (int student = 0; student < varStudents.GetLength(0); student++) { int idOfSupervisor = ctx.Students[student].Supervisor.Id; model.AddConstr(varStudents[student, ts] - varInstructors[idOfSupervisor, ts] <= 0.0, "Supervisor" + ts + "_" + student); } } // Add constraint: be examiner there for (int student = 0; student < varStudents.GetLength(0); student++) { GRBLinExpr[] sumOfExaminersVarsPerTs = SumOfPersonVarsPerTs(GetExaminersVars(varInstructors, ctx.Students[student].ExamCourse)); for (int ts = 0; ts < varStudents.GetLength(1); ts++) { model.AddConstr(varStudents[student, ts] - sumOfExaminersVarsPerTs[ts] <= 0.0, "Examiner" + ts + "_" + student); } } // Add constraint: president not change GRBVar[,] presidentsVars = GetPresidentsVars(varInstructors); for (int session = 0; session < 20; session++) { for (int president = 0; president < ctx.Presidents.Length; president++) { GRBVar[] presidentsVarsInSession = new GRBVar[] { presidentsVars[president, session *5], presidentsVars[president, session *5 + 1], presidentsVars[president, session *5 + 2], presidentsVars[president, session *5 + 3], presidentsVars[president, session *5 + 4] }; model.AddGenConstrAnd(varPresidentsSessions[president, session], presidentsVarsInSession, "PresindentInSession" + president + "_" + session); } } string[] nameOfPresidentsSessionsConstraints = Enumerable.Range(0, 100).Select(x => "PresidentSession" + x).ToArray(); model.AddConstrs(SumOfPersonVarsPerTs(varPresidentsSessions), equalArray, NrArray(1.0), nameOfPresidentsSessionsConstraints); // Add constraint: secretary not change GRBVar[,] secretariesVars = GetSecretariesVars(varInstructors); for (int session = 0; session < 20; session++) { for (int secretary = 0; secretary < ctx.Secretaries.Length; secretary++) { GRBVar[] secretariesVarsInSession = new GRBVar[] { secretariesVars[secretary, session *5], secretariesVars[secretary, session *5 + 1], secretariesVars[secretary, session *5 + 2], secretariesVars[secretary, session *5 + 3], secretariesVars[secretary, session *5 + 4] }; model.AddGenConstrAnd(varSecretariesSessions[secretary, session], secretariesVarsInSession, "SecretaryInSession" + secretary + "_" + session); } } string[] nameOfSecretariesSessionsConstraints = Enumerable.Range(0, 100).Select(x => "SecretariesSession" + x).ToArray(); model.AddConstrs(SumOfPersonVarsPerTs(varSecretariesSessions), equalArray, NrArray(1.0), nameOfSecretariesSessionsConstraints); // Add constraint: presidents available model.AddConstr(SumProduct(GetPresidentsVars(varInstructors), ctx.Presidents) == 0.0, "PresindetsAvailable"); // Add constraint: secretaries available model.AddConstr(SumProduct(GetSecretariesVars(varInstructors), ctx.Secretaries) == 0.0, "SecretariesAvailable"); // Add constraint: workload of presidents string[] nameOfPresidentWorkloadMinConstrs = Enumerable.Range(0, 100).Select(x => "PresintWorkloadMin" + x).ToArray(); string[] nameOfPresidentWorkloadMaxConstrs = Enumerable.Range(0, 100).Select(x => "PresintWorkloadMax" + x).ToArray(); model.AddConstrs(SumOfPersonVarsPerPerson(varPresidentsSessions), greaterArray, NrArray(3.0), nameOfPresidentWorkloadMinConstrs); model.AddConstrs(SumOfPersonVarsPerPerson(varPresidentsSessions), lessArray, NrArray(7.0), nameOfPresidentWorkloadMaxConstrs); for (int president = 0; president < ctx.Presidents.Length; president++) { // for soft constraint: model.AddConstr(varPresidentsTempP[president] - varPresidentsTempQ[president] == SumOfPersonVarsPerPerson(varPresidentsSessions)[president] - 5.0, "workloadSoft" + president); } // Add constraint: workload of secretaries string[] nameOfSecretaryWorkloadMinConstrs = Enumerable.Range(0, 100).Select(x => "SecretaryWorkloadMin" + x).ToArray(); string[] nameOfSecretaryWorkloadMaxConstrs = Enumerable.Range(0, 100).Select(x => "SecretaryWorkloadMax" + x).ToArray(); model.AddConstrs(SumOfPersonVarsPerPerson(varSecretariesSessions), greaterArray, NrArray(1.0), nameOfSecretaryWorkloadMinConstrs); model.AddConstrs(SumOfPersonVarsPerPerson(varSecretariesSessions), lessArray, NrArray(3.0), nameOfSecretaryWorkloadMaxConstrs); for (int secretary = 0; secretary < ctx.Secretaries.Length; secretary++) { // for soft constraint: model.AddConstr(varSecretariesTempP[secretary] - varSecretariesTempQ[secretary] == SumOfPersonVarsPerPerson(varSecretariesSessions)[secretary] - 2.0, "workloadSoft" + secretary); } // Add constraint: workload of members string[] nameOfMemberWorkloadMinConstrs = Enumerable.Range(0, 100).Select(x => "MemberWorkloadMin" + x).ToArray(); string[] nameOfMemberWorkloadMaxConstrs = Enumerable.Range(0, 100).Select(x => "MemberWorkloadMax" + x).ToArray(); model.AddConstrs(SumOfPersonVarsPerPerson(GetMembersVars(varInstructors)), greaterArray, NrArray(7.0), nameOfMemberWorkloadMinConstrs); //model.AddConstrs(SumOfPersonVarsPerPerson(GetMembersVars(varInstructors)), lessArray, NrArray(12.0), nameOfMemberWorkloadMaxConstrs); for (int member = 0; member < ctx.Members.Length; member++) { // for soft constraint: model.AddConstr(varMembersTempP[member] - varMembersTempQ[member] == SumOfPersonVarsPerPerson(GetMembersVars(varInstructors))[member] - 10.0, "workloadSoft" + member); } // Optimize model model.Optimize(); for (int ts = 0; ts < 100; ts++) { List <Instructor> instructorsTS = new List <Instructor>(); for (int person = 0; person < ctx.Instructors.Length; person++) { if (varInstructors[person, ts].X == 1.0) { instructorsTS.Add(ctx.Instructors[person]); } } schedule.FinalExams[ts] = new FinalExam(); schedule.FinalExams[ts].Id = ts; //schedule.FinalExams[ts].President = instructorsTS.Find(i => i.Roles.HasFlag(Roles.President)); //schedule.FinalExams[ts].Secretary = instructorsTS.Find(i => i.Roles.HasFlag(Roles.Secretary)); schedule.FinalExams[ts].Member = instructorsTS.Find(i => i.Roles.HasFlag(Roles.Member)); for (int i = 0; i < ctx.Students.Length; i++) { if (varStudents[i, ts].X == 1.0) { schedule.FinalExams[ts].Student = ctx.Students[i]; } } if (instructorsTS.Contains(schedule.FinalExams[ts].Student.Supervisor)) { schedule.FinalExams[ts].Supervisor = schedule.FinalExams[ts].Student.Supervisor; } Course courseOfStudent = schedule.FinalExams[ts].Student.ExamCourse; for (int i = 0; i < courseOfStudent.Instructors.Length; i++) { if (instructorsTS.Contains(courseOfStudent.Instructors[i])) { schedule.FinalExams[ts].Examiner = courseOfStudent.Instructors[i]; } } } for (int session = 0; session < 20; session++) { Instructor presindetInSession = new Instructor(); Instructor secretaryInSession = new Instructor(); for (int president = 0; president < ctx.Presidents.Length; president++) { if (varPresidentsSessions[president, session].X == 1) { presindetInSession = ctx.Presidents[president]; } } for (int secretary = 0; secretary < ctx.Secretaries.Length; secretary++) { if (varSecretariesSessions[secretary, session].X == 1) { secretaryInSession = ctx.Secretaries[secretary]; } } for (int ts = session * 5 + 0; ts < session * 5 + 5; ts++) { schedule.FinalExams[ts].President = presindetInSession; schedule.FinalExams[ts].Secretary = secretaryInSession; } } Console.WriteLine("Obj: " + model.ObjVal); // Dispose of model and env model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } return(schedule); }