- Timestamp:
- 03/11/12 20:17:07 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/SolutionCreators/SlackMinimizationSolutionCreator.cs
r7593 r7595 46 46 get { return (IValueLookupParameter<IntValue>)Parameters["Depth"]; } 47 47 } 48 public IValueLookupParameter<IntValue> RandomWalkLengthParameter { 49 get { return (IValueLookupParameter<IntValue>)Parameters["RandomWalkLength"]; } 50 } 48 51 49 52 [StorableConstructor] … … 55 58 Parameters.Add(new ValueLookupParameter<BoolValue>("CreateMostFeasibleSolution", "If this is set to true the operator will always succeed, and outputs the solution with the least violation instead of throwing an exception.", new BoolValue(false))); 56 59 Parameters.Add(new ValueLookupParameter<IntValue>("Depth", "How deep the algorithm should look forward.", new IntValue(3))); 60 Parameters.Add(new ValueLookupParameter<IntValue>("RandomWalkLength", "The length of the random walk in the feasible region that is used to diversify the found assignments.", new IntValue(10))); 57 61 } 58 62 … … 66 70 Parameters.Add(new ValueLookupParameter<IntValue>("Depth", "How deep the algorithm should look forward.", new IntValue(3))); 67 71 } 72 if (!Parameters.ContainsKey("RandomWalkLength")) { 73 Parameters.Add(new ValueLookupParameter<IntValue>("RandomWalkLength", "The length of the random walk in the feasible region that is used to diversify the found assignments.", new IntValue(10))); 74 } 68 75 } 69 76 70 public static IntegerVector CreateSolution(IRandom random, DoubleArray demands, DoubleArray capacities, int depth, int maximumTries, bool createMostFeasibleSolution, CancellationToken cancel) {77 public static IntegerVector CreateSolution(IRandom random, DoubleArray demands, DoubleArray capacities, int depth, int maximumTries, bool createMostFeasibleSolution, int randomWalkLength, CancellationToken cancel) { 71 78 IntegerVector result = null; 72 79 bool isFeasible = false; … … 89 96 var remainingEquipment = new HashSet<int>(Enumerable.Range(0, demands.Length)); 90 97 while (remainingEquipment.Any()) { 91 var equipment = remainingEquipment.ChooseProportionalRandom(random, 1, x => demands[x], true, true).Single(); 92 remainingEquipment.Remove(equipment); 93 94 var freeLocations = GetLocationsByFillLevel(equipment, demands[equipment], slack); 95 if (!freeLocations.Any()) break; 96 double bestSlack = double.MaxValue; 97 int bestLocation = -1; 98 int[] additionalEquipment = new int[0]; 99 foreach (var location in freeLocations.Shuffle(random)) { 100 HashSet<int> newEquipment; 101 var estimatedSlack = EstimatePotentialSlack(location.Key, location.Value, remainingEquipment, demands, out newEquipment, depth); 102 if (estimatedSlack < bestSlack || (estimatedSlack == bestSlack && newEquipment.Count < additionalEquipment.Length)) { 103 bestSlack = estimatedSlack; 104 bestLocation = location.Key; 105 additionalEquipment = newEquipment.ToArray(); 98 var minimumDemand = remainingEquipment.Min(x => demands[x]); 99 var possibleLocations = Enumerable.Range(0, capacities.Length).Where(x => slack[x] >= minimumDemand); 100 if (!possibleLocations.Any()) break; 101 foreach (var location in possibleLocations.Shuffle(random)) { 102 var group = FindBestGroup(location, slack[location], remainingEquipment, demands, depth); 103 foreach (var eq in group) { 104 remainingEquipment.Remove(eq); 105 assignment[eq] = location; 106 slack[location] -= demands[eq]; 106 107 } 107 }108 assignment[equipment] = bestLocation;109 slack[bestLocation] -= demands[equipment];110 foreach (var eq in additionalEquipment) {111 remainingEquipment.Remove(eq);112 assignment[eq] = bestLocation;113 slack[bestLocation] -= demands[eq];114 108 } 115 109 } … … 124 118 } 125 119 } 120 RandomFeasibleWalk(random, assignment, demands, slack, randomWalkLength); 126 121 double violation = GQAPEvaluator.EvaluateOverbooking(slack, capacities); 127 122 isFeasible = violation == 0; … … 134 129 } 135 130 136 private static double EstimatePotentialSlack(int location, double slack, HashSet<int> remainingEquipment, DoubleArray demands, out HashSet<int> addedEquipment, int depth = 3) { 137 var feasibleEquipment = remainingEquipment.Where(x => demands[x] < slack).ToArray(); 138 addedEquipment = new HashSet<int>(); 131 private static IEnumerable<int> FindBestGroup(int location, double slack, HashSet<int> remainingEquipment, DoubleArray demands, int depth = 3) { 132 var feasibleEquipment = remainingEquipment.Where(x => demands[x] <= slack).ToArray(); 139 133 140 if (!feasibleEquipment.Any()) return slack;134 if (!feasibleEquipment.Any()) yield break; 141 135 if (depth == 0) { 142 136 var e = feasibleEquipment.ChooseMax(x => demands[x]); 143 addedEquipment.Add(e);144 return slack - demands[e];137 yield return e; 138 yield break; 145 139 } 146 140 147 141 double bestSlack = slack; 148 int minSlackEquipment = -1; 142 int bestEquipment = -1; 143 int[] bestColleagues = new int[0]; 149 144 foreach (var e in feasibleEquipment) { 150 145 remainingEquipment.Remove(e); 151 HashSet<int> childEquipment; 152 var potentialSlack = EstimatePotentialSlack(location, slack - demands[e], remainingEquipment, demands, out childEquipment, depth - 1); 153 if (bestSlack > potentialSlack || (bestSlack == potentialSlack && childEquipment.Count < addedEquipment.Count)) { 154 bestSlack = potentialSlack; 155 minSlackEquipment = e; 156 addedEquipment.Clear(); 157 foreach (var child in childEquipment) addedEquipment.Add(child); 146 var colleagues = FindBestGroup(location, slack - demands[e], remainingEquipment, demands, depth - 1).ToArray(); 147 var slackWithColleagues = slack - demands[e] - colleagues.Sum(x => demands[x]); 148 if (bestSlack > slackWithColleagues || (bestSlack == slackWithColleagues && colleagues.Length < bestColleagues.Length)) { 149 bestSlack = slackWithColleagues; 150 bestEquipment = e; 151 bestColleagues = colleagues; 158 152 } 159 153 remainingEquipment.Add(e); 160 154 } 161 if (minSlackEquipment > -1) 162 addedEquipment.Add(minSlackEquipment); 163 return bestSlack; 155 yield return bestEquipment; 156 foreach (var a in bestColleagues) yield return a; 157 } 158 159 private static void RandomFeasibleWalk(IRandom random, Dictionary<int, int> assignment, DoubleArray demands, DoubleArray slack, int walkLength) { 160 for (int i = 0; i < walkLength; i++) { 161 var equipments = Enumerable.Range(0, demands.Length).Shuffle(random); 162 foreach (var e in equipments) { 163 var partners = Enumerable.Range(0, demands.Length) 164 .Where(x => slack[assignment[x]] + demands[x] - demands[e] >= 0 165 && slack[assignment[e]] + demands[e] - demands[x] >= 0); 166 if (!partners.Any()) continue; 167 var f = partners.ChooseUniformRandom(random); 168 int h = assignment[e]; 169 assignment[e] = assignment[f]; 170 assignment[f] = h; 171 slack[assignment[e]] += demands[f] - demands[e]; 172 slack[assignment[f]] += demands[e] - demands[f]; 173 break; 174 } 175 } 164 176 } 165 177 … … 169 181 MaximumTriesParameter.ActualValue.Value, 170 182 CreateMostFeasibleSolutionParameter.ActualValue.Value, 183 RandomWalkLengthParameter.ActualValue.Value, 171 184 CancellationToken); 172 }173 174 private static IEnumerable<KeyValuePair<int, double>> GetLocationsByFillLevel(int equipment, double demand, DoubleArray slack) {175 var freeLocations = slack176 .Select((v, idx) => new KeyValuePair<int, double>(idx, v))177 .Where(x => x.Value >= demand);178 if (!freeLocations.Any()) {179 return Enumerable.Empty<KeyValuePair<int, double>>();180 }181 return freeLocations.Select(x => new KeyValuePair<int, double>(x.Key, slack[x.Key] - demand)).OrderBy(x => x.Value);182 185 } 183 186 }
Note: See TracChangeset
for help on using the changeset viewer.