Пример #1
0
        public void SonnetCbcTest2()
        {
            Console.WriteLine("SonnetCbcTest2 - Cbc set CbcStrategyDefault");

            Model  model  = Model.New("MIP-124725.mps"); // added file to project, "Copy Always"
            Solver solver = new Solver(model, typeof(OsiCbcSolverInterface));

            model.ObjectiveSense = ObjectiveSense.Minimise;

            OsiCbcSolverInterface osisolver = solver.OsiSolver as OsiCbcSolverInterface;

            Assert.IsTrue(osisolver != null);

            CbcModel cbcModel = osisolver.getModelPtr();

            cbcModel.setStrategy(new CbcStrategyDefault(1, 5, 5));
            //cbcModel.strategy().setupCutGenerators(cbcModel);

            solver.AutoResetMIPSolve = true;
            solver.Minimise();

            string message = "Used cut generators: " + string.Join(", ", cbcModel.cutGenerators().Select(generator => generator.generator().GetType().Name));

            Console.WriteLine(message);

            Assert.IsTrue(Utils.EqualsDouble(model.Objective.Value, 124725));

            solver.Solve(true);
            Assert.IsTrue(Utils.EqualsDouble(model.Objective.Value, 104713.12807881772));
        }
Пример #2
0
        public void SonnetCbcTest7()
        {
            Console.WriteLine("SonnetCbcTest7 - Test CbcModel setObjValue for Maximization");
            SonnetLog.Default.LogLevel = 4;
            // This test check the improvement of solving when a good solution obj value is given in advance.
            // This should help most if the relaxation bound is tight.

            Model model = Model.New("mip-124725.mps");

            Assert.IsTrue(model.ObjectiveSense == ObjectiveSense.Minimise);

            model.Objective      = new Objective(-1.0 * (Expression)model.Objective);
            model.ObjectiveSense = ObjectiveSense.Maximise;

            Solver solver = new Solver(model, typeof(OsiCbcSolverInterface));
            OsiCbcSolverInterface osiCbc = solver.OsiSolver as OsiCbcSolverInterface;

            osiCbc.AddCbcSolverArgs("-preprocess", "off");
            osiCbc.AddCbcSolverArgs("-strong", "0");
            osiCbc.AddCbcSolverArgs("-heurist", "off");
            osiCbc.AddCbcSolverArgs("-cuts", "off");

            solver.Solve();
            Assert.IsTrue(solver.IsFeasible());
            Assert.IsTrue(solver.IsProvenOptimal, "should be optimal");

            solver.Solve();
            Assert.IsTrue(solver.IsFeasible());
            Assert.IsTrue(solver.IsProvenOptimal, "should be optimal");

            // but use at least one solve (or generate and savebefore) to ensure there's something to reset to
            solver.AutoResetMIPSolve = false; // dont reset after mip solve, otherwise CbcModel has been reset after solver.Solve()

            solver.Solve();
            Assert.IsTrue(solver.IsFeasible());
            Assert.IsTrue(solver.IsProvenOptimal, "should be optimal");
            int    nodes1    = osiCbc.getNodeCount();
            double objValue1 = model.Objective.Value;

            solver.ResetAfterMIPSolve();

            osiCbc.Model.setObjValue(-125035.0);
            solver.Solve();
            Assert.IsTrue(solver.IsFeasible());
            Assert.IsTrue(solver.IsProvenOptimal, "should be optimal");
            int nodes2 = osiCbc.getNodeCount();

            Assert.IsTrue(nodes1 > nodes2, "Providing a feasible obj value must result in improved performance, but number of nodes went from {nodes1} to {nodes2}.");

            solver.ResetAfterMIPSolve();

            solver.Solve();
            Assert.IsTrue(solver.IsFeasible());
            Assert.IsTrue(solver.IsProvenOptimal, "should be optimal");
            int nodes1b = osiCbc.getNodeCount();

            Assert.IsTrue(nodes1 == nodes1b, "Number of nodes should be equal to original but {nodes1} != {nodes1b}.");

            // Not advised to use osiCbc.Model.setCutoff  Unreliable results especially for Maximisation
        }
Пример #3
0
        public void SonnetCbcTest8()
        {
            Console.WriteLine("SonnetCbcTest8 - Test solver.SetMIPStart");
            SonnetLog.Default.LogLevel = 4;

            Model model    = Model.New("mip-124725.mps");
            var   objLimit = model.Add((Expression)model.Objective >= 125035.0);

            // try get the intermediate solution with value 125035 by adding a constraint and then solving
            Solver solver = new Solver(model, typeof(OsiCbcSolverInterface));

            solver.Solve();
            Assert.IsTrue(solver.IsProvenOptimal, "should be optimal");
            Assert.IsTrue(Utils.EqualsDouble(model.Objective.Value, 125035));
            // Now the Variable Values represent the solution 125035

            // To see the benefit, disable preprocessing etc.
            OsiCbcSolverInterface osiCbc = solver.OsiSolver as OsiCbcSolverInterface;

            osiCbc.AddCbcSolverArgs("-preprocess", "off");
            osiCbc.AddCbcSolverArgs("-strong", "0");
            osiCbc.AddCbcSolverArgs("-heurist", "off");
            osiCbc.AddCbcSolverArgs("-cuts", "off");

            solver.AutoResetMIPSolve = false;
            objLimit.Enabled         = false; // disable the artificial constraint on objective value
            solver.SetMIPStart(true);         // take the Variable Values

            solver.Solve();
            Assert.IsTrue(solver.IsProvenOptimal, "should be optimal");
            Assert.IsTrue(solver.IsFeasible());
            int nodes1 = osiCbc.getNodeCount(); // nodes using setMIPStart

            Assert.IsTrue(Utils.EqualsDouble(model.Objective.Value, 124725));

            solver.ResetAfterMIPSolve();
            //objLimit.Enabled = true;
            //objLimit.Enabled = false;
            solver.Solve();
            Assert.IsTrue(solver.IsProvenOptimal, "should be optimal");
            Assert.IsTrue(solver.IsFeasible());
            Assert.IsTrue(solver.IsProvenOptimal, "should be optimal");
            int nodes2 = osiCbc.getNodeCount(); // nodes using setMIPStart

            Assert.IsTrue(Utils.EqualsDouble(model.Objective.Value, 124725));

            Assert.IsTrue(nodes1 < nodes2, "Providing a feasible solution must result in improved performance, but number of nodes went from {nodes1} to {nodes2}.");
        }
Пример #4
0
        public void SonnetCbcTest3()
        {
            Console.WriteLine("SonnetCbcTest3 - Test log message handler vs CbcMain");

            Model  model  = Model.New("MIP-124725.mps"); // added file to project, "Copy Always";
            Solver solver = new Solver(model, typeof(OsiCbcSolverInterface));

            SonnetLog.Default.LogLevel = 2;

            OsiCbcSolverInterface osisolver = solver.OsiSolver as OsiCbcSolverInterface;

            //SonnetLog.Default.PassToSolver(osisolver);
            Assert.IsTrue(osisolver != null);

            CbcModel cbcModel = osisolver.getModelPtr();

            solver.Minimise();
            Ensure.IsTrue(SonnetLog.Default.LogLevel == 2, "Somehow the SonnetLog LogLevel changed!");

            Assert.IsTrue(Utils.EqualsDouble(model.Objective.Value, 124725));
        }
Пример #5
0
        public void SonnetCbcTest1()
        {
            Console.WriteLine("SonnetCbcTest1 - Cbc test set CbcStrategyNull and addCutGenerator");

            Model  model  = Model.New("MIP-124725.mps"); // added file to project, "Copy Always";
            Solver solver = new Solver(model, typeof(OsiCbcSolverInterface));

            OsiCbcSolverInterface osisolver = solver.OsiSolver as OsiCbcSolverInterface;

            Assert.IsTrue(osisolver != null);

            CbcModel cbcModel = osisolver.getModelPtr();

            cbcModel.setStrategy(new CbcStrategyNull());
            cbcModel.addCutGenerator(new CglProbing());
            Assert.IsTrue(cbcModel.numberCutGenerators() == 1);
            //cbcModel.cutGenerators();

            solver.Minimise();

            Assert.IsTrue(Utils.EqualsDouble(model.Objective.Value, 124725));
            //Assert.IsTrue(Utils.EqualsDouble(model.Objective.Value, 104713.12807881772));
        }
Пример #6
0
        public void SonnetCbcTest4()
        {
            Console.WriteLine("SonnetCbcTest4 - Test CbcModel with args to stop after solution");

            SonnetLog.Default.LogLevel = 0;
            SonnetLog.Default.Debug("Log Debug");
            SonnetLog.Default.Info("Log Info");
            SonnetLog.Default.Warn("Log Warn");
            SonnetLog.Default.Error("Log Error");

            Model      model = Model.New("mas74.mps");
            Expression obj   = (Expression)model.Objective;

            obj.Add(10000.0); // check that the objective constant is taken into account.
            model.Objective = obj;

            Solver solver = new Solver(model, typeof(OsiCbcSolverInterface));
            OsiCbcSolverInterface osiCbc = solver.OsiSolver as OsiCbcSolverInterface;

            osiCbc.getModelPtr().setMaximumSeconds(5.0); // Stop within 5 seconds
            solver.Solve();

            Assert.IsTrue(solver.IsFeasible(), "with solution and hence feasible");
            Assert.IsFalse(solver.IsProvenOptimal, "should not be optimal yet (unless solver got a lot better)");
            Assert.IsTrue(model.Objective.Bound < model.Objective.Value, "Bound must be less than current solution.");

            // The problem is minimization.
            // Allow also better solutions, but not worse.
            // If your machine is significantly slower, the solution value will be worse (higher) and this test will fail--but can be ignored.
            Assert.IsTrue(model.Objective.Value >= 21801.18 && model.Objective.Value <= 22465, $"Best minimization solution of mas74 until now is ${model.Objective.Value} but should be between 21801.18 (opt) and 22465");

            // bound is expected to be 20482 on the reference machine.
            // If your machine is slower, the bound will be worse (lower)
            // If your machine is faster, the bound could be better (higher)
            Assert.IsTrue(model.Objective.Bound >= 20300.0 && model.Objective.Bound <= 20700.0, $"Bound (Gap) is now ${model.Objective.Bound} but should be betweeen 20300 and 20700");
        }
Пример #7
0
        public void SonnetCbcTest5()
        {
            Console.WriteLine("SonnetCbcTest5 - Test CbcModel Event Handler");

            SonnetLog.Default.LogLevel = 4;
            SonnetLog.Default.Debug("Log Debug");
            SonnetLog.Default.Info("Log Info");
            SonnetLog.Default.Warn("Log Warn");
            SonnetLog.Default.Error("Log Error");

            Model  model  = Model.New("mas74.mps");
            Solver solver = new Solver(model, typeof(OsiCbcSolverInterface));
            OsiCbcSolverInterface osiCbc = solver.OsiSolver as OsiCbcSolverInterface;

            osiCbc.getModelPtr().setMaximumSeconds(5.0); // Stop within 5 seconds

            CbcEventHandler handler = delegate(CbcModel m, CbcEvent cbcEvent) { return(CbcAction.noAction); };

            handler += new CbcEventHandler(SonnetCbcTest5EventHandler); // will stop after 2nd solution
            osiCbc.Model.passInEventHandler(handler);                   //

            int numCalls = 0;

            CbcSolver.CallBack = delegate(CbcModel m, int whereFrom) { numCalls++; return(0); };
            solver.Solve();
            // DONT use the cbcModel after solver.Solve() because of ResetAfterMIPSolveInternal at the end of Solve()

            Assert.IsTrue(solver.IsFeasible());
            Assert.IsFalse(solver.IsProvenOptimal, "should not be optimal yet");
            Assert.IsTrue(SonnetCbcTest5numSolutions >= 2, "should have found at least two solutions by now");
            Assert.IsTrue(numCalls == 5);

            // Allow also better solutions, but not worse. The problem is minimization.
            // If you machine is significantly slower, the solution will be worse and this test will fail--but can be ignored.
            Assert.IsTrue(model.Objective.Value >= 11801.18 && model.Objective.Value <= 14168.34, $"Best minimization solution of mas74 until now is ${model.Objective.Value} but should be between 11801.18 (opt) and 14168.34");
        }