public void computeCourses() throws GRBException { env = new GRBEnv(); env.set(GRB.IntParam.LogToConsole, 0); model = new GRBModel(env); y_ijk = new GRBVar[studentList.size()][classList.size()][semesterList.size()]; for (int a = 0; a < studentList.size(); a++) { for (int b = 0; b < classList.size(); b++) { for (int c = 0; c < semesterList.size(); c++) { y_ijk[a][b][c] = model.addVar(0, 1, 0, GRB.BINARY, "Demand_" + a + b + c); } } } x = model.addVar(0, GRB.INFINITY, 0, GRB.INTEGER, null); obj = new GRBLinExpr(); obj.addTerm(1, x); model.set(GRB.IntAttr.ModelSense, 1); model.update(); for (int a = 0; a < studentList.size(); a++) { for (int b = 0; b < classList.size(); b++) { GRBLinExpr studentClassListCon = new GRBLinExpr(); for (int c = 0; c < semesterList.size(); c++) { studentClassListCon.addTerm(1, y_ijk[a][b][c]); } model.addConstr(studentClassListCon, GRB.EQUAL, A_s[a][b], "Student Schedule" + a + b); } } // Set maximum seat capacity aka X for (int c = 0; c < semesterList.size(); c++) { for (int b = 0; b < classList.size(); b++) { GRBLinExpr maxClassCapCon = new GRBLinExpr(); for (int a = 0; a < studentList.size(); a++) { maxClassCapCon.addTerm(1, y_ijk[a][b][c]); } model.addConstr(maxClassCapCon, GRB.LESS_EQUAL, x, "X"); } } for (int a = 0; a < studentList.size(); a++) { for (int c = 0; c < semesterList.size(); c++) { GRBLinExpr maxClassCon = new GRBLinExpr(); for (int b = 0; b < classList.size(); b++) { maxClassCon.addTerm(1, y_ijk[a][b][c]); } model.addConstr(maxClassCon, GRB.LESS_EQUAL, 2, "ClassLimit"); } } // Available Constriant for (int a = 0; a < studentList.size(); a++) { for (int b = 0; b < classList.size(); b++) { GRBLinExpr classAvalCon = new GRBLinExpr(); for (int c = 0; c < semesterList.size(); c++) { if (courseAvalMatrix[b][c] == 0) { classAvalCon.addTerm(1, y_ijk[a][b][c]); // System.out.printf("Course %d during Semester %d\n", (b + 1), (c + 1)); } } model.addConstr(classAvalCon, GRB.EQUAL, 0, "NotAval"); } } // Can't take first semester for (int a = 0; a < studentList.size(); a++) { GRBLinExpr firstSemesterCon = new GRBLinExpr(); for (int b = 0; b < classList.size(); b++) { if (classList.get(b).preqCourseId != 0) { firstSemesterCon.addTerm(1, y_ijk[a][b][0]); } } model.addConstr(firstSemesterCon, GRB.EQUAL, 0, "firstSemester"); } // Prereq Constraint GRBLinExpr preReqConLeft = new GRBLinExpr(); GRBLinExpr preReqConRight = new GRBLinExpr(); for (int a = 0; a < studentList.size(); a++) { for (int c = 0; c < (semesterList.size() - 1); c++) { preReqConLeft.addTerm(1, y_ijk[a][15][c + 1]); preReqConRight.addTerm(1, y_ijk[a][3][c]); preReqConLeft.addTerm(1, y_ijk[a][0][c + 1]); preReqConRight.addTerm(1, y_ijk[a][11][c]); preReqConLeft.addTerm(1, y_ijk[a][12][c + 1]); preReqConRight.addTerm(1, y_ijk[a][8][c]); preReqConLeft.addTerm(1, y_ijk[a][6][c + 1]); preReqConRight.addTerm(1, y_ijk[a][2][c]); } model.addConstr((preReqConRight), GRB.GREATER_EQUAL, preReqConLeft, "PrereqClass"); } for (int b = 0; b < classList.size(); b++) { for (int a = 0; a < studentList.size(); a++) { GRBLinExpr mustTakeReq = new GRBLinExpr(); for (int c = 0; c < semesterList.size(); c++) { for (int d = 0; d < studentList.get(a).demands.size(); d++) { // System.out.print(studentList.get(a).demands.get(d).courseId); if (preReqMatrix[(studentList.get(a).demands.get(d).courseId) - 1][b] == 1) { mustTakeReq.addTerm(1, y_ijk[a][b][c]); // System.out.printf("Student %d must takes Course %d \n", (a + 1), (b + 1)); } } } // model.addConstr(mustTakeReq,GRB.EQUAL, 1, "Must Take"); } } model.setObjective(obj); model.optimize(); int status = model.get(GRB.IntAttr.Status); System.out.println("X = " + model.get(GRB.DoubleAttr.ObjVal)); }
/** * Constructor * * @param ind * @param N * @param Us * @param Ds * @param ds * @param OP * @param SP * @param bestLB * @param fixTo1 * @param fixTo0 * @param varToFix * @param valueToFix * @throws GRBException */ public BBNode( int ind, int N, Matrix Us, Matrix Ds, Matrix ds, GRBModel OP, GRBModel SP, double bestLB, List<GRBVar> fixTo1, List<GRBVar> fixTo0, GRBVar varToFix, boolean valueToFix) throws GRBException { this.ind = ind; this.Us = Us; this.nodesBestUs = Us; this.bestLB = bestLB; this.varsFixedTo0.addAll(fixTo0); this.varsFixedTo1.addAll(fixTo1); if (valueToFix) this.varsFixedTo1.add(varToFix); else this.varsFixedTo0.add(varToFix); LR_Main.fixVar(varsFixedTo0, false, SP); LR_Main.fixVar(varsFixedTo1, true, SP); double miu; int cntr = 0; int k = 0; SP.optimize(); if (SP.get(GRB.IntAttr.Status) != 3) { // Model feasibility check UB = SP.get(GRB.DoubleAttr.ObjVal); // System.out.println("miu: " + miu + " - Itr" + k + ": LB = " + lb.value + " - UB = " + // UB); while ( /*this.gap > optGap &&*/ k < 5) { cntr = LR_Main.dissectEpsilon(cntr, 3); // miu = LR_Main.updateMiu(miu, k, N); miu = LR_Main.updateMiuC(Ds, ds); this.Us = LR_Main.updateU(SP, miu, this.Us, ds, Ds); // Update Lagrangian multipliers LR_Main.updateObjCoeffs(SP, this.Us, ds, Ds); // Update obj fun coefficients SP.optimize(); UB = SP.get(GRB.DoubleAttr.ObjVal); if (UB < this.bestUB) { this.bestUB = UB; cntr = 0; } else { cntr++; } this.selectedLocations = new ArrayList<String>(); for (int i = 1; i <= N; i++) { GRBVar var = SP.getVar(SP.get(GRB.IntAttr.NumVars) - i); if (var.get(GRB.DoubleAttr.X) > 0) this.selectedLocations.add(var.get(GRB.StringAttr.VarName)); } lb = LR_Main.obtainLB(OP, SP); LR_Main.updateLB(lb.value); k++; // Counter update updateGap(); updateBestResult(this.lb, this.UB, this.Us, this.selectedLocations); System.out.println( "miu: " + miu + " - Itr" + k + ": LB=" + lb.value + " - UB= " + UB + " - gap= " + this.gap + " - eps= " + LR_Main.epsilon); } updateNode(nodeBestUB, nodesBestLB, nodesBestUs, nodesBestSelectedLocations); } else { this.fathom = true; } // System.out.println("# of constraints: " + SP.get(GRB.IntAttr.NumConstrs)); noOfFixedVars = this.varsFixedTo0.size() + this.varsFixedTo1.size(); }