private static bool EvaluateRelativeTabuState(ItemList <IItem> tabuList, Swap2Move move, Permutation permutation, double moveQuality, bool maximization, bool useAspiration)
        {
            bool isTabu = false;
            StandardEdgeEqualityComparer eq = new StandardEdgeEqualityComparer();
            bool        bidirectional       = permutation.PermutationType == PermutationTypes.RelativeUndirected;
            List <Edge> deleted             = new List <Edge>();

            deleted.Add(new Edge(permutation.GetCircular(move.Index1 - 1), permutation[move.Index1], bidirectional));
            deleted.Add(new Edge(permutation[move.Index1], permutation.GetCircular(move.Index1 + 1), bidirectional));
            deleted.Add(new Edge(permutation.GetCircular(move.Index2 - 1), permutation[move.Index2], bidirectional));
            deleted.Add(new Edge(permutation[move.Index2], permutation.GetCircular(move.Index2 + 1), bidirectional));
            List <Edge> added = new List <Edge>();

            added.Add(new Edge(permutation.GetCircular(move.Index1 - 1), permutation[move.Index2], bidirectional));
            added.Add(new Edge(permutation[move.Index2], permutation.GetCircular(move.Index1 + 1), bidirectional));
            added.Add(new Edge(permutation.GetCircular(move.Index2 - 1), permutation[move.Index1], bidirectional));
            added.Add(new Edge(permutation[move.Index1], permutation.GetCircular(move.Index2 + 1), bidirectional));

            foreach (IItem tabuMove in tabuList)
            {
                Swap2MoveRelativeAttribute relAttrib = (tabuMove as Swap2MoveRelativeAttribute);
                if (relAttrib != null &&
                    (!useAspiration ||
                     maximization && moveQuality <= relAttrib.MoveQuality ||
                     !maximization && moveQuality >= relAttrib.MoveQuality))
                {
                    for (int i = 0; i < relAttrib.AddedEdges.Count; i++)
                    {
                        isTabu = eq.Equals(relAttrib.AddedEdges[i], deleted[0]) ||
                                 eq.Equals(relAttrib.AddedEdges[i], deleted[1]) ||
                                 eq.Equals(relAttrib.AddedEdges[i], deleted[2]) ||
                                 eq.Equals(relAttrib.AddedEdges[i], deleted[3]);
                        if (isTabu)
                        {
                            break;
                        }
                    }
                    if (isTabu)
                    {
                        break;
                    }
                    for (int i = 0; i < relAttrib.DeletedEdges.Count; i++)
                    {
                        isTabu = eq.Equals(relAttrib.DeletedEdges[i], added[0]) ||
                                 eq.Equals(relAttrib.DeletedEdges[i], added[1]) ||
                                 eq.Equals(relAttrib.DeletedEdges[i], added[2]) ||
                                 eq.Equals(relAttrib.DeletedEdges[i], added[3]);
                        if (isTabu)
                        {
                            break;
                        }
                    }
                }
                if (isTabu)
                {
                    break;
                }
            }
            return(isTabu);
        }
        private bool EvaluateAbsoluteTabuState(ItemList <IItem> tabuList, Swap2Move move, Permutation permutation, double moveQuality, bool maximization, bool useAspiration)
        {
            bool isTabu = false;

            foreach (IItem tabuMove in tabuList)
            {
                Swap2MoveAbsoluteAttribute attrib = (tabuMove as Swap2MoveAbsoluteAttribute);
                if (attrib != null &&
                    (!useAspiration ||
                     maximization && moveQuality <= attrib.MoveQuality ||
                     !maximization && moveQuality >= attrib.MoveQuality))
                {
                    int i1 = move.Index1;
                    int n1 = permutation[move.Index1];
                    int i2 = move.Index2;
                    int n2 = permutation[move.Index2];
                    if ((attrib.Index1 == i1 || attrib.Index1 == i2) && (attrib.Number1 == n1 || attrib.Number1 == n2) ||
                        (attrib.Index2 == i2 || attrib.Index2 == i1) && (attrib.Number2 == n2 || attrib.Number2 == n1))
                    {
                        isTabu = true;
                    }
                }
                if (isTabu)
                {
                    break;
                }
            }
            return(isTabu);
        }
Esempio n. 3
0
        protected override IItem GetTabuAttribute(bool maximization, double quality, double moveQuality)
        {
            Swap2Move   move        = Swap2MoveParameter.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)
            {
                return(new Swap2MoveAbsoluteAttribute(move.Index1, permutation[move.Index1], move.Index2, permutation[move.Index2], baseQuality));
            }
            else
            {
                Swap2MoveRelativeAttribute attrib = new Swap2MoveRelativeAttribute(baseQuality);
                bool bidirectional = permutation.PermutationType == PermutationTypes.RelativeUndirected;
                attrib.DeletedEdges.Add(new Edge(permutation.GetCircular(move.Index1 - 1), permutation[move.Index1], bidirectional));
                attrib.DeletedEdges.Add(new Edge(permutation[move.Index1], permutation.GetCircular(move.Index1 + 1), bidirectional));
                attrib.DeletedEdges.Add(new Edge(permutation.GetCircular(move.Index2 - 1), permutation[move.Index2], bidirectional));
                attrib.DeletedEdges.Add(new Edge(permutation[move.Index2], permutation.GetCircular(move.Index2 + 1), bidirectional));
                attrib.AddedEdges.Add(new Edge(permutation.GetCircular(move.Index1 - 1), permutation[move.Index2], bidirectional));
                attrib.AddedEdges.Add(new Edge(permutation[move.Index2], permutation.GetCircular(move.Index1 + 1), bidirectional));
                attrib.AddedEdges.Add(new Edge(permutation.GetCircular(move.Index2 - 1), permutation[move.Index1], bidirectional));
                attrib.AddedEdges.Add(new Edge(permutation[move.Index1], permutation.GetCircular(move.Index2 + 1), bidirectional));
                return(attrib);
            }
        }
 public static Swap2Move[] Apply(Permutation permutation, IRandom random, int sampleSize) {
   int length = permutation.Length;
   Swap2Move[] moves = new Swap2Move[sampleSize];
   for (int i = 0; i < sampleSize; i++) {
     moves[i] = StochasticSwap2SingleMoveGenerator.Apply(permutation, random);
   }
   return moves;
 }
 public static Swap2Move[] Apply(Permutation permutation) {
   int length = permutation.Length;
   int totalMoves = (length) * (length - 1) / 2;
   Swap2Move[] moves = new Swap2Move[totalMoves];
   int count = 0;
   foreach (Swap2Move move in Generate(permutation)) {
     moves[count++] = move;
   }
   return moves;
 }
        public static Swap2Move[] Apply(Permutation permutation, IRandom random, int sampleSize)
        {
            int length = permutation.Length;

            Swap2Move[] moves = new Swap2Move[sampleSize];
            for (int i = 0; i < sampleSize; i++)
            {
                moves[i] = StochasticSwap2SingleMoveGenerator.Apply(permutation, random);
            }
            return(moves);
        }
Esempio n. 7
0
        public override IOperation Apply()
        {
            Swap2Move   move        = Swap2MoveParameter.ActualValue;
            Permutation permutation = PermutationParameter.ActualValue;
            DoubleValue moveQuality = MoveQualityParameter.ActualValue;
            DoubleValue quality     = QualityParameter.ActualValue;

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

            return(base.Apply());
        }
        public static Swap2Move[] Apply(Permutation permutation)
        {
            int length     = permutation.Length;
            int totalMoves = (length) * (length - 1) / 2;

            Swap2Move[] moves = new Swap2Move[totalMoves];
            int         count = 0;

            foreach (Swap2Move move in Generate(permutation))
            {
                moves[count++] = move;
            }
            return(moves);
        }
        public override IOperation Apply()
        {
            ItemList <IItem> tabuList    = TabuListParameter.ActualValue;
            Swap2Move        move        = Swap2MoveParameter.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)
            {
                isTabu = EvaluateRelativeTabuState(tabuList, move, permutation, moveQuality, maximization, useAspiration);
            }
            else
            {
                isTabu = EvaluateAbsoluteTabuState(tabuList, move, permutation, moveQuality, maximization, useAspiration);
            }

            MoveTabuParameter.ActualValue = new BoolValue(isTabu);
            return(base.Apply());
        }
    /// <summary>
    /// Calculates the quality of the move <paramref name="move"/> by evaluating the changes.
    /// The runtime complexity of this method is O(N) with N being the size of the permutation.
    /// </summary>
    /// <param name="assignment">The current permutation.</param>
    /// <param name="move">The move that is to be evaluated if it was applied to the current permutation.</param>
    /// <param name="weights">The weights matrix.</param>
    /// <param name="distances">The distances matrix.</param>
    /// <returns>The relative change in quality if <paramref name="move"/> was applied to <paramref name="assignment"/>.</returns>
    public static double Apply(Permutation assignment, Swap2Move move, DoubleMatrix weights, DoubleMatrix distances) {
      if (move.Index1 == move.Index2) return 0;
      double moveQuality = 0;
      int fac1 = move.Index1, fac2 = move.Index2;
      int loc1 = assignment[fac1], loc2 = assignment[fac2];

      for (int j = 0; j < assignment.Length; j++) {
        if (j == fac1) {
          moveQuality += weights[fac1, fac1] * (distances[loc2, loc2] - distances[loc1, loc1]);
          moveQuality += weights[fac1, fac2] * (distances[loc2, loc1] - distances[loc1, loc2]);
        } else if (j == fac2) {
          moveQuality += weights[fac2, fac2] * (distances[loc1, loc1] - distances[loc2, loc2]);
          moveQuality += weights[fac2, fac1] * (distances[loc1, loc2] - distances[loc2, loc1]);
        } else {
          int locJ = assignment[j];
          moveQuality += weights[fac1, j] * (distances[loc2, locJ] - distances[loc1, locJ]);
          moveQuality += weights[j, fac1] * (distances[locJ, loc2] - distances[locJ, loc1]);
          moveQuality += weights[fac2, j] * (distances[loc1, locJ] - distances[loc2, locJ]);
          moveQuality += weights[j, fac2] * (distances[locJ, loc1] - distances[locJ, loc2]);
        }
      }
      return moveQuality;
    }
 private bool EvaluateAbsoluteTabuState(ItemList<IItem> tabuList, Swap2Move move, Permutation permutation, double moveQuality, bool maximization, bool useAspiration) {
   bool isTabu = false;
   foreach (IItem tabuMove in tabuList) {
     Swap2MoveAbsoluteAttribute attrib = (tabuMove as Swap2MoveAbsoluteAttribute);
     if (attrib != null
       && (!useAspiration
           || maximization && moveQuality <= attrib.MoveQuality
           || !maximization && moveQuality >= attrib.MoveQuality)) {
       int i1 = move.Index1;
       int n1 = permutation[move.Index1];
       int i2 = move.Index2;
       int n2 = permutation[move.Index2];
       if ((attrib.Index1 == i1 || attrib.Index1 == i2) && (attrib.Number1 == n1 || attrib.Number1 == n2)
         || (attrib.Index2 == i2 || attrib.Index2 == i1) && (attrib.Number2 == n2 || attrib.Number2 == n1))
         isTabu = true;
     }
     if (isTabu) break;
   }
   return isTabu;
 }
    private static bool EvaluateRelativeTabuState(ItemList<IItem> tabuList, Swap2Move move, Permutation permutation, double moveQuality, bool maximization, bool useAspiration) {
      bool isTabu = false;
      StandardEdgeEqualityComparer eq = new StandardEdgeEqualityComparer();
      bool bidirectional = permutation.PermutationType == PermutationTypes.RelativeUndirected;
      List<Edge> added = new List<Edge>();
      added.Add(new Edge(permutation.GetCircular(move.Index1 - 1), permutation[move.Index2], bidirectional));
      added.Add(new Edge(permutation[move.Index2], permutation.GetCircular(move.Index1 + 1), bidirectional));
      added.Add(new Edge(permutation.GetCircular(move.Index2 - 1), permutation[move.Index1], bidirectional));
      added.Add(new Edge(permutation[move.Index1], permutation.GetCircular(move.Index2 + 1), bidirectional));

      foreach (IItem tabuMove in tabuList) {
        Swap2MoveRelativeAttribute relAttrib = (tabuMove as Swap2MoveRelativeAttribute);
        if (relAttrib != null
          && (!useAspiration
              || maximization && moveQuality <= relAttrib.MoveQuality
              || !maximization && moveQuality >= relAttrib.MoveQuality)) {
          for (int i = 0; i < relAttrib.DeletedEdges.Count; i++) {
            isTabu = eq.Equals(relAttrib.DeletedEdges[i], added[0])
                  || eq.Equals(relAttrib.DeletedEdges[i], added[1])
                  || eq.Equals(relAttrib.DeletedEdges[i], added[2])
                  || eq.Equals(relAttrib.DeletedEdges[i], added[3]);
            if (isTabu) break;
          }
        }
        if (isTabu) break;
      }
      return isTabu;
    }
Esempio n. 13
0
 protected Swap2Move(Swap2Move original, Cloner cloner) : base(original, cloner)
 {
 }
Esempio n. 14
0
 protected Swap2Move(Swap2Move original, Cloner cloner) : base(original, cloner) { }
    /// <summary>
    /// Is able to compute the move qualities faster O(1) in some cases if it knows the quality of
    /// performing the move <paramref name="move"/> previously. In other cases it performs a
    /// standard move quality calculation with runtime complexity O(N).
    /// </summary>
    /// <remarks>
    /// The number of cases that the calculation can be performed faster grows with N^2
    /// while the number of cases which require a larger recalculation grows linearly with N.
    /// Larger problem instances thus benefit from this faster method to a larger degree.
    /// </remarks>
    /// <param name="assignment">The current permutation.</param>
    /// <param name="move">The current move that is to be evaluated.</param>
    /// <param name="previousQuality">The quality of that move as evaluated for the previous permutation.</param>
    /// <param name="weights">The weigths matrix.</param>
    /// <param name="distances">The distances matrix.</param>
    /// <param name="lastMove">The move that was applied to transform the permutation from the previous to the current one.</param>
    /// <returns>The relative change in quality if <paramref name="move"/> was applied to <paramref name="assignment"/>.</returns>
    public static double Apply(Permutation assignment, Swap2Move move, double previousQuality,
      DoubleMatrix weights, DoubleMatrix distances, Swap2Move lastMove) {
      bool overlapsLastMove = move.Index1 == lastMove.Index1
                           || move.Index2 == lastMove.Index1
                           || move.Index1 == lastMove.Index2
                           || move.Index2 == lastMove.Index2;

      if (!overlapsLastMove) {
        int r = lastMove.Index1, u = move.Index1, s = lastMove.Index2, v = move.Index2;
        int pR = assignment[lastMove.Index1], pU = assignment[move.Index1], pS = assignment[lastMove.Index2], pV = assignment[move.Index2];

        return previousQuality
          + (weights[r, u] - weights[r, v] + weights[s, v] - weights[s, u])
            * (distances[pS, pU] - distances[pS, pV] + distances[pR, pV] - distances[pR, pU])
          + (weights[u, r] - weights[v, r] + weights[v, s] - weights[u, s])
            * (distances[pU, pS] - distances[pV, pS] + distances[pV, pR] - distances[pU, pR]);
      } else {
        return Apply(assignment, move, weights, distances);
      }
    }
Esempio n. 16
0
    public void Swap2MoveEvaluatorFastEvaluationTest() {

      for (int i = 0; i < 500; i++) {
        Swap2Move lastMove = new Swap2Move(random.Next(ProblemSize), random.Next(ProblemSize));
        Permutation prevAssignment = (Permutation)assignment.Clone();
        Swap2Manipulator.Apply(assignment, lastMove.Index1, lastMove.Index2);
        Permutation nextAssignment = (Permutation)assignment.Clone();
        Swap2Move currentMove = new Swap2Move(random.Next(ProblemSize), random.Next(ProblemSize));
        Swap2Manipulator.Apply(nextAssignment, currentMove.Index1, currentMove.Index2);

        double moveBefore = QAPSwap2MoveEvaluator.Apply(prevAssignment, currentMove, symmetricWeights, symmetricDistances);
        double moveAfter = QAPSwap2MoveEvaluator.Apply(assignment, currentMove,
                moveBefore, symmetricWeights, symmetricDistances, lastMove);
        double before = QAPEvaluator.Apply(assignment, symmetricWeights, symmetricDistances);
        double after = QAPEvaluator.Apply(nextAssignment, symmetricWeights, symmetricDistances);

        Assert.IsTrue(moveAfter.IsAlmost(after - before), "Failed on symmetric matrices: " + Environment.NewLine
          + "Quality changed from " + before + " to " + after + " (" + (after - before).ToString() + "), but move quality change was " + moveAfter + ".");

        moveBefore = QAPSwap2MoveEvaluator.Apply(prevAssignment, currentMove, asymmetricWeights, asymmetricDistances);
        moveAfter = QAPSwap2MoveEvaluator.Apply(assignment, currentMove,
                moveBefore, asymmetricWeights, asymmetricDistances, lastMove);
        before = QAPEvaluator.Apply(assignment, asymmetricWeights, asymmetricDistances);
        after = QAPEvaluator.Apply(nextAssignment, asymmetricWeights, asymmetricDistances);

        Assert.IsTrue(moveAfter.IsAlmost(after - before), "Failed on asymmetric matrices: " + Environment.NewLine
          + "Quality changed from " + before + " to " + after + " (" + (after - before).ToString() + "), but move quality change was " + moveAfter + ".");

        moveBefore = QAPSwap2MoveEvaluator.Apply(prevAssignment, currentMove, nonZeroDiagonalWeights, nonZeroDiagonalDistances);
        moveAfter = QAPSwap2MoveEvaluator.Apply(assignment, currentMove,
                moveBefore, nonZeroDiagonalWeights, nonZeroDiagonalDistances, lastMove);
        before = QAPEvaluator.Apply(assignment, nonZeroDiagonalWeights, nonZeroDiagonalDistances);
        after = QAPEvaluator.Apply(nextAssignment, nonZeroDiagonalWeights, nonZeroDiagonalDistances);

        Assert.IsTrue(moveAfter.IsAlmost(after - before), "Failed on non-zero diagonal matrices: " + Environment.NewLine
          + "Quality changed from " + before + " to " + after + " (" + (after - before).ToString() + "), but move quality change was " + moveAfter + ".");
      }
    }