Changeset 14456
- Timestamp:
- 12/06/16 15:07:45 (8 years ago)
- Location:
- branches/MemPRAlgorithm
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/MemPRAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/BinaryMemPR.cs
r14453 r14456 97 97 } 98 98 99 protected override void TabuWalk(ISingleObjectiveSolutionScope<BinaryVector> scope, int steps, CancellationToken token, ISolutionSubspace<BinaryVector> subspace = null) {99 protected override int TabuWalk(ISingleObjectiveSolutionScope<BinaryVector> scope, int maxEvals, CancellationToken token, ISolutionSubspace<BinaryVector> subspace = null) { 100 100 var evaluations = 0; 101 101 var subset = subspace != null ? ((BinarySolutionSubspace)subspace).Subspace : null; … … 111 111 for (var i = 0; i < N; i++) tabu[i] = Tuple.Create(current[i] ? double.NaN : currentScope.Fitness, !current[i] ? double.NaN : currentScope.Fitness); 112 112 var subN = subset != null ? subset.Count(x => x) : N; 113 if (subN == 0) return ;113 if (subN == 0) return 0; 114 114 var order = Enumerable.Range(0, N).Where(x => subset == null || subset[x]).Shuffle(Context.Random).ToArray(); 115 115 116 for (var iter = 0; iter < steps; iter++) { 116 var steps = 0; 117 var stepsUntilBestOfWalk = 0; 118 for (var iter = 0; iter < int.MaxValue; iter++) { 117 119 var allTabu = true; 118 120 var bestOfTheRestF = double.NaN; … … 130 132 if (IsBetter(after, before) && (bestOfTheWalk == null || IsBetter(after, bestOfTheWalk.Fitness))) { 131 133 bestOfTheWalk = (SingleObjectiveSolutionScope<BinaryVector>)currentScope.Clone(); 134 stepsUntilBestOfWalk = steps; 132 135 } 133 136 … … 138 141 if (IsBetter(after, before) && !isTabu) { 139 142 improved = true; 143 steps++; 140 144 tabu[idx] = current[idx] ? Tuple.Create(after, tabu[idx].Item2) : Tuple.Create(tabu[idx].Item1, after); 141 145 } else { // undo the move … … 147 151 currentScope.Fitness = before; 148 152 } 153 if (evaluations >= maxEvals) break; 149 154 } 150 155 if (!allTabu && !improved) { … … 153 158 tabu[bestOfTheRest] = current[bestOfTheRest] ? Tuple.Create(better, tabu[bestOfTheRest].Item2) : Tuple.Create(tabu[bestOfTheRest].Item1, better); 154 159 currentScope.Fitness = bestOfTheRestF; 160 steps++; 155 161 } else if (allTabu) break; 162 if (evaluations >= maxEvals) break; 156 163 } 157 164 158 165 Context.IncrementEvaluatedSolutions(evaluations); 159 166 scope.Adopt(bestOfTheWalk ?? currentScope); 167 return stepsUntilBestOfWalk; 160 168 } 161 169 -
branches/MemPRAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/MemPRAlgorithm.cs
r14454 r14456 231 231 Analyze(token); 232 232 token.ThrowIfCancellationRequested(); 233 if (Terminate()) return; 233 234 } 234 235 Context.HcSteps /= 2; … … 314 315 Results.Add(new Result("Iterations", new IntValue(Context.Iterations))); 315 316 else ((IntValue)res.Value).Value = Context.Iterations; 317 if (!Results.TryGetValue("HcSteps", out res)) 318 Results.Add(new Result("HcSteps", new IntValue(Context.HcSteps))); 319 else ((IntValue)res.Value).Value = Context.HcSteps; 316 320 if (!Results.TryGetValue("ByBreeding", out res)) 317 321 Results.Add(new Result("ByBreeding", new IntValue(Context.ByBreeding))); … … 491 495 Context.HillclimbingStat.Add(Tuple.Create(before, after)); 492 496 Context.IncrementEvaluatedSolutions(lscontext.EvaluatedSolutions); 493 return lscontext. Iterations;497 return lscontext.EvaluatedSolutions; 494 498 } 495 499 … … 501 505 var before = scope.Fitness; 502 506 var newScope = (ISingleObjectiveSolutionScope<TSolution>)scope.Clone(); 503 TabuWalk(newScope, steps, token, subspace);507 var newSteps = TabuWalk(newScope, steps, token, subspace); 504 508 Context.TabuwalkingStat.Add(Tuple.Create(before, newScope.Fitness)); 509 //Context.HcSteps = (int)Math.Ceiling(Context.HcSteps * (1.0 + Context.TabuwalkingStat.Count) / (2.0 + Context.TabuwalkingStat.Count) + newSteps / (2.0 + Context.TabuwalkingStat.Count)); 505 510 if (IsBetter(newScope, scope) || (newScope.Fitness == scope.Fitness && Dist(newScope, scope) > 0)) 506 511 scope.Adopt(newScope); 507 512 } 508 protected abstract void TabuWalk(ISingleObjectiveSolutionScope<TSolution> scope, int steps, CancellationToken token, ISolutionSubspace<TSolution> subspace = null);513 protected abstract int TabuWalk(ISingleObjectiveSolutionScope<TSolution> scope, int maxEvals, CancellationToken token, ISolutionSubspace<TSolution> subspace = null); 509 514 protected virtual void TabuClimb(ISingleObjectiveSolutionScope<TSolution> scope, int steps, CancellationToken token, ISolutionSubspace<TSolution> subspace = null) { 510 515 if (double.IsNaN(scope.Fitness)) { … … 514 519 var before = scope.Fitness; 515 520 var newScope = (ISingleObjectiveSolutionScope<TSolution>)scope.Clone(); 516 TabuWalk(newScope, steps, token, subspace);521 var newSteps = TabuWalk(newScope, steps, token, subspace); 517 522 Context.TabuwalkingStat.Add(Tuple.Create(before, newScope.Fitness)); 523 //Context.HcSteps = (int)Math.Ceiling(Context.HcSteps * (1.0 + Context.TabuwalkingStat.Count) / (2.0 + Context.TabuwalkingStat.Count) + newSteps / (2.0 + Context.TabuwalkingStat.Count)); 518 524 if (IsBetter(newScope, scope) || (newScope.Fitness == scope.Fitness && Dist(newScope, scope) > 0)) 519 525 scope.Adopt(newScope); … … 557 563 || Context.Population.Any(p => IsBetter(offspring, p))) return offspring; 558 564 559 if (IsBetter(offspring.Fitness, Context.BestQuality)) 560 HillClimb(offspring, token); // perform hillclimb in full solution space 561 else if (HillclimbingSuited(offspring)) 565 if (HillclimbingSuited(offspring)) 562 566 HillClimb(offspring, token, subspace); // perform hillclimb in the solution sub-space 563 567 return offspring; … … 589 593 if (dist1 > 0 && dist2 > 0) { 590 594 var subspace = CalculateSubspace(new[] { a.Solution, b.Solution }, inverse: true); 591 if (IsBetter(child.Fitness, Context.BestQuality)) 592 HillClimb(child, token); // perform hillclimb in full solution space 593 else if (HillclimbingSuited(child)) { 595 if (HillclimbingSuited(child)) { 594 596 HillClimb(child, token, subspace); // perform hillclimb in solution sub-space 595 597 } -
branches/MemPRAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Permutation/LocalSearch/StaticAPI/Exhaustive.cs
r14450 r14456 35 35 public static Tuple<int, int> HillClimb(IRandom random, Encodings.PermutationEncoding.Permutation perm, 36 36 ref double quality, bool maximization, Func<Encodings.PermutationEncoding.Permutation, double> eval, 37 CancellationToken token, bool[,] noTouch= null) {37 CancellationToken token, bool[,] subspace = null) { 38 38 if (double.IsNaN(quality)) quality = eval(perm); 39 39 Tuple<int, int> changes; 40 40 switch (perm.PermutationType) { 41 41 case PermutationTypes.Absolute: 42 changes = ExhaustiveSwap2.HillClimb(random, perm, ref quality, maximization, eval, token, noTouch);42 changes = ExhaustiveSwap2.HillClimb(random, perm, ref quality, maximization, eval, token, subspace); 43 43 break; 44 44 case PermutationTypes.RelativeDirected: 45 changes = Exhaustive1Shift.HillClimb(random, perm, ref quality, maximization, eval, token, noTouch);45 changes = Exhaustive1Shift.HillClimb(random, perm, ref quality, maximization, eval, token, subspace); 46 46 break; 47 47 case PermutationTypes.RelativeUndirected: 48 changes = Exhaustive2Opt.HillClimb(random, perm, ref quality, maximization, eval, token, noTouch);48 changes = Exhaustive2Opt.HillClimb(random, perm, ref quality, maximization, eval, token, subspace); 49 49 break; 50 50 default: throw new ArgumentException(string.Format("Permutation type {0} is not known", perm.PermutationType)); -
branches/MemPRAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Permutation/LocalSearch/StaticAPI/Exhaustive1Shift.cs
r14453 r14456 21 21 22 22 using System; 23 using System.Linq; 23 24 using System.Threading; 24 25 using HeuristicLab.Algorithms.MemPR.Util; 25 26 using HeuristicLab.Core; 26 27 using HeuristicLab.Encodings.PermutationEncoding; 28 using HeuristicLab.Random; 27 29 28 30 namespace HeuristicLab.Algorithms.MemPR.Permutation.LocalSearch { … … 30 32 public static Tuple<int, int> HillClimb(IRandom random, Encodings.PermutationEncoding.Permutation perm, 31 33 ref double quality, bool maximization, Func<Encodings.PermutationEncoding.Permutation, double> eval, 32 CancellationToken token, bool[,] noTouch = null) { 34 CancellationToken token, bool[,] subspace = null) { 35 var evaluations = 0; 33 36 var current = perm; 34 if (double.IsNaN(quality)) quality = eval(current); 37 if (double.IsNaN(quality)) { 38 quality = eval(current); 39 evaluations++; 40 } 35 41 TranslocationMove lastSuccessMove = null; 36 int steps = 0, evaluations = 0; 42 var steps = 0; 43 var neighborhood = ExhaustiveInsertionMoveGenerator.Generate(current).Shuffle(random).ToList(); 37 44 while (true) { 38 foreach (var shift in ExhaustiveInsertionMoveGenerator.Generate(current)) {45 foreach (var shift in neighborhood) { 39 46 if (lastSuccessMove != null && shift.Index1 == lastSuccessMove.Index1 && shift.Index2 == lastSuccessMove.Index2 && shift.Index3 == lastSuccessMove.Index3) { 40 47 // been there, done that … … 48 55 var next3 = (shift.Index3 + 1) % current.Length; 49 56 if (prev3 < 0) prev3 += current.Length; 50 if ( noTouch != null && ((noTouch[current[prev1], current[shift.Index1]] || noTouch[current[shift.Index1], current[next1]]51 || noTouch[current[prev3], current[shift.Index3]] || noTouch[current[shift.Index3], current[next3]])))57 if (subspace != null && !(subspace[current[prev1], current[shift.Index1]] && subspace[current[shift.Index1], current[next1]] 58 && subspace[current[prev3], current[shift.Index3]] && subspace[current[shift.Index3], current[next3]])) 52 59 continue; 53 60 TranslocationManipulator.Apply(current, shift.Index1, shift.Index2, shift.Index3); -
branches/MemPRAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Permutation/LocalSearch/StaticAPI/Exhaustive2Opt.cs
r14453 r14456 21 21 22 22 using System; 23 using System.Linq; 23 24 using System.Threading; 24 25 using HeuristicLab.Algorithms.MemPR.Util; 25 26 using HeuristicLab.Core; 26 27 using HeuristicLab.Encodings.PermutationEncoding; 28 using HeuristicLab.Random; 27 29 28 30 namespace HeuristicLab.Algorithms.MemPR.Permutation.LocalSearch { … … 30 32 public static Tuple<int, int> HillClimb(IRandom random, Encodings.PermutationEncoding.Permutation perm, 31 33 ref double quality, bool maximization, Func<Encodings.PermutationEncoding.Permutation, double> eval, 32 CancellationToken token, bool[,] noTouch = null) { 34 CancellationToken token, bool[,] subspace = null) { 35 var evaluations = 0; 33 36 var current = perm; 34 if (double.IsNaN(quality)) quality = eval(current); 37 if (double.IsNaN(quality)) { 38 quality = eval(current); 39 evaluations++; 40 } 35 41 InversionMove lastSuccessMove = null; 36 int steps = 0, evaluations = 0; 42 var steps = 0; 43 var neighborhood = ExhaustiveInversionMoveGenerator.Generate(current).Shuffle(random).ToList(); 37 44 while (true) { 38 foreach (var opt in ExhaustiveInversionMoveGenerator.Generate(current)) {45 foreach (var opt in neighborhood) { 39 46 if (lastSuccessMove != null && opt.Index1 == lastSuccessMove.Index1 && opt.Index2 == lastSuccessMove.Index2) { 40 47 // been there, done that … … 45 52 var next = (opt.Index2 + 1) % current.Length; 46 53 if (prev < 0) prev += current.Length; 47 if ( noTouch != null && ((noTouch[current[prev], current[opt.Index1]]) || (noTouch[current[opt.Index2], current[next]])))54 if (subspace != null && !(subspace[current[prev], current[opt.Index1]] && subspace[current[opt.Index2], current[next]])) 48 55 continue; 49 56 -
branches/MemPRAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Permutation/LocalSearch/StaticAPI/ExhaustiveSwap2.cs
r14453 r14456 21 21 22 22 using System; 23 using System.Linq; 23 24 using System.Threading; 24 25 using HeuristicLab.Algorithms.MemPR.Util; 25 26 using HeuristicLab.Core; 26 27 using HeuristicLab.Encodings.PermutationEncoding; 28 using HeuristicLab.Random; 27 29 28 30 namespace HeuristicLab.Algorithms.MemPR.Permutation.LocalSearch { … … 30 32 public static Tuple<int, int> HillClimb(IRandom random, Encodings.PermutationEncoding.Permutation perm, 31 33 ref double quality, bool maximization, Func<Encodings.PermutationEncoding.Permutation, double> eval, 32 CancellationToken token, bool[,] noTouch = null) { 34 CancellationToken token, bool[,] subspace = null) { 35 var evaluations = 0; 33 36 var current = perm; 34 if (double.IsNaN(quality)) quality = eval(current); 37 if (double.IsNaN(quality)) { 38 quality = eval(current); 39 evaluations++; 40 } 35 41 Swap2Move lastSuccessMove = null; 36 int steps = 0, evaluations = 0; 42 var steps = 0; 43 var neighborhood = ExhaustiveSwap2MoveGenerator.Generate(current).Shuffle(random).ToList(); 37 44 while (true) { 38 foreach (var swap in ExhaustiveSwap2MoveGenerator.Generate(current)) {45 foreach (var swap in neighborhood) { 39 46 if (lastSuccessMove != null && swap.Index1 == lastSuccessMove.Index1 && swap.Index2 == lastSuccessMove.Index2) { 40 47 // been there, done that … … 42 49 break; 43 50 } 44 if ( noTouch != null && (noTouch[swap.Index1, 0] || noTouch[swap.Index2, 0]))51 if (subspace != null && !(subspace[swap.Index1, 0] && subspace[swap.Index2, 0])) 45 52 continue; 46 53 -
branches/MemPRAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Permutation/PermutationMemPR.cs
r14453 r14456 144 144 } 145 145 146 protected override void TabuWalk(ISingleObjectiveSolutionScope<Encodings.PermutationEncoding.Permutation> scope, int steps, CancellationToken token, ISolutionSubspace<Encodings.PermutationEncoding.Permutation> subspace = null) {146 protected override int TabuWalk(ISingleObjectiveSolutionScope<Encodings.PermutationEncoding.Permutation> scope, int maxEvals, CancellationToken token, ISolutionSubspace<Encodings.PermutationEncoding.Permutation> subspace = null) { 147 147 var wrapper = new EvaluationWrapper<Encodings.PermutationEncoding.Permutation>(Context.Problem, scope); 148 148 var quality = scope.Fitness; 149 149 try { 150 TabuWalk(Context.Random, scope.Solution, wrapper.Evaluate, ref quality, Context.HcSteps, subspace != null ? ((PermutationSolutionSubspace)subspace).Subspace : null);150 return TabuWalk(Context.Random, scope.Solution, wrapper.Evaluate, ref quality, maxEvals, subspace != null ? ((PermutationSolutionSubspace)subspace).Subspace : null); 151 151 } finally { 152 152 scope.Fitness = quality; … … 154 154 } 155 155 156 public void TabuWalk(IRandom random, Encodings.PermutationEncoding.Permutation perm, Func<Encodings.PermutationEncoding.Permutation, IRandom, double> eval, ref double quality, int maxIterations = int.MaxValue, bool[,] noTouch = null) { 156 public int TabuWalk(IRandom random, Encodings.PermutationEncoding.Permutation perm, Func<Encodings.PermutationEncoding.Permutation, IRandom, double> eval, ref double quality, int maxEvals = int.MaxValue, bool[,] subspace = null) { 157 int newSteps = 0; 157 158 switch (perm.PermutationType) { 158 159 case PermutationTypes.Absolute: 159 TabuWalkSwap(random, perm, eval, ref quality, maxIterations, noTouch);160 newSteps = TabuWalkSwap(random, perm, eval, ref quality, maxEvals, subspace); 160 161 break; 161 162 case PermutationTypes.RelativeDirected: 162 TabuWalkShift(random, perm, eval, ref quality, maxIterations, noTouch);163 newSteps = TabuWalkShift(random, perm, eval, ref quality, maxEvals, subspace); 163 164 break; 164 165 case PermutationTypes.RelativeUndirected: 165 TabuWalkOpt(random, perm, eval, ref quality, maxIterations, noTouch);166 newSteps = TabuWalkOpt(random, perm, eval, ref quality, maxEvals, subspace); 166 167 break; 167 168 default: throw new ArgumentException(string.Format("Permutation type {0} is not known", perm.PermutationType)); 168 169 } 169 170 if (VALIDATE && !perm.Validate()) throw new ArgumentException("TabuWalk produced invalid child"); 170 } 171 172 public void TabuWalkSwap(IRandom random, Encodings.PermutationEncoding.Permutation perm, Func<Encodings.PermutationEncoding.Permutation, IRandom, double> eval, ref double quality, int maxIterations = int.MaxValue, bool[,] noTouch = null) { 171 return newSteps; 172 } 173 174 public int TabuWalkSwap(IRandom random, Encodings.PermutationEncoding.Permutation perm, Func<Encodings.PermutationEncoding.Permutation, IRandom, double> eval, ref double quality, int maxEvals = int.MaxValue, bool[,] subspace = null) { 173 175 var evaluations = 0; 176 var maximization = Context.Problem.Maximization; 174 177 if (double.IsNaN(quality)) { 175 178 quality = eval(perm, random); … … 189 192 } 190 193 191 for (var iter = 0; iter < maxIterations; iter++) { 194 var steps = 0; 195 var stepsUntilBestOfWalk = 0; 196 for (var iter = 0; iter < int.MaxValue; iter++) { 192 197 var allTabu = true; 193 198 var bestOfTheRestF = double.NaN; … … 195 200 var improved = false; 196 201 foreach (var swap in ExhaustiveSwap2MoveGenerator.Generate(current).Shuffle(random)) { 197 if ( noTouch != null && (noTouch[swap.Index1, 0] || noTouch[swap.Index2, 0]))202 if (subspace != null && !(subspace[swap.Index1, 0] && subspace[swap.Index2, 0])) 198 203 continue; 199 204 … … 203 208 var q = eval(current, random); 204 209 evaluations++; 205 if ( q < quality) {210 if (FitnessComparer.IsBetter(maximization, q, quality)) { 206 211 overallImprovement = true; 207 212 quality = q; … … 209 214 } 210 215 // check if it would not be an improvement to swap these into their positions 211 var isTabu = q >= tabu[swap.Index1, current[swap.Index1]] && q >= tabu[swap.Index2, current[swap.Index2]]; 216 var isTabu = !FitnessComparer.IsBetter(maximization, q, tabu[swap.Index1, current[swap.Index1]]) 217 && !FitnessComparer.IsBetter(maximization, q, tabu[swap.Index2, current[swap.Index2]]); 212 218 if (!isTabu) allTabu = false; 213 if ( q < currentF&& !isTabu) {214 if ( double.IsNaN(bestOfTheWalkF) || bestOfTheWalkF > q) {219 if (FitnessComparer.IsBetter(maximization, q, currentF) && !isTabu) { 220 if (FitnessComparer.IsBetter(maximization, q, bestOfTheWalkF)) { 215 221 bestOfTheWalk = (Encodings.PermutationEncoding.Permutation)current.Clone(); 216 222 bestOfTheWalkF = q; 217 } 218 223 stepsUntilBestOfWalk = steps; 224 } 225 steps++; 219 226 improved = true; 220 227 // perform the move 221 228 currentF = q; 222 229 // mark that to move them to their previous position requires to make an improvement 223 tabu[swap.Index1, current[swap.Index2]] = Math.Min(q, tabu[swap.Index1, current[swap.Index2]]);224 //LogAlways("Making Tabu [{0},{1}] = {2}", swap.Index1, current[swap.Index2], tabu[swap.Index1, current[swap.Index2]]);225 tabu[swap.Index2, current[swap.Index1]] = Math.Min(q, tabu[swap.Index2, current[swap.Index1]]);226 //LogAlways("Making Tabu [{0},{1}] = {2}", swap.Index2, current[swap.Index1], tabu[swap.Index2, current[swap.Index1]]);230 tabu[swap.Index1, current[swap.Index2]] = maximization ? Math.Max(q, tabu[swap.Index1, current[swap.Index2]]) 231 : Math.Min(q, tabu[swap.Index1, current[swap.Index2]]); 232 tabu[swap.Index2, current[swap.Index1]] = maximization ? Math.Max(q, tabu[swap.Index2, current[swap.Index1]]) 233 : Math.Min(q, tabu[swap.Index2, current[swap.Index1]]); 227 234 } else { // undo the move 228 if (!isTabu && (double.IsNaN(bestOfTheRestF) || q <bestOfTheRestF)) {235 if (!isTabu && FitnessComparer.IsBetter(maximization, q, bestOfTheRestF)) { 229 236 bestOfTheRest = swap; 230 237 bestOfTheRestF = q; … … 233 240 current[swap.Index1] = h; 234 241 } 235 } 236 if (!allTabu && !improved) { 237 tabu[bestOfTheRest.Index1, current[bestOfTheRest.Index1]] = Math.Min(currentF, tabu[bestOfTheRest.Index1, current[bestOfTheRest.Index1]]); 238 tabu[bestOfTheRest.Index2, current[bestOfTheRest.Index2]] = Math.Min(currentF, tabu[bestOfTheRest.Index2, current[bestOfTheRest.Index2]]); 242 if (evaluations >= maxEvals) break; 243 } 244 if (!allTabu && !improved && bestOfTheRest != null) { 245 tabu[bestOfTheRest.Index1, current[bestOfTheRest.Index1]] = maximization ? Math.Max(currentF, tabu[bestOfTheRest.Index1, current[bestOfTheRest.Index1]]) 246 : Math.Min(currentF, tabu[bestOfTheRest.Index1, current[bestOfTheRest.Index1]]); 247 tabu[bestOfTheRest.Index2, current[bestOfTheRest.Index2]] = maximization ? Math.Max(currentF, tabu[bestOfTheRest.Index2, current[bestOfTheRest.Index2]]) 248 : Math.Min(currentF, tabu[bestOfTheRest.Index2, current[bestOfTheRest.Index2]]); 239 249 240 250 var h = current[bestOfTheRest.Index1]; … … 243 253 244 254 currentF = bestOfTheRestF; 255 steps++; 245 256 } else if (allTabu) break; 257 if (evaluations >= maxEvals) break; 246 258 } 247 259 Context.IncrementEvaluatedSolutions(evaluations); … … 250 262 for (var i = 0; i < current.Length; i++) perm[i] = bestOfTheWalk[i]; 251 263 } 252 } 253 254 public void TabuWalkShift(IRandom random, Encodings.PermutationEncoding.Permutation perm, Func<Encodings.PermutationEncoding.Permutation, IRandom, double> eval, ref double quality, int maxIterations = int.MaxValue, bool[,] noTouch = null) { 255 return; 256 } 257 258 public void TabuWalkOpt(IRandom random, Encodings.PermutationEncoding.Permutation perm, Func<Encodings.PermutationEncoding.Permutation, IRandom, double> eval, ref double quality, int maxIterations = int.MaxValue, bool[,] noTouch = null) { 264 return stepsUntilBestOfWalk; 265 } 266 267 public int TabuWalkShift(IRandom random, Encodings.PermutationEncoding.Permutation perm, Func<Encodings.PermutationEncoding.Permutation, IRandom, double> eval, ref double quality, int maxEvals = int.MaxValue, bool[,] subspace = null) { 268 return 0; 269 } 270 271 public int TabuWalkOpt(IRandom random, Encodings.PermutationEncoding.Permutation perm, Func<Encodings.PermutationEncoding.Permutation, IRandom, double> eval, ref double quality, int maxEvals = int.MaxValue, bool[,] subspace = null) { 272 var maximization = Context.Problem.Maximization; 259 273 var evaluations = 0; 260 274 if (double.IsNaN(quality)) { … … 263 277 } 264 278 Encodings.PermutationEncoding.Permutation bestOfTheWalk = null; 265 doublebestOfTheWalkF = double.NaN;279 var bestOfTheWalkF = double.NaN; 266 280 var current = (Encodings.PermutationEncoding.Permutation)perm.Clone(); 267 281 var currentF = quality; 268 282 var overallImprovement = false; 269 //Console.WriteLine("Current {0}", string.Join(", ", current));270 283 var tabu = new double[current.Length, current.Length]; 271 284 for (var i = 0; i < current.Length; i++) { … … 277 290 } 278 291 279 for (var iter = 0; iter < maxIterations; iter++) { 292 var steps = 0; 293 var stepsUntilBestOfWalk = 0; 294 for (var iter = 0; iter < int.MaxValue; iter++) { 280 295 var allTabu = true; 281 296 var bestOfTheRestF = double.NaN; … … 287 302 var next = (opt.Index2 + 1) % current.Length; 288 303 if (prev < 0) prev += current.Length; 289 if ( noTouch != null && ((noTouch[current[prev], current[opt.Index1]]) || (noTouch[current[opt.Index2], current[next]])))304 if (subspace != null && !(subspace[current[prev], current[opt.Index1]] && subspace[current[opt.Index2], current[next]])) 290 305 continue; 291 306 … … 294 309 var q = eval(current, random); 295 310 evaluations++; 296 if ( q < quality) {311 if (FitnessComparer.IsBetter(maximization, q, quality)) { 297 312 overallImprovement = true; 298 313 quality = q; … … 300 315 } 301 316 // check if it would not be an improvement to opt these into their positions 302 var isTabu = q >= tabu[current[prev], current[opt.Index1]] && q >= tabu[current[opt.Index2], current[next]]; 317 var isTabu = !FitnessComparer.IsBetter(maximization, q, tabu[current[prev], current[opt.Index1]]) 318 && !FitnessComparer.IsBetter(maximization, q, tabu[current[opt.Index2], current[next]]); 303 319 if (!isTabu) allTabu = false; 304 if ( q < currentF && !isTabu) {305 if ( double.IsNaN(bestOfTheWalkF) || bestOfTheWalkF > q) {320 if (!isTabu && FitnessComparer.IsBetter(maximization, q, currentF)) { 321 if (FitnessComparer.IsBetter(maximization, q, bestOfTheWalkF)) { 306 322 bestOfTheWalk = (Encodings.PermutationEncoding.Permutation)current.Clone(); 307 323 bestOfTheWalkF = q; 308 } 309 324 stepsUntilBestOfWalk = steps; 325 } 326 327 steps++; 310 328 improved = true; 311 329 // perform the move 312 330 currentF = q; 313 331 // mark that to move them to their previous position requires to make an improvement 314 tabu[current[prev], current[opt.Index2]] = Math.Min(q, tabu[current[prev], current[opt.Index2]]); 315 tabu[current[opt.Index2], current[prev]] = Math.Min(q, tabu[current[opt.Index2], current[prev]]); 316 tabu[current[opt.Index1], current[next]] = Math.Min(q, tabu[current[opt.Index1], current[next]]); 317 tabu[current[next], current[opt.Index1]] = Math.Min(q, tabu[current[next], current[opt.Index1]]); 332 if (maximization) { 333 tabu[current[prev], current[opt.Index2]] = Math.Max(q, tabu[current[prev], current[opt.Index2]]); 334 tabu[current[opt.Index2], current[prev]] = Math.Max(q, tabu[current[opt.Index2], current[prev]]); 335 tabu[current[opt.Index1], current[next]] = Math.Max(q, tabu[current[opt.Index1], current[next]]); 336 tabu[current[next], current[opt.Index1]] = Math.Max(q, tabu[current[next], current[opt.Index1]]); 337 } else { 338 tabu[current[prev], current[opt.Index2]] = Math.Min(q, tabu[current[prev], current[opt.Index2]]); 339 tabu[current[opt.Index2], current[prev]] = Math.Min(q, tabu[current[opt.Index2], current[prev]]); 340 tabu[current[opt.Index1], current[next]] = Math.Min(q, tabu[current[opt.Index1], current[next]]); 341 tabu[current[next], current[opt.Index1]] = Math.Min(q, tabu[current[next], current[opt.Index1]]); 342 } 318 343 } else { // undo the move 319 if (!isTabu && (double.IsNaN(bestOfTheRestF) || q <bestOfTheRestF)) {344 if (!isTabu && FitnessComparer.IsBetter(maximization, q, bestOfTheRestF)) { 320 345 bestOfTheRest = opt; 321 346 bestOfTheRestF = q; … … 324 349 InversionManipulator.Apply(current, opt.Index1, opt.Index2); 325 350 } 326 } 327 if (!allTabu && !improved) { 351 if (evaluations >= maxEvals) break; 352 } 353 if (!allTabu && !improved && bestOfTheRest != null) { 328 354 var prev = bestOfTheRest.Index1 - 1; 329 355 var next = (bestOfTheRest.Index2 + 1) % current.Length; 330 356 if (prev < 0) prev += current.Length; 331 357 332 tabu[current[prev], current[bestOfTheRest.Index1]] = Math.Min(currentF, tabu[current[prev], current[bestOfTheRest.Index1]]); 333 tabu[current[bestOfTheRest.Index1], current[prev]] = Math.Min(currentF, tabu[current[bestOfTheRest.Index1], current[prev]]); 334 tabu[current[bestOfTheRest.Index2], current[next]] = Math.Min(currentF, tabu[current[bestOfTheRest.Index2], current[next]]); 335 tabu[current[next], current[bestOfTheRest.Index2]] = Math.Min(currentF, tabu[current[next], current[bestOfTheRest.Index2]]); 336 358 if (maximization) { 359 tabu[current[prev], current[bestOfTheRest.Index1]] = Math.Max(currentF, tabu[current[prev], current[bestOfTheRest.Index1]]); 360 tabu[current[bestOfTheRest.Index1], current[prev]] = Math.Max(currentF, tabu[current[bestOfTheRest.Index1], current[prev]]); 361 tabu[current[bestOfTheRest.Index2], current[next]] = Math.Max(currentF, tabu[current[bestOfTheRest.Index2], current[next]]); 362 tabu[current[next], current[bestOfTheRest.Index2]] = Math.Max(currentF, tabu[current[next], current[bestOfTheRest.Index2]]); 363 } else { 364 tabu[current[prev], current[bestOfTheRest.Index1]] = Math.Min(currentF, tabu[current[prev], current[bestOfTheRest.Index1]]); 365 tabu[current[bestOfTheRest.Index1], current[prev]] = Math.Min(currentF, tabu[current[bestOfTheRest.Index1], current[prev]]); 366 tabu[current[bestOfTheRest.Index2], current[next]] = Math.Min(currentF, tabu[current[bestOfTheRest.Index2], current[next]]); 367 tabu[current[next], current[bestOfTheRest.Index2]] = Math.Min(currentF, tabu[current[next], current[bestOfTheRest.Index2]]); 368 } 337 369 InversionManipulator.Apply(current, bestOfTheRest.Index1, bestOfTheRest.Index2); 338 370 339 371 currentF = bestOfTheRestF; 372 steps++; 340 373 } else if (allTabu) break; 374 if (evaluations >= maxEvals) break; 341 375 } 342 376 Context.IncrementEvaluatedSolutions(evaluations); … … 345 379 for (var i = 0; i < current.Length; i++) perm[i] = bestOfTheWalk[i]; 346 380 } 381 return stepsUntilBestOfWalk; 347 382 } 348 383 … … 478 513 479 514 public Encodings.PermutationEncoding.Permutation RelinkSwap(IRandom random, Encodings.PermutationEncoding.Permutation p1, Encodings.PermutationEncoding.Permutation p2, Func<Encodings.PermutationEncoding.Permutation, IRandom, double> eval, out double best) { 515 var maximization = Context.Problem.Maximization; 480 516 var evaluations = 0; 481 517 var child = (Encodings.PermutationEncoding.Permutation)p1.Clone(); … … 502 538 var moveF = eval(child, random); 503 539 evaluations++; 504 if ( double.IsNaN(bestChange) || moveF < bestChange) {540 if (FitnessComparer.IsBetter(maximization, moveF, bestChange)) { 505 541 bestChange = moveF; 506 542 bestOption = j; … … 516 552 invChild[child[idx2]] = idx2; 517 553 //Log(string.Join(", ", child)); 518 if ( double.IsNaN(best) || bestChange < best) {554 if (FitnessComparer.IsBetter(maximization, bestChange, best)) { 519 555 if (Dist(child, p2) > 0) { 520 556 best = bestChange; … … 525 561 } 526 562 } 563 if (bestChild == null) { 564 best = eval(child, random); 565 evaluations++; 566 } 527 567 Context.IncrementEvaluatedSolutions(evaluations); 528 568 529 569 if (VALIDATE && bestChild != null && !bestChild.Validate()) throw new ArgumentException("Relinking produced invalid child"); 530 570 if (VALIDATE && Dist(child, p2) > 0) throw new InvalidOperationException("Child is not equal to p2 after relinking"); 531 532 if (bestChild == null) best = eval(child, random); 571 533 572 return bestChild ?? child; 534 573 } 535 574 536 575 public Encodings.PermutationEncoding.Permutation RelinkShift(IRandom random, Encodings.PermutationEncoding.Permutation p1, Encodings.PermutationEncoding.Permutation p2, Func<Encodings.PermutationEncoding.Permutation, IRandom, double> eval, out double best) { 576 var maximization = Context.Problem.Maximization; 537 577 var evaluations = 0; 538 578 var child = (Encodings.PermutationEncoding.Permutation)p1.Clone(); … … 557 597 var moveF = eval(child, random); 558 598 evaluations++; 559 if ( double.IsNaN(bestChange) || moveF < bestChange) {599 if (FitnessComparer.IsBetter(maximization, moveF, bestChange)) { 560 600 bestChange = moveF; 561 601 bestFrom = c < n ? n : c; … … 569 609 Shift(child, bestFrom, bestTo); 570 610 for (var i = Math.Min(bestFrom, bestTo); i < Math.Max(bestFrom, bestTo); i++) invChild[child[i]] = i; 571 if ( double.IsNaN(best) || bestChange < best) {611 if (FitnessComparer.IsBetter(maximization, bestChange, best)) { 572 612 best = bestChange; 573 613 bestChild = (Encodings.PermutationEncoding.Permutation)child.Clone(); … … 576 616 } while (!double.IsNaN(bestChange)); 577 617 618 if (bestChild == null) { 619 best = eval(child, random); 620 evaluations++; 621 } 578 622 Context.IncrementEvaluatedSolutions(evaluations); 579 if (VALIDATE && !bestChild.Validate()) throw new ArgumentException("Relinking produced invalid child"); 623 624 if (VALIDATE && bestChild != null && !bestChild.Validate()) throw new ArgumentException("Relinking produced invalid child"); 580 625 if (VALIDATE && Dist(child, p2) > 0) throw new InvalidOperationException("Child is not equal to p2 after relinking"); 581 return bestChild; 626 627 return bestChild ?? child; 582 628 } 583 629 584 630 public Encodings.PermutationEncoding.Permutation RelinkOpt(IRandom random, Encodings.PermutationEncoding.Permutation p1, Encodings.PermutationEncoding.Permutation p2, Func<Encodings.PermutationEncoding.Permutation, IRandom, double> eval, out double best) { 631 var maximization = Context.Problem.Maximization; 585 632 var evaluations = 0; 586 633 var child = (Encodings.PermutationEncoding.Permutation)p1.Clone(); … … 602 649 Queue<Tuple<int, int>> bestQueue = null; 603 650 bestChange = double.NaN; 604 //Log("{0}", string.Join(" ", child));605 651 for (var j = 0; j < p2.Length; j++) { 606 652 if (IsUndirectedEdge(invChild, p2[j], p2.GetCircular(j + 1))) continue; … … 661 707 var moveF = eval(child, random); 662 708 evaluations++; 663 if ( double.IsNaN(bestChange) || moveF < bestChange) {709 if (FitnessComparer.IsBetter(maximization, moveF, bestChange)) { 664 710 bestChange = moveF; 665 711 bestQueue = new Queue<Tuple<int, int>>(undoStack.Reverse()); … … 677 723 } 678 724 for (var i = 0; i < child.Length; i++) invChild[child[i]] = i; 679 if ( double.IsNaN(best) || bestChange < best) {725 if (FitnessComparer.IsBetter(maximization, bestChange, best)) { 680 726 best = bestChange; 681 727 bestChild = (Encodings.PermutationEncoding.Permutation)child.Clone(); … … 684 730 } while (!double.IsNaN(bestChange)); 685 731 732 if (bestChild == null) { 733 best = eval(child, random); 734 evaluations++; 735 } 686 736 Context.IncrementEvaluatedSolutions(evaluations); 687 737 688 if (VALIDATE && !bestChild.Validate()) throw new ArgumentException("Relinking produced invalid child");738 if (VALIDATE && bestChild != null && !bestChild.Validate()) throw new ArgumentException("Relinking produced invalid child"); 689 739 if (VALIDATE && Dist(child, p2) > 0) throw new InvalidOperationException("Child is not equal to p2 after relinking"); 690 return bestChild ;740 return bestChild ?? child; 691 741 } 692 742 -
branches/MemPRAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Util/FitnessComparer.cs
r14450 r14456 23 23 public static class FitnessComparer { 24 24 public static bool IsBetter(bool maximization, double a, double b) { 25 return maximization && a > b 26 || !maximization && a < b; 25 return double.IsNaN(b) && !double.IsNaN(a) 26 || maximization && a > b 27 || !maximization && a < b; 27 28 } 28 29 } -
branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/TravelingSalesmanProblem.cs
r14455 r14456 123 123 public TravelingSalesmanProblem() : base() { 124 124 Encoding = new PermutationEncoding("TSPTour") { Length = 16 }; 125 Encoding.PermutationTypeParameter.Value.Value = PermutationTypes.RelativeUndirected; 125 126 126 127 Parameters.Add(distanceFunctionParameter = new FixedValueParameter<EnumValue<TSPDistanceFunction>>("DistanceFunction", "The distance function that is used to calculate distance among the coordinates.", new EnumValue<TSPDistanceFunction>(TSPDistanceFunction.RoundedEuclidean)));
Note: See TracChangeset
for help on using the changeset viewer.