protected override void Manipulate(IRandom random, GVREncoding individual) {
      int customer = random.Next(1, individual.Cities + 1);
      Tour tour;
      int position;
      individual.FindCustomer(customer, out tour, out position);

      tour.Stops.RemoveAt(position);

      //with a probability of 1/(2*V) create a new tour, else insert at another position
      if (individual.GetTours().Count > 0 &&
        individual.GetTours().Count < ProblemInstance.Vehicles.Value &&
        random.Next(individual.GetTours().Count * 2) == 0) {
        Tour newTour = new Tour();
        newTour.Stops.Add(customer);

        individual.Tours.Add(newTour);
      } else {
        Tour newTour = individual.Tours[random.Next(individual.Tours.Count)];
        int newPosition = random.Next(newTour.Stops.Count + 1);

        newTour.Stops.Insert(newPosition, customer);
      }

      if (tour.Stops.Count == 0)
        individual.Tours.Remove(tour);
    }
    public static PotvinPDShiftMove Apply(PotvinEncoding individual, IVRPProblemInstance problemInstance, IRandom rand) {
      List<int> cities = new List<int>();

      IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance;
      for (int i = 1; i <= individual.Cities; i++) {
        if (pdp == null || pdp.GetDemand(i) >= 0)
          cities.Add(i);
      }

      if (cities.Count >= 1) {
        int city = cities[rand.Next(cities.Count)];
        Tour oldTour = individual.Tours.Find(t => t.Stops.Contains(city));
        int oldTourIndex = individual.Tours.IndexOf(oldTour);

        int max = individual.Tours.Count;
        if (individual.Tours.Count >= problemInstance.Vehicles.Value)
          max = max - 1;

        int newTourIndex = rand.Next(max);
        if (newTourIndex >= oldTourIndex)
          newTourIndex++;

        return new PotvinPDShiftMove(city, oldTourIndex, newTourIndex, individual);
      } else {
        return null;
      }
    }
    /// <summary>
    /// Moves a randomly chosen interval of elements to another (randomly chosen) position in the given
    /// <paramref name="permutation"/> array and reverses it.
    /// </summary>
    /// <param name="random">The random number generator.</param>
    /// <param name="permutation">The permutation array to manipulate.</param>
    public static void Apply(IRandom random, Permutation permutation) {
      Permutation original = (Permutation)permutation.Clone();
      int breakPoint1, breakPoint2, insertPoint, insertPointLimit;

      breakPoint1 = random.Next(original.Length - 1);
      breakPoint2 = random.Next(breakPoint1 + 1, original.Length);
      insertPointLimit = original.Length - breakPoint2 + breakPoint1 - 1;  // get insertion point in remaining part
      if (insertPointLimit > 0)
        insertPoint = random.Next(insertPointLimit);
      else
        insertPoint = 0;

      int i = 0;  // index in new permutation
      int j = 0;  // index in old permutation
      while (i < original.Length) {
        if (i == insertPoint) {  // copy translocated area
          for (int k = breakPoint2; k >= breakPoint1; k--) {
            permutation[i] = original[k];
            i++;
          }
        }
        if (j == breakPoint1) {  // skip area between breakpoints
          j = breakPoint2 + 1;
        }
        if ((i < original.Length) && (j < original.Length)) {
          permutation[i] = original[j];
          i++;
          j++;
        }
      }
    }
    protected override void Manipulate(IRandom rand, AlbaEncoding individual) {
      int index1 = -1;
      int index2 = -1;

      List<Tour> validTours = new List<Tour>();
      foreach (Tour tour in individual.GetTours()) {
        if (tour.Stops.Count >= 4)
          validTours.Add(tour);
      }

      if (validTours.Count > 0) {
        Tour chosenTour = validTours[rand.Next(validTours.Count)];
        int currentTourStart = -1;
        for (int i = 0; i < individual.Length; i++) {
          if (individual[i] + 1 == chosenTour.Stops[0]) {
            currentTourStart = i;
            break;
          }
        }

        int currentTourEnd = currentTourStart;
        while (currentTourEnd < individual.Length &&
          individual[currentTourEnd] < ProblemInstance.Cities.Value) {
          currentTourEnd++;
        }

        int tourLength = currentTourEnd - currentTourStart;
        int a = rand.Next(tourLength - 3);
        index1 = currentTourStart + a;
        index2 = currentTourStart + rand.Next(a + 2, tourLength - 1);
      }

      Apply(individual, index1, index2);
    }
    protected override void Manipulate(IRandom random, GVREncoding individual) {
      Tour tour = individual.Tours[random.Next(individual.Tours.Count)];
      int breakPoint1 = random.Next(tour.Stops.Count);
      int length = random.Next(1, tour.Stops.Count - breakPoint1 + 1);

      List<int> displaced = tour.Stops.GetRange(breakPoint1, length);
      tour.Stops.RemoveRange(breakPoint1, length);
      //with a probability of 1/(2*V) create a new tour, else insert at another position
      if (individual.GetTours().Count > 0 &&
        individual.GetTours().Count < ProblemInstance.Vehicles.Value &&
        random.Next(individual.GetTours().Count * 2) == 0) {
        Tour newTour = new Tour();
        newTour.Stops.InsertRange(0, displaced);

        individual.Tours.Add(newTour);
      } else {
        Tour newTour = individual.Tours[random.Next(individual.Tours.Count)];
        int newPosition = newTour.Stops.Count;

        newTour.Stops.InsertRange(newPosition, displaced);
      }

      if (tour.Stops.Count == 0)
        individual.Tours.Remove(tour);
    }
Example #6
0
    /// <summary>
    /// Performs the order crossover of two permutations.
    /// </summary>
    /// <exception cref="ArgumentException">Thrown when <paramref name="parent1"/> and <paramref name="parent2"/> are not of equal length.</exception>
    /// <exception cref="InvalidOperationException">Thrown if the numbers in the permutation elements are not in the range [0,N) with N = length of the permutation.</exception>
    /// <remarks>
    /// Crosses two permutations by copying a randomly chosen interval from the first permutation, preserving
    /// the positions. Then, starting from the end of the copied interval, copies the missing values from the second permutation
    /// in the order they occur.
    /// </remarks>
    /// <param name="random">A random number generator.</param>
    /// <param name="parent1">The first parent permutation to cross.</param>
    /// <param name="parent2">The second parent permutation to cross.</param>
    /// <returns>The new permutation resulting from the crossover.</returns>
    public static Permutation Apply(IRandom random, Permutation parent1, Permutation parent2) {
      if (parent1.Length != parent2.Length) throw new ArgumentException("OrderCrossover: The parent permutations are of unequal length.");
      int length = parent1.Length;
      int[] result = new int[length];
      bool[] copied = new bool[length];

      int breakPoint1 = random.Next(length - 1);
      int breakPoint2 = random.Next(breakPoint1 + 1, length);

      try {
        for (int j = breakPoint1; j <= breakPoint2; j++) {  // copy part of first permutation
          result[j] = parent1[j];
          copied[parent1[j]] = true;
        }

        int index = ((breakPoint2 + 1 >= length) ? (0) : (breakPoint2 + 1));
        int i = index; // for moving in parent2
        while (index != breakPoint1) {
          if (!copied[parent2[i]]) {
            result[index] = parent2[i];
            index++;
            if (index >= length) index = 0;
          }
          i++;
          if (i >= length) i = 0;
        }
      }
      catch (IndexOutOfRangeException) {
        throw new InvalidOperationException("OrderCrossover: The permutation must consist of numbers in the interval [0;N) with N = length of the permutation.");
      }
      return new Permutation(parent1.PermutationType, result);
    }
    /// <summary>
    /// Performs the partially matched crossover on <paramref name="parent1"/> and <paramref name="parent2"/>.
    /// </summary>
    /// <exception cref="ArgumentException">Thrown when <paramref name="parent1"/> and <paramref name="parent2"/> are not of equal length or when the permutations are shorter than 4 elements.</exception>
    /// <exception cref="InvalidOperationException">Thrown if the numbers in the permutation elements are not in the range [0,N) with N = length of the permutation.</exception>
    /// <remarks>
    /// Initially the new offspring is a clone of <paramref name="parent2"/>.
    /// Then a segment is extracted from <paramref name="parent1"/> and copied to the offspring position by position.
    /// Whenever a position is copied, the number at that position currently in the offspring is transfered to the position where the copied number has been.
    /// E.g.: Position 15 is selected to be copied from <paramref name="parent1"/> to <paramref name="parent2"/>. At position 15 there is a '3' in <paramref name="parent1"/> and a '5' in the new offspring.
    /// The '5' in the offspring is then moved to replace the '3' in the offspring and '3' is written at position 15.
    /// </remarks>
    /// <param name="random">A random number generator.</param>
    /// <param name="parent1">The first parent permutation to cross.</param>
    /// <param name="parent2">The second parent permutation to cross.</param>
    /// <returns>The new permutation resulting from the crossover.</returns>
    public static Permutation Apply(IRandom random, Permutation parent1, Permutation parent2) {
      if (parent1.Length != parent2.Length) throw new ArgumentException("PartiallyMatchedCrossover: The parent permutations are of unequal length.");
      if (parent1.Length < 4) throw new ArgumentException("PartiallyMatchedCrossover: The parent permutation must be at least of size 4.");
      int length = parent1.Length;
      int[] result = new int[length];
      int[] invResult = new int[length];

      int breakPoint1, breakPoint2;
      do {
        breakPoint1 = random.Next(length - 1);
        breakPoint2 = random.Next(breakPoint1 + 1, length);
      } while (breakPoint2 - breakPoint1 >= length - 2); // prevent the case [0,length-1) -> clone of parent1

      // clone parent2 and calculate inverse permutation (number -> index)
      try {
        for (int j = 0; j < length; j++) {
          result[j] = parent2[j];
          invResult[result[j]] = j;
        }
      }
      catch (IndexOutOfRangeException) {
        throw new InvalidOperationException("PartiallyMatchedCrossover: The permutation must consist of consecutive numbers from 0 to N-1 with N = length of the permutation.");
      }

      for (int j = breakPoint1; j <= breakPoint2; j++) {
        int orig = result[j]; // save the former value
        result[j] = parent1[j]; // overwrite the former value with the new value
        int index = invResult[result[j]]; // look where the new value is in the offspring
        result[index] = orig; // write the former value to this position
        invResult[orig] = index; // update the inverse mapping
        // it's not necessary to do 'invResult[result[j]] = j' as this will not be needed again
      }

      return new Permutation(parent1.PermutationType, result);
    }
    public static ScrambleMove GenerateRandomMove(Permutation permutation, IRandom random) {
      int breakPoint1, breakPoint2;
      int[] scrambledIndices;

      breakPoint1 = random.Next(permutation.Length);
      do {
        breakPoint2 = random.Next(permutation.Length);
      } while (Math.Abs(breakPoint2 - breakPoint1) <= 1);
      if (breakPoint2 < breakPoint1) { int h = breakPoint1; breakPoint1 = breakPoint2; breakPoint2 = h; }

      scrambledIndices = new int[breakPoint2 - breakPoint1 + 1];
      for (int i = 0; i < scrambledIndices.Length; i++)
        scrambledIndices[i] = i;
      bool[] moved = new bool[scrambledIndices.Length];
      bool changed = false;
      do {
        for (int i = scrambledIndices.Length - 1; i > 0; i--) {
          int j = random.Next(i + 1);
          int t = scrambledIndices[j];
          scrambledIndices[j] = scrambledIndices[i];
          scrambledIndices[i] = t;
          if (scrambledIndices[j] == j) moved[j] = false;
          else moved[j] = true;
          if (scrambledIndices[i] == i) moved[i] = false;
          else moved[i] = true;
        }
        changed = moved.Any(x => x);
      } while (!changed);

      return new ScrambleMove(breakPoint1, scrambledIndices);
    }
Example #9
0
    public static JSMEncoding Apply(IRandom random, JSMEncoding p1, JSMEncoding p2) {
      var result = new JSMEncoding();

      int nrOfResources = p1.JobSequenceMatrix.Count;
      int nrOfJobs = p1.JobSequenceMatrix[0].Length;

      //Determine randomly which jobindexes persist
      var persist = new BoolArray(nrOfJobs);
      for (int i = 0; i < persist.Length; i++) {
        persist[i] = random.Next(2) == 1;
      }

      bool dominantParent = random.Next(2) == 1;
      JSMEncoding parent1 = dominantParent ? p1 : p2;
      JSMEncoding parent2 = dominantParent ? p2 : p1;

      //Fill childmatrix with values
      for (int resIndex = 0; resIndex < nrOfResources; resIndex++) {
        result.JobSequenceMatrix.Add(new Permutation(PermutationTypes.Absolute, nrOfJobs));
        int parent2index = 0;
        for (int jobIndex = 0; jobIndex < nrOfJobs; jobIndex++) {
          if (persist[parent1.JobSequenceMatrix[resIndex][jobIndex]])
            result.JobSequenceMatrix[resIndex][jobIndex] = parent1.JobSequenceMatrix[resIndex][jobIndex];
          else {
            while (persist[parent2.JobSequenceMatrix[resIndex][parent2index]])
              parent2index++;
            result.JobSequenceMatrix[resIndex][jobIndex] = parent2.JobSequenceMatrix[resIndex][parent2index];
            parent2index++;
          }
        }
      }

      return result;
    }
    /// <summary>
    /// Moves an randomly chosen element in the specified <paramref name="permutation"/> array 
    /// to another randomly generated position.
    /// </summary>
    /// <param name="random">The random number generator.</param>
    /// <param name="permutation">The permutation to manipulate.</param>
    public static void Apply(IRandom random, Permutation permutation) {
      Permutation original = (Permutation)permutation.Clone();
      int cutIndex, insertIndex, number;

      cutIndex = random.Next(original.Length);
      insertIndex = random.Next(original.Length);
      number = original[cutIndex];

      int i = 0;  // index in new permutation
      int j = 0;  // index in old permutation
      while (i < original.Length) {
        if (j == cutIndex) {
          j++;
        }
        if (i == insertIndex) {
          permutation[i] = number;
          i++;
        }
        if ((i < original.Length) && (j < original.Length)) {
          permutation[i] = original[j];
          i++;
          j++;
        }
      }
    }
    protected override void Manipulate(IRandom random, PrinsEncoding individual) {
      List<Tour> tours = individual.GetTours();
      bool improvement = false;
      int iterations = 0;

      do {
        improvement = false;
        double originalQuality = GetQuality(individual);
        PrinsEncoding child = null;

        int samples = 0;
        while (!improvement &&
          samples < SampleSize.Value.Value) {
          int u = random.Next(ProblemInstance.Cities.Value);
          int v = random.Next(ProblemInstance.Cities.Value);

          child = Manipulate(individual,
                originalQuality, u, v);

          improvement = child != null;

          samples++;
        }

        if (improvement) {
          for (int i = 0; i < child.Length; i++) {
            individual[i] = child[i];
          }
        }

        iterations++;
      } while (improvement &&
        iterations < Iterations.Value.Value);
    }
    /// <summary>
    /// Performs a cross over permutation of <paramref name="parent1"/> and <paramref name="parent2"/>
    /// based on randomly chosen positions to define which position to take from where.
    /// </summary>
    /// <exception cref="ArgumentException">Thrown when <paramref name="parent1"/> and <paramref name="parent2"/> are not of equal length.</exception>
    /// <param name="random">The random number generator.</param>
    /// <param name="parent1">First parent</param>
    /// <param name="parent2">Second Parent</param>
    /// <returns>Child</returns>
    public static Permutation Apply(IRandom random, Permutation parent1, Permutation parent2) {
      if (parent1.Length != parent2.Length) throw new ArgumentException("PositionBasedCrossover: The parent permutations are of unequal length.");
      int length = parent1.Length;
      int[] result = new int[length];
      bool[] randomPosition = new bool[length];
      bool[] numberCopied = new bool[length];
      int randomPosNumber = random.Next(length);

      for (int i = 0; i < randomPosNumber; i++) {  // generate random bit mask
        randomPosition[random.Next(length)] = true;
      }

      for (int i = 0; i < length; i++) {  // copy numbers masked as true from second permutation
        if (randomPosition[i]) {
          result[i] = parent2[i];
          numberCopied[parent2[i]] = true;
        }
      }

      int index = 0;
      for (int i = 0; i < length; i++) {  // copy numbers masked as false from first permutation
        if (!numberCopied[parent1[i]]) {
          if (randomPosition[index]) {
            while (randomPosition[index]) {
              index++;
            }
          }
          result[index] = parent1[i];
          index++;
        }
      }

      return new Permutation(parent1.PermutationType, result);
    }
    /// <summary>
    /// Performs a slight variation of the order crossover of two permutations.
    /// </summary>
    /// <exception cref="ArgumentException">Thrown when <paramref name="parent1"/> and <paramref name="parent2"/> are not of equal length.</exception>
    /// <remarks>
    /// Crosses two permutations by copying a randomly chosen interval from the first permutation, preserving
    /// the positions. Then, from the beginning of the permutation, copies the missing values from the second permutation
    /// in the order they occur.
    /// </remarks>
    /// <param name="random">A random number generator.</param>
    /// <param name="parent1">The first parent permutation to cross.</param>
    /// <param name="parent2">The second parent permutation to cross.</param>
    /// <returns>The new permutation resulting from the crossover.</returns>
    public static Permutation Apply(IRandom random, Permutation parent1, Permutation parent2) {
      if (parent1.Length != parent2.Length) throw new ArgumentException("OrderCrossover2: The parent permutations are of unequal length.");
      int[] result = new int[parent1.Length];
      bool[] copied = new bool[result.Length];

      int breakPoint1 = random.Next(result.Length - 1);
      int breakPoint2 = random.Next(breakPoint1 + 1, result.Length);

      for (int i = breakPoint1; i <= breakPoint2; i++) {  // copy part of first permutation
        result[i] = parent1[i];
        copied[parent1[i]] = true;
      }

      int index = 0;
      for (int i = 0; i < parent2.Length; i++) {  // copy remaining part of second permutation
        if (index == breakPoint1) {  // skip already copied part
          index = breakPoint2 + 1;
        }
        if (!copied[parent2[i]]) {
          result[index] = parent2[i];
          index++;
        }
      }
      return new Permutation(parent1.PermutationType, result);
    }
    protected override void Manipulate(IRandom random, AlbaEncoding individual) {
      AlbaEncoding original = (AlbaEncoding)individual.Clone();
      int cutIndex, insertIndex, number;

      int customer = random.Next(ProblemInstance.Cities.Value);
      cutIndex = FindCustomerLocation(customer, individual);

      insertIndex = random.Next(original.Length);
      number = original[cutIndex];

      int i = 0;  // index in new permutation
      int j = 0;  // index in old permutation
      while (i < original.Length) {
        if (j == cutIndex) {
          j++;
        }
        if (i == insertIndex) {
          individual[i] = number;
          i++;
        }
        if ((i < original.Length) && (j < original.Length)) {
          individual[i] = original[j];
          i++;
          j++;
        }
      }
    }
    /// <summary>
    /// Mixes the elements of the given <paramref name="permutation"/> randomly 
    /// in a randomly chosen interval.
    /// </summary>
    /// <param name="random">The random number generator.</param>
    /// <param name="permutation">The permutation to manipulate.</param>
    public static void Apply(IRandom random, Permutation permutation) {
      int breakPoint1, breakPoint2;
      int[] scrambledIndices, remainingIndices, temp;
      int selectedIndex, index;

      breakPoint1 = random.Next(permutation.Length - 1);
      breakPoint2 = random.Next(breakPoint1 + 1, permutation.Length);

      scrambledIndices = new int[breakPoint2 - breakPoint1 + 1];
      remainingIndices = new int[breakPoint2 - breakPoint1 + 1];
      for (int i = 0; i < remainingIndices.Length; i++) {  // initialise indices
        remainingIndices[i] = i;
      }
      for (int i = 0; i < scrambledIndices.Length; i++) {  // generate permutation of indices
        selectedIndex = random.Next(remainingIndices.Length);
        scrambledIndices[i] = remainingIndices[selectedIndex];

        temp = remainingIndices;
        remainingIndices = new int[temp.Length - 1];
        index = 0;
        for (int j = 0; j < remainingIndices.Length; j++) {
          if (index == selectedIndex) {
            index++;
          }
          remainingIndices[j] = temp[index];
          index++;
        }
      }

      Apply(permutation, breakPoint1, scrambledIndices);
    }
    protected override void Manipulate(IRandom random, GVREncoding individual) {
      Tour tour = individual.Tours[random.Next(individual.Tours.Count)];
      int breakPoint1 = random.Next(tour.Stops.Count);
      int length = random.Next(1, tour.Stops.Count - breakPoint1 + 1);

      tour.Stops.Reverse(breakPoint1, length);
    }
    /// <summary>
    /// Swaps two randomly chosen elements in the given <paramref name="permutation"/> permutation.
    /// </summary>
    /// <param name="random">The random number generator.</param>
    /// <param name="permutation">The permutation to manipulate.</param>
    public static void Apply(IRandom random, Permutation permutation) {
      int index1, index2;

      index1 = random.Next(permutation.Length);
      index2 = random.Next(permutation.Length);

      Apply(permutation, index1, index2);
    }
 public static void Apply(IRandom random, LinearLinkage lle) {
   int tries = lle.Length;
   var index = random.Next(lle.Length);
   while (tries > 0 && lle[index] == index) {
     index = random.Next(lle.Length);
     tries--;
   }
   if (lle[index] != index) Apply(random, lle, index);
 }
Example #19
0
 public static void Apply(IRandom random, JSMEncoding individual) {
   int resourceIndex = random.Next(individual.JobSequenceMatrix.Count);
   Permutation p = individual.JobSequenceMatrix[resourceIndex];
   int seqIndex1 = random.Next(p.Length);
   int seqIndex2 = random.Next(p.Length);
   int aux = p[seqIndex1];
   p[seqIndex1] = p[seqIndex2];
   p[seqIndex2] = aux;
 }
 public static Swap2Move Apply(Permutation permutation, IRandom random) {
   int length = permutation.Length;
   if (length < 2) throw new ArgumentException("StochasticSwap2SingleMoveGenerator: There cannot be a swap-2 move given a permutation of length less than 2.", "permutation");
   int index1 = random.Next(length), index2 = 0;
   do {
     index2 = random.Next(length);
   } while (index1 == index2);
   return new Swap2Move(index1, index2);
 }
    /// <summary>
    /// Inverts a randomly chosen part of a permutation.
    /// </summary>
    /// <param name="random">A random number generator.</param>
    /// <param name="permutation">The permutation to manipulate.</param>
    public static void Apply(IRandom random, Permutation permutation) {
      int breakPoint1, breakPoint2;

      breakPoint1 = random.Next(permutation.Length - 1);
      do {
        breakPoint2 = random.Next(permutation.Length - 1);
      } while (breakPoint2 == breakPoint1);
      if (breakPoint2 < breakPoint1) { int h = breakPoint1; breakPoint1 = breakPoint2; breakPoint2 = h; }
      Apply(permutation, breakPoint1, breakPoint2);
    }
    public static PotvinVehicleAssignmentMove Apply(PotvinEncoding individual, IVRPProblemInstance problemInstance, IRandom rand) {
      if (individual.Tours.Count > 1) {
        int tour1 = rand.Next(individual.Tours.Count);
        int tour2 = rand.Next(problemInstance.Vehicles.Value);

        while (tour2 == tour1)
          tour2 = rand.Next(problemInstance.Vehicles.Value);

        return new PotvinVehicleAssignmentMove(tour1, tour2, individual);
      } else {
        return null;
      }
    }
Example #23
0
        public static System.Decimal GetDecimal(IRandom rand,
												System.Decimal min = System.Decimal.MinValue,
												System.Decimal max = System.Decimal.MaxValue)
        {
            System.Decimal result = new System.Decimal(rand.Next(), rand.Next(), rand.Next(), GetBoolean(rand), GetByte(rand, 0, 29));

            if(result < min)
                return min;
            else if (result >= max)
                return max - 1m;
            else
                return result;
        }
    /// <summary>
    /// Moves a randomly chosen interval of elements to another (randomly chosen) position in the given
    /// <paramref name="permutation"/> array.
    /// </summary>
    /// <param name="random">The random number generator.</param>
    /// <param name="permutation">The permutation array to manipulate.</param>
    public static void Apply(IRandom random, Permutation permutation) {
      int breakPoint1, breakPoint2, insertPoint, insertPointLimit;

      breakPoint1 = random.Next(permutation.Length - 1);
      breakPoint2 = random.Next(breakPoint1 + 1, permutation.Length);
      insertPointLimit = permutation.Length - breakPoint2 + breakPoint1 - 1;  // get insertion point in remaining part
      if (insertPointLimit > 0)
        insertPoint = random.Next(insertPointLimit);
      else
        insertPoint = 0;

      Apply(permutation, breakPoint1, breakPoint2, insertPoint);
    }
 public static InversionMove Apply(Permutation permutation, IRandom random) {
   int length = permutation.Length;
   if (length == 1) throw new ArgumentException("StochasticInversionSingleMoveGenerator: There cannot be an inversion move given a permutation of length 1.", "permutation");
   int index1 = random.Next(length - 1);
   int index2 = random.Next(index1 + 1, length);
   if (permutation.PermutationType == PermutationTypes.RelativeUndirected) {
     if (length > 3) {
       while (index2 - index1 >= length - 2)
         index2 = random.Next(index1 + 1, length);
     }
   }
   return new InversionMove(index1, index2);
 }
    protected override void Manipulate(IRandom random, AlbaEncoding individual) {
      int index1, index2, temp;

      int customer1 = random.Next(ProblemInstance.Cities.Value);
      index1 = FindCustomerLocation(customer1, individual);

      int customer2 = random.Next(ProblemInstance.Cities.Value);
      index2 = FindCustomerLocation(customer2, individual);

      temp = individual[index1];
      individual[index1] = individual[index2];
      individual[index2] = temp;
    }
    public static PotvinTwoOptStarMove Apply(PotvinEncoding individual, IVRPProblemInstance problemInstance, IRandom rand) {
      int route1Idx = rand.Next(individual.Tours.Count);
      int route2Idx = rand.Next(individual.Tours.Count - 1);
      if (route2Idx >= route1Idx)
        route2Idx++;

      Tour route1 = individual.Tours[route1Idx];
      Tour route2 = individual.Tours[route2Idx];

      int x1 = rand.Next(route1.Stops.Count + 1);
      int x2 = rand.Next(route2.Stops.Count + 1);

      return new PotvinTwoOptStarMove(route1Idx, x1, route2Idx, x2, individual);
    }
Example #28
0
    private GVREncoding Crossover(IRandom random, GVREncoding parent1, GVREncoding parent2) {
      GVREncoding child = parent1.Clone() as GVREncoding;

      Tour tour = parent2.Tours[random.Next(parent2.Tours.Count)];
      int breakPoint1 = random.Next(tour.Stops.Count);
      int length = random.Next(1, tour.Stops.Count - breakPoint1 + 1);
      List<int> subroute = tour.Stops.GetRange(breakPoint1, length);

      //remove duplicates
      List<Tour> toBeRemoved = new List<Tour>();

      foreach (Tour route in child.Tours) {
        foreach (int city in subroute) {
          route.Stops.Remove(city);
        }

        if (route.Stops.Count == 0)
          toBeRemoved.Add(route);
      }
      foreach (Tour route in toBeRemoved) {
        child.Tours.Remove(route);
      }

      //choose nearest customer
      double minDistance = -1;
      int customer = -1;
      for (int i = 1; i <= ProblemInstance.Cities.Value; i++) {
        if (!subroute.Contains(i)) {
          double distance = ProblemInstance.GetDistance(subroute[0], i, child);

          if (customer == -1 || distance < minDistance) {
            customer = i;
            minDistance = distance;
          }
        }
      }

      //insert
      if (customer != -1) {
        Tour newTour;
        int newPosition;
        child.FindCustomer(customer, out newTour, out newPosition);
        newTour.Stops.InsertRange(newPosition + 1, subroute);
      } else {
        //special case -> only one tour, whole tour has been chosen as subroute
        child = parent1.Clone() as GVREncoding;
      }

      return child;
    }
 public static void Apply(IRandom random, PWREncoding individual) {
   int cutIndex = random.Next(individual.PermutationWithRepetition.Length);
   int insertIndex = random.Next(individual.PermutationWithRepetition.Length);
   List<int> perm = ((IntegerVector)(individual.PermutationWithRepetition.Clone())).ToList<int>();
   int aux = perm[cutIndex];
   if (cutIndex > insertIndex) {
     perm.RemoveAt(cutIndex);
     perm.Insert(insertIndex, aux);
   } else {
     perm.Insert(insertIndex, aux);
     perm.RemoveAt(cutIndex);
   }
   individual.PermutationWithRepetition = new IntegerVector(perm.ToArray());
 }
    public static PotvinCustomerRelocationMove Apply(PotvinEncoding individual, IVRPProblemInstance problemInstance, IRandom rand) {
      int city = 1 + rand.Next(individual.Cities);
      Tour oldTour = individual.Tours.Find(t => t.Stops.Contains(city));
      int oldTourIndex = individual.Tours.IndexOf(oldTour);

      int max = individual.Tours.Count;
      if (individual.Tours.Count < problemInstance.Vehicles.Value)
        max = max - 1;

      int newTourIndex = rand.Next(max);
      if (newTourIndex >= oldTourIndex)
        newTourIndex++;

      return new PotvinCustomerRelocationMove(city, oldTourIndex, newTourIndex, individual);
    }