public OptimizationResult Solve(long timeLimitMilliseconds, EventHandler <ProgressReport> progress, EventHandler <string> consoleProgress) { // convenience void LogPercentage(double percentage) { progress?.Invoke(this, new ProgressReport(percentage)); } void LogMessage(string message) { consoleProgress?.Invoke(this, message); } var sw = Stopwatch.StartNew(); LogMessage("Solving started."); LogPercentage(0.0); // Create input data for internal solver. // Use mostly one per core. var runs = GetStrategies(Environment.ProcessorCount).Select(s => (data: Converter.Convert(input, config.MaxNumberOfAdditionalSantas), strategy: s)).ToArray(); // adapt timelimit so that no overdraw is made if (runs.Length > Environment.ProcessorCount) { timeLimitMilliseconds /= (long)Math.Ceiling((double)runs.Length / Environment.ProcessorCount); } LogMessage("Conversion of input finished."); LogPercentage(0.01); // solve var results = runs.AsParallel().Select(r => InternalSolver.Solve(r.data, timeLimitMilliseconds, r.strategy)).ToArray(); // print strategies / results LogPercentage(0.99); LogMessage("Runs finished. Printing result:"); for (int i = 0; i < runs.Length; i++) { LogMessage($"Strategy: {runs[i].strategy.GetType().Name} Cost: {results[i].Cost()}"); } // get best result var bestResult = results.OrderBy(r => r.Cost()).First(); bestResult.TimeElapsed = (int)sw.Elapsed.TotalSeconds; LogMessage("Solver finished."); LogPercentage(1); return(bestResult); }
public void AddConstraints(RoutingData data, RoutingModel model, IntVar cumulTime, RoutingDimension timeDim, int visit) { var desired = InternalSolver.GetDesired(data, visit); if (desired.HasValue) { // add soft time window for desired cumulTime.SetRange(desired.Value.from, desired.Value.to); } else { // forbid visit in unavailable new UnavailableOnlyStrategy().AddConstraints(data, model, cumulTime, timeDim, visit); } }
public void AddConstraints(RoutingData data, RoutingModel model, IntVar cumulTime, RoutingDimension timeDim, int visit) { // forbid visit in unavailable new UnavailableOnlyStrategy().AddConstraints(data, model, cumulTime, timeDim, visit); // add soft time window for desired var desired = InternalSolver.GetDesired(data, visit); if (desired.HasValue) { var cost = InternalSolver.GetDesiredCoefficient(data, visit); timeDim.SetCumulVarSoftUpperBound(visit, desired.Value.to, cost); timeDim.SetCumulVarSoftLowerBound(visit, desired.Value.from, cost); } }