Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
11/30/16 14:49:22 (7 years ago)
Author:
jzenisek
Message:

#2707 updated clustering: implemented a quite generic version

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.VRPEnhancements/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Creators/TemporalDistanceClusterCreator.cs

    r14430 r14431  
    4949    }
    5050
    51     public static List<TemporalDistanceClusterElement> CreateClusterObjects(ITimeWindowedProblemInstance instance) {
     51    public static List<TemporalDistanceClusterElement> CreateClusterElements(ITimeWindowedProblemInstance instance) {
    5252      IPickupAndDeliveryProblemInstance pdp = instance as IPickupAndDeliveryProblemInstance;
    5353
     
    7070      PotvinEncoding result = new PotvinEncoding(instance);
    7171
    72       List<TemporalDistanceClusterElement> clusterObjects = CreateClusterObjects(instance);
     72      // (1) wrap stops in cluster elements
     73      List<TemporalDistanceClusterElement> clusterElements = CreateClusterElements(instance);
    7374
     75      // (2) create a random number k of clusters
    7476      int k = random.Next(minK, maxK);
    75       List<TemporalDistanceCluster> clusters = KMeans(instance, random, clusterObjects, k, clusterChangeThreshold);
     77      List<TemporalDistanceCluster> clusters = ClusterAlgorithm<TemporalDistanceCluster, TemporalDistanceClusterElement>
     78        .KMeans(random, clusterElements, k, clusterChangeThreshold, false);
    7679
    77       // (3) build tours
    78       // (a) shuffle
    79       // (b) greedy
     80      // (3) build tours with a (a) shuffling (b) greedy tour creation routine
    8081      foreach (var c in clusters) {
    8182        Tour newTour = new Tour();
     
    9394            newTour.Stops.Add(o.Id);
    9495          }
    95           GreedyTourCreation(instance, result, newTour, false);
     96          GreedyTourCreation(instance, result, newTour, true); // "true" means include costs
    9697        }
    9798      }
    9899
    99100      return result;
    100     }
    101 
    102     private static List<TemporalDistanceCluster> KMeans(ITimeWindowedProblemInstance instance, IRandom random, List<TemporalDistanceClusterElement> objects, int k, double changeTreshold) {
    103 
    104       List<TemporalDistanceCluster> clusters = new List<TemporalDistanceCluster>();
    105       HashSet<int> initMeans = new HashSet<int>();
    106       int nextMean = -1;
    107 
    108       // (1) initialize each cluster with a random first object (i.e. mean)
    109       for (int i = 0; i < k && i < objects.Count; i++) {
    110         TemporalDistanceCluster cluster = new TemporalDistanceCluster(instance, i);
    111 
    112         do {
    113           nextMean = random.Next(0, objects.Count);
    114         } while (initMeans.Contains(nextMean));
    115         initMeans.Add(nextMean);
    116         cluster.SetMean(objects[nextMean]);
    117         clusters.Add(cluster);
    118       }
    119 
    120       // (2) repeat clustering until change rate is below threshold
    121       int changes = 0;
    122       double changeRate = 1.0;
    123 
    124       do {
    125         changes = KMeansRun(clusters, objects);
    126         changeRate = changes / objects.Count;
    127 
    128       } while (changeRate > changeTreshold);
    129 
    130       // remove empty clusters
    131       clusters.RemoveAll(c => c.Elements.Count.Equals(0));
    132 
    133       return clusters;
    134     }
    135 
    136     private static int KMeansRun(List<TemporalDistanceCluster> clusters, List<TemporalDistanceClusterElement> objects) {
    137       int changes = 0;
    138 
    139       foreach (var c in clusters) {
    140         c.Elements.Clear();
    141       }
    142 
    143       foreach (var o in objects) {
    144         int bestClusterIdx = 0;
    145         double minImpact = clusters[0].CalculateImpact(o);
    146         for (int i = 1; i < clusters.Count; i++) {
    147           double impact = clusters[i].CalculateImpact(o);
    148           if ((minImpact > 0 && impact < minImpact) || (minImpact < 0 && impact > minImpact)) { // V1: min positive impact
    149           //if(impact > minImpact) { // V2: max impact
    150             minImpact = impact;
    151             bestClusterIdx = i;
    152           }
    153         }
    154         if (clusters[bestClusterIdx].AddObject(o))
    155           changes++;
    156       }
    157 
    158       foreach (var c in clusters) {
    159         c.CalculateMean();
    160         c.CalculateVariance();
    161       }
    162 
    163       return changes;
    164101    }
    165102
Note: See TracChangeset for help on using the changeset viewer.