Пример #1
0
        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);
        }
Пример #2
0
        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);
            }
        }
Пример #3
0
        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);
            }
        }