protected InversionMoveAbsoluteAttribute(InversionMoveAbsoluteAttribute original, Cloner cloner)
   : base(original, cloner) {
   this.Index1 = original.Index1;
   this.Number1 = original.Number1;
   this.Index2 = original.Index2;
   this.Number2 = original.Number2;
 }
 protected InversionMoveAbsoluteAttribute(InversionMoveAbsoluteAttribute original, Cloner cloner)
     : base(original, cloner)
 {
     this.Index1  = original.Index1;
     this.Number1 = original.Number1;
     this.Index2  = original.Index2;
     this.Number2 = original.Number2;
 }
        public override IOperation Apply()
        {
            ItemList <IItem> tabuList    = TabuListParameter.ActualValue;
            InversionMove    move        = InversionMoveParameter.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;

            foreach (IItem tabuMove in tabuList)
            {
                PermutationMoveAttribute attrib = (tabuMove as PermutationMoveAttribute);
                if (!useAspiration ||
                    maximization && moveQuality <= attrib.MoveQuality ||
                    !maximization && moveQuality >= attrib.MoveQuality)
                {
                    switch (permutation.PermutationType)
                    {
                    case PermutationTypes.RelativeUndirected: {
                        int E1S = permutation.GetCircular(move.Index1 - 1);
                        int E1T = permutation[move.Index1];
                        int E2S = permutation[move.Index2];
                        int E2T = permutation.GetCircular(move.Index2 + 1);
                        InversionMoveRelativeAttribute relAttrib = (attrib as InversionMoveRelativeAttribute);
                        if (relAttrib != null)
                        {
                            if (relAttrib.Edge1Source == E1S && relAttrib.Edge2Source == E1T || relAttrib.Edge1Source == E1T && relAttrib.Edge2Source == E1S ||
                                relAttrib.Edge1Source == E2S && relAttrib.Edge2Source == E2T || relAttrib.Edge1Source == E2T && relAttrib.Edge2Source == E2S
                                // if previously added Edge1Target-Edge2Target is deleted
                                || relAttrib.Edge1Target == E2S && relAttrib.Edge2Target == E2T || relAttrib.Edge1Target == E2T && relAttrib.Edge2Target == E2S ||
                                relAttrib.Edge1Target == E1S && relAttrib.Edge2Target == E1T || relAttrib.Edge1Target == E1T && relAttrib.Edge2Target == E1S)
                            {
                                isTabu = true;
                            }
                        }
                    }
                    break;

                    case PermutationTypes.RelativeDirected: {
                        int E1S = permutation.GetCircular(move.Index1 - 1);
                        int E1T = permutation[move.Index1];
                        int E2S = permutation[move.Index2];
                        int E2T = permutation.GetCircular(move.Index2 + 1);
                        InversionMoveRelativeAttribute relAttrib = (attrib as InversionMoveRelativeAttribute);
                        if (relAttrib != null)
                        {
                            if (relAttrib.Edge1Source == E1S && relAttrib.Edge2Source == E1T ||
                                relAttrib.Edge1Source == E2S && relAttrib.Edge2Source == E2T
                                // if previously added Edge1Target-Edge2Target is deleted
                                || relAttrib.Edge1Target == E2S && relAttrib.Edge2Target == E2T ||
                                relAttrib.Edge1Target == E1S && relAttrib.Edge2Target == E1T)
                            {
                                isTabu = true;
                            }
                        }
                    }
                    break;

                    case PermutationTypes.Absolute: {
                        int i1 = move.Index1;
                        int n1 = permutation[move.Index1];
                        int i2 = move.Index2;
                        int n2 = permutation[move.Index2];
                        InversionMoveAbsoluteAttribute absAttrib = (attrib as InversionMoveAbsoluteAttribute);
                        if (absAttrib != null)
                        {
                            if (absAttrib.Number1 == n1 || absAttrib.Number1 == n2 ||
                                absAttrib.Number2 == n2 || absAttrib.Number2 == n1)
                            {
                                isTabu = true;
                            }
                        }
                    }
                    break;

                    default: {
                        throw new InvalidOperationException(Name + ": Unknown permutation type.");
                    }
                    }
                }
                if (isTabu)
                {
                    break;
                }
            }
            MoveTabuParameter.ActualValue = new BoolValue(isTabu);
            return(base.Apply());
        }