/// <summary> /// Indicates whether a solution was found. /// </summary> /// <returns><code>true</code> if a solution was found, <code>false</code> otherwise.</returns> public bool HasSolution() { switch (Type) { case SolverType.CPLEX: if ((CplexModel.IsMIP()) ? CplexModel.SolnPoolNsolns > 0 : (CplexModel.GetStatus() == ILOG.CPLEX.Cplex.Status.Optimal)) { return(true); } else { return(false); } case SolverType.Gurobi: if (GurobiModel.Get(GRB.IntAttr.SolCount) > 0) { return(true); } else { return(false); } default: throw new ArgumentException("Unknown solver type: " + Type); } }
private static void PrintSolution(GRBModel model, GRBVar[] buy, GRBVar[] nutrition) { if (model.Get(GRB.IntAttr.Status) == GRB.Status.OPTIMAL) { Console.WriteLine("\nCost: " + model.Get(GRB.DoubleAttr.ObjVal)); Console.WriteLine("\nBuy:"); for (int j = 0; j < buy.Length; ++j) { if (buy[j].Get(GRB.DoubleAttr.X) > 0.0001) { Console.WriteLine(buy[j].Get(GRB.StringAttr.VarName) + " " + buy[j].Get(GRB.DoubleAttr.X)); } } Console.WriteLine("\nNutrition:"); for (int i = 0; i < nutrition.Length; ++i) { Console.WriteLine(nutrition[i].Get(GRB.StringAttr.VarName) + " " + nutrition[i].Get(GRB.DoubleAttr.X)); } } else { Console.WriteLine("No solution"); } }
bool SolveMaster() { _grbModel.Optimize(); int status = _grbModel.Get(GRB.IntAttr.Status); int solution = _grbModel.Get(GRB.IntAttr.SolCount); if (status == GRB.Status.OPTIMAL || (status == GRB.Status.TIME_LIMIT && solution > 0)) { foreach (Node n in Data.NodeSet) { GRBConstr constr = _grbModel.GetConstrByName("ct1_" + n.ID); Dual[n] = constr.Get(GRB.DoubleAttr.Pi); n.ParseSolution(2); n.ParseSolution(1); } foreach (Arc a in Data.ArcSet) { a.ParseSolution(); } double k0 = _grbModel.GetVarByName("k_0").Get(GRB.DoubleAttr.X); double k1 = _grbModel.GetVarByName("k_1").Get(GRB.DoubleAttr.X); return(true); } else { return(false); } }
public void Optimize() { Data = new DataStructure(); Data.LoadData(); //生成乘子 foreach (Node n in Data.NodeSet) { multiplier_p.Add(n, 0); } for (int i = 1; i <= IterationTimes; i++) { double LB = 0; BuildModel_SubProblem1(); if (Solve()) { ParseSolution_SubProblem1(); LB += _grbModel.Get(GRB.DoubleAttr.ObjVal); } _grbModel.Dispose(); _env.Dispose(); BuildModel_SubProblem2(); if (Solve()) { ParseSolution_SubProblem2(); LB += _grbModel.Get(GRB.DoubleAttr.ObjVal); } _grbModel.Dispose(); _env.Dispose(); UpdateMultiplier(i); BuildFeasibleSolutionModel(); if (Solve()) { ParseSolution_SubProblem2(); StreamWriter sw = File.AppendText("solution.csv"); sw.Write("{0},{1},{2}", i, _grbModel.Get(GRB.DoubleAttr.ObjVal), LB); sw.WriteLine(); sw.Close(); } else { StreamWriter sw = File.AppendText("solution.csv"); sw.Write("{0},{1},{2}", i, "infeasible", LB); sw.WriteLine(); sw.Close(); } _grbModel.Dispose(); _env.Dispose(); } ParseSolution(); }
public static Status GetResultStatus(this GRBModel model) { if (model.Get(GRB.IntAttr.SolCount) <= 0) { return(model.Get(GRB.IntAttr.Status) == GRB.Status.INFEASIBLE ? Status.Infeasible : Status.NoSolution); } else { return(model.Get(GRB.IntAttr.Status) == GRB.Status.OPTIMAL ? Status.Optimal : Status.Heuristic); } }
// Simple function to determine the MIP gap private static double Gap(GRBModel model) { if ((model.Get(GRB.IntAttr.SolCount) == 0) || (Math.Abs(model.Get(GRB.DoubleAttr.ObjVal)) < 1e-6)) { return(GRB.INFINITY); } return(Math.Abs(model.Get(GRB.DoubleAttr.ObjBound) - model.Get(GRB.DoubleAttr.ObjVal)) / Math.Abs(model.Get(GRB.DoubleAttr.ObjVal))); }
static void Main(string[] args) { if (args.Length < 1) { Console.Out.WriteLine("Usage: lp_cs filename"); return; } try { GRBEnv env = new GRBEnv(); GRBModel model = new GRBModel(env, args[0]); model.Optimize(); int optimstatus = model.Get(GRB.IntAttr.Status); if (optimstatus == GRB.Status.INF_OR_UNBD) { model.GetEnv().Set(GRB.IntParam.Presolve, 0); model.Optimize(); optimstatus = model.Get(GRB.IntAttr.Status); } if (optimstatus == GRB.Status.OPTIMAL) { double objval = model.Get(GRB.DoubleAttr.ObjVal); Console.WriteLine("Optimal objective: " + objval); } else if (optimstatus == GRB.Status.INFEASIBLE) { Console.WriteLine("Model is infeasible"); // compute and write out IIS model.ComputeIIS(); model.Write("model.ilp"); } else if (optimstatus == GRB.Status.UNBOUNDED) { Console.WriteLine("Model is unbounded"); } else { Console.WriteLine("Optimization was stopped with status = " + optimstatus); } // Dispose of model and env model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } }
private void PrintSolution() { if (model.Get(GRB.IntAttr.Status) == GRB.Status.OPTIMAL) { _writer.WriteLine("\nCost: " + model.Get(GRB.DoubleAttr.ObjVal)); DietLpProblem.WriteDecisionVaribleValues(_writer); } else { _writer.WriteLine("No solution"); } }
static void Main(string[] args) { if (args.Length < 1) { Console.Out.WriteLine("Usage: lpmethod_cs filename"); return; } try { // Read model GRBEnv env = new GRBEnv(); GRBModel model = new GRBModel(env, args[0]); GRBEnv menv = model.GetEnv(); // Solve the model with different values of Method int bestMethod = -1; double bestTime = menv.Get(GRB.DoubleParam.TimeLimit); for (int i = 0; i <= 2; ++i) { model.Reset(); menv.Set(GRB.IntParam.Method, i); model.Optimize(); if (model.Get(GRB.IntAttr.Status) == GRB.Status.OPTIMAL) { bestTime = model.Get(GRB.DoubleAttr.Runtime); bestMethod = i; // Reduce the TimeLimit parameter to save time // with other methods menv.Set(GRB.DoubleParam.TimeLimit, bestTime); } } // Report which method was fastest if (bestMethod == -1) { Console.WriteLine("Unable to solve this model"); } else { Console.WriteLine("Solved in " + bestTime + " seconds with Method: " + bestMethod); } // Dispose of model and env model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } }
public OptimizationResults GetQuantities(IEnumerable <MenuItem> items, double totalPrice) { CreateVariables(items); CreateConstraints(totalPrice, items); CreateObjective(items); _model.Optimize(); var results = new OptimizationResults(); results.Items = _model.Get(GRB.DoubleAttr.X, _v).ToIntArray(); results.ObjectiveValue = _model.Get(GRB.DoubleAttr.ObjVal); return(results); }
// This method will work irrespective of the size of the solution space public ProductionTarget GetTargets(double claySupply, double glazeSupply) { GRBEnv env = new GRBEnv(); GRBModel model = new GRBModel(env); GRBVar xS = CreateSmallVasesVariable(claySupply, model); GRBVar xL = CreateLargeVasesVariable(glazeSupply, model); model.Update(); // Create Constraints CreateConstraints(model, xS, xL, claySupply, glazeSupply); // Define Objective model.SetObjective(3 * xS + 9 * xL, GRB.MAXIMIZE); // Find the optimum model.Optimize(); // Load the results var results = model.Get(GRB.DoubleAttr.X, new GRBVar[] { xS, xL }); return(new Entities.ProductionTarget() { Small = Convert.ToInt32(results[0]), Large = Convert.ToInt32(results[1]) }); }
private static int solveAndPrint(GRBModel model, GRBVar totSlack, int nWorkers, String[] Workers, GRBVar[] totShifts) { model.Optimize(); int status = model.Get(GRB.IntAttr.Status); if ((status == GRB.Status.INF_OR_UNBD) || (status == GRB.Status.INFEASIBLE) || (status == GRB.Status.UNBOUNDED)) { Console.WriteLine("The model cannot be solved " + "because it is infeasible or unbounded"); return(status); } if (status != GRB.Status.OPTIMAL) { Console.WriteLine("Optimization was stopped with status " + status); return(status); } // Print total slack and the number of shifts worked for each worker Console.WriteLine("\nTotal slack required: " + totSlack.Get(GRB.DoubleAttr.X)); for (int w = 0; w < nWorkers; ++w) { Console.WriteLine(Workers[w] + " worked " + totShifts[w].Get(GRB.DoubleAttr.X) + " shifts"); } Console.WriteLine("\n"); return(status); }
bool Solve() { _grbModel.Write("OrgModel.lp"); _grbModel.Optimize(); int status = _grbModel.Get(GRB.IntAttr.Status); int solution = _grbModel.Get(GRB.IntAttr.SolCount); if (status == GRB.Status.OPTIMAL || (status == GRB.Status.TIME_LIMIT && solution > 0)) { return(true); } else { return(false); } }
private void ChangeNBreaksGurobi(GRBModel pModel, GRBLinExpr pTotalStepsConst, GRBVar[] pDecVar, int intNClasses, int intNFeatures) { try { Cs = new double[intNClasses + 1]; cbIdx = new int[intNClasses + 1]; // For Graph int intNDecVar = (intNFeatures * (intNFeatures + 1)) / 2; // Add L0_0 pModel.Remove(pModel.GetConstrByName("Nsteps")); pModel.AddConstr(pTotalStepsConst, GRB.EQUAL, intNClasses, "Nsteps"); //Solving pModel.Optimize(); //Add Results to CS array Cs[0] = arrEst[0]; //Estimate Array was sorted int intIdxCs = 0; if (pModel.Get(GRB.IntAttr.Status) == GRB.Status.OPTIMAL) { for (int i = 0; i < intNDecVar; i++) { if (pDecVar[i].Get(GRB.DoubleAttr.X) == 1) { intIdxCs++; string strName = pDecVar[i].Get(GRB.StringAttr.VarName); int intIndexUBar = strName.IndexOf("_"); string strTo = strName.Substring(intIndexUBar + 1); int intToValue = Convert.ToInt16(strTo); Cs[intIdxCs] = arrEst[intToValue - 1]; //Closed cbIdx[intIdxCs] = intToValue - 1; } } } txtObjValue.Text = pModel.Get(GRB.DoubleAttr.ObjVal).ToString("N5"); } catch (Exception ex) { MessageBox.Show(this.Handle.ToString() + " Error:" + ex.Message); return; } }
static void Main() { try { GRBEnv env = new GRBEnv("qcp.log"); GRBModel model = new GRBModel(env); // Create variables GRBVar x = model.AddVar(0.0, GRB.INFINITY, 0.0, GRB.CONTINUOUS, "x"); GRBVar y = model.AddVar(0.0, GRB.INFINITY, 0.0, GRB.CONTINUOUS, "y"); GRBVar z = model.AddVar(0.0, GRB.INFINITY, 0.0, GRB.CONTINUOUS, "z"); // Integrate new variables model.Update(); // Set objective GRBLinExpr obj = x; model.SetObjective(obj, GRB.MAXIMIZE); // Add linear constraint: x + y + z = 1 model.AddConstr(x + y + z == 1.0, "c0"); // Add second-order cone: x^2 + y^2 <= z^2 model.AddQConstr(x * x + y * y <= z * z, "qc0"); // Add rotated cone: x^2 <= yz model.AddQConstr(x * x <= y * z, "qc1"); // Optimize model model.Optimize(); Console.WriteLine(x.Get(GRB.StringAttr.VarName) + " " + x.Get(GRB.DoubleAttr.X)); Console.WriteLine(y.Get(GRB.StringAttr.VarName) + " " + y.Get(GRB.DoubleAttr.X)); Console.WriteLine(z.Get(GRB.StringAttr.VarName) + " " + z.Get(GRB.DoubleAttr.X)); Console.WriteLine("Obj: " + model.Get(GRB.DoubleAttr.ObjVal) + " " + obj.Value); // Dispose of model and env model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } }
static void Main() { try { GRBEnv env = new GRBEnv("mip1.log"); GRBModel model = new GRBModel(env); // Create variables GRBVar x = model.AddVar(0.0, 1.0, 0.0, GRB.BINARY, "x"); GRBVar y = model.AddVar(0.0, 1.0, 0.0, GRB.BINARY, "y"); GRBVar z = model.AddVar(0.0, 1.0, 0.0, GRB.BINARY, "z"); // Integrate new variables model.Update(); // Set objective: maximize x + y + 2 z model.SetObjective(x + y + 2 * z, GRB.MAXIMIZE); // Add constraint: x + 2 y + 3 z <= 4 model.AddConstr(x + 2 * y + 3 * z <= 4.0, "c0"); // Add constraint: x + y >= 1 model.AddConstr(x + y >= 1.0, "c1"); // Optimize model model.Optimize(); Console.WriteLine(x.Get(GRB.StringAttr.VarName) + " " + x.Get(GRB.DoubleAttr.X)); Console.WriteLine(y.Get(GRB.StringAttr.VarName) + " " + y.Get(GRB.DoubleAttr.X)); Console.WriteLine(z.Get(GRB.StringAttr.VarName) + " " + z.Get(GRB.DoubleAttr.X)); Console.WriteLine("Obj: " + model.Get(GRB.DoubleAttr.ObjVal)); // Dispose of model and env model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } }
static void SolveDual(GRBEnv env, HashSet <string> nodes_set, List <Arc> arcs) { GRBModel dual = new GRBModel(env); Star forward_stars = new Star(); Star reverse_stars = new Star(); GetStars(nodes_set, arcs, forward_stars, reverse_stars); Dictionary <Arc, GRBVar> arc_traversed = new Dictionary <Arc, GRBVar>(); foreach (Arc a in arcs) { arc_traversed[a] = dual.AddVar(0, 1, a.length, GRB.CONTINUOUS, "arc_traversed." + a.source + "." + a.dest); } dual.Update(); Dictionary <string, GRBConstr> flow_balance = new Dictionary <string, GRBConstr>(); foreach (string node in nodes_set) { GRBLinExpr lhs = new GRBLinExpr(); List <Arc> forward_star = forward_stars[node]; List <Arc> reverse_star = reverse_stars[node]; Console.WriteLine("node " + node); Console.Write("Forward star: "); foreach (Arc a in forward_star) { Console.Write(a.dest + ' '); // lhs -= arc_traversed[a]; lhs.AddTerm(-1, arc_traversed[a]); } Console.Write("\nReverse star: "); foreach (Arc a in reverse_star) { Console.Write(a.source + ' '); lhs.AddTerm(1, arc_traversed[a]); } Console.WriteLine(""); flow_balance[node] = dual.AddConstr(lhs, 'E', 0, "flow_balance." + node); } dual.Update(); flow_balance[ORIGIN].Set(GRB.DoubleAttr.RHS, -1); flow_balance[DESTINATION].Set(GRB.DoubleAttr.RHS, 1); dual.Optimize(); foreach (var pair in arc_traversed) { Console.WriteLine("Arc {0}:{1} traversed = {2}", pair.Key.source, pair.Key.dest, pair.Value.Get(GRB.DoubleAttr.X)); } Console.WriteLine("length of shortest path = " + dual.Get(GRB.DoubleAttr.ObjVal)); dual.Dispose(); }
static void Main(string[] args) { if (args.Length < 1) { Console.Out.WriteLine("Usage: callback_cs filename"); return; } try { GRBEnv env = new GRBEnv(); GRBModel model = new GRBModel(env, args[0]); GRBVar[] vars = model.GetVars(); // Create a callback object and associate it with the model model.SetCallback(new callback_cs(vars)); model.Optimize(); double[] x = model.Get(GRB.DoubleAttr.X, vars); string[] vnames = model.Get(GRB.StringAttr.VarName, vars); for (int j = 0; j < vars.Length; j++) { if (x[j] != 0.0) { Console.WriteLine(vnames[j] + " " + x[j]); } } // Dispose of model and env model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); Console.WriteLine(e.StackTrace); } }
static void Main(string[] args) { if (args.Length < 1) { Console.Out.WriteLine("Usage: params_cs filename"); return; } try { // Read model and verify that it is a MIP GRBEnv env = new GRBEnv(); GRBModel basemodel = new GRBModel(env, args[0]); if (basemodel.Get(GRB.IntAttr.IsMIP) == 0) { Console.WriteLine("The model is not an integer program"); Environment.Exit(1); } // Set a 5 second time limit basemodel.GetEnv().Set(GRB.DoubleParam.TimeLimit, 5); // Now solve the model with different values of MIPFocus double bestGap = GRB.INFINITY; GRBModel bestModel = null; for (int i = 0; i <= 3; ++i) { GRBModel m = new GRBModel(basemodel); m.GetEnv().Set(GRB.IntParam.MIPFocus, i); m.Optimize(); if (bestModel == null || bestGap > Gap(m)) { bestModel = m; bestGap = Gap(bestModel); } } // Finally, reset the time limit and continue to solve the // best model to optimality bestModel.GetEnv().Set(GRB.DoubleParam.TimeLimit, GRB.INFINITY); bestModel.Optimize(); Console.WriteLine("Solved with MIPFocus: " + bestModel.GetEnv().Get(GRB.IntParam.MIPFocus)); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } }
static void SolvePrimal(GRBEnv env, HashSet <string> nodes_set, List <Arc> arcs) { GRBModel m = new GRBModel(env); Dictionary <string, GRBVar> distances = new Dictionary <string, GRBVar>(); // pi foreach (string node in nodes_set) { distances[node] = m.AddVar(0, GRB.INFINITY, 0, GRB.CONTINUOUS, "distance." + node); } m.Update(); distances[ORIGIN].Set(GRB.DoubleAttr.Obj, -1); distances[DESTINATION].Set(GRB.DoubleAttr.Obj, 1); m.Set(GRB.IntAttr.ModelSense, -1); Dictionary <Arc, GRBConstr> constrs = new Dictionary <Arc, GRBConstr>(); foreach (Arc a in arcs) { constrs[a] = m.AddConstr(distances[a.dest] <= distances[a.source] + a.length, "distance_con." + a.source + "." + a.dest); } m.Update(); m.Write("shortest_path.lp"); m.Optimize(); foreach (var pair in distances) { Console.WriteLine("distance to {0} is {1}", pair.Key, pair.Value.Get(GRB.DoubleAttr.X)); } foreach (var pair in constrs) { GRBConstr con = pair.Value; if (con.Get(GRB.DoubleAttr.Pi) > 0.5) { Console.WriteLine("Arc {0}, {1} is in shortest path", pair.Key.source, pair.Key.dest); } } Console.WriteLine("Length of shortest path is {0}", m.Get(GRB.DoubleAttr.ObjVal)); m.Dispose(); }
static void Main(string[] args) { if (args.Length < 1) { Console.Out.WriteLine("Usage: tune_cs filename"); return; } try { GRBEnv env = new GRBEnv(); // Read model from file GRBModel model = new GRBModel(env, args[0]); // Set the TuneResults parameter to 1 model.GetEnv().Set(GRB.IntParam.TuneResults, 1); // Tune the model model.Tune(); // Get the number of tuning results int resultcount = model.Get(GRB.IntAttr.TuneResultCount); if (resultcount > 0) { // Load the tuned parameters into the model's environment model.GetTuneResult(0); // Write the tuned parameters to a file model.Write("tune.prm"); // Solve the model using the tuned parameters model.Optimize(); } // Dispose of model and environment model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } }
public void Optimize(double timelimit = GRB.INFINITY, double mipGap = 0.00) { _model.GetEnv().Set(GRB.DoubleParam.TimeLimit, timelimit); _model.GetEnv().Set(GRB.DoubleParam.MIPGap, mipGap); _model.Optimize(); if (_model.Get(GRB.IntAttr.Status) == GRB.Status.INFEASIBLE) { _model.ComputeIIS(); Console.WriteLine("\nThe following constraints cannot be satisfied:"); foreach (GRBConstr c in _model.GetConstrs()) { if (c.Get(GRB.IntAttr.IISConstr) == 1) { Console.WriteLine(c.Get(GRB.StringAttr.ConstrName)); // Remove a single constraint from the model } } throw new Exception("Infeasible"); } }
static void Main(string[] args) { if (args.Length < 1) { Console.Out.WriteLine("Usage: fixanddive_cs filename"); return; } try { // Read model GRBEnv env = new GRBEnv(); GRBModel model = new GRBModel(env, args[0]); // Collect integer variables and relax them List <GRBVar> intvars = new List <GRBVar>(); foreach (GRBVar v in model.GetVars()) { if (v.Get(GRB.CharAttr.VType) != GRB.CONTINUOUS) { intvars.Add(v); v.Set(GRB.CharAttr.VType, GRB.CONTINUOUS); } } model.GetEnv().Set(GRB.IntParam.OutputFlag, 0); model.Optimize(); // Perform multiple iterations. In each iteration, identify the first // quartile of integer variables that are closest to an integer value // in the relaxation, fix them to the nearest integer, and repeat. for (int iter = 0; iter < 1000; ++iter) { // create a list of fractional variables, sorted in order of // increasing distance from the relaxation solution to the nearest // integer value List <GRBVar> fractional = new List <GRBVar>(); foreach (GRBVar v in intvars) { double sol = Math.Abs(v.Get(GRB.DoubleAttr.X)); if (Math.Abs(sol - Math.Floor(sol + 0.5)) > 1e-5) { fractional.Add(v); } } Console.WriteLine("Iteration " + iter + ", obj " + model.Get(GRB.DoubleAttr.ObjVal) + ", fractional " + fractional.Count); if (fractional.Count == 0) { Console.WriteLine("Found feasible solution - objective " + model.Get(GRB.DoubleAttr.ObjVal)); break; } // Fix the first quartile to the nearest integer value fractional.Sort(new FractionalCompare()); int nfix = Math.Max(fractional.Count / 4, 1); for (int i = 0; i < nfix; ++i) { GRBVar v = fractional[i]; double fixval = Math.Floor(v.Get(GRB.DoubleAttr.X) + 0.5); v.Set(GRB.DoubleAttr.LB, fixval); v.Set(GRB.DoubleAttr.UB, fixval); Console.WriteLine(" Fix " + v.Get(GRB.StringAttr.VarName) + " to " + fixval + " ( rel " + v.Get(GRB.DoubleAttr.X) + " )"); } model.Optimize(); // Check optimization result if (model.Get(GRB.IntAttr.Status) != GRB.Status.OPTIMAL) { Console.WriteLine("Relaxation is infeasible"); break; } } // Dispose of model and env model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } }
public static void Main(String[] args) { if (args.Length < 1) { Console.WriteLine("Usage: tsp_cs nnodes"); return; } int n = Convert.ToInt32(args[0]); try { GRBEnv env = new GRBEnv(); GRBModel model = new GRBModel(env); // Must set LazyConstraints parameter when using lazy constraints model.Parameters.LazyConstraints = 1; double[] x = new double[n]; double[] y = new double[n]; Random r = new Random(); for (int i = 0; i < n; i++) { x[i] = r.NextDouble(); y[i] = r.NextDouble(); } // Create variables GRBVar[,] vars = new GRBVar[n, n]; for (int i = 0; i < n; i++) { for (int j = 0; j <= i; j++) { vars[i, j] = model.AddVar(0.0, 1.0, distance(x, y, i, j), GRB.BINARY, "x" + i + "_" + j); vars[j, i] = vars[i, j]; } } // Degree-2 constraints for (int i = 0; i < n; i++) { GRBLinExpr expr = 0; for (int j = 0; j < n; j++) { expr.AddTerm(1.0, vars[i, j]); } model.AddConstr(expr == 2.0, "deg2_" + i); } // Forbid edge from node back to itself for (int i = 0; i < n; i++) { vars[i, i].UB = 0.0; } model.SetCallback(new tsp_cs(vars)); model.Optimize(); if (model.SolCount > 0) { int[] tour = findsubtour(model.Get(GRB.DoubleAttr.X, vars)); Console.Write("Tour: "); for (int i = 0; i < tour.Length; i++) { Console.Write(tour[i] + " "); } Console.WriteLine(); } // Dispose of model and environment model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); Console.WriteLine(e.StackTrace); } }
static void Main(string[] args) { int n = 9; int s = 3; if (args.Length < 1) { Console.Out.WriteLine("Usage: sudoku_cs filename"); return; } try { GRBEnv env = new GRBEnv(); GRBModel model = new GRBModel(env); // Create 3-D array of model variables GRBVar[,,] vars = new GRBVar[n,n,n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { for (int v = 0; v < n; v++) { string st = "G_" + i.ToString() + "_" + j.ToString() + "_" + v.ToString(); vars[i,j,v] = model.AddVar(0.0, 1.0, 0.0, GRB.BINARY, st); } } } // Integrate variables into model model.Update(); // Add constraints GRBLinExpr expr; // Each cell must take one value for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { expr = 0.0; for (int v = 0; v < n; v++) expr += vars[i,j,v]; string st = "V_" + i.ToString() + "_" + j.ToString(); model.AddConstr(expr == 1.0, st); } } // Each value appears once per row for (int i = 0; i < n; i++) { for (int v = 0; v < n; v++) { expr = 0.0; for (int j = 0; j < n; j++) expr += vars[i,j,v]; string st = "R_" + i.ToString() + "_" + v.ToString(); model.AddConstr(expr == 1.0, st); } } // Each value appears once per column for (int j = 0; j < n; j++) { for (int v = 0; v < n; v++) { expr = 0.0; for (int i = 0; i < n; i++) expr += vars[i,j,v]; string st = "C_" + j.ToString() + "_" + v.ToString(); model.AddConstr(expr == 1.0, st); } } // Each value appears once per sub-grid for (int v = 0; v < n; v++) { for (int i0 = 0; i0 < s; i0++) { for (int j0 = 0; j0 < s; j0++) { expr = 0.0; for (int i1 = 0; i1 < s; i1++) { for (int j1 = 0; j1 < s; j1++) { expr += vars[i0*s+i1,j0*s+j1,v]; } } string st = "Sub_" + v.ToString() + "_" + i0.ToString() + "_" + j0.ToString(); model.AddConstr(expr == 1.0, st); } } } // Update model model.Update(); // Fix variables associated with pre-specified cells StreamReader sr = File.OpenText(args[0]); for (int i = 0; i < n; i++) { string input = sr.ReadLine(); for (int j = 0; j < n; j++) { int val = (int) input[j] - 48 - 1; // 0-based if (val >= 0) vars[i,j,val].Set(GRB.DoubleAttr.LB, 1.0); } } // Optimize model model.Optimize(); // Write model to file model.Write("sudoku.lp"); double[,,] x = model.Get(GRB.DoubleAttr.X, vars); Console.WriteLine(); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { for (int v = 0; v < n; v++) { if (x[i,j,v] > 0.5) { Console.Write(v+1); } } } Console.WriteLine(); } // Dispose of model and env model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } }
static void Main(string[] args) { if (args.Length < 1) { Console.Out.WriteLine("Usage: sensitivity_cs filename"); return; } try { // Read model GRBEnv env = new GRBEnv(); GRBModel a = new GRBModel(env, args[0]); a.Optimize(); a.GetEnv().Set(GRB.IntParam.OutputFlag, 0); // Extract variables from model GRBVar[] avars = a.GetVars(); for (int i = 0; i < avars.Length; ++i) { GRBVar v = avars[i]; if (v.Get(GRB.CharAttr.VType) == GRB.BINARY) { // Create clone and fix variable GRBModel b = new GRBModel(a); GRBVar bv = b.GetVars()[i]; if (v.Get(GRB.DoubleAttr.X) - v.Get(GRB.DoubleAttr.LB) < 0.5) { bv.Set(GRB.DoubleAttr.LB, bv.Get(GRB.DoubleAttr.UB)); } else { bv.Set(GRB.DoubleAttr.UB, bv.Get(GRB.DoubleAttr.LB)); } b.Optimize(); if (b.Get(GRB.IntAttr.Status) == GRB.Status.OPTIMAL) { double objchg = b.Get(GRB.DoubleAttr.ObjVal) - a.Get(GRB.DoubleAttr.ObjVal); if (objchg < 0) { objchg = 0; } Console.WriteLine("Objective sensitivity for variable " + v.Get(GRB.StringAttr.VarName) + " is " + objchg); } else { Console.WriteLine("Objective sensitivity for variable " + v.Get(GRB.StringAttr.VarName) + " is infinite"); } // Dispose of model b.Dispose(); } } // Dispose of model and env a.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } }
static void Main(string[] args) { if (args.Length < 1) { Console.Out.WriteLine("Usage: callback_cs filename"); return; } StreamWriter logfile = null; try { // Create environment GRBEnv env = new GRBEnv(); // Read model from file GRBModel model = new GRBModel(env, args[0]); // Turn off display and heuristics model.Parameters.OutputFlag = 0; model.Parameters.Heuristics = 0.0; // Open log file logfile = new StreamWriter("cb.log"); // Create a callback object and associate it with the model GRBVar[] vars = model.GetVars(); callback_cs cb = new callback_cs(vars, logfile); model.SetCallback(cb); // Solve model and capture solution information model.Optimize(); Console.WriteLine(""); Console.WriteLine("Optimization complete"); if (model.SolCount == 0) { Console.WriteLine("No solution found, optimization status = " + model.Status); } else { Console.WriteLine("Solution found, objective = " + model.ObjVal); string[] vnames = model.Get(GRB.StringAttr.VarName, vars); double[] x = model.Get(GRB.DoubleAttr.X, vars); for (int j = 0; j < vars.Length; j++) { if (x[j] != 0.0) { Console.WriteLine(vnames[j] + " " + x[j]); } } } // Dispose of model and environment model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode); Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); } catch (Exception e) { Console.WriteLine("Error during optimization"); Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); } finally { // Close log file if (logfile != null) { logfile.Close(); } } }
static void Main() { try { GRBEnv env = new GRBEnv("qp.log"); GRBModel model = new GRBModel(env); // Create variables GRBVar x = model.AddVar(0.0, 1.0, 0.0, GRB.CONTINUOUS, "x"); GRBVar y = model.AddVar(0.0, 1.0, 0.0, GRB.CONTINUOUS, "y"); GRBVar z = model.AddVar(0.0, 1.0, 0.0, GRB.CONTINUOUS, "z"); // Integrate new variables model.Update(); // Set objective GRBQuadExpr obj = x*x + x*y + y*y + y*z + z*z; model.SetObjective(obj); // Add constraint: x + 2 y + 3 z >= 4 model.AddConstr(x + 2 * y + 3 * z >= 4.0, "c0"); // Add constraint: x + y >= 1 model.AddConstr(x + y >= 1.0, "c1"); // Optimize model model.Optimize(); Console.WriteLine(x.Get(GRB.StringAttr.VarName) + " " + x.Get(GRB.DoubleAttr.X)); Console.WriteLine(y.Get(GRB.StringAttr.VarName) + " " + y.Get(GRB.DoubleAttr.X)); Console.WriteLine(z.Get(GRB.StringAttr.VarName) + " " + z.Get(GRB.DoubleAttr.X)); Console.WriteLine("Obj: " + model.Get(GRB.DoubleAttr.ObjVal) + " " + obj.Value); // Change variable types to integer x.Set(GRB.CharAttr.VType, GRB.INTEGER); y.Set(GRB.CharAttr.VType, GRB.INTEGER); z.Set(GRB.CharAttr.VType, GRB.INTEGER); // Optimize model model.Optimize(); Console.WriteLine(x.Get(GRB.StringAttr.VarName) + " " + x.Get(GRB.DoubleAttr.X)); Console.WriteLine(y.Get(GRB.StringAttr.VarName) + " " + y.Get(GRB.DoubleAttr.X)); Console.WriteLine(z.Get(GRB.StringAttr.VarName) + " " + z.Get(GRB.DoubleAttr.X)); Console.WriteLine("Obj: " + model.Get(GRB.DoubleAttr.ObjVal) + " " + obj.Value); // Dispose of model and env model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } }
public static void Main(String[] args) { if (args.Length < 1) { Console.WriteLine("Usage: tsp_cs nnodes"); return; } int n = Convert.ToInt32(args[0]); try { GRBEnv env = new GRBEnv(); GRBModel model = new GRBModel(env); // Must disable dual reductions when using lazy constraints model.GetEnv().Set(GRB.IntParam.DualReductions, 0); double[] x = new double[n]; double[] y = new double[n]; Random r = new Random(); for (int i = 0; i < n; i++) { x[i] = r.NextDouble(); y[i] = r.NextDouble(); } // Create variables GRBVar[,] vars = new GRBVar[n, n]; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) vars[i, j] = model.AddVar(0.0, 1.0, distance(x, y, i, j), GRB.BINARY, "x"+i+"_"+j); // Integrate variables model.Update(); // Degree-2 constraints for (int i = 0; i < n; i++) { GRBLinExpr expr = 0; for (int j = 0; j < n; j++) expr += vars[i, j]; model.AddConstr(expr == 2.0, "deg2_"+i); } // Forbid edge from node back to itself for (int i = 0; i < n; i++) vars[i, i].Set(GRB.DoubleAttr.UB, 0.0); // Symmetric TSP for (int i = 0; i < n; i++) for (int j = 0; j < i; j++) model.AddConstr(vars[i, j]== vars[j, i], ""); model.SetCallback(new tsp_cs(vars)); model.Optimize(); if (model.Get(GRB.IntAttr.SolCount) > 0) { int[] tour = findsubtour(model.Get(GRB.DoubleAttr.X, vars)); Console.Write("Tour: "); for (int i = 0; i < tour.Length; i++) Console.Write(tour[i] + " "); Console.WriteLine(); } // Dispose of model and environment model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); Console.WriteLine(e.StackTrace); } }
static void Main(string[] args) { if (args.Length < 1) { Console.Out.WriteLine("Usage: callback_cs filename"); return; } try { GRBEnv env = new GRBEnv(); GRBModel model = new GRBModel(env, args[0]); GRBVar[] vars = model.GetVars(); model.SetCallback(new callback_cs(vars)); model.Optimize(); double[] x = model.Get(GRB.DoubleAttr.X, vars); string[] vnames = model.Get(GRB.StringAttr.VarName, vars); for (int j = 0; j < vars.Length; j++) { if (x[j] != 0.0) Console.WriteLine(vnames[j] + " " + x[j]); } for (int j = 0; j < vars.Length; j++) { if (x[j] != 0.0) Console.WriteLine(vnames[j] + " " + x[j]); } // Dispose of model and env model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); Console.WriteLine(e.StackTrace); } }
protected static bool dense_optimize(GRBEnv env, int rows, int cols, double[] c, // linear portion of objective function double[,] Q, // quadratic portion of objective function double[,] A, // constraint matrix char[] sense, // constraint senses double[] rhs, // RHS vector double[] lb, // variable lower bounds double[] ub, // variable upper bounds char[] vtype, // variable types (continuous, binary, etc.) double[] solution) { bool success = false; try { GRBModel model = new GRBModel(env); // Add variables to the model GRBVar[] vars = model.AddVars(lb, ub, null, vtype, null); model.Update(); // Populate A matrix for (int i = 0; i < rows; i++) { GRBLinExpr expr = new GRBLinExpr(); for (int j = 0; j < cols; j++) if (A[i,j] != 0) expr.AddTerm(A[i,j], vars[j]); // Note: '+=' would be much slower model.AddConstr(expr, sense[i], rhs[i], ""); } // Populate objective GRBQuadExpr obj = new GRBQuadExpr(); if (Q != null) { for (int i = 0; i < cols; i++) for (int j = 0; j < cols; j++) if (Q[i,j] != 0) obj.AddTerm(Q[i,j], vars[i], vars[j]); // Note: '+=' would be much slower for (int j = 0; j < cols; j++) if (c[j] != 0) obj.AddTerm(c[j], vars[j]); // Note: '+=' would be much slower model.SetObjective(obj); } // Solve model model.Optimize(); // Extract solution if (model.Get(GRB.IntAttr.Status) == GRB.Status.OPTIMAL) { success = true; for (int j = 0; j < cols; j++) solution[j] = vars[j].Get(GRB.DoubleAttr.X); } model.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } return success; }
static void Main() { try { // Sample data // Sets of days and workers string[] Shifts = new string[] { "Mon1", "Tue2", "Wed3", "Thu4", "Fri5", "Sat6", "Sun7", "Mon8", "Tue9", "Wed10", "Thu11", "Fri12", "Sat13", "Sun14" }; string[] Workers = new string[] { "Amy", "Bob", "Cathy", "Dan", "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 }; // Amount each worker is paid to work one shift double[] pay = new double[] { 10, 12, 10, 8, 8, 9, 11 }; // 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. Since an assignment model always produces integer // solutions, we use continuous variables and solve as an LP. 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], pay[w], GRB.CONTINUOUS, Workers[w] + "." + Shifts[s]); } } // The objective is to minimize the total pay costs model.Set(GRB.IntAttr.ModelSense, 1); // Update model to integrate new variables model.Update(); // Constraint: assign exactly shiftRequirements[s] workers // to each shift s for (int s = 0; s < nShifts; ++s) { GRBLinExpr lhs = 0.0; for (int w = 0; w < nWorkers; ++w) lhs += x[w, s]; model.AddConstr(lhs == shiftRequirements[s], Shifts[s]); } // Optimize model.Optimize(); int status = model.Get(GRB.IntAttr.Status); if (status == GRB.Status.UNBOUNDED) { Console.WriteLine("The model cannot be solved " + "because it is unbounded"); return; } if (status == GRB.Status.OPTIMAL) { Console.WriteLine("The optimal objective is " + model.Get(GRB.DoubleAttr.ObjVal)); return; } if ((status != GRB.Status.INF_OR_UNBD) && (status != GRB.Status.INFEASIBLE)) { Console.WriteLine("Optimization was stopped with status " + status); return; } // Do IIS Console.WriteLine("The model is infeasible; computing IIS"); LinkedList<string> removed = new LinkedList<string>(); // Loop until we reduce to a model that can be solved while (true) { model.ComputeIIS(); Console.WriteLine("\nThe following constraint cannot be satisfied:"); foreach (GRBConstr c in model.GetConstrs()) { if (c.Get(GRB.IntAttr.IISConstr) == 1) { Console.WriteLine(c.Get(GRB.StringAttr.ConstrName)); // Remove a single constraint from the model removed.AddFirst(c.Get(GRB.StringAttr.ConstrName)); model.Remove(c); break; } } Console.WriteLine(); model.Optimize(); status = model.Get(GRB.IntAttr.Status); if (status == GRB.Status.UNBOUNDED) { Console.WriteLine("The model cannot be solved " + "because it is unbounded"); return; } if (status == GRB.Status.OPTIMAL) { break; } if ((status != GRB.Status.INF_OR_UNBD) && (status != GRB.Status.INFEASIBLE)) { Console.WriteLine("Optimization was stopped with status " + status); return; } } Console.WriteLine("\nThe following constraints were removed " + "to get a feasible LP:"); foreach (string s in removed) { Console.Write(s + " "); } Console.WriteLine(); // Dispose of model and env model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } }
public IEnumerable <Assignment> Process(IEnumerable <Session> sessions, IEnumerable <Room> rooms, IEnumerable <Timeslot> timeslots) { Validate(sessions, rooms, timeslots); _timeslotIds = new int[timeslots.Count()]; int index = 0; foreach (var timeslot in timeslots) { _timeslotIds[index] = timeslot.Id; index++; } _sessionIds = new int[sessions.Count()]; index = 0; foreach (var session in sessions) { _sessionIds[index] = session.Id; index++; } _roomIds = new int[rooms.Count()]; index = 0; foreach (var room in rooms) { _roomIds[index] = room.Id; index++; } CreateVariables(sessions.Count(), rooms.Count(), timeslots.Count()); CreateConstraints(sessions, rooms, timeslots.Count()); _model.Optimize(); var status = _model.Get(GRB.IntAttr.Status); if (status == GRB.Status.INFEASIBLE) { throw new NoFeasibleSolutionsException(); } var v = _model.Get(GRB.DoubleAttr.X, _v); var p = _model.Get(GRB.DoubleAttr.X, _s); for (int i = 0; i < sessions.Count(); i++) { Console.WriteLine($"s[{i}] = {p[i]}"); } var results = new List <Assignment>(); for (int s = 0; s < sessions.Count(); s++) { for (int r = 0; r < rooms.Count(); r++) { for (int t = 0; t < timeslots.Count(); t++) { if (v[s, r, t] == 1.0) { results.Add(new Assignment(_roomIds[r], _timeslotIds[t], _sessionIds[s])); } } } } return(results); }
public static bool IsFeasible(this GRBModel model) { var status = model.Get(GRB.IntAttr.Status); return(status == GRB.Status.OPTIMAL); }
static void Main(string[] args) { if (args.Length < 1) { Console.Out.WriteLine("Usage: mip2_cs filename"); return; } try { GRBEnv env = new GRBEnv(); GRBModel model = new GRBModel(env, args[0]); if (model.Get(GRB.IntAttr.IsMIP) == 0) { Console.WriteLine("Model is not a MIP"); return; } model.Optimize(); int optimstatus = model.Get(GRB.IntAttr.Status); double objval = 0; if (optimstatus == GRB.Status.OPTIMAL) { objval = model.Get(GRB.DoubleAttr.ObjVal); Console.WriteLine("Optimal objective: " + objval); } else if (optimstatus == GRB.Status.INF_OR_UNBD) { Console.WriteLine("Model is infeasible or unbounded"); return; } else if (optimstatus == GRB.Status.INFEASIBLE) { Console.WriteLine("Model is infeasible"); return; } else if (optimstatus == GRB.Status.UNBOUNDED) { Console.WriteLine("Model is unbounded"); return; } else { Console.WriteLine("Optimization was stopped with status = " + optimstatus); return; } /* Iterate over the solutions and compute the objectives */ GRBVar[] vars = model.GetVars(); model.GetEnv().Set(GRB.IntParam.OutputFlag, 0); Console.WriteLine(); for (int k = 0; k < model.Get(GRB.IntAttr.SolCount); ++k) { model.GetEnv().Set(GRB.IntParam.SolutionNumber, k); double objn = 0.0; for (int j = 0; j < vars.Length; j++) { objn += vars[j].Get(GRB.DoubleAttr.Obj) * vars[j].Get(GRB.DoubleAttr.Xn); } Console.WriteLine("Solution " + k + " has objective: " + objn); } Console.WriteLine(); model.GetEnv().Set(GRB.IntParam.OutputFlag, 1); /* Create a fixed model, turn off presolve and solve */ GRBModel fixedmodel = model.FixedModel(); fixedmodel.GetEnv().Set(GRB.IntParam.Presolve, 0); fixedmodel.Optimize(); int foptimstatus = fixedmodel.Get(GRB.IntAttr.Status); if (foptimstatus != GRB.Status.OPTIMAL) { Console.WriteLine("Error: fixed model isn't optimal"); return; } double fobjval = fixedmodel.Get(GRB.DoubleAttr.ObjVal); if (Math.Abs(fobjval - objval) > 1.0e-6 * (1.0 + Math.Abs(objval))) { Console.WriteLine("Error: objective values are different"); return; } GRBVar[] fvars = fixedmodel.GetVars(); double[] x = fixedmodel.Get(GRB.DoubleAttr.X, fvars); string[] vnames = fixedmodel.Get(GRB.StringAttr.VarName, fvars); for (int j = 0; j < fvars.Length; j++) { if (x[j] != 0.0) Console.WriteLine(vnames[j] + " " + x[j]); } // Dispose of models and env fixedmodel.Dispose(); model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } }
static void Main() { try { // Sample data // Sets of days and workers string[] Shifts = new string[] { "Mon1", "Tue2", "Wed3", "Thu4", "Fri5", "Sat6", "Sun7", "Mon8", "Tue9", "Wed10", "Thu11", "Fri12", "Sat13", "Sun14" }; string[] Workers = new string[] { "Amy", "Bob", "Cathy", "Dan", "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 }; // Amount each worker is paid to work one shift double[] pay = new double[] { 10, 12, 10, 8, 8, 9, 11 }; // 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. Since an assignment model always produces integer // solutions, we use continuous variables and solve as an LP. 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], pay[w], GRB.CONTINUOUS, Workers[w] + "." + Shifts[s]); } } // The objective is to minimize the total pay costs model.Set(GRB.IntAttr.ModelSense, 1); // Update model to integrate new variables model.Update(); // Constraint: assign exactly shiftRequirements[s] workers // to each shift s for (int s = 0; s < nShifts; ++s) { GRBLinExpr lhs = 0.0; for (int w = 0; w < nWorkers; ++w) { lhs.AddTerm(1.0, x[w, s]); } model.AddConstr(lhs == shiftRequirements[s], Shifts[s]); } // Optimize model.Optimize(); int status = model.Get(GRB.IntAttr.Status); if (status == GRB.Status.UNBOUNDED) { Console.WriteLine("The model cannot be solved " + "because it is unbounded"); return; } if (status == GRB.Status.OPTIMAL) { Console.WriteLine("The optimal objective is " + model.Get(GRB.DoubleAttr.ObjVal)); return; } if ((status != GRB.Status.INF_OR_UNBD) && (status != GRB.Status.INFEASIBLE)) { Console.WriteLine("Optimization was stopped with status " + status); return; } // Do IIS Console.WriteLine("The model is infeasible; computing IIS"); model.ComputeIIS(); Console.WriteLine("\nThe following constraint(s) " + "cannot be satisfied:"); foreach (GRBConstr c in model.GetConstrs()) { if (c.Get(GRB.IntAttr.IISConstr) == 1) { Console.WriteLine(c.Get(GRB.StringAttr.ConstrName)); } } // Dispose of model and env model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } }
static void Main(string[] args) { int n = 9; int s = 3; if (args.Length < 1) { Console.Out.WriteLine("Usage: sudoku_cs filename"); return; } try { GRBEnv env = new GRBEnv(); GRBModel model = new GRBModel(env); // Create 3-D array of model variables GRBVar[,,] vars = new GRBVar[n, n, n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { for (int v = 0; v < n; v++) { string st = "G_" + i.ToString() + "_" + j.ToString() + "_" + v.ToString(); vars[i, j, v] = model.AddVar(0.0, 1.0, 0.0, GRB.BINARY, st); } } } // Add constraints GRBLinExpr expr; // Each cell must take one value for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { expr = 0.0; for (int v = 0; v < n; v++) { expr.AddTerm(1.0, vars[i, j, v]); } string st = "V_" + i.ToString() + "_" + j.ToString(); model.AddConstr(expr == 1.0, st); } } // Each value appears once per row for (int i = 0; i < n; i++) { for (int v = 0; v < n; v++) { expr = 0.0; for (int j = 0; j < n; j++) { expr.AddTerm(1.0, vars[i, j, v]); } string st = "R_" + i.ToString() + "_" + v.ToString(); model.AddConstr(expr == 1.0, st); } } // Each value appears once per column for (int j = 0; j < n; j++) { for (int v = 0; v < n; v++) { expr = 0.0; for (int i = 0; i < n; i++) { expr.AddTerm(1.0, vars[i, j, v]); } string st = "C_" + j.ToString() + "_" + v.ToString(); model.AddConstr(expr == 1.0, st); } } // Each value appears once per sub-grid for (int v = 0; v < n; v++) { for (int i0 = 0; i0 < s; i0++) { for (int j0 = 0; j0 < s; j0++) { expr = 0.0; for (int i1 = 0; i1 < s; i1++) { for (int j1 = 0; j1 < s; j1++) { expr.AddTerm(1.0, vars[i0 * s + i1, j0 * s + j1, v]); } } string st = "Sub_" + v.ToString() + "_" + i0.ToString() + "_" + j0.ToString(); model.AddConstr(expr == 1.0, st); } } } // Fix variables associated with pre-specified cells StreamReader sr = File.OpenText(args[0]); for (int i = 0; i < n; i++) { string input = sr.ReadLine(); for (int j = 0; j < n; j++) { int val = (int)input[j] - 48 - 1; // 0-based if (val >= 0) { vars[i, j, val].LB = 1.0; } } } // Optimize model model.Optimize(); // Write model to file model.Write("sudoku.lp"); double[,,] x = model.Get(GRB.DoubleAttr.X, vars); Console.WriteLine(); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { for (int v = 0; v < n; v++) { if (x[i, j, v] > 0.5) { Console.Write(v + 1); } } } Console.WriteLine(); } // Dispose of model and env model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } }
static void Main() { try { // Warehouse demand in thousands of units double[] Demand = new double[] { 15, 18, 14, 20 }; // Plant capacity in thousands of units double[] Capacity = new double[] { 20, 22, 17, 19, 18 }; // Fixed costs for each plant double[] FixedCosts = new double[] { 12000, 15000, 17000, 13000, 16000 }; // Transportation costs per thousand units double[,] TransCosts = new double[,] { { 4000, 2000, 3000, 2500, 4500 }, { 2500, 2600, 3400, 3000, 4000 }, { 1200, 1800, 2600, 4100, 3000 }, { 2200, 2600, 3100, 3700, 3200 } }; // Number of plants and warehouses int nPlants = Capacity.Length; int nWarehouses = Demand.Length; // Model GRBEnv env = new GRBEnv(); GRBModel model = new GRBModel(env); model.Set(GRB.StringAttr.ModelName, "facility"); // Plant open decision variables: open[p] == 1 if plant p is open. GRBVar[] open = new GRBVar[nPlants]; for (int p = 0; p < nPlants; ++p) { open[p] = model.AddVar(0, 1, FixedCosts[p], GRB.BINARY, "Open" + p); } // Transportation decision variables: how much to transport from // a plant p to a warehouse w GRBVar[,] transport = new GRBVar[nWarehouses,nPlants]; for (int w = 0; w < nWarehouses; ++w) { for (int p = 0; p < nPlants; ++p) { transport[w,p] = model.AddVar(0, GRB.INFINITY, TransCosts[w,p], GRB.CONTINUOUS, "Trans" + p + "." + w); } } // The objective is to minimize the total fixed and variable costs model.Set(GRB.IntAttr.ModelSense, 1); // Update model to integrate new variables model.Update(); // Production constraints // Note that the right-hand limit sets the production to zero if // the plant is closed for (int p = 0; p < nPlants; ++p) { GRBLinExpr ptot = 0.0; for (int w = 0; w < nWarehouses; ++w) ptot += transport[w,p]; model.AddConstr(ptot <= Capacity[p] * open[p], "Capacity" + p); } // Demand constraints for (int w = 0; w < nWarehouses; ++w) { GRBLinExpr dtot = 0.0; for (int p = 0; p < nPlants; ++p) dtot += transport[w,p]; model.AddConstr(dtot == Demand[w], "Demand" + w); } // Guess at the starting point: close the plant with the highest // fixed costs; open all others // First, open all plants for (int p = 0; p < nPlants; ++p) { open[p].Set(GRB.DoubleAttr.Start, 1.0); } // Now close the plant with the highest fixed cost Console.WriteLine("Initial guess:"); double maxFixed = -GRB.INFINITY; for (int p = 0; p < nPlants; ++p) { if (FixedCosts[p] > maxFixed) { maxFixed = FixedCosts[p]; } } for (int p = 0; p < nPlants; ++p) { if (FixedCosts[p] == maxFixed) { open[p].Set(GRB.DoubleAttr.Start, 0.0); Console.WriteLine("Closing plant " + p + "\n"); break; } } // Use barrier to solve root relaxation model.GetEnv().Set(GRB.IntParam.Method, GRB.METHOD_BARRIER); // Solve model.Optimize(); // Print solution Console.WriteLine("\nTOTAL COSTS: " + model.Get(GRB.DoubleAttr.ObjVal)); Console.WriteLine("SOLUTION:"); for (int p = 0; p < nPlants; ++p) { if (open[p].Get(GRB.DoubleAttr.X) == 1.0) { Console.WriteLine("Plant " + p + " open:"); for (int w = 0; w < nWarehouses; ++w) { if (transport[w,p].Get(GRB.DoubleAttr.X) > 0.0001) { Console.WriteLine(" Transport " + transport[w,p].Get(GRB.DoubleAttr.X) + " units to warehouse " + w); } } } else { Console.WriteLine("Plant " + p + " closed!"); } } // Dispose of model and env model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } }
public HttpResponseMessage Optimize(string RunName) { using (var dbConn = new ApplicationDbContext()) { //Variables for students, semesters, courses, and course/semester offerings students = dbConn.StudentPreferences.Where(m => m.IsActive == true).Include(m => m.Courses).Include(m => m.Student.CompletedCourses).OrderByDescending(m => m.Student.CompletedCourses.Count()).ToArray(); crssems = dbConn.CourseSemesters.Where(m => m.IsActive == true).Include(m => m.Course).Include(m => m.Semester).ToArray(); courses = crssems.Select(m => m.Course).Distinct().ToArray(); sems = crssems.Select(m => m.Semester).Distinct().OrderBy(m => m.Type).OrderBy(m => m.Year).ToArray(); var completed = dbConn.CompletedCourses.ToList(); try { GRBEnv env = new GRBEnv("mip1.log"); GRBModel model = new GRBModel(env); model.Set(GRB.StringAttr.ModelName, "Course Optimizer"); GRBVar[,] slacks = new GRBVar[courses.Length, sems.Length]; //Assignment of student, course, and semester. Student must have a desire to take the coure, has not taken the course, and the course is offered to be included GRBVar[,,] CourseAllocation = new GRBVar[students.Length, courses.Length, sems.Length]; for (int i = 0; i < students.Length; i++) { for (int j = 0; j < courses.Length; j++) { for (int k = 0; k < sems.Length; k++) { if (students[i].Courses.Contains(courses[j]) && !completed.Any(m => m.GaTechId == students[i].GaTechId && courses[j].ID == m.Course_ID) && crssems.Contains(crssems.SingleOrDefault(m => m.Course == courses[j] && m.Semester == sems[k]))) CourseAllocation[i, j, k] = model.AddVar(0, 1, 1, GRB.BINARY, "students." + (i + 1).ToString() + "_Course." + (j + 1).ToString() + "_Semester." + (k + 1).ToString()); else CourseAllocation[i, j, k] = model.AddVar(0, 0, 1, GRB.BINARY, "students." + (i + 1).ToString() + "_Course." + (j + 1).ToString() + "_Semester." + (k + 1).ToString()); } } } model.Set(GRB.IntAttr.ModelSense, 1); model.Update(); //MUST TAKE DESIRED COURSE ONLY ONCE //Constrains the students to only take courses they desire once and for when the course is offered and does not allow a repeat of a course in another semester for (int i = 0; i < students.Length; i++) { for (int j = 0; j < courses.Length; j++) { if (students[i].Courses.Contains(courses[j]) && !completed.Any(m => m.GaTechId == students[i].GaTechId && courses[j].ID == m.Course_ID)) { GRBLinExpr constStudentDesiredCourses = 0.0; for (int k = 0; k < sems.Length; k++) { if (crssems.Any(m => m.Course.ID == courses[j].ID && m.Semester.Type == sems[k].Type && m.Semester.Year == sems[k].Year)) constStudentDesiredCourses.AddTerm(1.0, CourseAllocation[i, j, k]); } String sStudentDesiredCourses = "DesiredCourse." + j + 1 + "_Student." + i + 1; model.AddConstr(constStudentDesiredCourses == 1, sStudentDesiredCourses); } } //MAX COURSES PER SEMESTER //Constrains the students to only have a maximum number of 2 courses per semester. for (int k = 0; k < sems.Length; k++) { GRBLinExpr constMaxPerSem = 0.0; for (int j = 0; j < courses.Length; j++) { if (!completed.Any(m => m.GaTechId == students[i].GaTechId && courses[j].ID == m.Course_ID) && (crssems.Any(m => m.Course.ID == courses[j].ID && m.Semester.Type == sems[k].Type && m.Semester.Year == sems[k].Year))) constMaxPerSem.AddTerm(1, CourseAllocation[i, j, k]); } String sCourseSem = "maxCourseStudent." + i + 1 + "_Semester." + k + 1; model.AddConstr(constMaxPerSem <= MAX_COURSES_PER_SEMESTER, sCourseSem); } //PREREQUISITES //Constrains the students to take prerequisite courses prior to taking a course that needs the prerequisite for (int j = 0; j < courses.Length; j++) { if (courses[j].Prerequisites.Any() && students[i].Courses.Contains(courses[j]) && !completed.Any(m => m.GaTechId == students[i].GaTechId && courses[j].ID == m.Course_ID)) { foreach (var prereq in courses[j].Prerequisites) { int prereqIndex = Array.IndexOf(courses, prereq); GRBLinExpr coursePrereqConst1 = 0.0; GRBLinExpr coursePrereqConst2 = 0.0; if (!completed.Any(m => m.GaTechId == students[i].GaTechId && m.Course.ID == prereq.ID)) { for (int k = 0; k < sems.Length; k++) { if (prereqIndex >= 0) { coursePrereqConst1.AddTerm(k + 1, CourseAllocation[i, prereqIndex, k]); coursePrereqConst2.AddTerm(k, CourseAllocation[i, j, k]); } } } model.AddConstr(coursePrereqConst1, GRB.LESS_EQUAL, coursePrereqConst2, "PREREQ_Student" + i + "_Course+" + j + "_Prereq" + prereqIndex); } } } } //SENIORITY //Students are already ordered from dB query by seniority in descending order and puts a preference to senior students over the next student that desires that //same course with less seniority. for (int j = 0; j < courses.Length; j++) { for (int i = 0; i < students.Length - 1; i++) { if (students[i].Courses.Contains(courses[j]) && !completed.Any(m => m.GaTechId == students[i].GaTechId && courses[j].ID == m.Course_ID)) { int SemsRemain = (students[i].Courses.Count - students[i].Student.CompletedCourses.Count) / 2 + (students[i].Courses.Count - students[i].Student.CompletedCourses.Count) % 2; for (int n = i + 1; n < students.Length; n++) { if (students[n].Courses.Contains(courses[j]) && !completed.Any(m => m.GaTechId == students[n].GaTechId && courses[j].ID == m.Course_ID)) { GRBLinExpr seniority = 0.0; for (int k = 0; k < sems.Length; k++) { if (crssems.Any(m => m.Course.ID == courses[j].ID && m.Semester.Type == sems[k].Type && m.Semester.Year == sems[k].Year)) { if (k <= SemsRemain) { seniority.AddTerm(1.0, CourseAllocation[i, j, k]); seniority.AddTerm(-1.0, CourseAllocation[n, j, k]); } else { seniority.AddTerm(-1.0, CourseAllocation[i, j, k]); seniority.AddTerm(1.0, CourseAllocation[n, j, k]); } } } model.AddConstr(seniority, GRB.GREATER_EQUAL, 0, "Seniority for Student." + students[i] + "_Course." + courses[j]); break; } } } } } //Add the slack variable for all semester & course offerings then constrain the maximum number of students //to take a couse in a semester. for (int k = 0; k < sems.Length; k++) { for (int j = 0; j < courses.Length; j++) { if (crssems.Any(m => m.Course.ID == courses[j].ID && m.Semester.Type == sems[k].Type && m.Semester.Year == sems[k].Year)) { slacks[j, k] = model.AddVar(0, GRB.INFINITY, 0, GRB.INTEGER, sems[k].Type.ToString() + "." + sems[k].Year.ToString() + "." + courses[j].Name + ".Slacks"); GRBLinExpr constMaxStudCrsSem = 0.0; for (int i = 0; i < students.Length; i++) { if (!completed.Any(m => m.GaTechId == students[i].GaTechId && courses[j].ID == m.Course_ID)) constMaxStudCrsSem.AddTerm(1.0, CourseAllocation[i, j, k]); } model.Update(); constMaxStudCrsSem.AddTerm(-1.0, slacks[j, k]); model.AddConstr(constMaxStudCrsSem <= crssems.Single(m => m.Course.ID == courses[j].ID && m.Semester.Type == sems[k].Type && m.Semester.Year == sems[k].Year).StudentLimit, sems[k].Type.ToString() + "." + sems[k].Year.ToString() + "." + courses[j].Name); } } } //Add total slack to the optimization model for all courses in the semesters they are offered. GRBVar totSlack = model.AddVar(0, GRB.INFINITY, 0, GRB.INTEGER, "totSlack"); GRBLinExpr lhs = new GRBLinExpr(); lhs.AddTerm(-1.0, totSlack); for (int j = 0; j < courses.Length; j++) { for (int k = 0; k < sems.Length; k++) { if (crssems.Any(m => m.Course.ID == courses[j].ID && m.Semester.Type == sems[k].Type && m.Semester.Year == sems[k].Year)) lhs.AddTerm(1.0, slacks[j, k]); } } model.Update(); model.AddConstr(lhs, GRB.EQUAL, 0, "totSlack"); // Objective: minimize the total slack GRBLinExpr obj = new GRBLinExpr(); obj.AddTerm(1.0, totSlack); model.SetObjective(obj); //Optimize the model to minimize the total slack and maximize students to course offerings based on input variables and constraints. model.Optimize(); //Write Results optimization results to database writeResults(CourseAllocation, students, courses, sems, crssems, dbConn, Convert.ToInt32(model.Get(GRB.DoubleAttr.ObjVal)), RunName); //Clean-Up model.Dispose(); env.Dispose(); } catch (Exception e) { return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "An Error occured while running the optimization."); } } return Request.CreateResponse(HttpStatusCode.OK); }
static void Main() { try { // Sample data // Sets of days and workers string[] Shifts = new string[] { "Mon1", "Tue2", "Wed3", "Thu4", "Fri5", "Sat6", "Sun7", "Mon8", "Tue9", "Wed10", "Thu11", "Fri12", "Sat13", "Sun14" }; string[] Workers = new string[] { "Amy", "Bob", "Cathy", "Dan", "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 }; // Amount each worker is paid to work one shift double[] pay = new double[] { 10, 12, 10, 8, 8, 9, 11 }; // 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. Since an assignment model always produces integer // solutions, we use continuous variables and solve as an LP. 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], pay[w], GRB.CONTINUOUS, Workers[w] + "." + Shifts[s]); } } // The objective is to minimize the total pay costs model.Set(GRB.IntAttr.ModelSense, 1); // Update model to integrate new variables model.Update(); // Constraint: assign exactly shiftRequirements[s] workers // to each shift s LinkedList<GRBConstr> reqCts = new LinkedList<GRBConstr>(); for (int s = 0; s < nShifts; ++s) { GRBLinExpr lhs = 0.0; for (int w = 0; w < nWorkers; ++w) lhs += x[w,s]; GRBConstr newCt = model.AddConstr(lhs == shiftRequirements[s], Shifts[s]); reqCts.AddFirst(newCt); } // Optimize model.Optimize(); int status = model.Get(GRB.IntAttr.Status); if (status == GRB.Status.UNBOUNDED) { Console.WriteLine("The model cannot be solved " + "because it is unbounded"); return; } if (status == GRB.Status.OPTIMAL) { Console.WriteLine("The optimal objective is " + model.Get(GRB.DoubleAttr.ObjVal)); return; } if ((status != GRB.Status.INF_OR_UNBD) && (status != GRB.Status.INFEASIBLE)) { Console.WriteLine("Optimization was stopped with status " + status); return; } // Add slack variables to make the model feasible Console.WriteLine("The model is infeasible; adding slack variables"); // Set original objective coefficients to zero model.SetObjective(new GRBLinExpr()); // Add a new slack variable to each shift constraint so that the shifts // can be satisfied LinkedList<GRBVar> slacks = new LinkedList<GRBVar>(); foreach (GRBConstr c in reqCts) { GRBColumn col = new GRBColumn(); col.AddTerm(1.0, c); GRBVar newvar = model.AddVar(0, GRB.INFINITY, 1.0, GRB.CONTINUOUS, col, c.Get(GRB.StringAttr.ConstrName) + "Slack"); slacks.AddFirst(newvar); } // Solve the model with slacks model.Optimize(); status = model.Get(GRB.IntAttr.Status); if ((status == GRB.Status.INF_OR_UNBD) || (status == GRB.Status.INFEASIBLE) || (status == GRB.Status.UNBOUNDED)) { Console.WriteLine("The model with slacks cannot be solved " + "because it is infeasible or unbounded"); return; } if (status != GRB.Status.OPTIMAL) { Console.WriteLine("Optimization was stopped with status " + status); return; } Console.WriteLine("\nSlack values:"); foreach (GRBVar sv in slacks) { if (sv.Get(GRB.DoubleAttr.X) > 1e-6) { Console.WriteLine(sv.Get(GRB.StringAttr.VarName) + " = " + sv.Get(GRB.DoubleAttr.X)); } } // Dispose of model and env model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } }