private ResultState SolveInternal()
        {
            PrintDebugRessourcesBefore("SolveInternal");

            var param = new MPSolverParameters();

            param.SetDoubleParam(MPSolverParameters.RELATIVE_MIP_GAP, MIP_GAP);
            if (timelimit != 0)
            {
                solver.SetTimeLimit(timelimit);
            }
#if DEBUG
            solver.EnableOutput();
#else
            solver.SuppressOutput();
#endif
            resultState = FromGoogleResultState(solver.Solve(param));

            PrintDebugRessourcesAfter();
#if DEBUG
            PrintDebugOutput();
#endif

            return(resultState);
        }
 public override void Solve()
 {
     _solutionStatus = Solver.Solve();
 }
예제 #3
0
        public static void Run(string inputFile)
        {
            Console.WriteLine("Start Knapsack solver...");

            //read input
            string[] inputs = File.ReadAllLines(inputFile);
            string[] line   = inputs[0].Split(' ');

            int N = Convert.ToInt32(line[0]); // number of objects to pick from
            int K = Convert.ToInt32(line[1]); // capacity of the sack

            //create solver
            // GLOP_LINEAR_PROGRAMMING, CBC_MIXED_INTEGER_PROGRAMMING
            Google.OrTools.LinearSolver.Solver solver
                = Google.OrTools.LinearSolver.Solver.CreateSolver("knapsack", "CBC_MIXED_INTEGER_PROGRAMMING");

            //objective
            Objective objective = solver.Objective();

            objective.SetMaximization();

            //variables
            Variable[] variables = solver.MakeBoolVarArray(N);

            //constraints
            Constraint capacityConstraint = solver.MakeConstraint(0, K);

            for (int i = 0; i < N; i++)
            {
                //get input parameters
                line = inputs[i + 1].Split(' ');
                double value  = Convert.ToDouble(line[0]);
                double weight = Convert.ToDouble(line[1]);

                Variable x = variables[i];

                //add to objective
                objective.SetCoefficient(x, value);

                //add to constraint
                capacityConstraint.SetCoefficient(x, weight);
            }

            MPSolverParameters solverParams = new MPSolverParameters();

            Console.WriteLine("Start solving...");
            int resultStatus = solver.Solve();

            double resultObjective = 0.0;
            string resultVariables = "";

            Console.WriteLine("Solver finished");
            Console.WriteLine("Solution status: " + resultStatus.ToString());

            string outputFile = new FileInfo(inputFile).Directory.FullName + @"\output.txt";

            if (File.Exists(outputFile))
            {
                File.Delete(outputFile);
            }

            if (resultStatus != Google.OrTools.LinearSolver.Solver.OPTIMAL)
            {
                resultStatus = 0;
                Console.WriteLine("The problem don't have an optimal solution.");
            }
            else
            {
                resultStatus = 1;
                Console.WriteLine("Solution objective: " + solver.Objective().Value().ToString());
                resultObjective = solver.Objective().Value();

                foreach (Variable x in variables)
                {
                    if (resultVariables == "")
                    {
                        resultVariables = x.SolutionValue().ToString();
                    }
                    else
                    {
                        resultVariables += " " + x.SolutionValue().ToString();
                    }
                }
                Console.WriteLine("Solution variables: " + resultVariables.ToString());
            }

            using (System.IO.StreamWriter file = new System.IO.StreamWriter(outputFile))
            {
                file.WriteLine(resultObjective.ToString() + " " + resultStatus.ToString());
                file.WriteLine(resultVariables);
            }
        }
예제 #4
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);
        }