Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
01/12/17 16:42:50 (7 years ago)
Author:
pfleck
Message:

#2707 Simplified k-means clustering for ClusterCreators.

File:
1 edited

Legend:

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

    r14442 r14559  
    2020#endregion
    2121
     22using System;
    2223using System.Collections.Generic;
    2324using System.Linq;
     
    4849    }
    4950
    50     public static List<SpatialDistanceClusterElement> CreateClusterElements(IVRPProblemInstance instance) {
    51       IPickupAndDeliveryProblemInstance pdp = instance as IPickupAndDeliveryProblemInstance;
    52 
    53       // add all customers
    54       List<int> customers = new List<int>();
    55       for (int i = 1; i <= instance.Cities.Value; i++) {
    56         if (pdp == null || pdp.GetDemand(i) >= 0)
    57           customers.Add(i);
    58       }
    59 
    60       // wrap stops in SpatialDistanceClusterElement
    61       List<SpatialDistanceClusterElement> clusterElements = new List<SpatialDistanceClusterElement>();
    62       foreach (int customer in customers) {
    63         clusterElements.Add(new SpatialDistanceClusterElement(customer, instance.GetCoordinates(customer)));
    64       }
    65       return clusterElements;
    66     }
    6751
    6852    public static PotvinEncoding CreateSolution(IVRPProblemInstance instance, IRandom random, int minK, int maxK, double clusterChangeThreshold, int creationOption) {
    6953      PotvinEncoding result = new PotvinEncoding(instance);
    7054
    71       // (1) wrap stops in cluster elements
    72       List<SpatialDistanceClusterElement> clusterElements = CreateClusterElements(instance);
     55      // (1) init data
     56      var coordinates = new List<double[]>(instance.Cities.Value);
     57      var pdp = instance as IPickupAndDeliveryProblemInstance;
     58      for (int i = 1; i <= instance.Cities.Value; i++) {
     59        if (pdp == null || pdp.GetDemand(i) >= 0)
     60          coordinates.Add(instance.GetCoordinates(i));
     61      }
    7362
    7463      // (2) create a random number k of clusters
    7564      int k = random.Next(minK, maxK);
    76       List<SpatialDistanceCluster> clusters = ClusterAlgorithm<SpatialDistanceCluster, SpatialDistanceClusterElement>
    77         .KMeans(random, clusterElements, k, clusterChangeThreshold);
    78      
     65      var kMeans = new KMeansAlgorithm<double[]>(CalculateMeanHelper, CalculateDistanceHelper);
     66      var clusters = kMeans.Run(coordinates, k, clusterChangeThreshold, random);
     67
    7968      // (3) build tours with a (a) shuffling (b) greedy tour creation routine
    80       foreach (var c in clusters) {
     69      foreach (var cluster in clusters) {
    8170        Tour newTour = new Tour();
    8271        result.Tours.Add(newTour);
     
    8473        if (creationOption == 0) {
    8574          // (a) shuffle
    86           c.Elements.Shuffle(random);
    87           foreach (var o in c.Elements) {
    88             newTour.Stops.Add(o.Id);
     75          cluster.ShuffleInPlace(random);
     76          newTour.Stops.AddRange(cluster);
     77          foreach (var customer in cluster) {
     78            newTour.Stops.Add(customer + 1);
    8979          }
    9080        } else {
    9181          // (b) greedy
    92           foreach (var o in c.Elements) {
    93             newTour.Stops.Add(o.Id);
     82          foreach (var customer in cluster) {
     83            newTour.Stops.Add(customer + 1);
    9484          }
    9585          GreedyTourCreation(instance, result, newTour, false);
     
    9888
    9989      return result;
     90    }
     91
     92    private static double[] CalculateMeanHelper(List<double[]> coordinates) {
     93      var mean = new double[coordinates[0].Length];
     94      foreach (double[] coord in coordinates) {
     95        for (int i = 0; i < mean.Length; i++) {
     96          mean[i] += coord[i] / coordinates.Count;
     97        }
     98      }
     99      return mean;
     100    }
     101    private static double CalculateDistanceHelper(double[] coord1, double[] coord2) {
     102      double distance = 0.0;
     103      for (int i = 0; i < coord1.Length; i++) {
     104        distance += Math.Pow(coord1[i] - coord2[i], 2);
     105      }
     106      return Math.Sqrt(distance);
    100107    }
    101108
Note: See TracChangeset for help on using the changeset viewer.