Changeset 15553 for branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/SolutionCreators
- Timestamp:
- 12/20/17 15:41:27 (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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;
Note: See TracChangeset
for help on using the changeset viewer.