private void AddTargetFunction() { PrintDebugRessourcesBefore("AddTargetFunction"); var factory = new TargetFunctionFactory(solverData); var targetFunction = new GLS.LinearExpr(); targetFunction += factory.CreateTargetFunction(TargetType.MinTime, WaytimeWeight); targetFunction += factory.CreateTargetFunction(TargetType.TryVisitDesired, DesiredWeight); solverData.Solver.Minimize(targetFunction); // 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]; solver.Add(targetFunction <= totalTimePresolved * WaytimeWeight); } var minWayTime = solverData.Input.Distances.Cast <int>().Where(i => i > 0).Min(); solver.Add(targetFunction >= (minWayTime * (solverData.NumberOfVisits + 1) + solverData.Input.VisitsDuration.Sum()) * (WaytimeWeight - DesiredWeight)); PrintDebugRessourcesAfter(); }
/** * * Volsay problem. * * From the OPL model volsay.mod. * * * Also see http://www.hakank.org/or-tools/volsay.py * */ private static void Solve() { Solver solver = new Solver("Volsay", Solver.CLP_LINEAR_PROGRAMMING); // // Variables // Variable Gas = solver.MakeNumVar(0, 100000, "Gas"); Variable Chloride = solver.MakeNumVar(0, 100000, "Cloride"); Constraint c1 = solver.Add(Gas + Chloride <= 50); Constraint c2 = solver.Add(3 * Gas + 4 * Chloride <= 180); solver.Maximize(40 * Gas + 50 * Chloride); int resultStatus = solver.Solve(); if (resultStatus != Solver.OPTIMAL) { Console.WriteLine("The problem don't have an optimal solution."); return; } Console.WriteLine("Objective: {0}", solver.ObjectiveValue()); Console.WriteLine("Gas : {0} ReducedCost: {1}", Gas.SolutionValue(), Gas.ReducedCost()); Console.WriteLine("Chloride : {0} ReducedCost: {1}", Chloride.SolutionValue(), Chloride.ReducedCost()); Console.WriteLine("c1 : DualValue: {0} Activity: {1}", c1.DualValue(), c1.Activity()); Console.WriteLine("c2 : DualValue: {0} Activity: {1}", c2.DualValue(), c2.Activity()); Console.WriteLine("\nWallTime: " + solver.WallTime()); Console.WriteLine("Iterations: " + solver.Iterations()); }
private void AddTargetFunction() { PrintDebugRessourcesBefore("AddTargetFunction"); var targetFunction = new LinearExpr(); var hour = 3600; var santaWorkingTime = new LinearExpr[solverData.NumberOfSantas]; var longestDay = solver.MakeIntVar(0, int.MaxValue, "longest day"); foreach (var santa in Enumerable.Range(0, solverData.NumberOfSantas)) { santaWorkingTime[santa] = solverData.Variables.SantaVisitTime[santa] + solverData.Variables.SantaRouteCost[santa]; solver.Add(longestDay >= santaWorkingTime[santa]); } var workingTimeFactor = (40d / hour); var longestDayFactor = (30d / hour); targetFunction = workingTimeFactor * santaWorkingTime.Sum() + longestDayFactor * longestDay; solverData.Solver.Minimize(targetFunction); PrintDebugRessourcesAfter(); }
static void TestVarAddition() { Console.WriteLine("Running TestVarAddition"); Solver solver = new Solver("TestVarAddition", Solver.CLP_LINEAR_PROGRAMMING); Variable x = solver.MakeNumVar(0.0, 100.0, "x"); Variable y = solver.MakeNumVar(0.0, 100.0, "y"); Constraint ct1 = solver.Add(x + y == 1); CheckDoubleEq(ct1.GetCoefficient(x), 1.0, "test1"); CheckDoubleEq(ct1.GetCoefficient(y), 1.0, "test2"); Constraint ct2 = solver.Add(x + x == 1); CheckDoubleEq(ct2.GetCoefficient(x), 2.0, "test3"); Constraint ct3 = solver.Add(x + (y + x) == 1); CheckDoubleEq(ct3.GetCoefficient(x), 2.0, "test4"); CheckDoubleEq(ct3.GetCoefficient(y), 1.0, "test5"); Constraint ct4 = solver.Add(x + (y + x + 3) == 1); CheckDoubleEq(ct4.GetCoefficient(x), 2.0, "test4"); CheckDoubleEq(ct4.GetCoefficient(y), 1.0, "test5"); CheckDoubleEq(ct4.Lb(), -2.0, "test6"); CheckDoubleEq(ct4.Ub(), -2.0, "test7"); }
static void TestVarOperator() { Console.WriteLine("Running TestVarOperator"); Solver solver = new Solver("TestVarOperator", Solver.CLP_LINEAR_PROGRAMMING); Variable x = solver.MakeNumVar(0.0, 100.0, "x"); Constraint ct1 = solver.Add(x >= 1); Constraint ct2 = solver.Add(x <= 1); Constraint ct3 = solver.Add(x == 1); Constraint ct4 = solver.Add(1 >= x); Constraint ct5 = solver.Add(1 <= x); Constraint ct6 = solver.Add(1 == x); CheckDoubleEq(ct1.GetCoefficient(x), 1.0, "test1"); CheckDoubleEq(ct2.GetCoefficient(x), 1.0, "test2"); CheckDoubleEq(ct3.GetCoefficient(x), 1.0, "test3"); CheckDoubleEq(ct4.GetCoefficient(x), 1.0, "test4"); CheckDoubleEq(ct5.GetCoefficient(x), 1.0, "test5"); CheckDoubleEq(ct6.GetCoefficient(x), 1.0, "test6"); CheckDoubleEq(ct1.Lb(), 1.0, "test7"); CheckDoubleEq(ct1.Ub(), double.PositiveInfinity, "test8"); CheckDoubleEq(ct2.Lb(), double.NegativeInfinity, "test9"); CheckDoubleEq(ct2.Ub(), 1.0, "test10"); CheckDoubleEq(ct3.Lb(), 1.0, "test11"); CheckDoubleEq(ct3.Ub(), 1.0, "test12"); CheckDoubleEq(ct4.Lb(), double.NegativeInfinity, "test13"); CheckDoubleEq(ct4.Ub(), 1.0, "test14"); CheckDoubleEq(ct5.Lb(), 1.0, "test15"); CheckDoubleEq(ct5.Ub(), double.PositiveInfinity, "test16"); CheckDoubleEq(ct6.Lb(), 1.0, "test17"); CheckDoubleEq(ct6.Ub(), 1.0, "test18"); }
/** * * Volsay problem. * * From the OPL model volsay.mod. * This version use arrays and matrices * * * Also see * http://www.hakank.org/or-tools/volsay2.cs * http://www.hakank.org/or-tools/volsay3.py * */ private static void Solve() { Solver solver = new Solver("Volsay3", Solver.CLP_LINEAR_PROGRAMMING); int num_products = 2; IEnumerable<int> PRODUCTS = Enumerable.Range(0, num_products); String[] products = {"Gas", "Chloride"}; String[] components = {"nitrogen", "hydrogen", "chlorine"}; int[,] demand = { {1,3,0}, {1,4,1}}; int[] profit = {30,40}; int[] stock = {50,180,40}; // // Variables // Variable[] production = new Variable[num_products]; foreach(int p in PRODUCTS) { production[p] = solver.MakeNumVar(0, 100000, products[p]); } // // Constraints // int c_len = components.Length; Constraint[] cons = new Constraint[c_len]; for(int c = 0; c < c_len; c++) { cons[c] = solver.Add( (from p in PRODUCTS select (demand[p,c]*production[p])). ToArray().Sum() <= stock[c]); } // // Objective // solver.Maximize( (from p in PRODUCTS select (profit[p]*production[p])). ToArray().Sum() ); if (solver.Solve() != Solver.OPTIMAL) { Console.WriteLine("The problem don't have an optimal solution."); return; } Console.WriteLine("Objective: {0}", solver.ObjectiveValue()); foreach(int p in PRODUCTS) { Console.WriteLine("{0,-10}: {1} ReducedCost: {2}", products[p], production[p].SolutionValue(), production[p].ReducedCost()); } for(int c = 0; c < c_len; c++) { Console.WriteLine("Constraint {0} DualValue {1} Activity: {2} lb: {3} ub: {4}", c, cons[c].DualValue(), cons[c].Activity(), cons[c].Lb(), cons[c].Ub()); } Console.WriteLine("\nWallTime: " + solver.WallTime()); Console.WriteLine("Iterations: " + solver.Iterations()); }
static void TestVarMultiplication() { Console.WriteLine("Running TestVarMultiplication"); Solver solver = new Solver("TestVarMultiplication", Solver.CLP_LINEAR_PROGRAMMING); Variable x = solver.MakeNumVar(0.0, 100.0, "x"); Variable y = solver.MakeNumVar(0.0, 100.0, "y"); Constraint ct1 = solver.Add(3 * x == 1); CheckDoubleEq(ct1.GetCoefficient(x), 3.0, "test1"); Constraint ct2 = solver.Add(x * 3 == 1); CheckDoubleEq(ct2.GetCoefficient(x), 3.0, "test2"); Constraint ct3 = solver.Add(x + (2 * y + 3 * x) == 1); CheckDoubleEq(ct3.GetCoefficient(x), 4.0, "test3"); CheckDoubleEq(ct3.GetCoefficient(y), 2.0, "test4"); Constraint ct4 = solver.Add(x + 5 * (y + x + 3) == 1); CheckDoubleEq(ct4.GetCoefficient(x), 6.0, "test5"); CheckDoubleEq(ct4.GetCoefficient(y), 5.0, "test6"); CheckDoubleEq(ct4.Lb(), -14.0, "test7"); CheckDoubleEq(ct4.Ub(), -14.0, "test8"); Constraint ct5 = solver.Add(x + (2 * y + x + 3) * 3 == 1); CheckDoubleEq(ct5.GetCoefficient(x), 4.0, "test9"); CheckDoubleEq(ct5.GetCoefficient(y), 6.0, "test10"); CheckDoubleEq(ct5.Lb(), -8.0, "test11"); CheckDoubleEq(ct5.Ub(), -8.0, "test12"); }
static void TestSumArray() { Console.WriteLine("Running TestSumArray"); Solver solver = new Solver("TestSumArray", Solver.CLP_LINEAR_PROGRAMMING); Variable[] x = solver.MakeBoolVarArray(10, "x"); Constraint ct1 = solver.Add(x.Sum() == 3); CheckDoubleEq(ct1.GetCoefficient(x[0]), 1.0, "test1"); Constraint ct2 = solver.Add(-2 * x.Sum() == 3); CheckDoubleEq(ct2.GetCoefficient(x[0]), -2.0, "test2"); LinearExpr[] array = new LinearExpr[] { x[0]+ 2.0, x[0] + 3, x[0] + 4 }; Constraint ct3 = solver.Add(array.Sum() == 1); CheckDoubleEq(ct3.GetCoefficient(x[0]), 3.0, "test3"); CheckDoubleEq(ct3.Lb(), -8.0, "test4"); CheckDoubleEq(ct3.Ub(), -8.0, "test5"); }
static void TestInequalities() { Console.WriteLine("Running TestInequalities"); Solver solver = new Solver("TestInequalities", Solver.CLP_LINEAR_PROGRAMMING); Variable x = solver.MakeNumVar(0.0, 100.0, "x"); Variable y = solver.MakeNumVar(0.0, 100.0, "y"); Constraint ct1 = solver.Add(2 * (x + 3) + 5 * (y + x -1) >= 3); CheckDoubleEq(ct1.GetCoefficient(x), 7.0, "test1"); CheckDoubleEq(ct1.GetCoefficient(y), 5.0, "test2"); CheckDoubleEq(ct1.Lb(), 2.0, "test3"); CheckDoubleEq(ct1.Ub(), double.PositiveInfinity, "test4"); Constraint ct2 = solver.Add(2 * (x + 3) + 5 * (y + x -1) <= 3); CheckDoubleEq(ct2.GetCoefficient(x), 7.0, "test5"); CheckDoubleEq(ct2.GetCoefficient(y), 5.0, "test6"); CheckDoubleEq(ct2.Lb(), double.NegativeInfinity, "test7"); CheckDoubleEq(ct2.Ub(), 2.0, "test8"); Constraint ct3 = solver.Add(2 * (x + 3) + 5 * (y + x -1) >= 3 - x - y); CheckDoubleEq(ct3.GetCoefficient(x), 8.0, "test9"); CheckDoubleEq(ct3.GetCoefficient(y), 6.0, "test10"); CheckDoubleEq(ct3.Lb(), 2.0, "test11"); CheckDoubleEq(ct3.Ub(), double.PositiveInfinity, "test12"); Constraint ct4 = solver.Add(2 * (x + 3) + 5 * (y + x -1) <= -x - y + 3); CheckDoubleEq(ct4.GetCoefficient(x), 8.0, "test13"); CheckDoubleEq(ct4.GetCoefficient(y), 6.0, "test14"); CheckDoubleEq(ct4.Lb(), double.NegativeInfinity, "test15"); CheckDoubleEq(ct4.Ub(), 2.0, "test16"); }
static void TestBinaryOperations() { Console.WriteLine("Running TestBinaryOperations"); Solver solver = new Solver("TestBinaryOperations", Solver.CLP_LINEAR_PROGRAMMING); Variable x = solver.MakeNumVar(0.0, 100.0, "x"); Variable y = solver.MakeNumVar(0.0, 100.0, "y"); Constraint ct1 = solver.Add(x == y); CheckDoubleEq(ct1.GetCoefficient(x), 1.0, "test1"); CheckDoubleEq(ct1.GetCoefficient(y), -1.0, "test2"); Constraint ct2 = solver.Add(x == 3 * y + 5); CheckDoubleEq(ct2.GetCoefficient(x), 1.0, "test3"); CheckDoubleEq(ct2.GetCoefficient(y), -3.0, "test4"); CheckDoubleEq(ct2.Lb(), 5.0, "test5"); CheckDoubleEq(ct2.Ub(), 5.0, "test6"); Constraint ct3 = solver.Add(2 * x - 9 == y); CheckDoubleEq(ct3.GetCoefficient(x), 2.0, "test7"); CheckDoubleEq(ct3.GetCoefficient(y), -1.0, "test8"); CheckDoubleEq(ct3.Lb(), 9.0, "test9"); CheckDoubleEq(ct3.Ub(), 9.0, "test10"); Check(x == x, "test11"); Check(!(x == y), "test12"); Check(!(x != x), "test13"); Check((x != y), "test14"); }
public ProblemSolution Solve(ProblemConfiguration config) { var res = new ProblemSolution(); //https://developers.google.com/optimization/mip/mip_var_array#c_1 if (config.AvailableAmount <= 0) { throw new ArgumentException("Invalid configuration - Available amount"); } if (config.Products == null || config.Products.Count == 0) { throw new ArgumentException("Invalid configuration - Products"); } // [START solver] // Create the linear solver with the CBC backend. Solver solver = Solver.CreateSolver(/*"SimpleMipProgram",*/ "CBC"); // [END solver] // [START variables] // x, y and z are integer non-negative variables. var variables = new List <Variable>(); foreach (var p in config.Products) { var variable = solver.MakeIntVar(0.0, double.PositiveInfinity, GetVariableName(p)); variables.Add(variable); if (p.MaxUnits == 0) { solver.Add(variable == 0); } else if ( (p.MinUnits >= 0 && p.MaxUnits > 0 && p.MinUnits < p.MaxUnits) || (p.MaxUnits == p.MinUnits && p.MaxUnits > 0) ) { // other constraints solver.Add(variable >= p.MinUnits); solver.Add(variable <= p.MaxUnits); } } res.TotalVariables = solver.NumVariables(); // [END variables] // [START constraints] // (unitPriceX * x) + (unitPriceY * y) + (unitPriceZ *z) <= maxValue. var c = solver.MakeConstraint(0, config.AvailableAmount); int i = 0; foreach (var variable in variables) { c.SetCoefficient(variable, (double)config.Products[i].UnitPrice); i++; } res.TotalConstraints = solver.NumConstraints(); // [END constraints] Objective objective = solver.Objective(); i = 0; foreach (var variable in variables) { objective.SetCoefficient(variable, (double)config.Products[i].UnitPrice); i++; } objective.SetMaximization(); // [START solve] Solver.ResultStatus resultStatus = solver.Solve(); // [END solve] // [START print_solution] // Check that the problem has an optimal solution. if (resultStatus != Solver.ResultStatus.OPTIMAL) { res.HasOptimalSolution = false; return(res); } res.HasOptimalSolution = true; res.FinalAmount = (decimal)solver.Objective().Value(); res.RemainingAmount = Math.Round(config.AvailableAmount - (double)res.FinalAmount, 2); i = 0; foreach (var variable in variables) { var itemValue = variable.SolutionValue() * (double)config.Products[i].UnitPrice; itemValue = Math.Round(itemValue, 2); res.ResponseVariables.Add( new SolutionVariable() { Name = config.Products[i].Name, //variable.Name(), Code = config.Products[i].Code, SolutionValue = variable.SolutionValue(), UnitPrice = config.Products[i].UnitPrice, FinalAmount = itemValue, Description = variable.Name(), Details = $"{variable.Name()} = {variable.SolutionValue()} /// {variable.SolutionValue()} * {config.Products[i].UnitPrice} = {itemValue} euros " }); i++; } res.SolveTimeMs = solver.WallTime(); res.Iterations = solver.Iterations(); res.Nodes = solver.Nodes(); return(res); }
/** * * Volsay problem. * * From the OPL model volsay.mod. * * * * Also see * http://www.hakank.org/or-tools/volsay.cs * http://www.hakank.org/or-tools/volsay2.py * */ private static void Solve() { Solver solver = new Solver("Volsay2", Solver.CLP_LINEAR_PROGRAMMING); int num_products = 2; IEnumerable<int> PRODUCTS = Enumerable.Range(0, num_products); int Gas = 0; int Chloride = 1; String[] products = {"Gas", "Chloride"}; // // Variables // Variable[] production = new Variable[num_products]; foreach(int p in PRODUCTS) { production[p] = solver.MakeNumVar(0, 100000, products[p]); } int num_constraints = 2; IEnumerable<int> CONSTRAINTS = Enumerable.Range(0, num_constraints); Constraint[] cons = new Constraint[num_constraints]; cons[0] = solver.Add(production[Gas] + production[Chloride] <= 50); cons[1] = solver.Add(3 * production[Gas] + 4 * production[Chloride] <= 180); solver.Maximize(40 * production[Gas] + 50 * production[Chloride]); Console.WriteLine("NumConstraints: {0}", solver.NumConstraints()); int resultStatus = solver.Solve(); if (resultStatus != Solver.OPTIMAL) { Console.WriteLine("The problem don't have an optimal solution."); return; } foreach(int p in PRODUCTS) { Console.WriteLine("{0,-10}: {1} ReducedCost: {2}", products[p], production[p].SolutionValue(), production[p].ReducedCost()); } foreach(int c in CONSTRAINTS) { Console.WriteLine("Constraint {0} DualValue {1} Activity: {2} lb: {3} ub: {4}", c.ToString(), cons[c].DualValue(), cons[c].Activity(), cons[c].Lb(), cons[c].Ub() ); } Console.WriteLine("\nWallTime: " + solver.WallTime()); Console.WriteLine("Iterations: " + solver.Iterations()); }