private void BuildConst() { //GRBLinExpr myExpr = 0; //foreach (Node n in Frmk.Data.NodeSet) //{ // myExpr += _model.GetVarByName("x_" + n.ID); //} //_model.AddConstr(myExpr >= 9, "custom"); foreach (LazyConstr constr in Frmk.ConstrPool) { GRBLinExpr expr = 0; foreach (Node n in constr.Alpha.Keys) { expr += (-Frmk.Data.M * constr.Alpha[n]) * _model.GetVarByName("x_" + n.ID); } foreach (Node n in constr.Beta.Keys) { expr += n.Demand * constr.Beta[n]; } foreach (Arc a in constr.Gamma.Keys) { expr += (-a.Capacity) * constr.Gamma[a]; } if (constr.Type == "OPTIMAL") { _model.AddConstr(expr <= _model.GetVarByName("z"), "ct_o_" + constr.ID); } else if (constr.Type == "FEASIBLE") { _model.AddConstr(expr <= 0, "ct_f_" + constr.ID); } } }
private void BuildMIPModel() { _env = new GRBEnv(); _model = new GRBModel(_env); //room used. varR = new Dictionary <Room, GRBVar>(); foreach (var room in Data.Rooms) { varR[room] = _model.AddVar(0, GRB.INFINITY, room.Cost, GRB.INTEGER, $"r_{room}"); } _model.Update(); _model.AddConstr(Data.TimeSlots.Count * varR.Values.Sumx(), GRB.GREATER_EQUAL, Data.Courses.Sum(c => c.Lectures), ""); foreach (var roomCapacity in Data.RoomCapacities) { var overCap = OverCapacity * ((double)Data.Courses.Where(c => c.NumberOfStudents > roomCapacity.Value).Sum(c => c.Lectures) / Data.TimeSlots.Count); _model.AddConstr(varR.Where(r => r.Key.Capacity > roomCapacity.Value).Sumx(r => r.Value) * Data.TimeSlots.Count, GRB.GREATER_EQUAL, Data.Courses.Where(c => c.NumberOfStudents > roomCapacity.Value).Sum(c => c.Lectures) + overCap, $"roomcapcut_{roomCapacity.Value}"); } _model.SetCallback(new OutputCallback()); }
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(); }
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"); // Set objective GRBQuadExpr obj = x * x + x * y + y * y + y * z + z * z + 2 * x; 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.VarName + " " + x.X); Console.WriteLine(y.VarName + " " + y.X); Console.WriteLine(z.VarName + " " + z.X); Console.WriteLine("Obj: " + model.ObjVal + " " + obj.Value); // Change variable types to integer x.VType = GRB.INTEGER; y.VType = GRB.INTEGER; z.VType = GRB.INTEGER; // Optimize model model.Optimize(); Console.WriteLine(x.VarName + " " + x.X); Console.WriteLine(y.VarName + " " + y.X); Console.WriteLine(z.VarName + " " + z.X); Console.WriteLine("Obj: " + model.ObjVal + " " + obj.Value); // Dispose of model and env model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } }
private void GenerateConst() { GRBLinExpr expr1 = 0; foreach (Scheme s in SchemeColumnPool) { expr1 += _grbModelMaster.GetVarByName("lambda_" + s.ID); } _grbModelMaster.AddConstr(expr1 == 1, "ct1"); GRBLinExpr expr2 = 0; foreach (ExtremePoint e in EPColumnPool) { expr2 += _grbModelMaster.GetVarByName("mu_" + e.ID); } _grbModelMaster.AddConstr(expr2 == 1, "ct2"); foreach (Node n in Data.NodeSet) { GRBLinExpr expr = 0; foreach (Scheme s in SchemeColumnPool) { GRBVar lambda = _grbModelMaster.GetVarByName("lambda_" + s.ID); expr += Data.ServerCapacity * s.Value[n] * lambda; } foreach (ExtremePoint e in EPColumnPool) { GRBVar mu = _grbModelMaster.GetVarByName("mu_" + e.ID); expr += -e.Value[n] * mu; } _grbModelMaster.AddConstr(expr >= 0, "ct3_" + n.ID); } }
internal void AddCalculationTime(double calculationSeconds) { var calculationVar = _model.AddVar(0, double.PositiveInfinity, 0, GRB.CONTINUOUS, "calculationTime"); _model.AddConstr(calculationSeconds == calculationVar, "calculationTimeConstraint"); _variables[(int)VariableTypes.CalculationTime] = calculationVar; }
private void BuildFlowBalanceConst() { foreach (Node n in Data.NodeSet) { GRBLinExpr exprLeft = 0; foreach (Arc a in Data.ArcSet) { if (a.FromNode == n) { GRBVar x = _grbModel_FlowAssignmentSub.GetVarByName("x_" + a.FromNode.ID + "_" + a.ToNode.ID); exprLeft += x; } } exprLeft += n.Demand; GRBLinExpr exprRight = 0; foreach (Arc a in Data.ArcSet) { if (a.ToNode == n) { GRBVar x = _grbModel_FlowAssignmentSub.GetVarByName("x_" + a.FromNode.ID + "_" + a.ToNode.ID); exprRight += x; } } exprRight += _grbModel_FlowAssignmentSub.GetVarByName("g_" + n.ID); _grbModel_FlowAssignmentSub.AddConstr(exprLeft == exprRight, "ct_FlBal_" + n.ID); } }
private void IncomingOutgoingWaysConstraints(GRBModel model, int numberOfRoutes, GRBVar[][] w, GRBVar[][] v) { for (int i = 1; i < distances.GetLength(0); i++) { if (input.Visits[i - 1].IsBreak) { continue; } var wki = new GRBLinExpr(0); var wik = new GRBLinExpr(0); for (int s = 0; s < numberOfRoutes; s++) { for (int k = 0; k < distances.GetLength(1); k++) { var swki = AccessW(w[s], k, i); var swik = AccessW(w[s], i, k); wki += swki; wik += swik; } } model.AddConstr(wki == 1, $"v{i} incoming ways == 1"); model.AddConstr(wik == 1, $"v{i} outgoing ways == 1"); } }
private void AddTargetFunction() { PrintDebugRessourcesBefore("AddTargetFunction"); var factory = new TargetFunctionFactory(solverData); var targetFunction = new GRBLinExpr(0); targetFunction += factory.CreateTargetFunction(TargetType.MinTime, WaytimeWeight); targetFunction += factory.CreateTargetFunction(TargetType.TryVisitDesired, DesiredWeight); solverData.Model.SetObjective(targetFunction, GRB.MINIMIZE); // constraint target function based on presolved solution if (solverData.Input.Presolved.Length > 0) { var totalTimePresolved = 0; for (int i = 1; i < solverData.Input.Presolved.Length; i++) { totalTimePresolved += solverData.Input.VisitsDuration[Array.IndexOf(solverData.Input.VisitIds, solverData.Input.Presolved[i] - 1)]; totalTimePresolved += solverData.Input.Distances[i > 1 ? Array.IndexOf(solverData.Input.VisitIds, solverData.Input.Presolved[i - 1] - 1) : 0, Array.IndexOf(solverData.Input.VisitIds, solverData.Input.Presolved[i] - 1)]; } totalTimePresolved += solverData.Input.Distances[Array.IndexOf(solverData.Input.VisitIds, solverData.Input.Presolved.Last() - 1), 0]; model.AddConstr(targetFunction <= totalTimePresolved * WaytimeWeight, null); } var minWayTime = solverData.Input.Distances.Cast <int>().Where(i => i > 0).Min(); model.AddConstr(targetFunction >= (minWayTime * (solverData.NumberOfVisits + 1) + solverData.Input.VisitsDuration.Sum()) * (WaytimeWeight - DesiredWeight), null); PrintDebugRessourcesAfter(); }
/// <summary> /// Cria todas as restrições relativas às horas regulares de trabalho disponíveis /// </summary> /// <param name="entrada">Instância de <see cref="EntradaViewModel"/> contendo os dados informados na planilha de dados</param> private void CriaRestricaoHE(EntradaViewModel entrada) { foreach (var diaSemana in Enum.GetValues(typeof(DiaDaSemana))) { var diaSemanaEnum = (DiaDaSemana)diaSemana; var expressaoLinear = new GRBLinExpr(); var cargaHorariaExtraDisponivelDiaria = entrada.CargaHorariaExtraDisponivel[diaSemanaEnum]; entrada.Produtos.ForEach(produto => { var taxaProducao = produto.GetTaxaUnidadeHora(); var variavelProduto = _varArray[produto.GetNomeVariavel(diaSemanaEnum, true)]; expressaoLinear.AddTerm(taxaProducao, variavelProduto); }); _grbModel.AddConstr( expressaoLinear, GRB.LESS_EQUAL, cargaHorariaExtraDisponivelDiaria, $"HorasExtrasDisponiveis[{diaSemana}]" ); } }
/// <summary> /// Basicly the same as DesiredOverlap but with unavailable /// </summary> /// <param name="model"></param> /// <param name="numberOfRoutes"></param> /// <param name="v"></param> /// <param name="w"></param> /// <param name="c"></param> /// <param name="unavailableDuration"></param> private void UnavailableOverlap(GRBModel model, int numberOfRoutes, GRBVar[][] v, GRBVar[][] w, GRBVar[][] c, GRBVar[][][] unavailableDuration, bool hardConstraint = false) { for (int s = 0; s < numberOfRoutes; s++) { var day = s / input.Santas.Length; var(dayStart, dayEnd) = input.Days[day]; var dayDuration = dayEnd - dayStart; for (int i = 1; i < visitDurations.Length; i++) { var visit = input.Visits[i - 1]; for (int d = 0; d < visit.Unavailable.Length; d++) { // check if unavailable is on this day var(unavailableFrom, unavailableTo) = visit.Unavailable[d]; if (unavailableTo < dayStart || unavailableFrom > dayEnd) { model.Remove(unavailableDuration[s][i][d]); unavailableDuration[s][i][d] = null; //model.AddConstr(unavailableDuration[s][i][d] == 0, GurobiVarName($"unavailalbe[{s}][{i}][{d}] == 0, outside of day")); continue; } // temp if (hardConstraint) { model.AddConstr(unavailableDuration[s][i][d] == 0, GurobiVarName($"unavailalbe[{s}][{i}][{d}] == 0, hard constraint")); } var maxUnavailableDuration = Math.Min(visit.Duration, unavailableTo - unavailableFrom); model.AddConstr(unavailableDuration[s][i][d] <= maxUnavailableDuration * v[s][i], GurobiVarName($"unavailable[{s}][{i}][{d}] only possible if v[{s}][{i}]")); var unavailableStart = model.AddVar(unavailableFrom - dayStart, dayDuration, 0, GRB.CONTINUOUS, GurobiVarName($"unavailableStart[{s}][{i}][{d}]")); var binHelperStart = model.AddVar(0, 1, 0, GRB.BINARY, GurobiVarName($"binHelperUnavailableStart[{s}][{i}][{d}]")); var visitStart = c[s][i]; model.AddConstr(unavailableStart >= visitStart, null); model.AddGenConstrIndicator(binHelperStart, 0, unavailableStart <= unavailableFrom - dayStart, null); model.AddGenConstrIndicator(binHelperStart, 1, unavailableStart <= visitStart, null); var unavailableEnd = model.AddVar(0, unavailableTo - dayStart, 0, GRB.CONTINUOUS, GurobiVarName($"unavailableEnd[{s}][{i}][{d}]")); var binHelperEnd = model.AddVar(0, 1, 0, GRB.BINARY, GurobiVarName($"binHelperUnavailableEnd[{s}][{i}][{d}]")); var visitEnd = visitStart + visit.Duration * v[s][i]; model.AddConstr(unavailableEnd <= visitEnd, GurobiVarName($"unavailableEnd[{s}[{i}][{d}] <= visitEnd")); model.AddGenConstrIndicator(binHelperEnd, 0, unavailableEnd >= unavailableTo - dayStart, null); model.AddGenConstrIndicator(binHelperEnd, 1, unavailableEnd >= visitEnd, null); model.AddConstr( unavailableDuration[s][i][d] >= unavailableEnd - unavailableStart, GurobiVarName($"unavailable overlap[{s}][{i}][{d}]")); } } } }
// If the solution space is very large, this method will not return. // The most likely result is that it will exceed memory capacity // and then fail. As a result, we shouldn't use this method in // any production optimization. public IEnumerable <ProductionTarget> GetFeasibleTargets(double claySupply, double glazeSupply) { List <ProductionTarget> targets = new List <ProductionTarget>(); // Setup the Gurobi environment & Model GRBEnv env = new GRBEnv(); GRBModel model = new GRBModel(env); // Setup the decision variables GRBVar xS = CreateSmallVasesVariable(claySupply, model); GRBVar xL = CreateLargeVasesVariable(glazeSupply, model); model.Update(); // Create Constraints CreateConstraints(model, xS, xL, claySupply, glazeSupply); // Find the greatest number of small vases we can make var maxSmall = System.Math.Min(claySupply, glazeSupply); // Find the greatest number of large vases we can make var maxLarge = System.Math.Min(claySupply / 4.0, glazeSupply / 2.0); // Find all feasible combinations of small and large vases // Note: There are probably several better ways of doing this // that are more efficient and organic. For example, we could make // a tree that represents all of the possible decisions and let the // optimizer find the solutions from within that tree. var results = new List <ProductionTarget>(); for (int nSmall = 0; nSmall <= maxSmall; nSmall++) { for (int nLarge = 0; nLarge <= maxLarge; nLarge++) { // Force the solution to the target set of values var c1 = model.AddConstr(xS == nSmall, $"xS_Equals_{nSmall}"); var c2 = model.AddConstr(xL == nLarge, $"xL_Equals_{nLarge}"); model.Update(); // See if the solution is feasible with those values model.Optimize(); if (model.IsFeasible()) { results.Add(new ProductionTarget() { Small = nSmall, Large = nLarge }); } model.Remove(c1); model.Remove(c2); model.Update(); } } return(results); }
private void btnModelo2_Click(object sender, EventArgs e) { GRBEnv Ambinte = new GRBEnv(); GRBModel Modelo = new GRBModel(Ambinte); Random Aleatorio = new Random(4); int m = 1600; GRBVar[,] X = new GRBVar[m, m]; for (int i = 0; i < m; i++) { for (int j = 0; j < m; j++) { X[i, j] = Modelo.AddVar(0, 1, Aleatorio.Next(1, 20), GRB.BINARY, "x_" + i.ToString() + "_" + j.ToString()); } } Modelo.ModelSense = GRB.MAXIMIZE; GRBLinExpr Expressao = new GRBLinExpr(); for (int i = 0; i < m; i++) { Expressao.Clear(); for (int j = 0; j < m; j++) { Expressao.AddTerm(1, X[i, j]); } Modelo.AddConstr(Expressao == 1, "Vendedor_" + i); } for (int j = 0; j < m; j++) { Expressao.Clear(); for (int i = 0; i < m; i++) { Expressao.AddTerm(1, X[i, j]); } Modelo.AddConstr(Expressao == 1, "Regiao_" + j); } Stopwatch Cronometro = new Stopwatch(); Cronometro.Start(); Modelo.Optimize(); Cronometro.Stop(); MessageBox.Show("O valor do lucro é: " + Modelo.ObjVal.ToString()); MessageBox.Show("O tempo para resolver foi de: " + Cronometro.ElapsedMilliseconds.ToString() + " ms"); MessageBox.Show("Se quiser saber a alocação que gera esse lucro é só me pagar"); //for (int j = 0; j < m; j++) //{ // for (int i = 0; i < m; i++) // { // if(X[i,j].X>0) // { // MessageBox.Show("O vendedor " + i + " é alocado para a região " + j); // } // } //} Modelo.Write("C:\\Teste\\Modelo2.lp"); }
public static GRBLinExpr MinimizeDeltaDistance(GRBModel model, GRBLinExpr value, GRBVar v, double c, string name) { GRBVar absAvgDelta = model.AddVar(0, double.PositiveInfinity, 0, GRB.CONTINUOUS, name + "_absval"); model.AddConstr(v - c <= absAvgDelta, name + "_v-c_bound"); model.AddConstr(c - v <= absAvgDelta, name + "_c-v_bound"); value += absAvgDelta; return(value); }
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 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); } }
private void AllVehiclesMustEndAtTheDepot() { for (int v = 0; v < _vehicles.Count; v++) { var vehicleEnd = new GRBLinExpr(); for (int s = 0; s < _vertices.Count; s++) { vehicleEnd.AddTerm(1.0, _vehicleTraverse[v][s][_vertices.Count - 1]); } _model.AddConstr(vehicleEnd, GRB.EQUAL, 1.0, "_AllVehiclesMustEndAtTheDepot"); } }
public string Example() { StringBuilder sb = new StringBuilder(); try { //GRBEnv env = new GRBEnv("mip1.log"); GRBEnv env = new GRBEnv(); GRBModel model = new GRBModel(env); 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"); // 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(); sb.AppendLine(x.VarName + " " + x.X); sb.AppendLine(y.VarName + " " + y.X); sb.AppendLine(z.VarName + " " + z.X); sb.AppendLine("Obj: " + model.ObjVal); // Dispose of model and env model.Dispose(); env.Dispose(); } catch (GRBException e) { //pokemon } return(sb.ToString()); }
static void SolveDual2(GRBEnv env, HashSet <string> nodes_set, List <Arc> arcs) { GRBModel dual = new GRBModel(env); Dictionary <string, GRBLinExpr> lhs = new Dictionary <string, GRBLinExpr>(); Dictionary <string, GRBConstr> flow_balance = new Dictionary <string, GRBConstr>(); Dictionary <Arc, GRBVar> arc_traversed = new Dictionary <Arc, GRBVar>(); foreach (string node in nodes_set) { lhs[node] = new GRBLinExpr(); } foreach (Arc a in arcs) { GRBVar var = dual.AddVar(0, 1, a.length, GRB.CONTINUOUS, "arc_traversed." + a.source + "_" + a.dest); lhs[a.source].AddTerm(-1, var); lhs[a.dest].AddTerm(1, var); } dual.Update(); foreach (string node in nodes_set) { flow_balance[node] = dual.AddConstr(lhs[node], '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(); dual.Dispose(); }
/// <summary> /// I used this Gurobi model to calculate the fixed point baseline. /// </summary> public mae_sdo() { string path = @"C:\Users\Roman Bolzern\Desktop\D4\neu\meta_data_training.csv"; var lines = File.ReadLines(path).ToArray(); GRBEnv env = new GRBEnv(); GRBModel m = new GRBModel(env); var scale = 1e9; var y = m.AddVar(1e-9 * scale, 1e-2 * scale, 0d, GRB.CONTINUOUS, "y"); var obj = new GRBLinExpr(); for (int i = 1; i < lines.Length; i++) { var diff = double.Parse(lines[i].Split(',')[3]) * scale - y; var diffinput = m.AddVar(-1e-2 * scale, 1e-2 * scale, 0d, GRB.CONTINUOUS, "diffinput"); m.AddConstr(diffinput == diff); var diffres = m.AddVar(0, 1e-2 * scale, 0d, GRB.CONTINUOUS, "diffres"); m.AddGenConstrAbs(diffres, diffinput, "diffAbs"); obj += diffres; } m.SetObjective(obj, GRB.MINIMIZE); m.Optimize(); Console.WriteLine($"Objective: {((GRBLinExpr)m.GetObjective()).Value / scale}"); Console.WriteLine($"fixed point: {y.X / scale}"); }
private void MinRouteSmallerThanMaxRoute(GRBModel model, GRBVar[] minRoutes, GRBVar[] maxRoutes) { for (int s = 0; s < minRoutes.Length; s++) { model.AddConstr(minRoutes[s] <= maxRoutes[s], GurobiVarName($"minRoutesSmallerThanMaxRoutesForSanta{s}")); } }
private void AddDoNotSeatOutOfBoundsConstraint(GRBModel model, GRBVar[,,] seated) { for (int x = 0; x < Cinema.Width; x++) { for (int y = 0; y < Cinema.Height; y++) { for (int g = 0; g < Cinema.TotalNumberOfGroups; g++) { var anyZeroes = false; for (int i = 0; i < Cinema.GroupSizes[g]; i++) { if (x + i >= Cinema.Width || Cinema.Seats[x + i, y] == 0) { anyZeroes = true; break; } } if (anyZeroes) { model.AddConstr(seated[x, y, g], GRB.LESS_EQUAL, 0, "Out of bounds constraint"); } } } } }
private void AddDistanceConstraints(GRBModel model, GRBVar[,,] seated) { for (int g1 = 0; g1 < Cinema.TotalNumberOfGroups; g1++) { for (int g2 = 0; g2 < Cinema.TotalNumberOfGroups; g2++) { if (g1 < g2) { var size1 = Cinema.GroupSizes[g1]; var size2 = Cinema.GroupSizes[g2]; // Loop over all legal start positions for group 1 foreach (var pos1 in Cinema.LegalStartPositions[size1 - 1]) { var x1 = pos1.Item1; var y1 = pos1.Item2; // Collect invalid seats var invalidSeats = Cinema.GetInvalidSeats(x1, y1, size1, size2); foreach (var pos2 in invalidSeats) { if (Cinema.LegalStartPositions[size2 - 1].Any(m => m == pos2)) { var x2 = pos2.Item1; var y2 = pos2.Item2; model.AddConstr(seated[x1, y1, g1] + seated[x2, y2, g2], GRB.LESS_EQUAL, 1, "Distance constaint"); } } } } } } }
private void AddTargetFunction() { PrintDebugRessourcesBefore("AddTargetFunction"); var targetFunction = new GRBLinExpr(0); var hour = 3600; var longestDay = model.AddVar(0, int.MaxValue, 0, GRB.INTEGER, "longest day"); var workingTimeSum = new GRBLinExpr(0); foreach (var santa in Enumerable.Range(0, solverData.NumberOfSantas)) { var santaWorkingTime = solverData.Variables.SantaVisitTime[santa] + solverData.Variables.SantaRouteCost[santa]; model.AddConstr(longestDay >= santaWorkingTime, null); workingTimeSum += santaWorkingTime; } var workingTimeFactor = (40d / hour); var longestDayFactor = (30d / hour); targetFunction = workingTimeFactor * workingTimeSum + longestDayFactor * longestDay; solverData.Model.SetObjective(targetFunction, GRB.MINIMIZE); PrintDebugRessourcesAfter(); }
private void BreakHandling(GRBModel model, int numberOfRoutes, GRBVar[][] v) { for (int i = 1; i < visitDurations.Length; i++) { if (!input.Visits[i - 1].IsBreak) { continue; } var visit = input.Visits[i - 1]; var breakRoutes = new List <int>(); for (var day = 0; day < input.Days.Length; day++) { var s = visit.SantaId + day * input.Santas.Length; model.AddGenConstrOr(v[s][i], v[s].Take(i - 1).Skip(1).ToArray(), null); // assignment if used breakRoutes.Add(s); } // break cannot be visited by another santa foreach (var nonBreakRoute in Enumerable.Range(0, numberOfRoutes).Except(breakRoutes)) { model.AddConstr(v[nonBreakRoute][i] == 0, null); } } }
private void BuildConstr() { foreach (Node n in Frmk.Data.NodeSet) { GRBVar alpha = _model.GetVarByName("alpha_" + n.ID); GRBVar beta = _model.GetVarByName("beta_" + n.ID); _model.AddConstr(-alpha + beta <= 0, "ct_g_" + n.ID); } foreach (Arc a in Frmk.Data.ArcSet) { GRBVar fromBeta = _model.GetVarByName("beta_" + a.FromNode.ID); GRBVar toBeta = _model.GetVarByName("beta_" + a.ToNode.ID); GRBVar gamma = _model.GetVarByName("gamma_" + a.FromNode.ID + "_" + a.ToNode.ID); _model.AddConstr(-fromBeta + toBeta - gamma <= Frmk.Data.FlowFeePerUnit, "ct_f+_" + a.FromNode.ID + "_" + a.ToNode.ID); _model.AddConstr(fromBeta - toBeta - gamma <= Frmk.Data.FlowFeePerUnit, "ct_f-_" + a.FromNode.ID + "_" + a.ToNode.ID); } }
private void btnOi_Click(object sender, EventArgs e) { GRBEnv Ambiente = new GRBEnv(); GRBModel Modelo = new GRBModel(Ambiente); GRBVar x = Modelo.AddVar(0, 1, 0, GRB.BINARY, "x"); GRBVar y = Modelo.AddVar(0, 1, 0, GRB.BINARY, "y"); GRBVar z = Modelo.AddVar(0, 1, 0, GRB.BINARY, "z"); Modelo.SetObjective(x + y + 2 * z, GRB.MAXIMIZE); Modelo.AddConstr(x + 2 * y + 3 * z <= 4.0, "c0"); Modelo.AddConstr(x + y >= 1.0, "c1"); Modelo.Write("C:\\Teste\\ModeloAula.lp"); Modelo.Optimize(); MessageBox.Show("O valor da variável x é: " + x.X.ToString()); MessageBox.Show("O valor da variável y é: " + y.X.ToString()); MessageBox.Show("O valor da variável z é: " + z.X.ToString()); }
private void BuildConst_SG() { GRBLinExpr expr = 0; foreach (Node n in Data.NodeSet) { expr += _grbModel_SchemeGenerateSub.GetVarByName("y_" + n.ID); } _grbModel_SchemeGenerateSub.AddConstr(expr >= 1, "ct_1"); /*分支定界的约束*/ foreach (Node n in CurrentBranchNode.ConstrPool.Keys) { GRBVar var = _grbModel_SchemeGenerateSub.GetVarByName("y_" + n.ID); _grbModel_SchemeGenerateSub.AddConstr(var == CurrentBranchNode.ConstrPool[n], "ct_2" + "_" + n.ID); } }
public void mip1_cs() { try { // Create an empty environment, set options and start GRBEnv env = new GRBEnv(true); env.Set("LogFile", "mip1.log"); env.Start(); // Create empty model GRBModel model = new GRBModel(env); // Create variables GRBVar x = model.AddVar(0.0, 1.0, 1.0, GRB.BINARY, "x"); GRBVar y = model.AddVar(0.0, 1.0, 1.0, GRB.BINARY, "y"); GRBVar z = model.AddVar(0.0, 1.0, 1.0, GRB.BINARY, "z"); // 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.VarName + " " + x.X); Console.WriteLine(y.VarName + " " + y.X); Console.WriteLine(z.VarName + " " + z.X); Console.WriteLine("Obj: " + model.ObjVal); // Dispose of model and env model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } }
private void DesiredOverlap(GRBModel model, int numberOfRoutes, GRBVar[][] v, GRBVar[][] w, GRBVar[][] c, GRBVar[][][] desiredDuration) { for (int s = 0; s < numberOfRoutes; s++) { var day = s / input.Santas.Length; var(dayStart, dayEnd) = input.Days[day]; var dayDuration = dayEnd - dayStart; for (int i = 1; i < visitDurations.Length; i++) { var visit = input.Visits[i - 1]; for (int d = 0; d < visit.Desired.Length; d++) { var(desiredFrom, desiredTo) = visit.Desired[d]; // check if desired on day if (desiredTo < dayStart || desiredFrom > dayEnd) { model.Remove(desiredDuration[s][i][d]); desiredDuration[s][i][d] = null; //free up memory //model.AddConstr(desiredDuration[s][i][d] == 0, GurobiVarName($"desiredDuration[{s}][{i}][{d}] == 0, outside of day")); continue; } var maxDesiredDuration = Math.Min(visit.Duration, desiredTo - desiredFrom); model.AddConstr(desiredDuration[s][i][d] <= maxDesiredDuration * v[s][i], GurobiVarName($"desired[{s}][{i}][{d}] only possible if v[{s}][{i}]")); var desiredStart = model.AddVar(Math.Max(desiredFrom - dayStart, 0), dayDuration, 0, GRB.CONTINUOUS, GurobiVarName($"desiredStart[{s}][{i}][{d}]")); model.AddConstr(desiredStart >= c[s][i], GurobiVarName($"desiredStart[{s}[{i}][{d}] >= visitStart")); var desiredEnd = model.AddVar(0, desiredTo - dayStart, 0, GRB.CONTINUOUS, GurobiVarName($"desiredEnd[{s}][{i}][{d}]")); model.AddConstr(desiredEnd <= c[s][i] + visit.Duration * v[s][i], GurobiVarName($"desiredEnd[{s}[{i}][{d}] <= visitEnd")); var binDecisionVariable = model.AddVar(0, 1, 0, GRB.BINARY, GurobiVarName($"binDesiredDecisionVar[{s}][{i}][{d}]")); // if positive, duration = end -start model.AddGenConstrIndicator(binDecisionVariable, 0, desiredEnd - desiredStart >= 0, null); model.AddGenConstrIndicator(binDecisionVariable, 0, desiredDuration[s][i][d] == desiredEnd - desiredStart, null); // if negative, duration = 0 model.AddGenConstrIndicator(binDecisionVariable, 1, desiredEnd - desiredStart <= 0, null); model.AddGenConstrIndicator(binDecisionVariable, 1, desiredDuration[s][i][d] == 0, null); } } } }
private void BuildConst_SG() { GRBLinExpr expr = 0; foreach (Node n in Data.NodeSet) { expr += _grbModel_SchemeGenerateSub.GetVarByName("y_" + n.ID); } _grbModel_SchemeGenerateSub.AddConstr(expr >= 1, "ct_1"); }
public static Graph RunSolver(Graph graph) { GRBEnv env = new GRBEnv(); env.Set(GRB.IntParam.OutputFlag, 0); env.Set(GRB.IntParam.LogToConsole, 0); env.Set(GRB.IntParam.Presolve, 2); env.Set(GRB.DoubleParam.Heuristics, 0.0); GRBModel model = new GRBModel(env); GRBVar[] variables = new GRBVar[graph.NumberOfEdges]; model.SetCallback(new LPSolverCallback()); Dictionary<Edge, GRBVar> edgeVars = new Dictionary<Edge, GRBVar>(); // Add variables to the LP model for (int i = 0; i < graph.NumberOfEdges; i++) { variables[i] = model.AddVar(0.0, 1.0, 0.0, GRB.BINARY, "x_" + i); edgeVars.Add(graph.Edges[i], variables[i]); } model.Update(); // Add constraints to the LP model Console.Write("\rRunning LP. Creating constraints...\r"); //var nonTerminals = graph.Vertices.Except(graph.Terminals).ToList(); ulong conNr = 0; //var terminalCombinations = new List<List<Vertex>>(); // Assume, without loss of generality, that Terminals[0] is the root, and thus is always included int rootNr = 1; foreach (var rootTerminal in graph.Terminals) //var rootTerminal = graph.Terminals[0]; { Console.Write("\rRunning LP. Creating constraints... {0}/{1}\r", rootNr, graph.Terminals.Count); foreach (var combination in GetBFS(graph, rootTerminal)) { var nodes = combination.ToList(); //new HashSet<Vertex>(combination); if (nodes.Count == graph.NumberOfVertices || graph.Terminals.All(nodes.Contains)) continue; //Debug.WriteLine("Combination: {0}", string.Join(" ", nodes)); //for (int i = 1; i <= nodes.Count; i++) { var edges = nodes//.Take(i) .SelectMany(graph.GetEdgesForVertex) .Distinct() .Where(x => x.WhereOne(y => !nodes.Contains(y))); GRBLinExpr expression = 0; foreach (var edge in edges) expression.AddTerm(1, edgeVars[edge]); model.AddConstr(expression >= 1.0, "subset_" + conNr); conNr++; if (conNr % 100000 == 0) { //model = model.Presolve(); //Pre-solve the model every 1000 constraints. int constrBefore = model.GetConstrs().Length, varsBefore = model.GetVars().Length; Debug.WriteLine("Presolve called."); var presolved = model.Presolve(); Debug.WriteLine("Model has {0} constraints, {1} variables. Presolve has {2} constraints, {3} variables", constrBefore, varsBefore, presolved.GetConstrs().Length, presolved.GetVars().Length); } } } //Debug.WriteLine(" "); //Debug.WriteLine(" "); rootNr++; } //terminalCombinations.Add(new List<Vertex>(new[] { graph.Terminals[0] })); //for (int j = 1; j < graph.Terminals.Count - 1; j++) // terminalCombinations.AddRange(new Combinations<Vertex>(graph.Terminals.Skip(1), j).Select(combination => combination.Union(new[] { graph.Terminals[0] }).ToList())); //long nonTerminalSetsDone = 0; //long nonTerminalSets = 0; //for (int i = 0; i <= nonTerminals.Count; i++) // nonTerminalSets += Combinations<Vertex>.NumberOfCombinations(nonTerminals.Count, i); //for (int i = 0; i <= nonTerminals.Count; i++) //{ // foreach (var nonTerminalSet in new Combinations<Vertex>(nonTerminals, i)) // { // foreach (var nodes in (from a in terminalCombinations // select new HashSet<Vertex>(a.Union(nonTerminalSet)))) // { // var edges = nodes.SelectMany(graph.GetEdgesForVertex) // .Distinct() // .Where(x => x.WhereOne(y => !nodes.Contains(y))); // GRBLinExpr expression = 0; // foreach (var edge in edges) // expression.AddTerm(1, edgeVars[edge]); // model.AddConstr(expression >= 1.0, "subset_" + conNr); // conNr++; // } // nonTerminalSetsDone++; // if (nonTerminalSetsDone % 100 == 0) // Console.Write("\rRunning LP. Creating constraints... {0}/{1} ({2:0.000}%)\r", nonTerminalSetsDone, nonTerminalSets, nonTerminalSetsDone * 100.0 / nonTerminalSets); // } //} // Solve the LP model Console.Write("\rRunning LP. Creating objective & updating... \r"); GRBLinExpr objective = new GRBLinExpr(); for (int i = 0; i < graph.NumberOfEdges; i++) objective.AddTerm(graph.Edges[i].Cost, variables[i]); model.SetObjective(objective, GRB.MINIMIZE); Console.Write("\rRunning LP. Tuning... \r"); model.Tune(); Debug.WriteLine("Presolve called."); model.Presolve(); Console.Write("\rRunning LP. Solving... \r"); Debug.WriteLine("Optimize called."); model.Optimize(); Graph solution = graph.Clone(); HashSet<Edge> includedEdges = new HashSet<Edge>(); for (int i = 0; i < solution.NumberOfEdges; i++) { var value = variables[i].Get(GRB.DoubleAttr.X); if (value == 1) includedEdges.Add(solution.Edges[i]); } foreach (var edge in solution.Edges.ToList()) if (!includedEdges.Contains(edge)) solution.RemoveEdge(edge); Console.Write("\r \r"); return solution; }
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 Instance Match(Instance instance, string path, bool print) { try { LP = ""; if (!System.IO.Directory.Exists(path) && print) System.IO.Directory.CreateDirectory(path); GRBEnv env = new GRBEnv("mip1.log"); GRBModel model = new GRBModel(env); List<LPEdge> LPEdges = new List<LPEdge>(); if (print) { instance.Draw().Save(path + "/0Start.bmp"); } int EdgeCounter = 0; foreach (Instance.Applicant a in instance.Applicants) { EdgeCounter += a.Priorities.Count; foreach (Instance.Priority Prio in a.Priorities) { { LPEdges.Add(new LPEdge(a, instance.Posts[Prio.Target], Prio.Rank)); if (Prio.Rank == 0) instance.Posts[Prio.Target].IsF = 1; } } } // Create variables GRBVar[] Edges = new GRBVar[EdgeCounter]; for (int i = 0; i < Edges.Length; i++) { Edges[i] = model.AddVar(0.0, 1.0, 0.0, GRB.BINARY, "ve" + i.ToString()); } // Integrate new variables model.Update(); if (print) LP += "Applicant Matching Conditions:" + Environment.NewLine; foreach (Instance.Applicant a in instance.Applicants) { GRBLinExpr Temp = new GRBLinExpr(); for (int i = 0; i < LPEdges.Count; i++) { if (LPEdges[i].Applicant == a) { Temp += Edges[i]; if (print) LP += "(a" + LPEdges[i].Applicant.ID + ", p" + LPEdges[i].Post.ID + ") + "; } } model.AddConstr(Temp == 1.0, "a" + a.ID.ToString()); if (print) LP += " = 1;" + Environment.NewLine; } if (print) LP += Environment.NewLine + "Post Matching Conditions:" + Environment.NewLine; foreach (Instance.Post p in instance.Posts) { GRBLinExpr Temp = new GRBLinExpr(); for (int i = 0; i < LPEdges.Count; i++) { if (LPEdges[i].Post == p) { Temp += Edges[i]; if (print) LP += "(a" + LPEdges[i].Applicant.ID + ", p" + LPEdges[i].Post.ID + ") + "; } } model.AddConstr(Temp <= 1.0, "p" + p.ID.ToString()); if (print) LP += " <= 1;" + Environment.NewLine; } if (print) LP += Environment.NewLine + "First Choice Conditions:" + Environment.NewLine; for (int i = 0; i < LPEdges.Count; i++) { LPEdge le1 = LPEdges[i]; if (le1.Post.IsF == 1 && le1.Rank != 0) { model.AddConstr(Edges[i] <= 0, "s" + i.ToString()); if (print) LP += "(a" + LPEdges[i].Applicant.ID + ", p" + LPEdges[i].Post.ID + ") <= 0;" + Environment.NewLine; for (int j = 0; j < LPEdges[i].Applicant.Priorities.Count; j++) { if (LPEdges[i].Applicant.Priorities[j].Target == LPEdges[i].Post.ID && LPEdges[i].Rank == LPEdges[i].Applicant.Priorities[j].Rank) { LPEdges[i].Applicant.Priorities.RemoveAt(j); } } } } if (print) LP += Environment.NewLine + "Second Choice Conditions:" + Environment.NewLine; for (int i = 0; i < LPEdges.Count; i++) { LPEdge le1 = LPEdges[i]; foreach (LPEdge le2 in LPEdges) { if (le2 != le1 && le2.Post.IsF == 0 && le1.Applicant == le2.Applicant && le2.Rank != 0 && le2.Rank < le1.Rank) { model.AddConstr(Edges[i] <= 0, "s" + i.ToString()); if (print) LP += "(a" + LPEdges[i].Applicant.ID + ", p" + LPEdges[i].Post.ID + ") <= 0;" + Environment.NewLine; for (int j = 0; j < LPEdges[i].Applicant.Priorities.Count; j++) { if (LPEdges[i].Applicant.Priorities[j].Target == LPEdges[i].Post.ID && LPEdges[i].Rank == LPEdges[i].Applicant.Priorities[j].Rank) { LPEdges[i].Applicant.Priorities.RemoveAt(j); } } break; } } } if (print) LP += Environment.NewLine + "First Post Conditions:" + Environment.NewLine; foreach (Instance.Post p in instance.Posts) { if (p.IsF == 1) { GRBLinExpr Temp = new GRBLinExpr(); for (int i = 0; i < LPEdges.Count; i++) { if (LPEdges[i].Post == p) { Temp += Edges[i]; if (print) LP += "(a" + LPEdges[i].Applicant.ID + ", p" + LPEdges[i].Post.ID + ") + "; } } model.AddConstr(Temp >= 1.0, "f" + p.ID.ToString()); if (print) LP += ">= 1;" + Environment.NewLine; } } // Optimize model model.Optimize(); if (print) { instance.Draw().Save(path + "/1Reduced.bmp"); } for (int i = 0; i < Edges.Length; i++) { if (Edges[i].Get(GRB.DoubleAttr.X) == 1) { instance.AddMatch(LPEdges[i].Post.ID, LPEdges[i].Applicant.ID); } } if (print) { instance.Draw().Save(path + "/2Matched.bmp"); } // Dispose of model and env model.Dispose(); env.Dispose(); return instance; } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); return null; } }
static void Main() { try { // Nutrition guidelines, based on // USDA Dietary Guidelines for Americans, 2005 // http://www.health.gov/DietaryGuidelines/dga2005/ string[] Categories = new string[] { "calories", "protein", "fat", "sodium" }; int nCategories = Categories.Length; double[] minNutrition = new double[] { 1800, 91, 0, 0 }; double[] maxNutrition = new double[] { 2200, GRB.INFINITY, 65, 1779 }; // Set of foods string[] Foods = new string[] { "hamburger", "chicken", "hot dog", "fries", "macaroni", "pizza", "salad", "milk", "ice cream" }; int nFoods = Foods.Length; double[] cost = new double[] { 2.49, 2.89, 1.50, 1.89, 2.09, 1.99, 2.49, 0.89, 1.59 }; // Nutrition values for the foods double[,] nutritionValues = new double[,] { { 410, 24, 26, 730 }, // hamburger { 420, 32, 10, 1190 }, // chicken { 560, 20, 32, 1800 }, // hot dog { 380, 4, 19, 270 }, // fries { 320, 12, 10, 930 }, // macaroni { 320, 15, 12, 820 }, // pizza { 320, 31, 12, 1230 }, // salad { 100, 8, 2.5, 125 }, // milk { 330, 8, 10, 180 } // ice cream }; // Model GRBEnv env = new GRBEnv(); GRBModel model = new GRBModel(env); model.Set(GRB.StringAttr.ModelName, "diet"); // Create decision variables for the nutrition information, // which we limit via bounds GRBVar[] nutrition = new GRBVar[nCategories]; for (int i = 0; i < nCategories; ++i) { nutrition[i] = model.AddVar(minNutrition[i], maxNutrition[i], 0, GRB.CONTINUOUS, Categories[i]); } // Create decision variables for the foods to buy GRBVar[] buy = new GRBVar[nFoods]; for (int j = 0; j < nFoods; ++j) { buy[j] = model.AddVar(0, GRB.INFINITY, cost[j], GRB.CONTINUOUS, Foods[j]); } // The objective is to minimize the costs model.Set(GRB.IntAttr.ModelSense, 1); // Update model to integrate new variables model.Update(); // Nutrition constraints for (int i = 0; i < nCategories; ++i) { GRBLinExpr ntot = 0.0; for (int j = 0; j < nFoods; ++j) ntot += nutritionValues[j,i] * buy[j]; model.AddConstr(ntot == nutrition[i], Categories[i]); } // Solve model.Optimize(); PrintSolution(model, buy, nutrition); Console.WriteLine("\nAdding constraint: at most 6 servings of dairy"); model.AddConstr(buy[7] + buy[8] <= 6.0, "limit_dairy"); // Solve model.Optimize(); PrintSolution(model, buy, nutrition); // Dispose of model and env model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } }
public void AddNutritionConstraints(GRBModel model) { // Nutrition constraints for (int i = 0; i < NumberOfCategories; ++i) { GRBLinExpr ntot = 0.0; for (int j = 0; j < numberOfFoodTypes; ++j) ntot += nutritionValues[j, i] * boughtAmount[j]; model.AddConstr(ntot == nutritionDecisionVariables[i], categories[i]); } }
public void AddExtraConstraint(GRBModel model) { model.AddConstr(boughtAmount[7] + boughtAmount[8] <= 6.0, "limit_dairy"); }
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() { 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); } }
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 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); } }
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 { 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 void RangeSetup(GRBModel model, double lb, INumExpr expr, double ub, string name) { this.model = model; this.LB = lb; this.UB = ub; this._name = name; if (expr == null) { _expr = new INumExpr(); } else { _expr = expr; } this.constr = null; if (lb > -System.Double.MaxValue && ub < System.Double.MaxValue) { // "lb < expr < ub" --> " expr - newvar = lb, 0 < newvar < ub - lb" GRBVar var = model.AddVar(0, ub - lb, 0, GRB.CONTINUOUS, null); GRBLinExpr modExpr = Expr.expr - var; this.constr = model.AddConstr(modExpr, GRB.EQUAL, lb, name); } else if (lb > -System.Double.MaxValue) { this.constr = model.AddConstr(Expr.expr, GRB.GREATER_EQUAL, lb, name); } else { this.constr = model.AddConstr(Expr.expr, GRB.LESS_EQUAL, ub, name); } }
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); } }