static void Main(string[] args) { GRBEnv env = new GRBEnv(); GRBModel m = new GRBModel(env); GRBVar x1 = m.AddVar(0, GRB.INFINITY, 20, GRB.CONTINUOUS, "food.1"); GRBVar x2 = m.AddVar(0, GRB.INFINITY, 10, GRB.CONTINUOUS, "food.2"); GRBVar x3 = m.AddVar(0, GRB.INFINITY, 31, GRB.CONTINUOUS, "food.3"); GRBVar x4 = m.AddVar(0, GRB.INFINITY, 11, GRB.CONTINUOUS, "food.4"); GRBVar x5 = m.AddVar(0, GRB.INFINITY, 12, GRB.CONTINUOUS, "food.5"); m.Update(); GRBConstr con1 = m.AddConstr(2 * x1 + 3 * x3 + 1 * x4 + 2 * x5 >= 21, "nutrient.iron"); GRBConstr con2 = m.AddConstr(1 * x2 + 2 * x3 + 2 * x4 + 1 * x5 >= 12, "nutrient.calcium"); m.Optimize(); m.Write("diet.lp"); foreach (GRBVar var in m.GetVars()) { Console.WriteLine("{0} = {1}, reduced cost = {2}", var.Get(GRB.StringAttr.VarName), var.Get(GRB.DoubleAttr.X), var.Get(GRB.DoubleAttr.RC)); } foreach (GRBConstr constr in m.GetConstrs()) { Console.WriteLine("{0}, slack = {1}, pi = {2}", constr.Get(GRB.StringAttr.ConstrName), constr.Get(GRB.DoubleAttr.Slack), constr.Get(GRB.DoubleAttr.Pi)); } m.Dispose(); env.Dispose(); }
//ADD NEW VARIABLE TO CONSTRAINT //Constraint is selected private void cmbCon_SelectedIndexChanged(object sender, EventArgs e) { constraint = ((KeyValuePair <string, GRBConstr>)cmbCon.SelectedItem).Value; /////////////////////////////////////////////////////////////////// //display variables that are not in constraint already /*GRBLinExpr con_info = (GRBLinExpr)MyGlobals.model.GetRow(constraint); * GRBVar[] allVar = MyGlobals.model.GetVars(); * * Dictionary<string, GRBVar> D = new Dictionary<string, GRBVar>(); * for (int i = 0; i < allVar.Length; i++) * { * for (int j = 0; j < con_info.Size; j++) * { * if (allVar[i].Get(GRB.StringAttr.VarName) == con_info.GetVar(i).Get(GRB.StringAttr.VarName)) * continue; * * D.Add(allVar[i].Get(GRB.StringAttr.VarName), allVar[i]); * } * * }*/ GRBVar[] allVar = MyGlobals.model.GetVars(); Dictionary <string, GRBVar> D = new Dictionary <string, GRBVar>(); for (int i = 0; i < allVar.Length; i++) { D.Add(allVar[i].Get(GRB.StringAttr.VarName), allVar[i]); } // Bind combobox(add new var) to dictionary cmbAddVar.DataSource = new BindingSource(D, null); cmbAddVar.DisplayMember = "Key"; cmbAddVar.ValueMember = "Value"; //////////////////////////////////////////////////////////////////// }
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(); }
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); } }
static void Main(string[] args) { if (args.Length < 1) { Console.Out.WriteLine("Usage: feasopt_cs filename"); return; } try { GRBEnv env = new GRBEnv(); GRBModel feasmodel = new GRBModel(env, args[0]); // Create a copy to use FeasRelax feature later */ GRBModel feasmodel1 = new GRBModel(feasmodel); // Clear objective feasmodel.SetObjective(new GRBLinExpr()); // Add slack variables GRBConstr[] c = feasmodel.GetConstrs(); for (int i = 0; i < c.Length; ++i) { char sense = c[i].Get(GRB.CharAttr.Sense); if (sense != '>') { GRBConstr[] constrs = new GRBConstr[] { c[i] }; double[] coeffs = new double[] { -1 }; feasmodel.AddVar(0.0, GRB.INFINITY, 1.0, GRB.CONTINUOUS, constrs, coeffs, "ArtN_" + c[i].Get(GRB.StringAttr.ConstrName)); } if (sense != '<') { GRBConstr[] constrs = new GRBConstr[] { c[i] }; double[] coeffs = new double[] { 1 }; feasmodel.AddVar(0.0, GRB.INFINITY, 1.0, GRB.CONTINUOUS, constrs, coeffs, "ArtP_" + c[i].Get(GRB.StringAttr.ConstrName)); } } feasmodel.Update(); // Optimize modified model feasmodel.Write("feasopt.lp"); feasmodel.Optimize(); // Use FeasRelax feature */ feasmodel1.FeasRelax(GRB.FEASRELAX_LINEAR, true, false, true); feasmodel1.Write("feasopt1.lp"); feasmodel1.Optimize(); // Dispose of model and env feasmodel1.Dispose(); feasmodel.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } }
private void GetDual() { SchemeDualValue = _grbModelMaster.GetConstrByName("ct1").Pi; FADualValue = _grbModelMaster.GetConstrByName("ct2").Pi; DualSolution.Clear(); foreach (Node n in Data.NodeSet) { GRBConstr constr = _grbModelMaster.GetConstrByName("ct3_" + n.ID); double dualValue = constr.Pi; DualSolution.Add(n, dualValue); } }
public Column And(Column col) { if (col.objCoefSet) { this.objCoef = col.objCoef; } // for each constraint in col.column, add it to this.column double[] coefs = new double[col.column.Size]; GRBConstr[] constrs = new GRBConstr[col.column.Size]; for (int i = 0; i < col.column.Size; i++) { coefs[i] = col.column.GetCoeff(i); constrs[i] = col.column.GetConstr(i); } this.column.AddTerms(coefs, constrs); return this; }
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(); }
//DELETE Variable private void cmbCon5_SelectedIndexChanged(object sender, EventArgs e) { constraint = ((KeyValuePair <string, GRBConstr>)cmbCon5.SelectedItem).Value; GRBLinExpr con_info = (GRBLinExpr)MyGlobals.model.GetRow(constraint); Dictionary <string, GRBVar> D = new Dictionary <string, GRBVar>(); GRBVar var; for (int i = 0; i < con_info.Size; i++) { var = con_info.GetVar(i); D.Add(con_info.GetVar(i).Get(GRB.StringAttr.VarName), var); } // Bind combobox(delete var) to dictionary cmbVarName3.DataSource = new BindingSource(D, null); cmbVarName3.DisplayMember = "Key"; cmbVarName3.ValueMember = "Value"; }
//Add variable private void btnUpdate_Click(object sender, EventArgs e) { { try { //change GRBConst into GRBConst[] GRBConstr[] CON = new GRBConstr[1]; CON[0] = constraint; double var_coco; double.TryParse(txtAddCon.Text, out var_coco); //change double into double[] Double[] COEFF = new Double[1]; COEFF[0] = var_coco; //add variable to constraint MyGlobals.model.ChgCoeff(constraint, variable, var_coco); MyGlobals.model.Update(); populate_cmbConstraint(); BtnOK.Enabled = true; BtnCancel.Enabled = false; lblUpdate.Text = ""; lblUpdate.Text = constraint.Get(GRB.StringAttr.ConstrName) + ": "; GRBLinExpr con_info = (GRBLinExpr)MyGlobals.model.GetRow(constraint); for (int n = 0; n < con_info.Size; n++) { lblUpdate.Text += " " + con_info.GetCoeff(n) + con_info.GetVar(n).Get(GRB.StringAttr.VarName) + " +"; } lblUpdate.Text += " " + constraint.Get(GRB.CharAttr.Sense) + " " + constraint.Get(GRB.DoubleAttr.RHS) + "\n"; } catch (GRBException exc) { MessageBox.Show("Error code: " + exc.ErrorCode + ". " + exc.Message, "Error occured", MessageBoxButtons.OK); } } }
public void getOldList(GRBModel model, GRBConstr constr) { model.Update(); GRBLinExpr linExpr = model.GetRow(constr); oldDict = new Dictionary<GRBVar, double>(); for (int i = 0; i < linExpr.Size; i++) { GRBVar var = linExpr.GetVar(i); double val = linExpr.GetCoeff(i); if (oldDict.ContainsKey(var)) { oldDict[var] += val; } else { oldDict[var] = val; } } constrs = new GRBConstr[1]; constrs[0] = constr; }
//EDIT RHS private void cmbCon4_SelectedIndexChanged(object sender, EventArgs e) { constraint = ((KeyValuePair <string, GRBConstr>)cmbCon4.SelectedItem).Value; }
//new variable is added to constraint private void btnAdd_Click(object sender, EventArgs e) { try { string var_name = txtVarName.Text; string var_type = this.cmbVarType.GetItemText(this.cmbVarType.SelectedItem); double var_lb, var_ub; double var_obco, var_coco; double.TryParse(txtlb.Text, out var_lb); double.TryParse(txtub.Text, out var_ub); double.TryParse(txtObCo.Text, out var_obco); double.TryParse(txtCo_coeff.Text, out var_coco); //change GRBConst into GRBConst[] GRBConstr[] CON = new GRBConstr[1]; CON[0] = constraint; //change double into double[] Double[] COEFF = new Double[1]; COEFF[0] = var_coco; GRBVar x; switch (var_type) { case "BINARY": if (use_infinite_ub == false) { x = MyGlobals.model.AddVar(var_lb, var_ub, var_obco, 'B', CON, COEFF, var_name); } else { x = MyGlobals.model.AddVar(var_lb, GRB.INFINITY, var_obco, 'B', CON, COEFF, var_name); } break; case "CONTINUOUS": if (use_infinite_ub == false) { x = MyGlobals.model.AddVar(var_lb, var_ub, var_obco, 'C', CON, COEFF, var_name); } else { x = MyGlobals.model.AddVar(var_lb, GRB.INFINITY, var_obco, 'C', CON, COEFF, var_name); } break; case "INTERGER": if (use_infinite_ub == false) { x = MyGlobals.model.AddVar(var_lb, var_ub, var_obco, 'I', CON, COEFF, var_name); } else { x = MyGlobals.model.AddVar(var_lb, GRB.INFINITY, var_obco, 'I', CON, COEFF, var_name); } break; case "SEMI-CONTINUOUS": if (use_infinite_ub == false) { x = MyGlobals.model.AddVar(var_lb, var_ub, var_obco, 'S', CON, COEFF, var_name); } else { x = MyGlobals.model.AddVar(var_lb, GRB.INFINITY, var_obco, 'S', CON, COEFF, var_name); } break; case "SEMI-INTERGER": if (use_infinite_ub == false) { x = MyGlobals.model.AddVar(var_lb, var_ub, var_obco, 'N', CON, COEFF, var_name); } else { x = MyGlobals.model.AddVar(var_lb, GRB.INFINITY, var_obco, 'N', CON, COEFF, var_name); } break; } MyGlobals.model.Update(); populate_cmbConstraint(); BtnOK.Enabled = true; BtnCancel.Enabled = false; lblUpdate.Text = ""; lblUpdate.Text = constraint.Get(GRB.StringAttr.ConstrName) + ": "; GRBLinExpr con_info = (GRBLinExpr)MyGlobals.model.GetRow(constraint); for (int n = 0; n < con_info.Size; n++) { lblUpdate.Text += " " + con_info.GetCoeff(n) + con_info.GetVar(n).Get(GRB.StringAttr.VarName) + " +"; } lblUpdate.Text += " " + constraint.Get(GRB.CharAttr.Sense) + " " + constraint.Get(GRB.DoubleAttr.RHS) + "\n"; } catch (GRBException exc) { MessageBox.Show("Error code: " + exc.ErrorCode + ". " + exc.Message, "Error occured", MessageBoxButtons.OK); } txtVarName.Clear(); txtlb.Clear(); txtub.Clear(); }
static void Main(string[] args) { double[] Demand = new double[] { 15, 18, 14, 20 }; double[] Capacity = new double[] { 20, 22, 17, 19, 18 }; double[,] ShipCosts = new double[, ] { { 4000, 2500, 1200, 2200 }, { 2000, 2600, 1800, 2600 }, { 3000, 3400, 2600, 3100 }, { 2500, 3000, 4100, 3700 }, { 4500, 4000, 3000, 3200 } }; int nWarehouses = Capacity.Length; int nCustomers = Demand.Length; GRBEnv env = new GRBEnv(); GRBModel m = new GRBModel(env); GRBVar[,] Ship = new GRBVar[nWarehouses, nCustomers]; for (int i = 0; i < nWarehouses; ++i) { for (int j = 0; j < nCustomers; ++j) { Ship[i, j] = m.AddVar(0, GRB.INFINITY, 0, GRB.CONTINUOUS, "ship." + i + "." + j); } } GRBVar[] Shortage = new GRBVar[nCustomers]; for (int j = 0; j < nCustomers; ++j) { Shortage[j] = m.AddVar(0, GRB.INFINITY, 0, GRB.CONTINUOUS, "shortage." + j); } GRBVar TotalShortage = m.AddVar(0, GRB.INFINITY, 0, GRB.CONTINUOUS, "TotalShortage"); GRBVar TotalShippingCost = m.AddVar(0, GRB.INFINITY, 1, GRB.CONTINUOUS, "TotalShippingCost"); m.Update(); GRBConstr[] DemandCon = new GRBConstr[nCustomers]; for (int j = 0; j < nCustomers; ++j) { GRBLinExpr lhs = 0.0; for (int i = 0; i < nWarehouses; ++i) { lhs += Ship[i, j]; } DemandCon[j] = m.AddConstr(lhs == Demand[j] - Shortage[j], "demand." + j); } GRBConstr[] CapacityCon = new GRBConstr[nWarehouses]; for (int i = 0; i < nWarehouses; ++i) { GRBLinExpr lhs = 0.0; for (int j = 0; j < nCustomers; ++j) { lhs += Ship[i, j]; } CapacityCon[i] = m.AddConstr(lhs <= Capacity[i], "capacity." + i); } GRBLinExpr expr = 0.0; for (int j = 0; j < nCustomers; ++j) { expr += Shortage[j]; } GRBConstr TotalShortageCon = m.AddConstr(expr == TotalShortage, "total_shortage"); expr = 0.0; for (int i = 0; i < nWarehouses; ++i) { for (int j = 0; j < nCustomers; ++j) { expr += ShipCosts[i, j] * Ship[i, j]; } } GRBConstr TotalShippingCon = m.AddConstr(expr == TotalShippingCost, "total_shipping"); while (true) { m.Optimize(); double OptShortage = TotalShortage.Get(GRB.DoubleAttr.X); double OptShipping = TotalShippingCost.Get(GRB.DoubleAttr.X); Console.WriteLine("TotalShortage = {0}", OptShortage); Console.WriteLine("TotalShippingCost= {0}", OptShipping); if (OptShortage < EPS) { break; } double ObjectiveBound = TotalShortage.Get(GRB.DoubleAttr.SAObjUp); TotalShortage.Set(GRB.DoubleAttr.Obj, ((1 + EPS) * ObjectiveBound)); } }
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.AddTerm(1.0, 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); } }
public double GetDual(IRange rng) { GRBConstr[] grbConstrs = new GRBConstr[1]; grbConstrs[0] = rng.GetConstr(); double result = _model.Get(GRB.DoubleAttr.Pi, grbConstrs)[0]; return result; }
public double[] GetDuals(IRange[] rng) { double[] result = new double[rng.Length]; GRBConstr[] grbConstrs = new GRBConstr[rng.Length]; for (int i = 0; i < rng.Length; i++) { grbConstrs[i] = rng[i].GetConstr(); } result = _model.Get(GRB.DoubleAttr.Pi, grbConstrs); return result; }
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; double maxFixed = -GRB.INFINITY; double minFixed = GRB.INFINITY; for (int p = 0; p < nPlants; ++p) { if (FixedCosts[p] > maxFixed) { maxFixed = FixedCosts[p]; } if (FixedCosts[p] < minFixed) { minFixed = FixedCosts[p]; } } // Model GRBEnv env = new GRBEnv(); GRBModel model = new GRBModel(env); model.ModelName = "multiscenario"; // 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.ModelSense = GRB.MINIMIZE; // 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.AddTerm(1.0, transport[w, p]); } model.AddConstr(ptot <= Capacity[p] * open[p], "Capacity" + p); } // Demand constraints GRBConstr[] demandConstr = new GRBConstr[nWarehouses]; for (int w = 0; w < nWarehouses; ++w) { GRBLinExpr dtot = 0.0; for (int p = 0; p < nPlants; ++p) { dtot.AddTerm(1.0, transport[w, p]); } demandConstr[w] = model.AddConstr(dtot == Demand[w], "Demand" + w); } // We constructed the base model, now we add 7 scenarios // // Scenario 0: Represents the base model, hence, no manipulations. // Scenario 1: Manipulate the warehouses demands slightly (constraint right // hand sides). // Scenario 2: Double the warehouses demands (constraint right hand sides). // Scenario 3: Manipulate the plant fixed costs (objective coefficients). // Scenario 4: Manipulate the warehouses demands and fixed costs. // Scenario 5: Force the plant with the largest fixed cost to stay open // (variable bounds). // Scenario 6: Force the plant with the smallest fixed cost to be closed // (variable bounds). model.NumScenarios = 7; // Scenario 0: Base model, hence, nothing to do except giving the // scenario a name model.Parameters.ScenarioNumber = 0; model.ScenNName = "Base model"; // Scenario 1: Increase the warehouse demands by 10% model.Parameters.ScenarioNumber = 1; model.ScenNName = "Increased warehouse demands"; for (int w = 0; w < nWarehouses; w++) { demandConstr[w].ScenNRHS = Demand[w] * 1.1; } // Scenario 2: Double the warehouse demands model.Parameters.ScenarioNumber = 2; model.ScenNName = "Double the warehouse demands"; for (int w = 0; w < nWarehouses; w++) { demandConstr[w].ScenNRHS = Demand[w] * 2.0; } // Scenario 3: Decrease the plant fixed costs by 5% model.Parameters.ScenarioNumber = 3; model.ScenNName = "Decreased plant fixed costs"; for (int p = 0; p < nPlants; p++) { open[p].ScenNObj = FixedCosts[p] * 0.95; } // Scenario 4: Combine scenario 1 and scenario 3 */ model.Parameters.ScenarioNumber = 4; model.ScenNName = "Increased warehouse demands and decreased plant fixed costs"; for (int w = 0; w < nWarehouses; w++) { demandConstr[w].ScenNRHS = Demand[w] * 1.1; } for (int p = 0; p < nPlants; p++) { open[p].ScenNObj = FixedCosts[p] * 0.95; } // Scenario 5: Force the plant with the largest fixed cost to stay // open model.Parameters.ScenarioNumber = 5; model.ScenNName = "Force plant with largest fixed cost to stay open"; for (int p = 0; p < nPlants; p++) { if (FixedCosts[p] == maxFixed) { open[p].ScenNLB = 1.0; break; } } // Scenario 6: Force the plant with the smallest fixed cost to be // closed model.Parameters.ScenarioNumber = 6; model.ScenNName = "Force plant with smallest fixed cost to be closed"; for (int p = 0; p < nPlants; p++) { if (FixedCosts[p] == minFixed) { open[p].ScenNUB = 0.0; break; } } // 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].Start = 1.0; } // Now close the plant with the highest fixed cost Console.WriteLine("Initial guess:"); for (int p = 0; p < nPlants; ++p) { if (FixedCosts[p] == maxFixed) { open[p].Start = 0.0; Console.WriteLine("Closing plant " + p + "\n"); break; } } // Use barrier to solve root relaxation model.Parameters.Method = GRB.METHOD_BARRIER; // Solve multi-scenario model model.Optimize(); int nScenarios = model.NumScenarios; for (int s = 0; s < nScenarios; s++) { int modelSense = GRB.MINIMIZE; // Set the scenario number to query the information for this scenario model.Parameters.ScenarioNumber = s; // collect result for the scenario double scenNObjBound = model.ScenNObjBound; double scenNObjVal = model.ScenNObjVal; Console.WriteLine("\n\n------ Scenario " + s + " (" + model.ScenNName + ")"); // Check if we found a feasible solution for this scenario if (scenNObjVal >= modelSense * GRB.INFINITY) { if (scenNObjBound >= modelSense * GRB.INFINITY) { // Scenario was proven to be infeasible Console.WriteLine("\nINFEASIBLE"); } else { // We did not find any feasible solution - should not happen in // this case, because we did not set any limit (like a time // limit) on the optimization process Console.WriteLine("\nNO SOLUTION"); } } else { Console.WriteLine("\nTOTAL COSTS: " + scenNObjVal); Console.WriteLine("SOLUTION:"); for (int p = 0; p < nPlants; p++) { double scenNX = open[p].ScenNX; if (scenNX > 0.5) { Console.WriteLine("Plant " + p + " open"); for (int w = 0; w < nWarehouses; w++) { scenNX = transport[w, p].ScenNX; if (scenNX > 0.0001) { Console.WriteLine(" Transport " + scenNX + " units to warehouse " + w); } } } else { Console.WriteLine("Plant " + p + " closed!"); } } } } // Print a summary table: for each scenario we add a single summary // line Console.WriteLine("\n\nSummary: Closed plants depending on scenario\n"); Console.WriteLine("{0,8} | {1,17} {2,13}", "", "Plant", "|"); Console.Write("{0,8} |", "Scenario"); for (int p = 0; p < nPlants; p++) { Console.Write("{0,6}", p); } Console.WriteLine(" | {0,6} Name", "Costs"); for (int s = 0; s < nScenarios; s++) { int modelSense = GRB.MINIMIZE; // Set the scenario number to query the information for this scenario model.Parameters.ScenarioNumber = s; // Collect result for the scenario double scenNObjBound = model.ScenNObjBound; double scenNObjVal = model.ScenNObjVal; Console.Write("{0,-8} |", s); // Check if we found a feasible solution for this scenario if (scenNObjVal >= modelSense * GRB.INFINITY) { if (scenNObjBound >= modelSense * GRB.INFINITY) { // Scenario was proven to be infeasible Console.WriteLine(" {0,-30}| {1,6} " + model.ScenNName, "infeasible", "-"); } else { // We did not find any feasible solution - should not happen in // this case, because we did not set any limit (like a time // limit) on the optimization process Console.WriteLine(" {0,-30}| {1,6} " + model.ScenNName, "no solution found", "-"); } } else { for (int p = 0; p < nPlants; p++) { double scenNX = open[p].ScenNX; if (scenNX > 0.5) { Console.Write("{0,6}", " "); } else { Console.Write("{0,6}", "x"); } } Console.WriteLine(" | {0,6} " + model.ScenNName, scenNObjVal); } } // Dispose of model and env model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } }
public static GRBConstr SetLazy(this GRBConstr constr, bool isLazy) { constr.Lazy = isLazy ? 1 : 0; return(constr); }