Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
12/20/17 15:41:27 (7 years ago)
Author:
abeham
Message:

#1614:

  • Implementing basic algorithm according to paper (rechecking all operators)
  • Checking implementation with paper
  • Improved speed of move generator
  • Improved speed of randomized solution creator
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment/3.3/SolutionCreators/GreedyRandomizedSolutionCreator.cs

    r15504 r15553  
    6161      int maximumTries, bool createMostFeasibleSolution, CancellationToken cancelToken) {
    6262      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;
    6466      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];
    6769      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     
    7578      while (maximumTries <= 0 || tries < maximumTries) {
    7679        cancelToken.ThrowIfCancellationRequested();
    7780
    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();
    8185        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));
    8589
    8690        double threshold = 1.0;
    8791        do {
    88           if (L.Any() && random.NextDouble() < threshold) {
     92          if (L.Count > 0 && random.NextDouble() < threshold) {
    8993            int l = L.SampleRandom(random);
    9094            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));
    9398          }
    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;
    101107            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));
    103109            threshold = 1.0 - (double)T.Count / Math.Max(F.Count, 1.0);
    104110          }
    105         } while (T.Any() || L.Any());
     111        } while (T.Count > 0 || L.Count > 0);
    106112        if (maximumTries > 0) tries++;
    107         if (!F.Any()) {
     113        if (F.Count == 0) {
    108114          bestAssignment = assignment;
    109115          break;
     
    111117          // complete the solution and remember the one with least violation
    112118          foreach (var l in L.ToArray()) {
    113             CL.Add(l);
     119            CL_list.Add(l);
     120            CL_selected[l] = true;
    114121            L.Remove(l);
    115122          }
    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];
    122129          }
    123130          double violation = slack.Select(x => x < 0 ? -x : 0).Sum();
    124131          if (violation < minViolation) {
    125132            bestAssignment = assignment;
    126             assignment = new Dictionary<int, int>(demands.Length);
     133            assignment = new int[equipments];
    127134            minViolation = violation;
    128135          }
     
    130137      }
    131138
    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));
    133141
    134       return new IntegerVector(bestAssignment.OrderBy(x => x.Key).Select(x => x.Value).ToArray());
     142      return new IntegerVector(bestAssignment.Select(x => x - 1).ToArray());
    135143    }
    136144
     
    142150    }
    143151
    144     private static IEnumerable<int> WithDemandEqualOrLess(IEnumerable<int> facilities, double maximum, DoubleArray demands) {
     152    private static IEnumerable<int> WhereDemandEqualOrLess(IEnumerable<int> facilities, double maximum, DoubleArray demands) {
    145153      foreach (int f in facilities) {
    146154        if (demands[f] <= maximum) yield return f;
     
    148156    }
    149157
    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;
    152164    }
    153165
    154     private static IEnumerable<int> WithSlackGreaterOrEqual(HashSet<int> locations, double minimum, DoubleArray slack) {
     166    private static IEnumerable<int> WhereSlackGreaterOrEqual(IEnumerable<int> locations, double minimum, double[] slack) {
    155167      foreach (int l in locations) {
    156168        if (slack[l] >= minimum) yield return l;
Note: See TracChangeset for help on using the changeset viewer.