Examples : SolverCallbackExample.cs

using System;
using System.Diagnostics;
using System.Threading;
using VRSolver;
 
namespace Examples
{
    /// <summary>
    /// An example which shows how to get information about the best solution 
    /// found so far from the Solver as it is running. It also shows how to 
    /// manually stop the Solver early.
    /// </summary>
    internal class SolverCallbackExample
    { 
        Solver solver = null;         // The solver
        Problem problem = null;       // The problem
        Stopwatch stopwatch = null;   // A stopwatch for timing the solver
        bool newthread = true;        // If true then run the solver in a new thread to enable stopping early
        bool stopped = false;         // Stop the solver early by setting this true
        bool solverFinished = false;
        double lastElapsed = 0;
 
        internal void Start()
        {
            stopwatch = new Stopwatch(); 
            stopwatch.Start();
            lastElapsed = 0;
            solverFinished = false;
            stopped = false;
 
            //
            // Load the Problem from a JSON file
            //
            problem = Problem.Load("..\\..\\..\\ExampleData\\Demo-A.json");
 
            //
            // Create a solver
            //
            solver = new Solver
            {
                // Set the maximum time to give the solver
                MaximumSolveTime = new TimeSpan(0, 0, 10),
            };
 
            //
            // Add an event handler to receive information from the solver 
            // as it is solving. This will also allow is to manually stop the
            // solver early. This event is typically raised several times per 
            // second.
            //
            solver.SolverStatusUpdated += SolverStatusUpdated;
 
            if (newthread)
                Console.WriteLine("Solving... (Press 's' then enter to stop)");
            else
                Console.WriteLine("Solving...");
 
            if (newthread)
            {
                StartSolverInNewThread();
                AwaitInput();
            }
            else
            {
                StartSolver(); // Start the solver
            }
        }
 
        private void SolverStatusUpdated(object sender, SolverStatusUpdatedArgs e)
        {
            //
            // This event could be raised every 0.1 seconds so it is  
            // recommended to execute the main code once every half second 
            // (500 ms) for example. It is also recommended to keep this 
            // method fast because the solver waits while this method is 
            // executing (or execute this code in a new thread).
            //
            if ((e.ElapsedTime.TotalMilliseconds - lastElapsed) >= 500)
            {
                lastElapsed = e.ElapsedTime.TotalMilliseconds;
 
                if (stopped)
                {
                    // The solver can be stopped by setting this field to true.
                    // It will stop as soon as possible after calling this method
                    // (usually within a second).
                    solver.Stop = true;
                    return;
                }
 
                Console.WriteLine("Time elapsed=" + e.ElapsedTime.TotalMilliseconds + "ms." +
                                    " Best so far=" + e.BestSolution.ObjectiveFunctionValue
                                    + ", solution evaluations=" + e.TotalSolutionsGenerated);
 
                //Console.WriteLine(e.Message);
            }
        }
 
        private void StartSolverInNewThread()
        {
            ThreadStart entryPoint = new ThreadStart(StartSolver);
            Thread solverThread = new Thread(entryPoint);
            solverThread.Name = "Solver";
            solverThread.Start();
        }
 
        private void StartSolver()
        {
            // Solve the problem and get the solution
            Solution solution = solver.Solve(problem);
 
            // Report the solution
            TimeSpan elapsed = stopwatch.Elapsed;
 
            Console.WriteLine("Total distance   = " + solution.TotalDistance.ToString("0.00"));
            Console.WriteLine("Total routes     = " + solution.ResourcesUsedCount);
            Console.WriteLine("Total work time  = " + solution.TotalWorkTime.TotalMinutes.ToString("0.00"));
            Console.WriteLine("Solve time       = " + elapsed.TotalSeconds + " seconds.");
            Console.WriteLine("                 = " + elapsed.Days + " days, " + elapsed.Hours + " hours, "
                                                    + elapsed.Minutes + " minutes, " + elapsed.Seconds + " seconds, "
                                                    + elapsed.Milliseconds + " milliseconds");
 
            WriteSolutionExample.WriteSolutionBasicFormat(solution, "SolutionBasic.txt");
 
            solverFinished = true;
            Environment.Exit(0); // In case we are awaiting input in the threaded version
        }
 
        private void AwaitInput()
        {
            while (!solverFinished)
            {
                string line = Console.ReadLine();
 
                if (line.Equals("s"StringComparison.OrdinalIgnoreCase))
                {
                    Console.WriteLine(Environment.NewLine + "Solver stopping...");
                    StopSolver();
                    break;
                }
            }
        }
 
        /// <summary>
        /// Stop the solver.
        /// </summary>
        internal void StopSolver()
        {
            stopped = true;
            solver.Stop = true;
        }
    }
}