Changeset 15558 for branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Crossovers/GQAPPathRelinking.cs
- Timestamp:
- 12/22/17 01:32:13 (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Crossovers/GQAPPathRelinking.cs
r15555 r15558 45 45 get { return (IScopeTreeLookupParameter<Evaluation>)Parameters["Evaluation"]; } 46 46 } 47 48 47 public IValueParameter<PercentValue> CandidateSizeFactorParameter { 49 48 get { return (IValueParameter<PercentValue>)Parameters["CandidateSizeFactor"]; } 49 } 50 public IValueLookupParameter<BoolValue> GreedyParameter { 51 get { return (IValueLookupParameter<BoolValue>)Parameters["Greedy"]; } 50 52 } 51 53 … … 58 60 Parameters.Add(new ScopeTreeLookupParameter<Evaluation>("Evaluation", GQAP.EvaluationDescription)); 59 61 Parameters.Add(new ValueParameter<PercentValue>("CandidateSizeFactor", "(η) Determines the size of the set of feasible moves in each path-relinking step relative to the maximum size. A value of 50% means that only half of all possible moves are considered each step.", new PercentValue(0.5))); 62 Parameters.Add(new ValueLookupParameter<BoolValue>("Greedy", "Whether to use a greedy selection strategy or a probabilistic one.", new BoolValue(true))); 60 63 } 61 64 … … 68 71 IntegerVector target, Evaluation targetEval, 69 72 GQAPInstance problemInstance, double candidateSizeFactor, 70 out int evaluatedSolutions ) {73 out int evaluatedSolutions, bool greedy = true) { 71 74 evaluatedSolutions = 0; 72 75 var demands = problemInstance.Demands; 73 76 var capacities = problemInstance.Capacities; 74 77 var cmp = new IntegerVectorEqualityComparer(); 75 76 var greedy = true; // greedy performed better according to the paper 78 77 79 var sFit = problemInstance.ToSingleObjective(sourceEval); 78 80 var tFit = problemInstance.ToSingleObjective(targetEval); … … 83 85 //var fix = new bool[demands.Length]; // line 3 of Algorithm 4, note that according to the description it is not necessary to track the fixed equipments 84 86 var nonFix = Enumerable.Range(0, demands.Length).ToList(); // line 3 of Algorithm 4 85 var phi = new HashSet<int>(IntegerVectorEqualityComparer.GetDifferingIndices(pi_prime, target)); // line 4 of Algorithm 4 86 87 var phi = new List<int>(IntegerVectorEqualityComparer.GetDifferingIndices(pi_prime, target)); // line 4 of Algorithm 4 88 89 var B = new List<GQAPSolution>((int)Math.Ceiling(phi.Count * candidateSizeFactor)); 90 var B_fit = new List<double>(B.Capacity); 87 91 while (phi.Count > 0) { // line 5 of Algorithm 4 88 var B = new List<GQAPSolution>((int)Math.Ceiling(phi.Count * candidateSizeFactor)); // line 6 of Algorithm 489 var B_fit = new List<double>(B.Capacity); // line 6 of Algorithm 4 (B is split into two synchronized lists)92 B.Clear(); // line 6 of Algorithm 4 93 B_fit.Clear(); // line 6 of Algorithm 4 (B is split into two synchronized lists) 90 94 foreach (var v in phi) { // line 7 of Algorithm 4 91 95 int oldLocation = pi_prime[v]; … … 93 97 var pi_dash = MakeFeasible(random, pi_prime, v, nonFix, demands, capacities); // line 9 of Algorithm 4 94 98 pi_prime[v] = oldLocation; // not mentioned in Algorithm 4, but seems reasonable 95 var pi_dash_eval = problemInstance.Evaluate(pi_dash);96 evaluatedSolutions++;97 var pi_dash_fit = problemInstance.ToSingleObjective(pi_dash_eval);98 99 99 100 if (problemInstance.IsFeasible(pi_dash)) { // line 10 of Algorithm 4 101 var pi_dash_eval = problemInstance.Evaluate(pi_dash); 102 evaluatedSolutions++; 103 var pi_dash_fit = problemInstance.ToSingleObjective(pi_dash_eval); 104 100 105 if (B.Any(x => cmp.Equals(x.Assignment, pi_dash))) continue; // cond. 2 of line 12 and cond. 1 of line 16 in Algorithm 4 101 106 … … 103 108 var replacement = B_fit.Select((val, idx) => new { Index = idx, Fitness = val }) 104 109 .Where(x => x.Fitness >= pi_dash_fit) // cond. 1 in line 12 of Algorithm 4 105 .Select(x => new { Index = x.Index, Fitness =x.Fitness, Similarity = HammingSimilarityCalculator.CalculateSimilarity(B[x.Index].Assignment, pi_dash) })110 .Select(x => new { x.Index, x.Fitness, Similarity = HammingSimilarityCalculator.CalculateSimilarity(B[x.Index].Assignment, pi_dash) }) 106 111 .ToArray(); 107 112 if (replacement.Length > 0) { 108 var mostSimilar = replacement.MaxItems(x => x.Similarity). First().Index;113 var mostSimilar = replacement.MaxItems(x => x.Similarity).SampleRandom(random).Index; 109 114 B[mostSimilar].Assignment = pi_dash; // line 13 of Algorithm 4 110 115 B[mostSimilar].Evaluation = pi_dash_eval; // line 13 of Algorithm 4 … … 121 126 // line 22 of Algorithm 4 122 127 if (greedy) { 123 pi = B.Select((val, idx) => new { Index = idx, Value = val }).MinItems(x => B_fit[x.Index]).S huffle(random).First().Value;128 pi = B.Select((val, idx) => new { Index = idx, Value = val }).MinItems(x => B_fit[x.Index]).SampleRandom(random).Value; 124 129 } else { 125 130 pi = B.SampleProportional(random, 1, B_fit.Select(x => 1.0 / x), false).First(); … … 137 142 } 138 143 } else return pi_star; 139 phi = new HashSet<int>(IntegerVectorEqualityComparer.GetDifferingIndices(pi_prime, target));144 phi = new List<int>(IntegerVectorEqualityComparer.GetDifferingIndices(pi_prime, target)); 140 145 } 141 146 … … 156 161 return Apply(random, source, evaluations[betterParent], 157 162 target, evaluations[worseParent], problemInstance, 158 CandidateSizeFactorParameter.Value.Value, out evaluatedSolution).Assignment; 159 } 160 163 CandidateSizeFactorParameter.Value.Value, out evaluatedSolution, 164 GreedyParameter.ActualValue.Value).Assignment; 165 } 166 167 /// <summary> 168 /// Relocates equipments in the same location as <paramref name="equipment"/> to other locations in case the location 169 /// is overutilized. 170 /// </summary> 171 /// <remarks> 172 /// This method is performance critical, called very often and should run as fast as possible. 173 /// </remarks> 174 /// <param name="random">The random number generator.</param> 175 /// <param name="pi">The current solution.</param> 176 /// <param name="equipment">The equipment that was just assigned to a new location.</param> 177 /// <param name="nonFix">The equipments that have not yet been fixed.</param> 178 /// <param name="demands">The demands for all equipments.</param> 179 /// <param name="capacities">The capacities of all locations.</param> 180 /// <param name="maximumTries">The number of tries that should be done in relocating the equipments.</param> 181 /// <returns>A feasible or infeasible solution</returns> 161 182 private static IntegerVector MakeFeasible(IRandom random, IntegerVector pi, int equipment, List<int> nonFix, DoubleArray demands, DoubleArray capacities, int maximumTries = 1000) { 162 183 int l = pi[equipment]; 163 184 var slack = ComputeSlack(pi, demands, capacities); 164 185 if (slack[l] >= 0) // line 1 of Algorithm 5 165 return new IntegerVector(pi); // line 2 of Algorithm 5186 return (IntegerVector)pi.Clone(); // line 2 of Algorithm 5 166 187 167 188 IntegerVector pi_prime = null; 168 189 int k = 0; // line 4 of Algorithm 5 169 while (k < maximumTries && slack[l] < 0) { // line 5 of Algorithm 5 170 pi_prime = new IntegerVector(pi); // line 6 of Algorithm 5 190 var maxSlack = slack.Max(); // line 8-9 of Algorithm 5 191 var slack_prime = (double[])slack.Clone(); 192 var maxSlack_prime = maxSlack; 193 // note that FTL can be computed only once for all tries as all tries restart with the same solution 194 var FTL = nonFix.Where(x => x != equipment && pi[x] == l && demands[x] <= maxSlack).ToList(); // line 8-9 of Algorithm 5 195 var FTLweight = FTL.Select(x => demands[x]).ToList(); 196 while (k < maximumTries && slack_prime[l] < 0) { // line 5 of Algorithm 5 197 pi_prime = (IntegerVector)pi.Clone(); // line 6 of Algorithm 5 198 // set T can only shrink and not grow, thus it is created outside the loop and only updated inside 199 var T = new List<int>(FTL); // line 8-9 of Algorithm 5 200 var weightT = new List<double>(FTLweight); 171 201 do { // line 7 of Algorithm 5 172 var maxSlack = slack.Max(); // line 8-9 of Algorithm 5173 var T = nonFix.Where(x => pi[x] == l && demands[x] <= maxSlack).ToList(); // line 8-9 of Algorithm 5174 202 if (T.Count > 0) { // line 10 of Algorithm 5 175 int i = T.SampleProportional(random, 1, T.Select(x => demands[x]), false).First(); // line 11 of Algorithm 5 203 var idx = Enumerable.Range(0, T.Count).SampleProportional(random, 1, weightT, false, false).First(); // line 11 of Algorithm 5 204 int i = T[idx]; // line 11 of Algorithm 5 176 205 var j = Enumerable.Range(0, capacities.Length) 177 .Where(x => slack [x] >= demands[i]) // line 12 of Algorithm 5206 .Where(x => slack_prime[x] >= demands[i]) // line 12 of Algorithm 5 178 207 .SampleRandom(random); // line 13 of Algorithm 5 179 208 pi_prime[i] = j; // line 14 of Algorithm 5 180 slack[j] -= demands[i]; // line 14 of Algorithm 5 181 slack[l] += demands[i]; // line 14 of Algorithm 5 209 T.RemoveAt(idx); 210 weightT.RemoveAt(idx); 211 var recomputeMaxSlack = slack_prime[j] == maxSlack_prime; // efficiency improvement: recompute max slack only if we assign to a location whose slack equals maxSlack 212 slack_prime[j] -= demands[i]; // line 14 of Algorithm 5 213 slack_prime[l] += demands[i]; // line 14 of Algorithm 5 214 if (recomputeMaxSlack) { 215 maxSlack_prime = slack_prime.Max(); 216 // T needs to be removed of equipments whose demand is higher than maxSlack only if maxSlack changes 217 for (var h = 0; h < T.Count; h++) { 218 var f = T[h]; 219 if (demands[f] > maxSlack_prime) { 220 T.RemoveAt(h); 221 weightT.RemoveAt(h); 222 h--; 223 } 224 } 225 } 182 226 } else break; // cond. 1 in line 16 of Algorithm 5 183 } while (slack [l] < 0); // cond. 2 in line 16 of Algorithm 5227 } while (slack_prime[l] < 0); // cond. 2 in line 16 of Algorithm 5 184 228 k++; // line 17 of Algorithm 5 229 if (slack_prime[l] < 0) { 230 // reset 231 Array.Copy(slack, slack_prime, slack.Length); 232 maxSlack_prime = maxSlack; 233 } 185 234 } 186 235 return pi_prime; // line 19-23 of Algorithm 5 … … 188 237 189 238 private static double[] ComputeSlack(IntegerVector assignment, DoubleArray demands, DoubleArray capacities) { 190 var slack = new double[capacities.Length];239 var slack = capacities.ToArray(); 191 240 for (int i = 0; i < assignment.Length; i++) { 192 241 slack[assignment[i]] -= demands[i];
Note: See TracChangeset
for help on using the changeset viewer.