Changeset 15533 for branches/CFSAP/HeuristicLab.Problems.Scheduling.CFSAP/3.3/MultiNestCFSAPSolvingStrategy.cs
- Timestamp:
- 12/18/17 14:38:18 (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/CFSAP/HeuristicLab.Problems.Scheduling.CFSAP/3.3/MultiNestCFSAPSolvingStrategy.cs
r15472 r15533 12 12 13 13 namespace HeuristicLab.Problems.Scheduling.CFSAP { 14 [Item("MultiNest CFSAP Solver", "Solving strategy that applies an algorithm insta ce to the worst nest.")]14 [Item("MultiNest CFSAP Solver", "Solving strategy that applies an algorithm instance to the worst nest.")] 15 15 [StorableClass] 16 16 [Creatable(CreatableAttribute.Categories.Algorithms)] … … 33 33 } 34 34 35 36 35 public IFixedValueParameter<StringValue> EvaluatedSolutionsNameParameter { 37 36 get { return (IFixedValueParameter<StringValue>)Parameters["EvaluatedSolutionsName"]; } 37 } 38 39 public IValueParameter<BoolValue> RestartParameter { 40 get { return (IValueParameter<BoolValue>)Parameters["Restart"]; } 41 } 42 43 public IValueParameter<IntValue> MinTriesParameter { 44 get { return (IValueParameter<IntValue>)Parameters["Restart.MinTries"]; } 45 } 46 47 public IValueParameter<DoubleValue> LastSuccessPercentageParameter { 48 get { return (IValueParameter<DoubleValue>)Parameters["Restart.LastSuccessPercentage"]; } 38 49 } 39 50 … … 53 64 } 54 65 66 public bool Restart { 67 get => RestartParameter.Value.Value; 68 set => RestartParameter.Value.Value = value; 69 } 70 71 public int MinTries { 72 get => MinTriesParameter.Value.Value; 73 set => MinTriesParameter.Value.Value = value; 74 } 75 76 public double LastSuccessPercentage { 77 get => LastSuccessPercentageParameter.Value.Value; 78 set => LastSuccessPercentageParameter.Value.Value = value; 79 } 80 55 81 [StorableConstructor] 56 82 protected MultiNestCFSAPSolvingStrategy(bool deserializing) : base(deserializing) { } 83 57 84 protected MultiNestCFSAPSolvingStrategy(MultiNestCFSAPSolvingStrategy original, Cloner cloner) 58 85 : base(original, cloner) { … … 67 94 if (original.qualityPerEvaluations != null) 68 95 qualityPerEvaluations = cloner.Clone(original.qualityPerEvaluations); 69 } 96 97 restart = original.restart; 98 minTries = original.minTries; 99 lastSuccessPercentage = original.lastSuccessPercentage; 100 } 101 70 102 public MultiNestCFSAPSolvingStrategy() { 71 103 Parameters.Add(new ValueParameter<IAlgorithm>("Solver", "The actual solver template.") { GetsCollected = false }); 72 104 Parameters.Add(new FixedValueParameter<TimeSpanValue>("MaximumRuntime", "The maximum time that the strategy should run.", new TimeSpanValue(TimeSpan.FromSeconds(60)))); 73 105 Parameters.Add(new FixedValueParameter<StringValue>("EvaluatedSolutionsName", "The name of the result that shows the number of evaluated solutions by the actual solver.", new StringValue("EvaluatedSolutions"))); 74 } 75 106 Parameters.Add(new ValueParameter<BoolValue>("Restart", "Whether the worst algorithm should be restarted, if it doesn't find any better solutions.", new BoolValue(restart))); 107 Parameters.Add(new ValueParameter<IntValue>("Restart.MinTries", "The minimum number of tries before the worst algorithm is restarted.", new IntValue(minTries))); 108 Parameters.Add(new ValueParameter<DoubleValue>("Restart.LastSuccessPercentage", "Only if the last found best solution is older than x percent of the total number of tries, the worst algorithm is restarted.", new DoubleValue(lastSuccessPercentage))); 109 } 110 76 111 public override IDeepCloneable Clone(Cloner cloner) { 77 112 return new MultiNestCFSAPSolvingStrategy(this, cloner); 78 113 } 79 80 114 81 115 [StorableHook(HookType.AfterDeserialization)] … … 83 117 if (!Parameters.ContainsKey("EvaluatedSolutionsName")) 84 118 Parameters.Add(new FixedValueParameter<StringValue>("EvaluatedSolutionsName", "The name of the result that shows the number of evaluated solutions by the actual solver.", new StringValue("EvaluatedSolutions"))); 119 if (!Parameters.ContainsKey("Restart")) 120 Parameters.Add(new ValueParameter<BoolValue>(nameof(Restart), "Whether the worst algorithm should be restarted, if it doesn't find any better solutions.", new BoolValue(restart))); 121 if (!Parameters.ContainsKey("Restart.MinTries")) 122 Parameters.Add(new ValueParameter<IntValue>("Restart.MinTries", "The minimum number of tries before the worst algorithm is restarted.", new IntValue(minTries))); 123 if (!Parameters.ContainsKey("Restart.LastSuccessPercentage")) 124 Parameters.Add(new ValueParameter<DoubleValue>("Restart.LastSuccessPercentage", "Only if the last found best solution is older than x percent of the total number of tries, the worst algorithm is restarted.", new DoubleValue(lastSuccessPercentage))); 85 125 } 86 126 … … 95 135 [Storable] 96 136 private IndexedDataTable<double> qualityPerEvaluations; 137 [Storable] 138 private bool restart = true; 139 [Storable] 140 private int minTries = 10000; 141 [Storable] 142 private double lastSuccessPercentage = 0.1; 97 143 98 144 protected override void OnPrepared() { … … 117 163 cfsap.UpdateEncoding(); 118 164 algorithms.Add(clone); 119 algorithmsResults.Add(new Result( "Nest " + (n + 1), clone.Results));165 algorithmsResults.Add(new Result($"Nest {n + 1}", clone.Results)); 120 166 clone.Start(); 121 167 } … … 133 179 qualityPerEvaluations.Rows.Add(qpeRow); 134 180 double evaluations = GetEvaluatedSolutions(); 135 qpeRow.Values.Add(Tuple.Create( (double)evaluations, (double)min));136 qpeRow.Values.Add(Tuple.Create( (double)evaluations, (double)min));181 qpeRow.Values.Add(Tuple.Create(evaluations, (double)min)); 182 qpeRow.Values.Add(Tuple.Create(evaluations, (double)min)); 137 183 138 184 Results.Add(new Result("Nest with maximum T", new IntValue(worst.Index + 1))); 139 185 Results.Add(new Result("Maximum T", new IntValue(min))); 140 186 Results.Add(new Result("BestQuality", new DoubleValue(min))); 187 Results.Add(new Result("Best Solution Found After Evaluated Solutions", new DoubleValue(evaluations))); 141 188 Results.Add(new Result("Best Solution Found At", new TimeSpanValue(ExecutionTime))); 142 189 Results.Add(new Result("Delta T", new PercentValue((min - Problem.BestKnownQuality) / Problem.BestKnownQuality))); … … 144 191 Results.Add(new Result("QualityPerClock", qualityPerClock)); 145 192 Results.Add(new Result("QualityPerEvaluations", qualityPerEvaluations)); 193 Results.Add(new Result("Tries", new IntValue(nests))); 194 Results.Add(new Result("Nests", new IntValue(nests))); 195 Results.Add(new Result("Jobs", new IntValue(Problem.ProcessingTimes.First().Count() / Problem.SetupTimes.First().Count()))); 146 196 147 197 base.Initialize(cancellationToken); … … 149 199 150 200 private double GetEvaluatedSolutions() { 151 if (algorithmsResults == null) throw new InvalidOperationException("Strategy has not been started yet."); 201 if (algorithmsResults == null) 202 throw new InvalidOperationException("Strategy has not been started yet."); 152 203 return algorithmsResults.Select(x => { 153 IResult res; 154 if (((ResultCollection)x.Value).TryGetValue(EvaluatedSolutionsName, out res)) { 204 if (((ResultCollection)x.Value).TryGetValue(EvaluatedSolutionsName, out var res)) { 155 205 var itm = res.Value; 156 if (itm is IntValue) return ((IntValue)itm).Value; 157 else if (itm is DoubleValue) return ((DoubleValue)itm).Value; 206 if (itm is IntValue) 207 return ((IntValue)itm).Value; 208 else if (itm is DoubleValue) 209 return ((DoubleValue)itm).Value; 158 210 } 159 throw new InvalidOperationException( "No result " + EvaluatedSolutionsName + " in the collection of " + x.Name);211 throw new InvalidOperationException($"No result {EvaluatedSolutionsName} in the collection of {x.Name}"); 160 212 }).Sum(); 161 213 } 162 214 163 215 protected override void Run(CancellationToken cancellationToken) { 216 var evaluationsPrevTries = 0.0; 164 217 var worst = qualities.Select((v, i) => new { Index = i, Quality = v }).MaxItems(x => x.Quality).First(); 165 218 var min = worst.Quality; 166 219 167 while (ExecutionTime < MaximumRuntime) { 168 algorithms[worst.Index].Start(cancellationToken); 169 qualities[worst.Index] = (int)((DoubleValue)algorithms[worst.Index].Results["BestQuality"].Value).Value; 170 worst = qualities.Select((v, i) => new { Index = i, Quality = v }).MaxItems(x => x.Quality).First(); 171 172 var evaluations = GetEvaluatedSolutions(); 173 var time = ExecutionTime.TotalSeconds; 174 var qpcRow = qualityPerClock.Rows.First(); 175 var qpeRow = qualityPerEvaluations.Rows.First(); 176 qpcRow.Values[qpcRow.Values.Count - 1] = Tuple.Create(time, (double)min); 177 qpeRow.Values[qpeRow.Values.Count - 1] = Tuple.Create(evaluations, (double)min); 178 179 if (worst.Quality < min) { 180 min = worst.Quality; 181 ((IntValue)Results["Nest with maximum T"].Value).Value = worst.Index + 1; 182 ((IntValue)Results["Maximum T"].Value).Value = min; 183 ((DoubleValue)Results["BestQuality"].Value).Value = min; 184 ((TimeSpanValue)Results["Best Solution Found At"].Value).Value = TimeSpan.FromSeconds(time); 185 ((PercentValue)Results["Delta T"].Value).Value = (min - Problem.BestKnownQuality) / Problem.BestKnownQuality; 186 qpcRow.Values.Add(Tuple.Create(time, (double)min)); 187 qpeRow.Values.Add(Tuple.Create(evaluations, (double)min)); 220 var overallBestQualities = algorithms.Select(a => ((DoubleValue)a.Results["BestQuality"].Value).Value).ToArray(); 221 222 do { 223 var tries = 0; 224 var lastSuccess = 0; 225 226 while (ExecutionTime < MaximumRuntime && !cancellationToken.IsCancellationRequested && 227 (!Restart || (tries < MinTries || (tries - lastSuccess) < tries * LastSuccessPercentage))) { 228 ++tries; 229 ++((IntValue)Results["Tries"].Value).Value; 230 231 algorithms[worst.Index].Start(cancellationToken); 232 qualities[worst.Index] = (int)((DoubleValue)algorithms[worst.Index].Results["BestQuality"].Value).Value; 233 worst = qualities.Select((v, i) => new { Index = i, Quality = v }).MaxItems(x => x.Quality).First(); 234 235 var evaluations = evaluationsPrevTries + GetEvaluatedSolutions(); 236 var time = ExecutionTime.TotalSeconds; 237 var qpcRow = qualityPerClock.Rows.First(); 238 var qpeRow = qualityPerEvaluations.Rows.First(); 239 qpcRow.Values[qpcRow.Values.Count - 1] = Tuple.Create(time, (double)Math.Min(worst.Quality, min)); 240 qpeRow.Values[qpeRow.Values.Count - 1] = Tuple.Create(evaluations, (double)Math.Min(worst.Quality, min)); 241 242 if (worst.Quality < min) { 243 min = worst.Quality; 244 overallBestQualities[worst.Index] = min; 245 ((IntValue)Results["Nest with maximum T"].Value).Value = worst.Index + 1; 246 ((IntValue)Results["Maximum T"].Value).Value = min; 247 ((DoubleValue)Results["BestQuality"].Value).Value = min; 248 ((DoubleValue)Results["Best Solution Found After Evaluated Solutions"].Value).Value = evaluations; 249 ((TimeSpanValue)Results["Best Solution Found At"].Value).Value = TimeSpan.FromSeconds(time); 250 ((PercentValue)Results["Delta T"].Value).Value = (min - Problem.BestKnownQuality) / Problem.BestKnownQuality; 251 qpcRow.Values.Add(Tuple.Create(time, (double)min)); 252 qpeRow.Values.Add(Tuple.Create(evaluations, (double)min)); 253 lastSuccess = tries; 254 } 188 255 } 189 256 190 if (cancellationToken.IsCancellationRequested) return; 257 if (cancellationToken.IsCancellationRequested || ExecutionTime >= MaximumRuntime || !Restart) 258 break; 259 260 evaluationsPrevTries += GetEvaluatedSolutions(); 261 262 // restart worst algorithm 263 var worstAlgorithm = algorithms[worst.Index]; 264 var prevGenerations = ((IntValue)worstAlgorithm.Results["Generation"].Value).Value; 265 var prevEvaluatedSolutions = ((IntValue)worstAlgorithm.Results["EvaluatedSolutions"].Value).Value; 266 267 worstAlgorithm.Prepare(); 268 worstAlgorithm.Start(cancellationToken); 269 ++((IntValue)Results["Tries"].Value).Value; 270 271 ((IntValue)worstAlgorithm.Results["Generation"].Value).Value += prevGenerations; 272 ((IntValue)worstAlgorithm.Results["EvaluatedSolutions"].Value).Value += prevEvaluatedSolutions; 273 } while (Restart); 274 275 for (var i = 0; i < algorithms.Count(); ++i) { 276 if (overallBestQualities[i] < ((DoubleValue)algorithms[i].Results["BestQuality"].Value).Value) { 277 ((DoubleValue)algorithms[i].Results["BestQuality"].Value).Value = overallBestQualities[i]; 278 } 191 279 } 192 280 }
Note: See TracChangeset
for help on using the changeset viewer.