manbet体育手机客户端


Workforce4.java.


/ *版权所有2019,Gurobi优狗万app足彩化,LLC * / / *分配工人转移;每个工人都可能或可能在特定日期都可以使用。我们使用Pareto优化来解决模型:首先,我们最小化休闲裤的线性总和。然后,我们限制了懈怠的总和,我们最大限度地减少了一个二次目标,试图平衡工人之间的工作量。* /进口gurobi。*;公共类Workforce4 {公共静态void main(String [] args){try {//示例数据//工作者和工人字符串shifts [] = new string [] {“mon1”,“tue2”,“wed3”,“Thu4”,“星期五”,“SAT6”,“Sun7”,“Mon8”,“Tue9”,“Wed10”,“星期三”,“星期五”,“星期五”,“SAT13”,“Sun14”};字符串工人[] =新字符串[] {“amy”,“bob”,“cathy”,“丹”,“ed”,“fred”,“gu”};int nshifts = shifts.length;int nworkers = workers.length; // Number of workers required for each shift double shiftRequirements[] = new double[] { 3, 2, 4, 4, 5, 6, 5, 2, 2, 3, 4, 6, 7, 5 }; // Worker availability: 0 if the worker is unavailable for a shift double availability[][] = new double[][] { { 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1 }, { 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0 }, { 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 }, { 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 }, { 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1 }, { 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1 }, { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } }; // Model GRBEnv env = new GRBEnv(); GRBModel model = new GRBModel(env); model.set(GRB.StringAttr.ModelName, "assignment"); // Assignment variables: x[w][s] == 1 if worker w is assigned // to shift s. This is no longer a pure assignment model, so we must // use binary variables. GRBVar[][] x = new GRBVar[nWorkers][nShifts]; for (int w = 0; w < nWorkers; ++w) { for (int s = 0; s < nShifts; ++s) { x[w][s] = model.addVar(0, availability[w][s], 0, GRB.BINARY, Workers[w] + "." + Shifts[s]); } } // Slack variables for each shift constraint so that the shifts can // be satisfied GRBVar[] slacks = new GRBVar[nShifts]; for (int s = 0; s < nShifts; ++s) { slacks[s] = model.addVar(0, GRB.INFINITY, 0, GRB.CONTINUOUS, Shifts[s] + "Slack"); } // Variable to represent the total slack GRBVar totSlack = model.addVar(0, GRB.INFINITY, 0, GRB.CONTINUOUS, "totSlack"); // Variables to count the total shifts worked by each worker GRBVar[] totShifts = new GRBVar[nWorkers]; for (int w = 0; w < nWorkers; ++w) { totShifts[w] = model.addVar(0, GRB.INFINITY, 0, GRB.CONTINUOUS, Workers[w] + "TotShifts"); } GRBLinExpr lhs; // Constraint: assign exactly shiftRequirements[s] workers // to each shift s, plus the slack for (int s = 0; s < nShifts; ++s) { lhs = new GRBLinExpr(); lhs.addTerm(1.0, slacks[s]); for (int w = 0; w < nWorkers; ++w) { lhs.addTerm(1.0, x[w][s]); } model.addConstr(lhs, GRB.EQUAL, shiftRequirements[s], Shifts[s]); } // Constraint: set totSlack equal to the total slack lhs = new GRBLinExpr(); lhs.addTerm(-1.0, totSlack); for (int s = 0; s < nShifts; ++s) { lhs.addTerm(1.0, slacks[s]); } model.addConstr(lhs, GRB.EQUAL, 0, "totSlack"); // Constraint: compute the total number of shifts for each worker for (int w = 0; w < nWorkers; ++w) { lhs = new GRBLinExpr(); lhs.addTerm(-1.0, totShifts[w]); for (int s = 0; s < nShifts; ++s) { lhs.addTerm(1.0, x[w][s]); } model.addConstr(lhs, GRB.EQUAL, 0, "totShifts" + Workers[w]); } // Objective: minimize the total slack GRBLinExpr obj = new GRBLinExpr(); obj.addTerm(1.0, totSlack); model.setObjective(obj); // Optimize int status = solveAndPrint(model, totSlack, nWorkers, Workers, totShifts); if (status != GRB.Status.OPTIMAL ) { return; } // Constrain the slack by setting its upper and lower bounds totSlack.set(GRB.DoubleAttr.UB, totSlack.get(GRB.DoubleAttr.X)); totSlack.set(GRB.DoubleAttr.LB, totSlack.get(GRB.DoubleAttr.X)); // Variable to count the average number of shifts worked GRBVar avgShifts = model.addVar(0, GRB.INFINITY, 0, GRB.CONTINUOUS, "avgShifts"); // Variables to count the difference from average for each worker; // note that these variables can take negative values. GRBVar[] diffShifts = new GRBVar[nWorkers]; for (int w = 0; w < nWorkers; ++w) { diffShifts[w] = model.addVar(-GRB.INFINITY, GRB.INFINITY, 0, GRB.CONTINUOUS, Workers[w] + "Diff"); } // Constraint: compute the average number of shifts worked lhs = new GRBLinExpr(); lhs.addTerm(-nWorkers, avgShifts); for (int w = 0; w < nWorkers; ++w) { lhs.addTerm(1.0, totShifts[w]); } model.addConstr(lhs, GRB.EQUAL, 0, "avgShifts"); // Constraint: compute the difference from the average number of shifts for (int w = 0; w < nWorkers; ++w) { lhs = new GRBLinExpr(); lhs.addTerm(-1, diffShifts[w]); lhs.addTerm(-1, avgShifts); lhs.addTerm( 1, totShifts[w]); model.addConstr(lhs, GRB.EQUAL, 0, Workers[w] + "Diff"); } // Objective: minimize the sum of the square of the difference from the // average number of shifts worked GRBQuadExpr qobj = new GRBQuadExpr(); for (int w = 0; w < nWorkers; ++w) { qobj.addTerm(1.0, diffShifts[w], diffShifts[w]); } model.setObjective(qobj); // Optimize status = solveAndPrint(model, totSlack, nWorkers, Workers, totShifts); if (status != GRB.Status.OPTIMAL ) { return; } // Dispose of model and environment model.dispose(); env.dispose(); } catch (GRBException e) { System.out.println("Error code: " + e.getErrorCode() + ". " + e.getMessage()); } } private static int solveAndPrint(GRBModel model, GRBVar totSlack, int nWorkers, String[] Workers, GRBVar[] totShifts) throws GRBException { model.optimize(); int status = model.get(GRB.IntAttr.Status); if (status == GRB.Status.INF_OR_UNBD || status == GRB.Status.INFEASIBLE || status == GRB.Status.UNBOUNDED ) { System.out.println("The model cannot be solved " + "because it is infeasible or unbounded"); return status; } if (status != GRB.Status.OPTIMAL ) { System.out.println("Optimization was stopped with status " + status); return status; } // Print total slack and the number of shifts worked for each worker System.out.println("\nTotal slack required: " + totSlack.get(GRB.DoubleAttr.X)); for (int w = 0; w < nWorkers; ++w) { System.out.println(Workers[w] + " worked " + totShifts[w].get(GRB.DoubleAttr.X) + " shifts"); } System.out.println("\n"); return status; } }