Changeset 16373 for branches/2931_OR-Tools_LP_MIP/HeuristicLab.MathematicalOptimization/3.3/LinearProgramming/Algorithms/Solvers/Base/IncrementalSolver.cs
- Timestamp:
- 12/12/18 14:23:45 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2931_OR-Tools_LP_MIP/HeuristicLab.MathematicalOptimization/3.3/LinearProgramming/Algorithms/Solvers/Base/IncrementalSolver.cs
r16288 r16373 23 23 using System.Linq; 24 24 using System.Threading; 25 using Google.OrTools.LinearSolver;26 25 using HeuristicLab.Analysis; 27 26 using HeuristicLab.Common; … … 35 34 [StorableClass] 36 35 public class IncrementalSolver : Solver, IIncrementalSolver { 37 38 [Storable]39 protected readonly IValueParameter<BoolValue> incrementalityParam;40 36 41 37 [Storable] … … 55 51 56 52 public IncrementalSolver() { 57 Parameters.Add(incrementalityParam = new ValueParameter<BoolValue>(nameof(Incrementality),58 "Advanced usage: incrementality from one solve to the next.",59 new BoolValue(MPSolverParameters.kDefaultIncrementality == MPSolverParameters.INCREMENTALITY_ON)));60 53 Parameters.Add(qualityUpdateIntervalParam = 61 54 new ValueParameter<TimeSpanValue>(nameof(QualityUpdateInterval), 62 "Time interval before solver is paused, resuls are retrieved and solver is resumed.", 63 new TimeSpanValue(new TimeSpan(0, 0, 10)))); 64 65 incrementalityParam.Value.ValueChanged += (sender, args) => { 66 if (((BoolValue)sender).Value) { 67 qualityUpdateIntervalParam.Value = new TimeSpanValue(qualityUpdateIntervalParam.Value.Value); 55 "Time interval before solver is paused, results are retrieved and solver is resumed. " + 56 "Set to zero for no intermediate results and faster solving.", new TimeSpanValue(new TimeSpan(0, 0, 10)))); 57 problemTypeParam.Value.ValueChanged += (sender, args) => { 58 if (SupportsQualityUpdate) { 59 if (!Parameters.Contains(qualityUpdateIntervalParam)) { 60 Parameters.Add(qualityUpdateIntervalParam); 61 } 68 62 } else { 69 qualityUpdateIntervalParam.Value = (TimeSpanValue)qualityUpdateIntervalParam.Value.AsReadOnly();63 Parameters.Remove(qualityUpdateIntervalParam); 70 64 } 71 65 }; … … 74 68 protected IncrementalSolver(IncrementalSolver original, Cloner cloner) 75 69 : base(original, cloner) { 76 pro grammingTypeParam = cloner.Clone(original.programmingTypeParam);70 problemTypeParam = cloner.Clone(original.problemTypeParam); 77 71 qualityUpdateIntervalParam = cloner.Clone(original.qualityUpdateIntervalParam); 78 incrementalityParam = cloner.Clone(original.incrementalityParam);79 72 if (original.qualityPerClock != null) 80 73 qualityPerClock = cloner.Clone(original.qualityPerClock); 81 74 } 82 75 83 public bool Incrementality { 84 get => incrementalityParam.Value.Value; 85 set => incrementalityParam.Value.Value = value; 86 } 76 public virtual bool SupportsQualityUpdate => true; 87 77 88 78 public TimeSpan QualityUpdateInterval { … … 91 81 } 92 82 83 protected virtual TimeSpan TimeLimit => QualityUpdateInterval; 84 93 85 public override void Solve(LinearProgrammingAlgorithm algorithm, CancellationToken cancellationToken) { 94 if (! Incrementality) {86 if (!SupportsQualityUpdate || QualityUpdateInterval == TimeSpan.Zero) { 95 87 base.Solve(algorithm, cancellationToken); 96 88 return; … … 101 93 102 94 if (!unlimitedRuntime) { 103 var wallTime = ((TimeSpanValue)algorithm.Results.SingleOrDefault(r => r.Name == "Wall Time")?.Value)?.Value; 104 if (wallTime.HasValue) { 105 timeLimit -= wallTime.Value; 106 } 95 timeLimit -= algorithm.ExecutionTime; 107 96 } 108 97 109 98 var iterations = (long)timeLimit.TotalMilliseconds / (long)QualityUpdateInterval.TotalMilliseconds; 110 99 var remaining = timeLimit - TimeSpan.FromMilliseconds(iterations * QualityUpdateInterval.TotalMilliseconds); 111 var validResultStatuses = new[] { ResultStatus.N OT_SOLVED, ResultStatus.FEASIBLE};100 var validResultStatuses = new[] { ResultStatus.NotSolved, ResultStatus.Feasible }; 112 101 113 102 while (unlimitedRuntime || iterations > 0) { 114 base.Solve(algorithm, QualityUpdateInterval, true); 103 if (cancellationToken.IsCancellationRequested) 104 return; 105 106 base.Solve(algorithm, TimeLimit); 115 107 UpdateQuality(algorithm); 116 108 117 var resultStatus = ((EnumValue<ResultStatus>)algorithm.Results[ "Result Status"].Value).Value;118 if (!validResultStatuses.Contains(resultStatus) || cancellationToken.IsCancellationRequested)109 var resultStatus = ((EnumValue<ResultStatus>)algorithm.Results[nameof(solver.ResultStatus)].Value).Value; 110 if (!validResultStatuses.Contains(resultStatus)) 119 111 return; 120 112 … … 124 116 125 117 if (remaining > TimeSpan.Zero) { 126 base.Solve(algorithm, remaining , true);118 base.Solve(algorithm, remaining); 127 119 UpdateQuality(algorithm); 128 120 } … … 132 124 if (!algorithm.Results.Exists(r => r.Name == "QualityPerClock")) { 133 125 qualityPerClock = new IndexedDataTable<double>("Quality per Clock"); 134 qpcRow = new IndexedDataRow<double>(" First-hit Graph Objective");135 bpcRow = new IndexedDataRow<double>(" First-hit GraphBound");126 qpcRow = new IndexedDataRow<double>("Objective Value"); 127 bpcRow = new IndexedDataRow<double>("Bound"); 136 128 algorithm.Results.AddOrUpdateResult("QualityPerClock", qualityPerClock); 137 129 } 138 130 139 var resultStatus = ((EnumValue<ResultStatus>)algorithm.Results[ "Result Status"].Value).Value;131 var resultStatus = ((EnumValue<ResultStatus>)algorithm.Results[nameof(solver.ResultStatus)].Value).Value; 140 132 141 if (new[] { ResultStatus.A BNORMAL, ResultStatus.NOT_SOLVED, ResultStatus.UNBOUNDED}.Contains(resultStatus))133 if (new[] { ResultStatus.Abnormal, ResultStatus.NotSolved, ResultStatus.Unbounded }.Contains(resultStatus)) 142 134 return; 143 135 144 var objective = ((DoubleValue)algorithm.Results[ "Best Objective Value"].Value).Value;145 var bound = ((DoubleValue)algorithm.Results["Best Objective Bound"].Value).Value;136 var objective = ((DoubleValue)algorithm.Results[$"Best{nameof(solver.ObjectiveValue)}"].Value).Value; 137 var bound = solver.IsMip ? ((DoubleValue)algorithm.Results[$"Best{nameof(solver.ObjectiveBound)}"].Value).Value : double.NaN; 146 138 var time = algorithm.ExecutionTime.TotalSeconds; 147 139 … … 151 143 qpcRow.Values.Add(Tuple.Create(time, objective)); 152 144 qualityPerClock.Rows.Add(qpcRow); 153 algorithm.Results.AddOrUpdateResult( "Best Solution FoundAt", new TimeSpanValue(TimeSpan.FromSeconds(time)));145 algorithm.Results.AddOrUpdateResult($"Best{nameof(solver.ObjectiveValue)}FoundAt", new TimeSpanValue(TimeSpan.FromSeconds(time))); 154 146 } 155 147 } else { … … 158 150 if (!objective.IsAlmost(previousBest)) { 159 151 qpcRow.Values.Add(Tuple.Create(time, objective)); 160 algorithm.Results.AddOrUpdateResult( "Best Solution FoundAt", new TimeSpanValue(TimeSpan.FromSeconds(time)));152 algorithm.Results.AddOrUpdateResult($"Best{nameof(solver.ObjectiveValue)}FoundAt", new TimeSpanValue(TimeSpan.FromSeconds(time))); 161 153 } 162 154 } 155 156 if (!solver.IsMip) 157 return; 163 158 164 159 if (!bpcRow.Values.Any()) {
Note: See TracChangeset
for help on using the changeset viewer.