Changeset 15553
- Timestamp:
- 12/20/17 15:41:27 (7 years ago)
- Location:
- branches/GeneralizedQAP
- Files:
-
- 11 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/GeneralizedQAP/GeneralizedQAP.sln
r15492 r15553 2 2 Microsoft Visual Studio Solution File, Format Version 12.00 3 3 # Visual Studio 15 4 VisualStudioVersion = 15.0.27 004.20024 VisualStudioVersion = 15.0.27130.2010 5 5 MinimumVisualStudioVersion = 10.0.40219.1 6 6 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.GeneralizedQuadraticAssignment-3.3", "HeuristicLab.Problems.GeneralizedQuadraticAssignment\3.3\HeuristicLab.Problems.GeneralizedQuadraticAssignment-3.3.csproj", "{C739E6D2-5680-4804-A810-8017DA0C238F}" … … 18 18 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Encodings.IntegerVectorEncoding-3.3", "HeuristicLab.Encodings.IntegerVectorEncoding\3.3\HeuristicLab.Encodings.IntegerVectorEncoding-3.3.csproj", "{DDFB14DD-2A85-493C-A52D-E69729BBAEB0}" 19 19 EndProject 20 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms-3.3", "HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms\3.3\HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms-3.3.csproj", "{577239EC-7D7F-4505-A0A4-572E34010DBA}" 21 EndProject 20 22 Global 23 GlobalSection(Performance) = preSolution 24 HasPerformanceSessions = true 25 EndGlobalSection 21 26 GlobalSection(SolutionConfigurationPlatforms) = preSolution 22 27 Debug|Any CPU = Debug|Any CPU … … 100 105 {DDFB14DD-2A85-493C-A52D-E69729BBAEB0}.Release|x86.ActiveCfg = Release|x86 101 106 {DDFB14DD-2A85-493C-A52D-E69729BBAEB0}.Release|x86.Build.0 = Release|x86 107 {577239EC-7D7F-4505-A0A4-572E34010DBA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 108 {577239EC-7D7F-4505-A0A4-572E34010DBA}.Debug|Any CPU.Build.0 = Debug|Any CPU 109 {577239EC-7D7F-4505-A0A4-572E34010DBA}.Debug|x64.ActiveCfg = Debug|Any CPU 110 {577239EC-7D7F-4505-A0A4-572E34010DBA}.Debug|x64.Build.0 = Debug|Any CPU 111 {577239EC-7D7F-4505-A0A4-572E34010DBA}.Debug|x86.ActiveCfg = Debug|Any CPU 112 {577239EC-7D7F-4505-A0A4-572E34010DBA}.Debug|x86.Build.0 = Debug|Any CPU 113 {577239EC-7D7F-4505-A0A4-572E34010DBA}.Release|Any CPU.ActiveCfg = Release|Any CPU 114 {577239EC-7D7F-4505-A0A4-572E34010DBA}.Release|Any CPU.Build.0 = Release|Any CPU 115 {577239EC-7D7F-4505-A0A4-572E34010DBA}.Release|x64.ActiveCfg = Release|Any CPU 116 {577239EC-7D7F-4505-A0A4-572E34010DBA}.Release|x64.Build.0 = Release|Any CPU 117 {577239EC-7D7F-4505-A0A4-572E34010DBA}.Release|x86.ActiveCfg = Release|Any CPU 118 {577239EC-7D7F-4505-A0A4-572E34010DBA}.Release|x86.Build.0 = Release|Any CPU 102 119 EndGlobalSection 103 120 GlobalSection(SolutionProperties) = preSolution … … 107 124 SolutionGuid = {B0BBF50B-4E62-4BAB-A730-881208150933} 108 125 EndGlobalSection 126 GlobalSection(Performance) = preSolution 127 HasPerformanceSessions = true 128 EndGlobalSection 129 GlobalSection(Performance) = preSolution 130 HasPerformanceSessions = true 131 EndGlobalSection 132 GlobalSection(Performance) = preSolution 133 HasPerformanceSessions = true 134 EndGlobalSection 109 135 EndGlobal -
branches/GeneralizedQAP/HeuristicLab.Algorithms.GRASP/3.3/GRASPWithPathRelinking.cs
r15507 r15553 39 39 /// </summary> 40 40 [Item("GRASP+PR", "The algorithm combines the Greedy Randomized Adaptive Search Procedure (GRASP) with Path Relinking and is described in Mateus, G., Resende, M., and Silva, R. 2011. GRASP with path-relinking for the generalized quadratic assignment problem. Journal of Heuristics 17, Springer Netherlands, pp. 527-565.")] 41 [Creatable( "Algorithms")]41 [Creatable(CreatableAttribute.Categories.PopulationBasedAlgorithms)] 42 42 [StorableClass] 43 43 public sealed class GRASPWithPathRelinking : HeuristicOptimizationEngineAlgorithm, IStorableContent { -
branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Evaluation/Evaluation.cs
r15510 r15553 1 using System.Collections.Generic; 1 #region License Information 2 /* HeuristicLab 3 * Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 * 5 * This file is part of HeuristicLab. 6 * 7 * HeuristicLab is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * HeuristicLab is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 #endregion 21 22 using System.Collections.Generic; 2 23 using System.Linq; 3 24 using HeuristicLab.Common; -
branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GQAPInstance.cs
r15510 r15553 191 191 192 192 public Evaluation Evaluate(IntegerVector assignment) { 193 returnEvaluateIntegerVector(assignment, Demands, Capacities,193 var evaluation = EvaluateIntegerVector(assignment, Demands, Capacities, 194 194 InstallationCosts, Weights, Distances); 195 return evaluation; 195 196 } 196 197 … … 217 218 } 218 219 220 public GQAPSolution ToEvaluatedSolution(IntegerVector assignment) { 221 var evaluation = EvaluateIntegerVector(assignment, Demands, Capacities, 222 InstallationCosts, Weights, Distances); 223 return new GQAPSolution(assignment, evaluation); 224 } 225 226 public bool IsFeasible(IntegerVector assignment) { 227 int len = assignment.Length; 228 var utilization = new double[Capacities.Length]; 229 for (var equip = 0; equip < len; equip++) { 230 var loc = assignment[equip]; 231 utilization[loc] += Demands[equip]; 232 if (utilization[loc] > Capacities[loc]) 233 return false; 234 } 235 return true; 236 } 237 219 238 public double ToSingleObjective(Evaluation fitness) { 220 239 return fitness.IsFeasible -
branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/GQAPSolution.cs
r15504 r15553 36 36 get { return assignment; } 37 37 set { 38 bool changed = (assignment != value);38 if (assignment == value) return; 39 39 assignment = value; 40 if (changed) OnPropertyChanged("Assignment");40 OnPropertyChanged(nameof(Assignment)); 41 41 } 42 42 } -
branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/HeuristicLab.Problems.GeneralizedQuadraticAssignment-3.3.csproj
r15507 r15553 41 41 </PropertyGroup> 42 42 <ItemGroup> 43 <Reference Include="HeuristicLab.Analysis-3.3 , Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=x86">44 < SpecificVersion>False</SpecificVersion>43 <Reference Include="HeuristicLab.Analysis-3.3"> 44 <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Analysis-3.3.dll</HintPath> 45 45 <Private>False</Private> 46 46 </Reference> … … 69 69 <Private>False</Private> 70 70 </Reference> 71 <Reference Include="HeuristicLab.Optimization.Operators-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL"> 71 <Reference Include="HeuristicLab.Optimization.Operators-3.3"> 72 <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Optimization.Operators-3.3.dll</HintPath> 72 73 <Private>False</Private> 73 74 </Reference> … … 84 85 <Private>False</Private> 85 86 </Reference> 86 <Reference Include="HeuristicLab.Problems.Instances-3.3 , Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">87 < SpecificVersion>False</SpecificVersion>87 <Reference Include="HeuristicLab.Problems.Instances-3.3"> 88 <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.Instances-3.3.dll</HintPath> 88 89 <Private>False</Private> 89 90 </Reference> 90 <Reference Include="HeuristicLab.Random-3.3 , Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">91 < SpecificVersion>False</SpecificVersion>91 <Reference Include="HeuristicLab.Random-3.3"> 92 <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Random-3.3.dll</HintPath> 92 93 <Private>False</Private> 93 94 </Reference> … … 170 171 </ProjectReference> 171 172 </ItemGroup> 172 <ItemGroup />173 173 <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> 174 174 <PropertyGroup> -
branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Moves/StochasticNMoveSingleMoveGenerator.cs
r15511 r15553 57 57 } 58 58 59 public static NMove GenerateOneMove(IRandom random, IntegerVector assignment, DoubleArray capacities) { 60 var locations = capacities.Length; 61 if (locations <= 1) throw new ArgumentException("There must be at least two locations."); 62 var dim = assignment.Length; 63 var equip = random.Next(dim); 64 var equipments = new List<int>(1) { equip }; 65 66 var reassignment = new int[dim]; 67 reassignment[equip] = ReassignEquipment(random, equip, assignment[equip], locations); 68 69 return new NMove(reassignment, equipments); 70 } 71 72 public static NMove GenerateTwoMove(IRandom random, IntegerVector assignment, DoubleArray capacities) { 73 var locations = capacities.Length; 74 if (locations <= 1) throw new ArgumentException("There must be at least two locations."); 75 var dim = assignment.Length; 76 var equipments = new List<int>(2) { random.Next(dim), -1 }; 77 do { 78 equipments[1] = random.Next(dim); 79 } while (equipments[0] == equipments[1]); 80 81 var reassignment = new int[dim]; 82 for (var i = 0; i < 2; i++) { 83 var equip = equipments[i]; 84 reassignment[equip] = ReassignEquipment(random, equip, assignment[equip], locations); 85 } 86 return new NMove(reassignment, equipments); 87 } 88 59 89 public static NMove GenerateExactlyN(IRandom random, IntegerVector assignment, int n, DoubleArray capacities) { 60 if (capacities.Length <= 1) throw new ArgumentException("There must be at least two locations."); 90 if (n == 1) return GenerateOneMove(random, assignment, capacities); 91 if (n == 2) return GenerateTwoMove(random, assignment, capacities); 92 var locations = capacities.Length; 93 if (locations <= 1) throw new ArgumentException("There must be at least two locations."); 61 94 var dim = assignment.Length; 95 var equipments = Enumerable.Range(0, dim).SampleRandomWithoutRepetition(random, n, dim).ToList(); 96 62 97 var reassignment = new int[dim]; 63 var equipments = Enumerable.Range(0, dim).SampleRandomWithoutRepetition(random, n, dim).ToList();64 98 for (var i = 0; i < n; i++) { 65 99 var equip = equipments[i]; 66 do { 67 reassignment[equip] = random.Next(capacities.Length) + 1; 68 } while (reassignment[equip] == assignment[equip] + 1); 100 reassignment[equip] = ReassignEquipment(random, equip, assignment[equip], locations); 69 101 } 70 102 return new NMove(reassignment, equipments); 103 } 104 105 private static int ReassignEquipment(IRandom random, int equip, int prevLocation, int locations) { 106 var newLoc = random.Next(locations) + 1; 107 while (newLoc == prevLocation + 1) 108 newLoc = random.Next(locations) + 1; 109 return newLoc; 71 110 } 72 111 -
branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/Crossovers/GQAPPathRelinking.cs
r15504 r15553 61 61 } 62 62 63 public static IntegerVector Apply(IRandom random, ItemArray<IntegerVector> parents, ItemArray<DoubleValue> qualities, 64 GQAPInstance problemInstance, double candidateSizeFactor) { 65 if (random == null) throw new ArgumentNullException("random", "No IRandom provider is given."); 66 if (parents == null || !parents.Any()) throw new ArgumentException("No parents given for path relinking.", "parents"); 67 if (parents.Length != 2) throw new ArgumentException(String.Format("Two parents were expected for path relinking, but {0} was/were given.", parents.Length.ToString()), "parents"); 68 if (parents[0].Length != parents[1].Length) throw new ArgumentException("The length of the parents is not equal.", "parents"); 69 if (qualities == null || qualities.Length == 0) throw new ArgumentException("The qualities are not given.", "qualities"); 70 if (qualities.Length != parents.Length) throw new ArgumentException(String.Format("There are a different number of parents ({0}) than quality values ({1})", parents.Length.ToString(), qualities.Length.ToString())); 71 72 var source = parents[0]; 73 var target = parents[1]; 74 IntegerVector result; 75 double resultQuality; 76 77 int betterParent = (qualities[0].Value <= qualities[1].Value) ? 0 : 1; 78 79 result = (IntegerVector)parents[betterParent].Clone(); 80 resultQuality = qualities[betterParent].Value; 81 63 public static GQAPSolution Apply(IRandom random, 64 IntegerVector source, Evaluation sourceEval, 65 IntegerVector target, Evaluation targetEval, 66 GQAPInstance problemInstance, double candidateSizeFactor, 67 out int evaluatedSolutions) { 68 evaluatedSolutions = 0; 82 69 var demands = problemInstance.Demands; 83 70 var capacities = problemInstance.Capacities; 84 85 71 var cmp = new IntegerVectorEqualityComparer(); 86 72 87 var pi_prime = (IntegerVector)source.Clone(); 88 var fix = new HashSet<int>(); 89 var nonFix = new HashSet<int>(Enumerable.Range(0, demands.Length)); 90 var phi = new HashSet<int>((IntegerVectorEqualityComparer.GetDifferingIndices(pi_prime, target))); 73 var sFit = problemInstance.ToSingleObjective(sourceEval); 74 var tFit = problemInstance.ToSingleObjective(targetEval); 75 GQAPSolution pi_star = sFit < tFit ? new GQAPSolution(source, sourceEval) : new GQAPSolution(target, targetEval); // line 1 of Algorithm 4 76 double pi_star_Fit = problemInstance.ToSingleObjective(pi_star.Evaluation); // line 2 of Algorithm 4 77 78 var pi_prime = (IntegerVector)source.Clone(); // line 3 of Algorithm 4 79 //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 80 var nonFix = Enumerable.Range(0, demands.Length).ToList(); // line 3 of Algorithm 4 81 var phi = new HashSet<int>(IntegerVectorEqualityComparer.GetDifferingIndices(pi_prime, target)); // line 4 of Algorithm 4 91 82 92 while (phi.Any()) { 93 var B = new List<Tuple<GQAPSolution, double>>(); 94 foreach (var v in phi) { 83 while (phi.Count > 0) { // line 5 of Algorithm 4 84 var B = new List<GQAPSolution>((int)Math.Ceiling(phi.Count * candidateSizeFactor)); // line 6 of Algorithm 4 85 var B_fit = new List<double>(B.Capacity); // line 6 of Algorithm 4 (B is split into two synchronized lists) 86 foreach (var v in phi) { // line 7 of Algorithm 4 95 87 int oldLocation = pi_prime[v]; 96 pi_prime[v] = target[v]; 97 var pi2 = MakeFeasible(random, pi_prime, v, nonFix, demands, capacities); 98 pi_prime[v] = oldLocation; 88 pi_prime[v] = target[v]; // line 8 of Algorithm 4 89 var pi_dash = MakeFeasible(random, pi_prime, v, nonFix, demands, capacities); // line 9 of Algorithm 4 90 pi_prime[v] = oldLocation; // not mentioned in Algorithm 4, but seems reasonable 91 var pi_dash_eval = problemInstance.Evaluate(pi_dash); 92 evaluatedSolutions++; 93 var pi_dash_fit = problemInstance.ToSingleObjective(pi_dash_eval); 99 94 100 var currentEval = problemInstance.Evaluate(pi2); 95 if (problemInstance.IsFeasible(pi_dash)) { // line 10 of Algorithm 4 96 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 97 102 if (currentEval.ExcessDemand <= 0.0) { 103 var quality = problemInstance.ToSingleObjective(currentEval); 104 105 var solution = new GQAPSolution(pi2, currentEval); 106 if (B.Count >= candidateSizeFactor * phi.Count) { 107 int mostSimilarIndex = -1; 108 double mostSimilarValue = 1.0; 109 for (int i = 0; i < B.Count; i++) { 110 if (quality < B[i].Item2) { 111 var similarity = HammingSimilarityCalculator.CalculateSimilarity(solution.Assignment, B[i].Item1.Assignment); 112 if (similarity == 1.0) { 113 mostSimilarIndex = -1; 114 break; 115 } else if (similarity < mostSimilarValue) { 116 mostSimilarValue = similarity; 117 mostSimilarIndex = i; 118 } 119 } 98 if (B.Count >= candidateSizeFactor * phi.Count) { // line 11 of Algorithm 4 99 var replacement = B_fit.Select((val, idx) => new { Index = idx, Fitness = val }) 100 .Where(x => x.Fitness >= pi_dash_fit) // cond. 1 in line 12 of Algorithm 4 101 .Select(x => new { Index = x.Index, Fitness = x.Fitness, Similarity = HammingSimilarityCalculator.CalculateSimilarity(B[x.Index].Assignment, pi_dash) }) 102 .ToArray(); 103 if (replacement.Length > 0) { 104 var mostSimilar = replacement.MaxItems(x => x.Similarity).First().Index; 105 B[mostSimilar].Assignment = pi_dash; // line 13 of Algorithm 4 106 B[mostSimilar].Evaluation = pi_dash_eval; // line 13 of Algorithm 4 107 B_fit[mostSimilar] = pi_dash_fit; // line 13 of Algorithm 4 120 108 } 121 if (mostSimilarIndex >= 0) 122 B[mostSimilarIndex] = Tuple.Create(solution, quality); 123 } else { 124 bool contains = false; 125 foreach (var b in B) { 126 if (cmp.Equals(solution.Assignment, b.Item1.Assignment)) { 127 contains = true; 128 break; 129 } 130 } 131 if (!contains) B.Add(Tuple.Create(solution, quality)); 109 } else { // line 16, condition has been checked above already 110 B.Add(new GQAPSolution(pi_dash, pi_dash_eval)); // line 17 of Algorithm 4 111 B_fit.Add(pi_dash_fit); // line 17 of Algorithm 4 132 112 } 133 113 } 134 114 } 135 if (B.Any()) { 136 var pi = B.SampleProportional(random, 1, B.Select(x => 1.0 / x.Item2), false).First(); 137 var diff = IntegerVectorEqualityComparer.GetDifferingIndices(pi.Item1.Assignment, target); 138 var I = phi.Except(diff); 139 var i = I.SampleRandom(random); 140 fix.Add(i); 141 nonFix.Remove(i); 142 pi_prime = pi.Item1.Assignment; 143 if (pi.Item2 < resultQuality) { 144 result = pi.Item1.Assignment; 145 resultQuality = pi.Item2; 115 if (B.Count > 0) { // line 21 of Algorithm 4 116 var pi = B.SampleProportional(random, 1, B_fit.Select(x => 1.0 / x), false).First(); // line 22 of Algorithm 4 117 var diff = IntegerVectorEqualityComparer.GetDifferingIndices(pi.Assignment, target); // line 23 of Algorithm 4 118 var I = phi.Except(diff); // line 24 of Algorithm 4 119 var i = I.SampleRandom(random); // line 25 of Algorithm 4 120 //fix[i] = true; // line 26 of Algorithm 4 121 nonFix.Remove(i); // line 26 of Algorithm 4 122 pi_prime = pi.Assignment; // line 27 of Algorithm 4 123 var fit = problemInstance.ToSingleObjective(pi.Evaluation); 124 if (fit < pi_star_Fit) { // line 28 of Algorithm 4 125 pi_star_Fit = fit; // line 29 of Algorithm 4 126 pi_star = pi; // line 30 of Algorithm 4 146 127 } 147 } else return result;128 } else return pi_star ?? new GQAPSolution((IntegerVector)source.Clone(), (Evaluation)sourceEval.Clone()); 148 129 phi = new HashSet<int>(IntegerVectorEqualityComparer.GetDifferingIndices(pi_prime, target)); 149 130 } 150 131 151 return result;132 return pi_star ?? new GQAPSolution((IntegerVector)source.Clone(), (Evaluation)sourceEval.Clone()); 152 133 } 153 134 154 135 protected override IntegerVector Cross(IRandom random, ItemArray<IntegerVector> parents, 155 136 GQAPInstance problemInstance) { 156 return Apply(random, parents, QualityParameter.ActualValue, problemInstance, 157 CandidateSizeFactorParameter.Value.Value); 137 138 var qualities = QualityParameter.ActualValue; 139 var evaluations = EvaluationParameter.ActualValue; 140 var betterParent = qualities[0].Value <= qualities[1].Value ? 0 : 1; 141 var worseParent = 1 - betterParent; 142 var source = parents[betterParent]; 143 var target = parents[worseParent]; 144 145 int evaluatedSolution; 146 return Apply(random, source, evaluations[betterParent], 147 target, evaluations[worseParent], problemInstance, 148 CandidateSizeFactorParameter.Value.Value, out evaluatedSolution).Assignment; 158 149 } 159 150 160 private static IntegerVector MakeFeasible(IRandom random, IntegerVector assignment, int equipment, HashSet<int> nonFix, DoubleArray demands, DoubleArray capacities, int maximumTries = 1000) { 161 int l = assignment[equipment]; 162 var slack = ComputeSlack(assignment, demands, capacities); 163 if (slack[l] >= 0) return (IntegerVector)assignment.Clone(); 151 private static IntegerVector MakeFeasible(IRandom random, IntegerVector pi, int equipment, List<int> nonFix, DoubleArray demands, DoubleArray capacities, int maximumTries = 1000) { 152 int l = pi[equipment]; 153 var slack = ComputeSlack(pi, demands, capacities); 154 if (slack[l] >= 0) // line 1 of Algorithm 5 155 return new IntegerVector(pi); // line 2 of Algorithm 5 164 156 165 IntegerVector result = null; 166 int k = 0; 167 while (k < maximumTries && slack[l] < 0) { 168 result = (IntegerVector)assignment.Clone(); 169 do { 170 var maxSlack = slack.Max(); 171 var T = nonFix.Where(x => x != equipment && assignment[x] == l && demands[x] <= maxSlack); 172 if (T.Any()) { 173 int i = T.SampleProportional(random, 1, T.Select(x => demands[x]), false).First(); 174 var j = Enumerable.Range(0, capacities.Length).Where(x => slack[x] >= demands[i]).SampleRandom(random); 175 result[i] = j; 176 slack[j] -= demands[i]; 177 slack[l] += demands[i]; 178 } else break; 179 } while (slack[l] < 0); 180 k++; 157 IntegerVector pi_prime = null; 158 int k = 0; // line 4 of Algorithm 5 159 while (k < maximumTries && slack[l] < 0) { // line 5 of Algorithm 5 160 pi_prime = new IntegerVector(pi); // line 6 of Algorithm 5 161 do { // line 7 of Algorithm 5 162 var maxSlack = slack.Max(); // line 8-9 of Algorithm 5 163 var T = nonFix.Where(x => pi[x] == l && demands[x] <= maxSlack).ToList(); // line 8-9 of Algorithm 5 164 if (T.Count > 0) { // line 10 of Algorithm 5 165 int i = T.SampleProportional(random, 1, T.Select(x => demands[x]), false).First(); // line 11 of Algorithm 5 166 var j = Enumerable.Range(0, capacities.Length) 167 .Where(x => slack[x] >= demands[i]) // line 12 of Algorithm 5 168 .SampleRandom(random); // line 13 of Algorithm 5 169 pi_prime[i] = j; // line 14 of Algorithm 5 170 slack[j] -= demands[i]; // line 14 of Algorithm 5 171 slack[l] += demands[i]; // line 14 of Algorithm 5 172 } else break; // cond. 1 in line 16 of Algorithm 5 173 } while (slack[l] < 0); // cond. 2 in line 16 of Algorithm 5 174 k++; // line 17 of Algorithm 5 181 175 } 182 return result;176 return pi_prime; // line 19-23 of Algorithm 5 183 177 } 184 178 185 private static DoubleArrayComputeSlack(IntegerVector assignment, DoubleArray demands, DoubleArray capacities) {186 var slack = (DoubleArray)capacities.Clone();179 private static double[] ComputeSlack(IntegerVector assignment, DoubleArray demands, DoubleArray capacities) { 180 var slack = new double[capacities.Length]; 187 181 for (int i = 0; i < assignment.Length; i++) { 188 182 slack[assignment[i]] -= demands[i]; -
branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/Operators/LocalImprovers/ApproximateLocalSearch.cs
r15512 r15553 94 94 } 95 95 96 /// <summary> 97 /// The implementation differs slightly from Mateus et al. in that the maximumIterations parameter defines a cap 98 /// on the number of steps that the local search can perform. While the maxSampleSize parameter corresponds to 99 /// the maxItr parameter defined by Mateus et al. 100 /// </summary> 101 /// <param name="random">The random number generator to use.</param> 102 /// <param name="assignment">The equipment-location assignment vector.</param> 103 /// <param name="quality">The solution quality.</param> 104 /// <param name="evaluation">The evaluation result of the solution.</param> 105 /// <param name="maxCLS">The maximum number of candidates that should be found in each step.</param> 106 /// <param name="maximumIterations">The maximum number of iterations that should be performed each time the candidate list is generated.</param> 107 /// <param name="problemInstance">The problem instance that contains the data.</param> 108 /// <param name="evaluatedSolutions">The number of evaluated solutions.</param> 109 /// <param name="oneMoveProbability">The probability for performing a 1-move, which is the opposite of performing a 2-move.</param> 110 public static void Apply(IRandom random, IntegerVector assignment, 111 DoubleValue quality, ref Evaluation evaluation, IntValue maxCLS, IntValue maximumIterations, 112 GQAPInstance problemInstance, IntValue evaluatedSolutions, PercentValue oneMoveProbability) { 96 public static void Apply(IRandom random, GQAPSolution sol, int maxCLS, 97 double oneMoveProbability, int maximumIterations, 98 GQAPInstance problemInstance, out int evaluatedSolutions) { 99 var fit = problemInstance.ToSingleObjective(sol.Evaluation); 100 var eval = sol.Evaluation; 101 Apply(random, sol.Assignment, ref fit, ref eval, maxCLS, oneMoveProbability, maximumIterations, problemInstance, 102 out evaluatedSolutions); 103 sol.Evaluation = eval; 104 } 105 106 /// <summary> 107 /// The implementation differs slightly from Mateus et al. in that the maximumIterations parameter defines a cap 108 /// on the number of steps that the local search can perform. While the maxSampleSize parameter corresponds to 109 /// the maxItr parameter defined by Mateus et al. 110 /// </summary> 111 /// <param name="random">The random number generator to use.</param> 112 /// <param name="assignment">The equipment-location assignment vector.</param> 113 /// <param name="quality">The solution quality.</param> 114 /// <param name="evaluation">The evaluation result of the solution.</param> 115 /// <param name="maxCLS">The maximum number of candidates that should be found in each step.</param> 116 /// <param name="oneMoveProbability">The probability for performing a 1-move, which is the opposite of performing a 2-move.</param> 117 /// <param name="maximumIterations">The maximum number of iterations that should be performed each time the candidate list is generated.</param> 118 /// <param name="problemInstance">The problem instance that contains the data.</param> 119 /// <param name="evaluatedSolutions">The number of evaluated solutions.</param> 120 public static void Apply(IRandom random, IntegerVector assignment, 121 ref double quality, ref Evaluation evaluation, int maxCLS, 122 double oneMoveProbability, int maximumIterations, 123 GQAPInstance problemInstance, out int evaluatedSolutions) { 124 evaluatedSolutions = 0; 113 125 var capacities = problemInstance.Capacities; 114 126 var demands = problemInstance.Demands; … … 121 133 do { 122 134 NMove move; 123 if (random.NextDouble() < oneMoveProbability .Value)124 move = StochasticNMoveSingleMoveGenerator.Generate ExactlyN(random, assignment, 1, capacities);125 else move = StochasticNMoveSingleMoveGenerator.Generate ExactlyN(random, assignment, 2, capacities);135 if (random.NextDouble() < oneMoveProbability) 136 move = StochasticNMoveSingleMoveGenerator.GenerateOneMove(random, assignment, capacities); 137 else move = StochasticNMoveSingleMoveGenerator.GenerateTwoMove(random, assignment, capacities); 126 138 127 139 var moveEval = GQAPNMoveEvaluator.Evaluate(move, assignment, evaluation, problemInstance); … … 129 141 double moveQuality = problemInstance.ToSingleObjective(moveEval); 130 142 131 if (moveEval.ExcessDemand <= 0.0 && moveQuality < quality .Value) {143 if (moveEval.ExcessDemand <= 0.0 && moveQuality < quality) { 132 144 CLS.Add(Tuple.Create(move, moveQuality, moveEval)); 133 145 sum += 1.0 / moveQuality; 134 146 } 135 147 count++; 136 } while (CLS.Count < maxCLS .Value && count < maximumIterations.Value);148 } while (CLS.Count < maxCLS && count < maximumIterations); 137 149 138 150 if (CLS.Count == 0) { 139 evaluatedSolutions .Value+= (int)Math.Ceiling(evaluations);151 evaluatedSolutions += (int)Math.Ceiling(evaluations); 140 152 return; // END 141 153 } else { … … 150 162 } 151 163 NMoveMaker.Apply(assignment, selected.Item1); 152 quality .Value= selected.Item2;164 quality = selected.Item2; 153 165 evaluation = selected.Item3; 154 166 } … … 158 170 public override IOperation Apply() { 159 171 var evaluation = EvaluationParameter.ActualValue; 172 var quality = QualityParameter.ActualValue; 173 var fit = quality.Value; 174 var evaluatedSolutions = 0; 175 160 176 Apply(RandomParameter.ActualValue, 161 177 AssignmentParameter.ActualValue, 162 QualityParameter.ActualValue,178 ref fit, 163 179 ref evaluation, 164 MaximumCandidateListSizeParameter.ActualValue, 165 MaximumIterationsParameter.ActualValue, 180 MaximumCandidateListSizeParameter.ActualValue.Value, 181 OneMoveProbabilityParameter.ActualValue.Value, 182 MaximumIterationsParameter.ActualValue.Value, 166 183 ProblemInstanceParameter.ActualValue, 167 EvaluatedSolutionsParameter.ActualValue,168 OneMoveProbabilityParameter.ActualValue); 184 out evaluatedSolutions); 185 169 186 EvaluationParameter.ActualValue = evaluation; 187 quality.Value = fit; 188 EvaluatedSolutionsParameter.ActualValue.Value += evaluatedSolutions; 170 189 return base.Apply(); 171 190 } -
branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/SolutionCreators/GreedyRandomizedSolutionCreator.cs
r15504 r15553 61 61 int maximumTries, bool createMostFeasibleSolution, CancellationToken cancelToken) { 62 62 var demands = problemInstance.Demands; 63 var capacities = problemInstance.Capacities; 63 var capacities = problemInstance.Capacities.ToArray(); 64 var equipments = demands.Length; 65 var locations = capacities.Length; 64 66 int tries = 0; 65 var assignment = new Dictionary<int, int>(demands.Length);66 DoubleArray slack = new DoubleArray(capacities.Length);67 var assignment = new int[equipments]; 68 var slack = new double[locations]; 67 69 double minViolation = double.MaxValue; 68 Dictionary<int, int> bestAssignment = null; 69 HashSet<int> CF = new HashSet<int>(), // set of chosen facilities / equipments 70 T = new HashSet<int>(), // set of facilities / equpiments that can be assigned to the set of chosen locations (CL) 71 CL = new HashSet<int>(), // set of chosen locations 72 F = new HashSet<int>(Enumerable.Range(0, demands.Length)), // set of (initially) all facilities / equipments 73 L = new HashSet<int>(Enumerable.Range(0, capacities.Length)); // set of (initially) all locations 74 70 int[] bestAssignment = null; 71 var CF = new bool[equipments]; // set of chosen facilities / equipments 72 var T = new List<int>(equipments); // set of facilities / equpiments that can be assigned to the set of chosen locations (CL) 73 var CL_list = new List<int>(locations); // list of chosen locations 74 var CL_selected = new bool[locations]; // bool decision if location is chosen 75 var F = new List<int>(equipments); // set of (initially) all facilities / equipments 76 var L = new List<int>(locations); // set of (initially) all locations 77 75 78 while (maximumTries <= 0 || tries < maximumTries) { 76 79 cancelToken.ThrowIfCancellationRequested(); 77 80 78 assignment.Clear(); 79 for (int i = 0; i < capacities.Length; i++) slack[i] = capacities[i]; 80 CF.Clear(); 81 Array.Copy(capacities, slack, locations); 82 Array.Clear(CF, 0, equipments); 83 Array.Clear(CL_selected, 0, locations); 84 CL_list.Clear(); 81 85 T.Clear(); 82 CL.Clear(); 83 F.Clear(); F. UnionWith(Enumerable.Range(0, demands.Length));84 L.Clear(); L. UnionWith(Enumerable.Range(0, capacities.Length));86 87 F.Clear(); F.AddRange(Enumerable.Range(0, equipments)); 88 L.Clear(); L.AddRange(Enumerable.Range(0, locations)); 85 89 86 90 double threshold = 1.0; 87 91 do { 88 if (L. Any()&& random.NextDouble() < threshold) {92 if (L.Count > 0 && random.NextDouble() < threshold) { 89 93 int l = L.SampleRandom(random); 90 94 L.Remove(l); 91 CL.Add(l); 92 T = new HashSet<int>(WithDemandEqualOrLess(F, GetMaximumSlack(slack, CL), demands)); 95 CL_list.Add(l); 96 CL_selected[l] = true; 97 T = new List<int>(WhereDemandEqualOrLess(F, GetMaximumSlack(slack, CL_selected), demands)); 93 98 } 94 if (T.Any()) { 95 int f = T.SampleRandom(random); 96 T.Remove(f); 97 F.Remove(f); 98 CF.Add(f); 99 int l = WithSlackGreaterOrEqual(CL, demands[f], slack).SampleRandom(random); 100 assignment.Add(f, l); 99 if (T.Count > 0) { 100 var fidx = Enumerable.Range(0, T.Count).SampleRandom(random); 101 var f = T[fidx]; 102 T.RemoveAt(fidx); 103 F.Remove(f); // TODO: slow 104 CF[f] = true; 105 int l = WhereSlackGreaterOrEqual(CL_list, demands[f], slack).SampleRandom(random); 106 assignment[f] = l + 1; 101 107 slack[l] -= demands[f]; 102 T = new HashSet<int>(WithDemandEqualOrLess(F, GetMaximumSlack(slack, CL), demands));108 T = new List<int>(WhereDemandEqualOrLess(F, GetMaximumSlack(slack, CL_selected), demands)); 103 109 threshold = 1.0 - (double)T.Count / Math.Max(F.Count, 1.0); 104 110 } 105 } while (T. Any() || L.Any());111 } while (T.Count > 0 || L.Count > 0); 106 112 if (maximumTries > 0) tries++; 107 if ( !F.Any()) {113 if (F.Count == 0) { 108 114 bestAssignment = assignment; 109 115 break; … … 111 117 // complete the solution and remember the one with least violation 112 118 foreach (var l in L.ToArray()) { 113 CL.Add(l); 119 CL_list.Add(l); 120 CL_selected[l] = true; 114 121 L.Remove(l); 115 122 } 116 while (F. Any()) {117 var f = F. MaxItems(x => demands[x]).SampleRandom(random);118 var l = CL .MaxItems(x => slack[x]).SampleRandom(random);119 F.Remove (f);120 assignment .Add(f, l);121 slack[l] -= demands[f ];123 while (F.Count > 0) { 124 var f = F.Select((v, i) => new { Index = i, Value = v }).MaxItems(x => demands[x.Value]).SampleRandom(random); 125 var l = CL_list.MaxItems(x => slack[x]).SampleRandom(random); 126 F.RemoveAt(f.Index); 127 assignment[f.Value] = l + 1; 128 slack[l] -= demands[f.Value]; 122 129 } 123 130 double violation = slack.Select(x => x < 0 ? -x : 0).Sum(); 124 131 if (violation < minViolation) { 125 132 bestAssignment = assignment; 126 assignment = new Dictionary<int, int>(demands.Length);133 assignment = new int[equipments]; 127 134 minViolation = violation; 128 135 } … … 130 137 } 131 138 132 if (bestAssignment == null || bestAssignment.Count != demands.Length) throw new InvalidOperationException(String.Format("No solution could be found in {0} tries.", maximumTries)); 139 if (bestAssignment == null || bestAssignment.Any(x => x == 0)) 140 throw new InvalidOperationException(String.Format("No solution could be found in {0} tries.", maximumTries)); 133 141 134 return new IntegerVector(bestAssignment. OrderBy(x => x.Key).Select(x => x.Value).ToArray());142 return new IntegerVector(bestAssignment.Select(x => x - 1).ToArray()); 135 143 } 136 144 … … 142 150 } 143 151 144 private static IEnumerable<int> W ithDemandEqualOrLess(IEnumerable<int> facilities, double maximum, DoubleArray demands) {152 private static IEnumerable<int> WhereDemandEqualOrLess(IEnumerable<int> facilities, double maximum, DoubleArray demands) { 145 153 foreach (int f in facilities) { 146 154 if (demands[f] <= maximum) yield return f; … … 148 156 } 149 157 150 private static double GetMaximumSlack(DoubleArray slack, HashSet<int> CL) { 151 return slack.Select((val, idx) => new { idx, val }).Where(x => CL.Contains(x.idx)).Select(x => x.val).Max(); 158 private static double GetMaximumSlack(double[] slack, bool[] CL) { 159 var max = double.MinValue; 160 for (var i = 0; i < slack.Length; i++) { 161 if (CL[i] && max < slack[i]) max = slack[i]; 162 } 163 return max; 152 164 } 153 165 154 private static IEnumerable<int> W ithSlackGreaterOrEqual(HashSet<int> locations, double minimum, DoubleArrayslack) {166 private static IEnumerable<int> WhereSlackGreaterOrEqual(IEnumerable<int> locations, double minimum, double[] slack) { 155 167 foreach (int l in locations) { 156 168 if (slack[l] >= minimum) yield return l; -
branches/GeneralizedQAP/UnitTests/ApproximateLocalSearchTest.cs
r15512 r15553 13 13 [TestMethod] 14 14 public void ApproximateLocalSearchApplyTest() { 15 CollectionAssert.AreEqual(new [] { 0, 3, 4, 2, 2, 0, 4, 3, 2, 0}, assignment.ToArray());15 CollectionAssert.AreEqual(new [] { 3, 2, 2, 0, 0, 0, 2, 3, 0, 2 }, assignment.ToArray()); 16 16 17 17 var evaluation = instance.Evaluate(assignment); 18 Assert.AreEqual( 7177824, evaluation.FlowCosts);19 Assert.AreEqual(4 5, evaluation.InstallationCosts);18 Assert.AreEqual(3764492, evaluation.FlowCosts); 19 Assert.AreEqual(46, evaluation.InstallationCosts); 20 20 Assert.AreEqual(0, evaluation.ExcessDemand); 21 21 22 var quality = new DoubleValue(instance.ToSingleObjective(evaluation));23 Assert.AreEqual( 27898616.781881168, quality.Value, 1e-9);22 var quality = instance.ToSingleObjective(evaluation); 23 Assert.AreEqual(14631771.476177376, quality, 1e-9); 24 24 25 var evaluatedSolutions = new IntValue(0);26 ApproximateLocalSearch.Apply(random, assignment, quality,27 ref evaluation, new IntValue(10), new IntValue(1000), instance,28 evaluatedSolutions, new PercentValue(0.5));29 Assert.AreEqual( 896, evaluatedSolutions.Value);30 CollectionAssert.AreEqual(new[] { 2, 0, 0, 3, 3, 1, 0, 0, 2, 0 }, assignment.ToArray());31 Assert.AreEqual(1 1733118.305768538, quality.Value, 1e-9);25 var evaluatedSolutions = 0; 26 ApproximateLocalSearch.Apply(random, assignment, ref quality, 27 ref evaluation, 10, 0.5, 1000, instance, 28 out evaluatedSolutions); 29 Assert.AreEqual(300, evaluatedSolutions); 30 CollectionAssert.AreEqual(new[] { 3, 2, 2, 0, 0, 2, 2, 3, 0, 0 }, assignment.ToArray()); 31 Assert.AreEqual(14271146.913257681, quality, 1e-9); 32 32 } 33 33
Note: See TracChangeset
for help on using the changeset viewer.