internal GetDlpPolicyTipsResponse(EvaluationResult evalResult, OptimizationResult optimizationResult) : this(evalResult) { this.OptimizationResult = optimizationResult; }
private static string ResultToString(string info, string method, OptimizationResult <double> result) { return(info + ";" + method + ";" + result.BestValue.ToString() + ";" + result.BestTime.ToString() + ";" + result.BestIteration.ToString() + ";" + result.BestFFE.ToString()); }
public OptimizationResult Solve(long timeLimitMilliseconds, EventHandler <ProgressReport> progress, EventHandler <string> consoleProgress) { if (timeLimitMilliseconds < ip5GurobiConfig.ClusteringTimeLimitMiliseconds + ip5GurobiConfig.SchedulingTimeLimitMiliseconds) { throw new ArgumentOutOfRangeException(nameof(timeLimitMilliseconds), timeLimitMilliseconds, "must be at least the sum of ClusteringTimeLimit and SchedulingTimeLimit"); } consoleProgress?.Invoke(this, "Solving started"); var sw = Stopwatch.StartNew(); var clusteringSolverVariableBuilder = new ClusteringSolverVariableBuilder(input, ip5GurobiConfig.TimeSliceDuration); var clusteringSolverInputData = clusteringSolverVariableBuilder.Build(); var clusteringSolver = new Algorithm.Clustering.ClusteringILPSolver(clusteringSolverInputData); #if WriteMPS && DEBUG System.IO.File.WriteAllText($@"C:\Temp\iRuettae\ILP\Clustering\{new Guid()}.mps", clusterinSolver.ExportMPS()); #endif var clusteringTimeLimitMiliseconds = ip5GurobiConfig.ClusteringTimeLimitMiliseconds; if (clusteringTimeLimitMiliseconds == 0) { // avoid surpassing timelimit clusteringTimeLimitMiliseconds = timeLimitMilliseconds; } var phase1ResultState = clusteringSolver.Solve(ip5GurobiConfig.ClusteringMIPGap, clusteringTimeLimitMiliseconds); if (!(new[] { ResultState.Feasible, ResultState.Optimal }).Contains(phase1ResultState)) { return(new OptimizationResult() { OptimizationInput = input, Routes = new Route[] { }, TimeElapsed = sw.ElapsedMilliseconds / 1000, }); } var phase1Result = clusteringSolver.GetResult(); progress?.Invoke(this, new ProgressReport(0.5)); consoleProgress?.Invoke(this, "Clustering done"); consoleProgress?.Invoke(this, $"Clustering Result: {phase1Result}"); var schedulingSovlerVariableBuilders = new List <SchedulingSolverVariableBuilder>(); foreach (var santa in Enumerable.Range(0, phase1Result.Waypoints.GetLength(0))) { foreach (var day in Enumerable.Range(0, phase1Result.Waypoints.GetLength(1))) { var cluster = phase1Result.Waypoints[santa, day]; var schedulingOptimizationInput = new OptimizationInput { Visits = input.Visits.Where(v => cluster.Select(w => w.Visit - 1).Contains(v.Id)).ToArray(), Santas = new[] { input.Santas[santa] }, Days = new[] { input.Days[day] }, RouteCosts = input.RouteCosts, }; schedulingSovlerVariableBuilders.Add(new SchedulingSolverVariableBuilder(ip5GurobiConfig.TimeSliceDuration, schedulingOptimizationInput, cluster.OrderBy(wp => wp.StartTime).Select(wp => wp.Visit).ToArray())); } } var schedulingInputVariables = schedulingSovlerVariableBuilders .Where(vb => vb.Visits != null && vb.Visits.Count > 1) .Select(vb => vb.Build()); var routeResults = schedulingInputVariables .AsParallel() .Select(schedulingInputVariable => { var schedulingSolver = new SchedulingILPSolver(schedulingInputVariable); #if WriteMPS && DEBUG System.IO.File.WriteAllText($@"C:\Temp\iRuettae\ILP\Scheduling\{new Guid()}.mps", schedulingSolver.ExportMPS()); #endif var clusteringExtraTime = Math.Max(0, clusteringTimeLimitMiliseconds - sw.ElapsedMilliseconds); var schedulingTimelimitMiliseconds = ip5GurobiConfig.SchedulingTimeLimitMiliseconds + clusteringExtraTime; if (schedulingTimelimitMiliseconds == 0 && timeLimitMilliseconds != 0) { // avoid surpassing timelimit schedulingTimelimitMiliseconds = Math.Max(1, timeLimitMilliseconds - sw.ElapsedMilliseconds); } var schedulingResultState = schedulingSolver.Solve(ip5GurobiConfig.SchedulingMIPGap, schedulingTimelimitMiliseconds); if (!(new[] { ResultState.Feasible, ResultState.Optimal }).Contains(schedulingResultState)) { var realWaypointList = new List <Algorithm.Waypoint>(); // take presolved and return it for (int i = 0; i < schedulingInputVariable.Presolved.Length; i++) { var i1 = i; var currVisit = input.Visits.FirstOrDefault(v => v.Id == schedulingInputVariable.Presolved[i1] - 1); var timeStamp = schedulingInputVariable.DayStarts[0]; if (i > 0) { var lastVisit = input.Visits.FirstOrDefault(v => v.Id == schedulingInputVariable.Presolved[i - 1] - 1); timeStamp = realWaypointList.Last().StartTime + lastVisit.Duration; timeStamp += i > 1 ? input.RouteCosts[lastVisit.Id, currVisit.Id] : currVisit.WayCostFromHome; } realWaypointList.Add(new Algorithm.Waypoint(currVisit.Equals(default(Visit)) ? Constants.VisitIdHome : currVisit.Id, timeStamp)); } var absolutlyLastVisit = input.Visits.FirstOrDefault(v => v.Id == schedulingInputVariable.Presolved[schedulingInputVariable.Presolved.Length - 1] - 1); realWaypointList.Add(new Algorithm.Waypoint(Constants.VisitIdHome, realWaypointList.Last().StartTime + absolutlyLastVisit.Duration + absolutlyLastVisit.WayCostToHome)); return(new Algorithm.Route(1, 1) { SantaIds = schedulingInputVariable.SantaIds, Waypoints = new[, ] { { realWaypointList } } }); } var route = schedulingSolver.GetResult(); for (int i = 0; i < route.Waypoints.GetLength(0); i++) { for (int j = 0; j < route.Waypoints.GetLength(1); j++) { var realWaypointList = new List <Algorithm.Waypoint>(); var waypointList = route.Waypoints[i, j]; // copy for later lambda expression var jCopy = j; waypointList.ForEach(wp => { wp.Visit = wp.Visit == 0 ? Constants.VisitIdHome : schedulingInputVariable.VisitIds[wp.Visit - 1]; wp.StartTime = Math.Max(wp.StartTime, 0); wp.StartTime *= ip5GurobiConfig.TimeSliceDuration; wp.StartTime += schedulingInputVariable.DayStarts[jCopy]; realWaypointList.Add(wp); }); route.Waypoints[i, j] = realWaypointList; } } return(route); }) .ToList(); progress?.Invoke(this, new ProgressReport(0.99)); consoleProgress?.Invoke(this, "Scheduling done"); consoleProgress?.Invoke(this, $"Scheduling Result:{Environment.NewLine}" + routeResults.Where(r => r != null).Select(r => r.ToString()).Aggregate((acc, c) => acc + Environment.NewLine + c)); // construct new output elem var optimizationResult = new OptimizationResult() { OptimizationInput = input, Routes = routeResults.Select(r => r != null ? new Route { SantaId = r.SantaIds[0], Waypoints = r.Waypoints[0, 0].Select(origWp => new Waypoint { VisitId = origWp.Visit, StartTime = origWp.StartTime }).ToArray(), } : new Route()).ToArray(), }; progress?.Invoke(this, new ProgressReport(1)); // assign total elapsed time sw.Stop(); optimizationResult.TimeElapsed = sw.ElapsedMilliseconds / 1000; return(optimizationResult); }
public OptimizationResult Solve(long timeLimitMilliseconds, EventHandler <ProgressReport> progress, EventHandler <string> consoleProgress) { this.progress = progress; this.consoleProgress = consoleProgress; var sw = Stopwatch.StartNew(); Log("Solving started"); Log(new ProgressReport(0.01)); // adjust time limit if unlimited if (timeLimitMilliseconds == 0) { timeLimitMilliseconds = long.MaxValue; } // init population var(population, mapping) = new PopulationGenerator(RandomFactory.Instance).Generate(input, config.PopulationSize, config.MaxNumberOfSantas); var decoder = new Decoder(input, mapping); // calculate costs var result = new OptimizationResult() { OptimizationInput = input, }; var costCalculator = new CostCalculator(decoder, new SimplifiedOptimizationResult(result)); costCalculator.RecalculateCost(population); // Log characteristics of initial population Log($"Genetic Algorithm started with following paramters:{Environment.NewLine}{config}"); var bestCost = GetMinCost(population); Log($"Best solution cost in initial population is: {bestCost}"); // evolution var evolutionOperation = new EvolutionOperation(config); var repairOperation = new RepairOperation(input, mapping); long generation = 0; for (; generation < config.MaxNumberOfGenerations && sw.ElapsedMilliseconds < timeLimitMilliseconds; generation++) { // evolve evolutionOperation.Evolve(population); // repair repairOperation.Repair(population); // recalculate costs costCalculator.RecalculateCost(population); // log current solution var currentBestCost = GetMinCost(population); if (currentBestCost < bestCost) { bestCost = currentBestCost; Log($"Found better solution in generation {generation} with cost={bestCost}"); } } Log($"Finished at generation {generation} with cost={bestCost}"); Log($"Current stdev is {StDev(population.Select(i => (double)i.Cost).ToList())}"); Log(new ProgressReport(0.99)); // build result var bestSolution = population.OrderBy(i => i.Cost).First(); result.Routes = decoder.Decode(bestSolution); result.ResultState = ResultState.Finished; Log(new ProgressReport(1)); sw.Stop(); result.TimeElapsed = sw.ElapsedMilliseconds / 1000; return(result); }
private void setResults(OptimizationResult oResults) { if (InvokeRequired) { Invoke(new setResultsDelegate(setResults), new object[1] { oResults }); } else { BindData(false); //if (m_nLastCall == 4) //{ // foreach (DataRow dataRow in (InternalDataCollectionBase) tblOscillator.Rows) // dataRow[2] = "undecided"; // foreach (ArrayList arrayList in oResults) // { // var str = (string) arrayList[0]; // var flag = (bool) arrayList[1]; // foreach (DataRow dataRow in (InternalDataCollectionBase) tblOscillator.Rows) // { // if ((string) dataRow[0] == str) // { // dataRow.BeginEdit(); // dataRow[2] = flag.ToString(); // dataRow.EndEdit(); // } // } // enableTest(true); // } //} //else if (m_nLastCall == 3) //{ // foreach ( // DataRow dataRow in // (InternalDataCollectionBase) m_oParameterDataSet.Tables["SwitchParameter"].Rows) // dataRow[2] = "undecided"; // foreach (ArrayList arrayList in oResults) // { // var str = (string) arrayList[0]; // var flag = (bool) arrayList[1]; // foreach ( // DataRow dataRow in // (InternalDataCollectionBase) m_oParameterDataSet.Tables["SwitchParameter"].Rows) // { // if ((string) dataRow[0] == str) // { // dataRow.BeginEdit(); // dataRow[2] = flag.ToString(); // dataRow.EndEdit(); // } // } // enableTest(true); // } //} //else { int num1 = oResults.Iterations; double num2 = oResults.Score; double[] numArray = oResults.Values.ToArray(); double[] realEigenValues = oResults.RealEigenValues.ToArray(); double[] complexEigenValues = oResults.ImagEigenValues.ToArray(); int num3 = 0; for (int index = 0; index < m_oLastSelection.Count; ++index) { m_oParameterDataSet.Tables["Parameters"].Rows[(int)m_oLastSelection[index]]["optimized value"] = numArray[num3++]; } m_oParameterDataSet.Tables["EigenValues"].Rows.Clear(); for (int index = 0; index < realEigenValues.Length; ++index) { DataRow row = m_oParameterDataSet.Tables["EigenValues"].NewRow(); row[0] = realEigenValues[index]; row[1] = complexEigenValues[index]; m_oParameterDataSet.Tables["EigenValues"].Rows.Add(row); } txtEigenValue.Text = "done"; txtFitness.Text = num2.ToString("E5"); if (m_nLastCall == 1) { m_dParameters = numArray; tblOscillator.Rows.Clear(); foreach ( DataRow dataRow in (InternalDataCollectionBase)m_oParameterDataSet.Tables["Parameters"].Rows) { DataRow row = tblOscillator.NewRow(); row[0] = dataRow[0]; row[1] = true; row[2] = "undecided"; tblOscillator.Rows.Add(row); } enableTest(true); } else if (m_nLastCall == 2) { m_dParameters = numArray; m_oParameterDataSet.Tables["SwitchParameter"].Rows.Clear(); foreach ( DataRow dataRow in (InternalDataCollectionBase)m_oParameterDataSet.Tables["Parameters"].Rows) { DataRow row = m_oParameterDataSet.Tables["SwitchParameter"].NewRow(); row[0] = dataRow[0]; row[1] = true; row[2] = "undecided"; m_oParameterDataSet.Tables["SwitchParameter"].Rows.Add(row); } enableTest(true); } lblDisplayResult.Text = CheckResult(m_nLastCall, realEigenValues, complexEigenValues); } BindData(true); } }
private void CheckNoAdditionalSantas(OptimizationResult actual) { Assert.AreEqual(0, actual.NumberOfAdditionalSantas()); }
/// <summary> /// Checks whether new lean compute job better than previous and run new iteration if necessary. /// </summary> /// <param name="result">Lean compute job result and corresponding parameter set</param> public override void PushNewResults(OptimizationResult result) { if (!Initialized) { throw new InvalidOperationException($"EulerSearchOptimizationStrategy.PushNewResults: strategy has not been initialized yet."); } lock (_locker) { if (!ReferenceEquals(result, OptimizationResult.Initial) && string.IsNullOrEmpty(result?.JsonBacktestResult)) { // one of the requested backtests failed _runningParameterSet.Remove(result.ParameterSet); return; } // check if the incoming result is not the initial seed if (result.Id > 0) { _runningParameterSet.Remove(result.ParameterSet); ProcessNewResult(result); } if (_runningParameterSet.Count > 0) { // we wait till all backtest end during each euler step return; } // Once all running backtests have ended, for the current collection of optimization parameters, for each parameter we determine if // we can create a new smaller/finer optimization scope if (Target.Current.HasValue && OptimizationParameters.OfType <OptimizationStepParameter>().Any(s => s.Step > s.MinStep)) { var boundaries = new HashSet <OptimizationParameter>(); var parameterSet = Solution.ParameterSet; foreach (var optimizationParameter in OptimizationParameters) { var optimizationStepParameter = optimizationParameter as OptimizationStepParameter; if (optimizationStepParameter != null && optimizationStepParameter.Step > optimizationStepParameter.MinStep) { var newStep = Math.Max(optimizationStepParameter.MinStep.Value, optimizationStepParameter.Step.Value / _segmentsAmount); var fractal = newStep * ((decimal)_segmentsAmount / 2); var parameter = parameterSet.Value.First(s => s.Key == optimizationParameter.Name); boundaries.Add(new OptimizationStepParameter( optimizationParameter.Name, Math.Max(optimizationStepParameter.MinValue, parameter.Value.ToDecimal() - fractal), Math.Min(optimizationStepParameter.MaxValue, parameter.Value.ToDecimal() + fractal), newStep, optimizationStepParameter.MinStep.Value)); } else { boundaries.Add(optimizationParameter); } } OptimizationParameters = boundaries; } else if (!ReferenceEquals(result, OptimizationResult.Initial)) { // we ended! return; } foreach (var parameterSet in Step(OptimizationParameters)) { OnNewParameterSet(parameterSet); } } }
/// <summary> /// Checks whether new lean compute job better than previous and run new iteration if necessary. /// </summary> /// <param name="result">Lean compute job result and corresponding parameter set</param> public abstract void PushNewResults(OptimizationResult result);
public CostCalculator(Decoder decoder, OptimizationResult temporaryResult) { this.decoder = decoder; this.result = temporaryResult; }
private static string ResultToString <Element>(OptimizationResult <Element> result) { return(result.BestValue.ToString() + "\t" + result.BestTime.ToString() + "\t" + result.BestIteration.ToString() + "\t" + result.BestFFE.ToString()); }
public void TrackEstimation() { Config.Set("optimization-update-interval", 1); OptimizationEstimate estimate = null; OptimizationResult result = null; var resetEvent = new ManualResetEvent(false); var packet = new OptimizationNodePacket { Criterion = new Target("Profit", new Minimization(), null), OptimizationParameters = new HashSet <OptimizationParameter> { new OptimizationStepParameter("ema-slow", 1, 10, 1), new OptimizationStepParameter("ema-fast", 10, 100, 3) }, Constraints = new List <Constraint> { new Constraint("Drawdown", ComparisonOperatorTypes.LessOrEqual, 0.15m) }, MaximumConcurrentBacktests = 5 }; var optimizer = new FakeLeanOptimizer(packet); // keep stats up-to-date int totalBacktest = optimizer.GetCurrentEstimate().TotalBacktest; int totalUpdates = 0; int completedTests = 0; int failed = 0; optimizer.Update += (s, e) => { estimate = optimizer.GetCurrentEstimate(); Assert.LessOrEqual(estimate.RunningBacktest, packet.MaximumConcurrentBacktests); Assert.LessOrEqual(completedTests, estimate.CompletedBacktest); Assert.LessOrEqual(failed, estimate.FailedBacktest); Assert.AreEqual(totalBacktest, estimate.TotalBacktest); completedTests = estimate.CompletedBacktest; failed = estimate.FailedBacktest; if (completedTests > 0) { Assert.Greater(estimate.AverageBacktest, TimeSpan.Zero); } totalUpdates++; }; optimizer.Ended += (s, solution) => { result = solution; estimate = optimizer.GetCurrentEstimate(); optimizer.DisposeSafely(); resetEvent.Set(); }; optimizer.Start(); resetEvent.WaitOne(); Assert.NotZero(estimate.CompletedBacktest); Assert.NotZero(estimate.FailedBacktest); // we have 2 force updates at least, expect a few more over it. Assert.Greater(totalUpdates, 2); Assert.AreEqual(estimate.CompletedBacktest + estimate.FailedBacktest + estimate.RunningBacktest, totalBacktest); }
public OptimizationResult Solve(long timelimitMiliseconds, EventHandler <ProgressReport> progress, EventHandler <string> consoleProgress) { var sw = Stopwatch.StartNew(); var output = new OptimizationResult { OptimizationInput = input }; var timeWindowIsRelevant = !input.Visits.All(visit => { if (visit.Desired.Length > 0) { return(false); } return(!visit.Unavailable.Any(unavailable => { var(unavailableFrom, unavailableTo) = unavailable; foreach (var(dayFrom, dayTo) in input.Days) { if (IntersectionLength(unavailableFrom, unavailableTo, dayFrom, dayTo) > 0) { return true; } } return false; })); }); // first solve vrp, take result as initial solution. if (!timeWindowIsRelevant) { vrpTimeLimitFactor = 1; } var vrpSolution = input.Visits.Length > 75 ? FakeVRPSolution(input.Santas.Length * input.Days.Length) : new VRPCallbackSolver(input).SolveVRP((int)(timelimitMiliseconds * vrpTimeLimitFactor)); consoleProgress?.Invoke(this, $"vrp needed {sw.ElapsedMilliseconds}ms, remaining {timelimitMiliseconds - sw.ElapsedMilliseconds}"); if (!timeWindowIsRelevant) { BuildResultFromVRP(output, vrpSolution); output.TimeElapsed = sw.ElapsedMilliseconds / 1000; return(output); } timelimitMiliseconds -= sw.ElapsedMilliseconds; using (var env = new GRBEnv($"{DateTime.Now:yy-MM-dd-HH-mm-ss}_gurobi.log")) using (var model = new GRBModel(env)) { #region initialize Variables var numberOfRoutes = input.Santas.Length * input.Days.Length; var v = new GRBVar[numberOfRoutes][]; // [santa] visits [visit] var w = new GRBVar[numberOfRoutes][]; // [santa] uses [way] var c = new GRBVar[numberOfRoutes][]; // [santa] visits visit at the end of [way] var desiredDuration = new GRBVar[numberOfRoutes][][]; var unavailableDuration = new GRBVar[numberOfRoutes][][]; var maxRoutes = new GRBVar[numberOfRoutes]; var minRoutes = new GRBVar[numberOfRoutes]; for (int s = 0; s < numberOfRoutes; s++) { v[s] = new GRBVar[visitDurations.Length]; c[s] = new GRBVar[visitDurations.Length]; desiredDuration[s] = new GRBVar[visitDurations.Length][]; unavailableDuration[s] = new GRBVar[visitDurations.Length][]; var(dayStart, dayEnd) = input.Days[s / input.Santas.Length]; var dayDuration = dayEnd - dayStart; for (int i = 0; i < v[s].Length; i++) { v[s][i] = model.AddVar(0, 1, 0.0, GRB.BINARY, GurobiVarName($"v[{s}][{i}]")); c[s][i] = model.AddVar(0, dayDuration, 0, GRB.CONTINUOUS, GurobiVarName($"c[{s}][{i}]")); if (i > 0) { var visit = input.Visits[i - 1]; desiredDuration[s][i] = new GRBVar[visit.Desired.Length]; unavailableDuration[s][i] = new GRBVar[visit.Unavailable.Length]; for (int d = 0; d < visit.Desired.Length; d++) { var ub = Math.Max(0, Math.Min(visit.Duration, visit.Desired[d].to - visit.Desired[d].from)); desiredDuration[s][i][d] = model.AddVar(0, ub, 0, GRB.CONTINUOUS, GurobiVarName($"desiredDuration[{s}][{i}][{d}]")); } for (int u = 0; u < visit.Unavailable.Length; u++) { var ub = Math.Max(0, Math.Min(visit.Duration, visit.Unavailable[u].to - visit.Unavailable[u].from)); unavailableDuration[s][i][u] = model.AddVar(0, ub, 0, GRB.CONTINUOUS, GurobiVarName($"unavailableDuration[{s}][{i}][{u}]")); } } } w[s] = model.AddVars(distances.GetLength(0) * distances.GetLength(1), GRB.BINARY); maxRoutes[s] = model.AddVar(0, dayEnd - dayStart, 0, GRB.CONTINUOUS, GurobiVarName($"santa{s} maxRoute")); minRoutes[s] = model.AddVar(0, dayEnd - dayStart, 0, GRB.CONTINUOUS, GurobiVarName($"santa{s} minRoute")); } #endregion initialize Variables #region add constraints SelfieConstraint(model, numberOfRoutes, w); // visit visited once VisitVisitedOnce(model, numberOfRoutes, v); // breaks BreakHandling(model, numberOfRoutes, v); // number of ways = number of visits + home NumberOfWaysMatchForSanta(model, numberOfRoutes, v, w); // incoming & outgoing constraint IncomingOutgoingGlobal(model, numberOfRoutes, w); IncomingOutgoingSanta(model, numberOfRoutes, v, w); IncomingOutgoingSantaHome(model, numberOfRoutes, w, v); IncreasingC(model, numberOfRoutes, w, c, v); DesiredOverlap(model, numberOfRoutes, v, w, c, desiredDuration); UnavailableOverlap(model, numberOfRoutes, v, w, c, unavailableDuration, true); FillMaxRoute(model, maxRoutes, c, v); FillMinRoutes(model, minRoutes, c, v); MinRouteSmallerThanMaxRoute(model, minRoutes, maxRoutes); // Symmetry breaking constraint if no breaks if (!input.Visits.Any(visit => visit.IsBreak)) { for (int d = 0; d < input.Days.Length; d++) { var dayOffset = d * input.Santas.Length; for (int s = 1; s < input.Santas.Length; s++) { model.AddConstr(maxRoutes[dayOffset + s] - minRoutes[dayOffset + s] <= maxRoutes[dayOffset + s - 1] - minRoutes[dayOffset + s - 1], null); } } } #endregion add constraints // TARGET FUNCTION var totalWayTime = new GRBLinExpr(0); var longestRoute = model.AddVar(0, input.Days.Max(d => d.to - d.from), 0, GRB.CONTINUOUS, "longestRoute"); for (int s = 0; s < numberOfRoutes; s++) { totalWayTime += (maxRoutes[s] - minRoutes[s]); model.AddConstr(longestRoute >= maxRoutes[s] - minRoutes[s], $"longesRouteConstr{s}"); } var desiredSum = new GRBLinExpr(0); var unavailableSum = new GRBLinExpr(0); for (int s = 0; s < numberOfRoutes; s++) { for (int i = 1; i < visitDurations.Length; i++) { var visit = input.Visits[i - 1]; for (int d = 0; d < visit.Desired.Length; d++) { if (!(desiredDuration[s][i][d] is null)) { desiredSum += desiredDuration[s][i][d]; } } for (int u = 0; u < visit.Unavailable.Length; u++) { if (!(unavailableDuration[s][i][u] is null)) { unavailableSum += unavailableDuration[s][i][u]; } } } } LowerBoundTotalWaytime(model, totalWayTime); model.SetObjective( +(12d) * unavailableSum + (4d) * totalWayTime - (2d) * desiredSum + (3d) * longestRoute , GRB.MINIMIZE); model.Parameters.TimeLimit = Math.Max(0, timelimitMiliseconds / 1000); InitializeWithVRPSolution(vrpSolution, numberOfRoutes, model, v, w, c); #if DEBUG model.Write($"{name}_{visitDurations.Length}.mst"); model.Write($"{name}_{visitDurations.Length}.mps"); model.Write($"{name}_{visitDurations.Length}.lp"); #endif model.Optimize(); output.TimeElapsed = sw.ElapsedMilliseconds / 1000; try { if (model.SolCount == 0 && vrpSolution != null) { consoleProgress?.Invoke(this, "No solution found -> try with vrpsolution"); BuildResultFromVRP(output, vrpSolution); return(output); } BuildResult(output, numberOfRoutes, w, c); consoleProgress?.Invoke(this, $"longestRoute: {longestRoute.X}"); consoleProgress?.Invoke(this, $"totalWayTime: {totalWayTime.Value}"); consoleProgress?.Invoke(this, $"DesiredDuration: {desiredSum.Value}"); consoleProgress?.Invoke(this, $"UnavailableDuration: {unavailableSum.Value}"); for (int s = 0; s < numberOfRoutes; s++) { consoleProgress?.Invoke(this, $"maxRoutes[{s}]: {maxRoutes[s].X}, {minRoutes[s].X} , ->{maxRoutes[s].X - minRoutes[s].X}"); for (int visitIndex = 0; visitIndex < visitDurations.Length; visitIndex++) { consoleProgress?.Invoke(this, $"c[{s}][{visitIndex}] ({v[s][visitIndex].X}): {c[s][visitIndex].X}"); } } } catch (Exception e) { consoleProgress?.Invoke(this, $"ERROR: {e.Message}"); output.Routes = new Route[0]; } } return(output); }
private void BuildResult(OptimizationResult output, int numberOfRoutes, GRBVar[][] w, GRBVar[][] c) { var routes = new List <Route>(); for (int s = 0; s < numberOfRoutes; s++) { Debug.WriteLine($"Santa {s} uses way"); var route = new Route(); var wpList = new List <Waypoint>(); route.SantaId = s % input.Santas.Length; var lastId = 0; var day = s / input.Santas.Length; do { var(id, startingTime) = GetNextVisit(lastId, w[s], c[s]); if (id == 0) { // if last visit var lastVisit = input.Visits[lastId - 1]; wpList.Add(new Waypoint { StartTime = wpList.Last().StartTime + lastVisit.Duration + lastVisit.WayCostToHome, VisitId = id - 1 }); } else { wpList.Add(new Waypoint { StartTime = startingTime + input.Days[day].from, VisitId = id - 1 }); } lastId = id; } while (lastId != 0 && lastId != -1); if (wpList.Count == 0 || lastId == -1) { continue; } var firstWaypoint = wpList.First(); var firstVisit = input.Visits[firstWaypoint.VisitId]; route.Waypoints = wpList .Prepend(new Waypoint { StartTime = firstWaypoint.StartTime - firstVisit.WayCostFromHome, VisitId = Constants.VisitIdHome }) .ToArray(); routes.Add(route); for (int i = 0; i < distances.GetLength(0); i++) { for (int j = 0; j < distances.GetLength(1); j++) { if (Math.Round(AccessW(w[s], i, j).X, 0) > 0) { Debug.WriteLine($"[{i},{j}]=\t{c[s][j].X}"); } } } } output.Routes = routes.ToArray(); }
public void TrackEstimation() { Config.Set("optimization-update-interval", 1); OptimizationResult result = null; var resetEvent = new ManualResetEvent(false); var packet = new OptimizationNodePacket { Criterion = new Target("Profit", new Minimization(), null), OptimizationParameters = new HashSet <OptimizationParameter> { new OptimizationStepParameter("ema-slow", 1, 10, 1), new OptimizationStepParameter("ema-fast", 10, 100, 10) }, Constraints = new List <Constraint> { new Constraint("Drawdown", ComparisonOperatorTypes.LessOrEqual, 0.15m) }, MaximumConcurrentBacktests = 5 }; var optimizer = new FakeLeanOptimizer(packet); // keep stats up-to-date int totalBacktest = optimizer.GetCurrentEstimate(); int totalUpdates = 0; int completedTests = 0; int failed = 0; optimizer.Update += (s, e) => { var runtimeStats = optimizer.GetRuntimeStatistics(); Assert.LessOrEqual(int.Parse(runtimeStats["Running"], CultureInfo.InvariantCulture), packet.MaximumConcurrentBacktests); Assert.LessOrEqual(completedTests, int.Parse(runtimeStats["Completed"], CultureInfo.InvariantCulture)); Assert.LessOrEqual(failed, int.Parse(runtimeStats["Failed"], CultureInfo.InvariantCulture)); Assert.AreEqual(totalBacktest, optimizer.GetCurrentEstimate()); completedTests = int.Parse(runtimeStats["Completed"], CultureInfo.InvariantCulture); failed = int.Parse(runtimeStats["Failed"], CultureInfo.InvariantCulture); if (completedTests > 0) { // 'ms' aren't stored so might be 0 Assert.GreaterOrEqual(TimeSpan.Parse(runtimeStats["Average Length"], CultureInfo.InvariantCulture), TimeSpan.Zero); } totalUpdates++; }; optimizer.Ended += (s, solution) => { result = solution; optimizer.DisposeSafely(); resetEvent.Set(); }; optimizer.Start(); resetEvent.WaitOne(); var runtimeStatistics = optimizer.GetRuntimeStatistics(); Assert.NotZero(int.Parse(runtimeStatistics["Completed"], CultureInfo.InvariantCulture)); Assert.NotZero(int.Parse(runtimeStatistics["Failed"], CultureInfo.InvariantCulture)); // we have 2 force updates at least, expect a few more over it. Assert.Greater(totalUpdates, 2); Assert.AreEqual(int.Parse(runtimeStatistics["Completed"], CultureInfo.InvariantCulture) + int.Parse(runtimeStatistics["Failed"], CultureInfo.InvariantCulture) + int.Parse(runtimeStatistics["Running"], CultureInfo.InvariantCulture), totalBacktest); }
private void CheckValid(OptimizationResult actual) { Assert.IsTrue(actual.IsValid(), actual.Validate()); }
// This will be the value that the optimization process optimizes. // It will search for the set of parameters that gives the highest result for this number. public virtual double EvaluateResults(OptimizationResult result) { // By default, just use the APR. return result.FinalStatistic.APR; }
private void CheckAllVisited(OptimizationResult actual) { Assert.AreEqual(0, actual.NumberOfNotVisitedFamilies()); }
public static void DrawResult(string path, OptimizationResult result, (int x, int y)[] coordinates)
private static void EvaluateAlgorithm(string[] args) { BigHr(); Console.WriteLine("Program written to evaluate the different optimisation algorithms."); Console.WriteLine(); var algorithmSelection = args.Length == 0 ? QueryAlgorithmSelection() : (Algorithms)Enum.Parse(typeof(Algorithms), args[0]); SmallHr(); Console.WriteLine(); var datasetSelection = args.Length == 0 ? QueryDatasetSelection() : GetDatasetSelection(int.Parse(args[1])); SmallHr(); Console.WriteLine(); var runs = args.Length == 0 ? QueryNumberOfRuns() : int.Parse(args[2]); SmallHr(); Console.WriteLine(); Console.WriteLine("Starting the algorithm now"); BigHr(); for (int i = 0; i < runs; i++) { foreach (var dataset in datasetSelection) { try { var(input, coordinates, timelimit) = GetDataset(dataset); string savepath = $"{DateTime.Now:yy-MM-dd-HH-mm-ss}_DataSet_{dataset}"; ISolver solver = null; var fastFactor = 60; switch (algorithmSelection) { case Algorithms.ILPFast: timelimit /= fastFactor; goto case Algorithms.ILP; case Algorithms.ILP: solver = new ILPSolver(input, new ILPConfig { ClusteringMIPGap = 0, SchedulingMIPGap = 0, ClusteringTimeLimitMiliseconds = (long)(0.7 * timelimit), SchedulingTimeLimitMiliseconds = (long)(0.3 * timelimit), TimeSliceDuration = 120 }); savepath += "_ILP"; break; case Algorithms.LocalSolverFast: timelimit /= fastFactor; goto case Algorithms.LocalSolver; case Algorithms.LocalSolver: solver = new Solver(input, new LocalSolverConfig { VrpTimeLimitFactor = 0.1, VrptwTimeLimitFactor = 0.8, MaxNumberOfAdditionalSantas = 0, }); savepath += "_LocalSolver"; break; case Algorithms.GA: solver = new GenAlgSolver(input, new GenAlgConfig(input)); savepath += "_GA"; break; case Algorithms.GAFast: timelimit /= fastFactor; solver = new GenAlgSolver(input, new GenAlgConfig(input)); savepath += "_GAFast"; break; case Algorithms.ILP2Fast: timelimit /= fastFactor; goto case Algorithms.ILP2; case Algorithms.ILP2: solver = new IRuettae.Core.ILP2.Solver(input, 0.1, dataset.ToString()); savepath += "_ILP2"; break; case Algorithms.ILPIP5GurobiFast: timelimit /= fastFactor; goto case Algorithms.ILPIP5Gurobi; case Algorithms.ILPIP5Gurobi: solver = new ILPIp5GurobiSolver(input, new ILPIp5GurobiConfig { ClusteringMIPGap = 0, SchedulingMIPGap = 0, ClusteringTimeLimitMiliseconds = (long)(0.7 * timelimit), SchedulingTimeLimitMiliseconds = (long)(0.3 * timelimit), TimeSliceDuration = 120 }); savepath += "_ILPIp5Gurobi"; break; case Algorithms.GoogleRoutingFast: timelimit /= fastFactor; solver = new GoogleRoutingSolver(input, GoogleRoutingConfig.GetDefault(input)); savepath += "_GoogleRoutingFast"; break; case Algorithms.GoogleRouting: solver = new GoogleRoutingSolver(input, GoogleRoutingConfig.GetDefault(input)); savepath += "_GoogleRouting"; break; } AddUnavailableBetweenDays(input); OptimizationResult result = null; void WriteConsoleInfo(object sender, string s) { Console.WriteLine($"Info ({DateTime.Now:HH-mm-ss}): {s}"); } void WriteConsoleProgress(object sender, ProgressReport report) { Console.WriteLine($"Progress: {report}"); } #if DEBUG using (var sw = new StreamWriter(savepath + "-log.txt", true)) { result = solver.Solve(timelimit, WriteConsoleProgress, (sender, s) => { WriteConsoleInfo(sender, s); sw.WriteLine(s); }); } #else result = solver.Solve(timelimit, WriteConsoleProgress, WriteConsoleInfo); #endif BigHr(); File.WriteAllText(savepath + ".json", JsonConvert.SerializeObject(result)); var summary = new StringBuilder(); summary.AppendLine($"Solver: {AlgorithmsDictionary[algorithmSelection]}"); summary.AppendLine($"Dataset{dataset}: {DatasetDictionary[dataset]}"); summary.AppendLine($"TimeElapsed [s]: {result.TimeElapsed}"); try { if (!result.IsValid()) { summary.AppendLine( $"IMPORTANT: This result seems to be invalid. The reason is \"{result.Validate()}\""); } } catch { summary.AppendLine("error while checking invalidity"); } summary.AppendLine($"Cost: {result.Cost()}"); summary.AppendLine($"NumberOfNotVisitedFamilies: {result.NumberOfNotVisitedFamilies()}"); summary.AppendLine($"NumberOfMissingBreaks: {result.NumberOfMissingBreaks()}"); summary.AppendLine($"NumberOfAdditionalSantas: {result.NumberOfAdditionalSantas()}"); summary.AppendLine($"AdditionalSantaWorkTime: {result.AdditionalSantaWorkTime()}"); summary.AppendLine($"VisitTimeInUnavailable: {result.VisitTimeInUnavailable()}"); summary.AppendLine($"WayTimeOutsideBusinessHours: {result.WayTimeOutsideBusinessHours()}"); summary.AppendLine($"VisitTimeInDesired: {result.VisitTimeInDesired()}"); summary.AppendLine($"SantaWorkTime: {result.SantaWorkTime()}"); summary.AppendLine($"LongestDay: {result.LongestDay()}"); summary.AppendLine($"NumberOfRoutes: {result.NumberOfRoutes()}"); File.WriteAllText(savepath + ".txt", summary.ToString()); Console.WriteLine(); Console.WriteLine("Done solving"); Console.WriteLine(summary.ToString()); ResultDrawer.DrawResult(savepath, result, coordinates); } catch (Exception e) { Console.WriteLine($"An exception occured: {e.Message}"); } } } }