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();
        }
예제 #2
0
  /**
   *
   * 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();
        }
예제 #4
0
 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");
 }
예제 #5
0
 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");
 }
예제 #6
0
  /**
   *
   * 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());

  }
예제 #7
0
 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");
 }
예제 #8
0
 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");
 }
예제 #9
0
 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");
 }
예제 #10
0
 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");
 }
예제 #11
0
        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);
        }
예제 #12
0
  /**
   *
   * 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());

  }