public static double EvaluateByDistanceMatrix(Permutation permutation, TranslocationMove move, DistanceMatrix distanceMatrix) {
      if (move.Index1 == move.Index3
        || move.Index2 == permutation.Length - 1 && move.Index3 == 0
        || move.Index1 == 0 && move.Index3 == permutation.Length - 1 - move.Index2) return 0;

      int edge1source = permutation.GetCircular(move.Index1 - 1);
      int edge1target = permutation[move.Index1];
      int edge2source = permutation[move.Index2];
      int edge2target = permutation.GetCircular(move.Index2 + 1);
      int edge3source, edge3target;
      if (move.Index3 > move.Index1) {
        edge3source = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1);
        edge3target = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1 + 1);
      } else {
        edge3source = permutation.GetCircular(move.Index3 - 1);
        edge3target = permutation[move.Index3];
      }
      double moveQuality = 0;
      // remove three edges
      moveQuality -= distanceMatrix[edge1source, edge1target];
      moveQuality -= distanceMatrix[edge2source, edge2target];
      moveQuality -= distanceMatrix[edge3source, edge3target];
      // add three edges
      moveQuality += distanceMatrix[edge3source, edge1target];
      moveQuality += distanceMatrix[edge2source, edge3target];
      moveQuality += distanceMatrix[edge1source, edge2target];
      return moveQuality;
    }
 public static double Apply(Permutation assignment, TranslocationMove move, DoubleMatrix weights, DoubleMatrix distances) {
   double moveQuality = 0;
   int min = Math.Min(move.Index1, move.Index3);
   int max = Math.Max(move.Index2, move.Index3 + (move.Index2 - move.Index1));
   int iOffset, changeOffset;
   if (move.Index1 < move.Index3) {
     iOffset = move.Index2 - move.Index1 + 1;
     changeOffset = min + max - move.Index2;
   } else {
     iOffset = move.Index1 - move.Index3;
     changeOffset = min + move.Index2 - move.Index1 + 1;
   }
   for (int i = min; i <= max; i++) {
     if (i == changeOffset) iOffset -= (max - min + 1);
     int jOffset = ((move.Index1 < move.Index3) ? (move.Index2 - move.Index1 + 1) : (move.Index1 - move.Index3));
     for (int j = 0; j < assignment.Length; j++) {
       moveQuality -= weights[i, j] * distances[assignment[i], assignment[j]];
       if (j < min || j > max) {
         moveQuality -= weights[j, i] * distances[assignment[j], assignment[i]];
         moveQuality += weights[i, j] * distances[assignment[i + iOffset], assignment[j]];
         moveQuality += weights[j, i] * distances[assignment[j], assignment[i + iOffset]];
       } else {
         if (j == changeOffset) jOffset -= (max - min + 1);
         moveQuality += weights[i, j] * distances[assignment[i + iOffset], assignment[j + jOffset]];
       }
     }
   }
   return moveQuality;
 }
    public static double EvaluateByCoordinates(Permutation permutation, TranslocationMove move, DoubleMatrix coordinates, TSPTranslocationMovePathEvaluator evaluator) {
      if (move.Index1 == move.Index3
        || move.Index2 == permutation.Length - 1 && move.Index3 == 0
        || move.Index1 == 0 && move.Index3 == permutation.Length - 1 - move.Index2) return 0;

      int edge1source = permutation.GetCircular(move.Index1 - 1);
      int edge1target = permutation[move.Index1];
      int edge2source = permutation[move.Index2];
      int edge2target = permutation.GetCircular(move.Index2 + 1);
      int edge3source, edge3target;
      if (move.Index3 > move.Index1) {
        edge3source = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1);
        edge3target = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1 + 1);
      } else {
        edge3source = permutation.GetCircular(move.Index3 - 1);
        edge3target = permutation[move.Index3];
      }
      double moveQuality = 0;
      // remove three edges
      moveQuality -= evaluator.CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],
        coordinates[edge1target, 0], coordinates[edge1target, 1]);
      moveQuality -= evaluator.CalculateDistance(coordinates[edge2source, 0], coordinates[edge2source, 1],
        coordinates[edge2target, 0], coordinates[edge2target, 1]);
      moveQuality -= evaluator.CalculateDistance(coordinates[edge3source, 0], coordinates[edge3source, 1],
        coordinates[edge3target, 0], coordinates[edge3target, 1]);
      // add three edges
      moveQuality += evaluator.CalculateDistance(coordinates[edge3source, 0], coordinates[edge3source, 1],
        coordinates[edge1target, 0], coordinates[edge1target, 1]);
      moveQuality += evaluator.CalculateDistance(coordinates[edge2source, 0], coordinates[edge2source, 1],
        coordinates[edge3target, 0], coordinates[edge3target, 1]);
      moveQuality += evaluator.CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],
        coordinates[edge2target, 0], coordinates[edge2target, 1]);
      return moveQuality;
    }
 public static TranslocationMove[] Apply(Permutation permutation, IRandom random, int sampleSize) {
   int length = permutation.Length;
   TranslocationMove[] moves = new TranslocationMove[sampleSize];
   for (int i = 0; i < sampleSize; i++) {
     moves[i] = StochasticTranslocationSingleMoveGenerator.Apply(permutation, random);
   }
   return moves;
 }
Пример #5
0
        public static TranslocationMove[] Apply(Permutation permutation, IRandom random, int sampleSize)
        {
            int length = permutation.Length;

            TranslocationMove[] moves = new TranslocationMove[sampleSize];
            for (int i = 0; i < sampleSize; i++)
            {
                moves[i] = StochasticTranslocationSingleMoveGenerator.Apply(permutation, random);
            }
            return(moves);
        }
Пример #6
0
        public override IOperation Apply()
        {
            TranslocationMove move        = TranslocationMoveParameter.ActualValue;
            Permutation       permutation = PermutationParameter.ActualValue;
            DoubleValue       moveQuality = MoveQualityParameter.ActualValue;
            DoubleValue       quality     = QualityParameter.ActualValue;

            TranslocationManipulator.Apply(permutation, move.Index1, move.Index2, move.Index3);
            quality.Value = moveQuality.Value;

            return(base.Apply());
        }
        protected override IItem GetTabuAttribute(bool maximization, double quality, double moveQuality)
        {
            TranslocationMove move        = TranslocationMoveParameter.ActualValue;
            Permutation       permutation = PermutationParameter.ActualValue;
            double            baseQuality = moveQuality;

            if (maximization && quality > moveQuality || !maximization && quality < moveQuality)
            {
                baseQuality = quality;                                                                            // we make an uphill move, the lower bound is the solution quality
            }
            if (permutation.PermutationType == PermutationTypes.Absolute)
            {
                int[] numbers = new int[move.Index2 - move.Index1 + 1];
                for (int i = 0; i < numbers.Length; i++)
                {
                    numbers[i] = permutation[i + move.Index1];
                }
                return(new TranslocationMoveAbsoluteAttribute(numbers, move.Index1, move.Index3, baseQuality));;
            }
            else
            {
                if (move.Index3 > move.Index1)
                {
                    return(new TranslocationMoveRelativeAttribute(permutation.GetCircular(move.Index1 - 1),
                                                                  permutation[move.Index1],
                                                                  permutation[move.Index2],
                                                                  permutation.GetCircular(move.Index2 + 1),
                                                                  permutation.GetCircular(move.Index3 + move.Index2 - move.Index1),
                                                                  permutation.GetCircular(move.Index3 + move.Index2 - move.Index1 + 1),
                                                                  baseQuality));
                }
                else
                {
                    return(new TranslocationMoveRelativeAttribute(permutation.GetCircular(move.Index1 - 1),
                                                                  permutation[move.Index1],
                                                                  permutation[move.Index2],
                                                                  permutation.GetCircular(move.Index2 + 1),
                                                                  permutation.GetCircular(move.Index3 - 1),
                                                                  permutation.GetCircular(move.Index3),
                                                                  baseQuality));
                }
            }
        }
    public static TranslocationMove[] Apply(Permutation permutation, IRandom random, int sampleSize) {
      int length = permutation.Length;
      if (length == 1) throw new ArgumentException("ExhaustiveSingleInsertionMoveGenerator: There cannot be an insertion move given a permutation of length 1.", "permutation");
      TranslocationMove[] moves = new TranslocationMove[sampleSize];
      int count = 0;
      HashSet<int> usedIndices = new HashSet<int>();
      while (count < sampleSize) {

        int index = random.Next(length);

        if (usedIndices.Count != length)
          while (usedIndices.Contains(index))
            index = random.Next(length);
        usedIndices.Add(index);

        if (permutation.PermutationType == PermutationTypes.Absolute) {
          for (int j = 1; j <= length - 1; j++) {
            moves[count++] = new TranslocationMove(index, index, (index + j) % length);
            if (count == sampleSize) break;
          }
        } else {
          if (length > 2) {
            for (int j = 1; j < length - 1; j++) {
              int insertPoint = (index + j) % length;
              if (index + j >= length) insertPoint++;
              moves[count++] = new TranslocationMove(index, index, insertPoint);
              if (count == sampleSize) break;
            }
          } else { // doesn't make sense, but just create a dummy move to not crash the algorithms
            moves = new TranslocationMove[1];
            moves[0] = new TranslocationMove(0, 0, 1);
            count = sampleSize;
          }
        }
      }
      return moves;
    }
        public static TranslocationMove[] Apply(Permutation permutation, IRandom random, int sampleSize)
        {
            int length = permutation.Length;

            if (length == 1)
            {
                throw new ArgumentException("ExhaustiveSingleInsertionMoveGenerator: There cannot be an insertion move given a permutation of length 1.", "permutation");
            }
            TranslocationMove[] moves = new TranslocationMove[sampleSize];
            int           count       = 0;
            HashSet <int> usedIndices = new HashSet <int>();

            while (count < sampleSize)
            {
                int index = random.Next(length);

                if (usedIndices.Count != length)
                {
                    while (usedIndices.Contains(index))
                    {
                        index = random.Next(length);
                    }
                }
                usedIndices.Add(index);

                if (permutation.PermutationType == PermutationTypes.Absolute)
                {
                    for (int j = 1; j <= length - 1; j++)
                    {
                        moves[count++] = new TranslocationMove(index, index, (index + j) % length);
                        if (count == sampleSize)
                        {
                            break;
                        }
                    }
                }
                else
                {
                    if (length > 2)
                    {
                        for (int j = 1; j < length - 1; j++)
                        {
                            int insertPoint = (index + j) % length;
                            if (index + j >= length)
                            {
                                insertPoint++;
                            }
                            moves[count++] = new TranslocationMove(index, index, insertPoint);
                            if (count == sampleSize)
                            {
                                break;
                            }
                        }
                    }
                    else // doesn't make sense, but just create a dummy move to not crash the algorithms
                    {
                        moves    = new TranslocationMove[1];
                        moves[0] = new TranslocationMove(0, 0, 1);
                        count    = sampleSize;
                    }
                }
            }
            return(moves);
        }
Пример #10
0
        public override IOperation Apply()
        {
            ItemList <IItem>  tabuList    = TabuListParameter.ActualValue;
            TranslocationMove move        = TranslocationMoveParameter.ActualValue;
            Permutation       permutation = PermutationParameter.ActualValue;
            int    length        = permutation.Length;
            double moveQuality   = MoveQualityParameter.ActualValue.Value;
            bool   maximization  = MaximizationParameter.ActualValue.Value;
            bool   useAspiration = UseAspirationCriterion.Value;
            bool   isTabu        = false;

            if (permutation.PermutationType == PermutationTypes.Absolute)
            {
                int   count   = move.Index2 - move.Index1 + 1;
                int[] numbers = new int[count];
                for (int i = move.Index1; i <= move.Index2; i++)
                {
                    numbers[i - move.Index1] = permutation[i];
                }

                foreach (IItem tabuMove in tabuList)
                {
                    TranslocationMoveAbsoluteAttribute attribute = (tabuMove as TranslocationMoveAbsoluteAttribute);
                    if (attribute != null)
                    {
                        if (!useAspiration ||
                            maximization && moveQuality <= attribute.MoveQuality ||
                            !maximization && moveQuality >= attribute.MoveQuality) // if the move quality is improving beyond what was recorded when the move in the tabu list was recorded the move is regarded as okay

                        {
                            for (int i = 0; i < count; i++)
                            {
                                for (int j = 0; j < attribute.Number.Length; j++)
                                {
                                    if (attribute.Number[j] == numbers[i])
                                    {
                                        isTabu = true;
                                        break;
                                    }
                                }
                                if (isTabu)
                                {
                                    break;
                                }
                            }
                        }
                    }
                    if (isTabu)
                    {
                        break;
                    }
                }
            }
            else
            {
                int E1S = permutation.GetCircular(move.Index1 - 1);
                int E1T = permutation[move.Index1];
                int E2S = permutation[move.Index2];
                int E2T = permutation.GetCircular(move.Index2 + 1);
                int E3S, E3T;
                if (move.Index3 > move.Index1)
                {
                    E3S = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1);
                    E3T = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1 + 1);
                }
                else
                {
                    E3S = permutation.GetCircular(move.Index3 - 1);
                    E3T = permutation[move.Index3];
                }
                foreach (IItem tabuMove in tabuList)
                {
                    TranslocationMoveRelativeAttribute attribute = (tabuMove as TranslocationMoveRelativeAttribute);
                    if (attribute != null)
                    {
                        if (!useAspiration ||
                            maximization && moveQuality <= attribute.MoveQuality ||
                            !maximization && moveQuality >= attribute.MoveQuality)
                        {
                            if (permutation.PermutationType == PermutationTypes.RelativeUndirected)
                            {
                                if (// if previously added Edge3Source-Edge1Target is deleted
                                    attribute.Edge3Source == E1S && attribute.Edge1Target == E1T || attribute.Edge3Source == E1T && attribute.Edge1Target == E1S ||
                                    attribute.Edge3Source == E2S && attribute.Edge1Target == E2T || attribute.Edge3Source == E2T && attribute.Edge1Target == E2S ||
                                    attribute.Edge3Source == E3S && attribute.Edge1Target == E3T || attribute.Edge3Source == E3T && attribute.Edge1Target == E3S
                                    // if previously added Edge2Source-Edge3Target is deleted
                                    || attribute.Edge2Source == E1S && attribute.Edge3Target == E1T || attribute.Edge2Source == E1T && attribute.Edge3Target == E1S ||
                                    attribute.Edge2Source == E2S && attribute.Edge3Target == E2T || attribute.Edge2Source == E2T && attribute.Edge3Target == E2S ||
                                    attribute.Edge2Source == E3S && attribute.Edge3Target == E3T || attribute.Edge2Source == E3T && attribute.Edge3Target == E3S
                                    // if previously added Edge1Source-Edge2Target is deleted
                                    || attribute.Edge1Source == E1S && attribute.Edge2Target == E1T || attribute.Edge1Source == E1T && attribute.Edge2Target == E1S ||
                                    attribute.Edge1Source == E2S && attribute.Edge2Target == E2T || attribute.Edge1Source == E2T && attribute.Edge2Target == E2S ||
                                    attribute.Edge1Source == E3S && attribute.Edge2Target == E3T || attribute.Edge1Source == E3T && attribute.Edge2Target == E3S)
                                {
                                    isTabu = true;
                                    break;
                                }
                            }
                            else
                            {
                                if (// if previously added Edge3Source-Edge1Target is deleted
                                    attribute.Edge3Source == E1S && attribute.Edge1Target == E1T ||
                                    attribute.Edge3Source == E2S && attribute.Edge1Target == E2T ||
                                    attribute.Edge3Source == E3S && attribute.Edge1Target == E3T
                                    // if previously added Edge2Source-Edge3Target is deleted
                                    || attribute.Edge2Source == E1S && attribute.Edge3Target == E1T ||
                                    attribute.Edge2Source == E2S && attribute.Edge3Target == E2T ||
                                    attribute.Edge2Source == E3S && attribute.Edge3Target == E3T
                                    // if previously added Edge1Source-Edge2Target is deleted
                                    || attribute.Edge1Source == E1S && attribute.Edge2Target == E1T ||
                                    attribute.Edge1Source == E2S && attribute.Edge2Target == E2T ||
                                    attribute.Edge1Source == E3S && attribute.Edge2Target == E3T)
                                {
                                    isTabu = true;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            MoveTabuParameter.ActualValue = new BoolValue(isTabu);
            return(base.Apply());
        }
Пример #11
0
 protected TranslocationMove(TranslocationMove original, Cloner cloner) : base(original, cloner)
 {
 }
Пример #12
0
 protected TranslocationMove(TranslocationMove original, Cloner cloner) : base(original, cloner) { }
    public static double EvaluateMove(Permutation tour, TranslocationMove move, Func<int, int, double> distance, ItemList<BoolArray> realizations) {
      var afterMove = (Permutation)tour.Clone();
      TranslocationManipulator.Apply(afterMove, move.Index1, move.Index1, move.Index3);
      double moveQuality = 0;
      var edges = new int[12];
      var indices = new int[12];
      edges[0] = tour.GetCircular(move.Index1 - 1);
      indices[0] = DecreaseCircularIndex(tour.Length, move.Index1);
      edges[1] = tour[move.Index1];
      indices[1] = move.Index1;
      edges[2] = tour[move.Index1];
      indices[2] = move.Index1;
      edges[3] = tour.GetCircular(move.Index1 + 1);
      indices[3] = IncreaseCircularIndex(tour.Length, move.Index1);

      edges[6] = afterMove.GetCircular(move.Index3 - 1);
      indices[6] = DecreaseCircularIndex(afterMove.Length, move.Index3);
      edges[7] = afterMove[move.Index3];
      indices[7] = move.Index3;
      edges[8] = afterMove[move.Index3];
      indices[8] = move.Index3;
      edges[9] = afterMove.GetCircular(move.Index3 + 1);
      indices[9] = IncreaseCircularIndex(afterMove.Length, move.Index3);

      if (move.Index3 > move.Index1) {
        edges[4] = tour[move.Index3];
        indices[4] = move.Index3;
        edges[5] = tour.GetCircular(move.Index3 + 1);
        indices[5] = indices[9];
        edges[10] = afterMove.GetCircular(move.Index1 - 1);
        indices[10] = indices[0];
        edges[11] = afterMove[move.Index1];
        indices[11] = move.Index1;
      } else {
        edges[4] = tour.GetCircular(move.Index3 - 1);
        indices[4] = indices[6];
        edges[5] = tour[move.Index3];
        indices[5] = move.Index3;
        edges[10] = afterMove[move.Index1];
        indices[10] = move.Index1;
        edges[11] = afterMove.GetCircular(move.Index1 + 1);
        indices[11] = indices[3];
      }
      int[] aPosteriori = new int[12];
      foreach (var realization in realizations) {
        for (int i = 0; i < edges.Length; i++) {
          Permutation tempPermutation;
          if (i < 6) {
            tempPermutation = tour;
          } else {
            tempPermutation = afterMove;
          }
          if (realization[edges[i]]) {
            aPosteriori[i] = edges[i];
          } else {
            int j = 1;
            if (i % 2 == 0) {
              // find nearest predecessor in realization if source edge
              while (!realization[tempPermutation.GetCircular(indices[i] - j)]) {
                j++;
              }
              aPosteriori[i] = tempPermutation.GetCircular(indices[i] - j);
            } else {
              // find nearest successor in realization if target edge
              while (!realization[tempPermutation.GetCircular(indices[i] + j)]) {
                j++;
              }
              aPosteriori[i] = tempPermutation.GetCircular(indices[i] + j);
            }
          }
        }
        if (!(aPosteriori[0] == aPosteriori[2] && aPosteriori[1] == aPosteriori[3]) &&
          !(aPosteriori[0] == aPosteriori[4] && aPosteriori[1] == aPosteriori[5]) &&
          !(aPosteriori[2] == aPosteriori[4] && aPosteriori[3] == aPosteriori[5])) {
          // compute cost difference between the two a posteriori solutions
          moveQuality = moveQuality + distance(aPosteriori[6], aPosteriori[7]) + distance(aPosteriori[8], aPosteriori[9]) + distance(aPosteriori[10], aPosteriori[11]);
          moveQuality = moveQuality - distance(aPosteriori[0], aPosteriori[1]) - distance(aPosteriori[2], aPosteriori[3]) - distance(aPosteriori[4], aPosteriori[5]);
        }
        Array.Clear(aPosteriori, 0, aPosteriori.Length);
      }
      // return average of cost differences
      return moveQuality / realizations.Count;
    }
 public static double EvaluateMove(Permutation tour, TranslocationMove move, Func<int, int, double> distance, DoubleArray probabilities) {
   var afterMove = (Permutation)tour.Clone();
   TranslocationManipulator.Apply(afterMove, move.Index1, move.Index1, move.Index3);
   return AnalyticalProbabilisticTravelingSalesmanProblem.Evaluate(afterMove, distance, probabilities);
 }