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;
}
}
}