Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
04/14/10 03:52:07 (14 years ago)
Author:
abeham
Message:

Updated Tabu search, permutation move operators, real vector move operators, binary vector move operators #840
Added a Tabu Search TSP workbench

Location:
trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt
Files:
1 deleted
4 edited
2 moved

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/ExhaustiveInversionMoveGenerator.cs

    r3233 r3340  
    3131    public static InversionMove[] Apply(Permutation permutation) {
    3232      int length = permutation.Length;
    33       int totalMoves = (length) * (length - 1) / 2; // - 3;
    34       InversionMove[] moves = new InversionMove[totalMoves];
     33      int totalMoves = (length) * (length - 1) / 2;
     34      InversionMove[] moves = null;
    3535      int count = 0;
    3636
    3737      if (permutation.PermutationType == PermutationTypes.RelativeUndirected) {
     38        moves = new InversionMove[totalMoves - 3];
    3839        for (int i = 0; i < length - 1; i++) {
    3940          for (int j = i + 1; j < length; j++) {
     
    4445        }
    4546      } else {
    46           for (int i = 0; i < length - 1; i++)
    47             for (int j = i + 1; j < length; j++) {
    48               moves[count++] = new InversionMove(i, j);
    49             }
     47        moves = new InversionMove[totalMoves];
     48        for (int i = 0; i < length - 1; i++)
     49          for (int j = i + 1; j < length; j++) {
     50            moves[count++] = new InversionMove(i, j);
     51          }
    5052      }
    5153      return moves;
  • trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveAbsoluteAttribute.cs

    r3233 r3340  
    2626  [Item("InversionMoveAbsoluteAttribute", "Specifies the tabu attributes for an inversion move (2-opt) on an absolute position permutation.")]
    2727  [StorableClass]
    28   public class InversionMoveAbsoluteAttribute : Item {
     28  public class InversionMoveAbsoluteAttribute : PermutationMoveAttribute {
    2929    [Storable]
    3030    public int Index1 { get; private set; }
     
    4242
    4343    public InversionMoveAbsoluteAttribute()
    44       : this(-1, -1, -1, -1) { }
     44      : this(-1, -1, -1, -1, -1) { }
    4545
    46     public InversionMoveAbsoluteAttribute(int index1, int number1, int index2, int number2)
    47       : base() {
     46    public InversionMoveAbsoluteAttribute(int index1, int number1, int index2, int number2, double moveQuality)
     47      : base(moveQuality) {
    4848      Index1 = index1;
    4949      Number1 = number1;
  • trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveHardTabuCriterion.cs

    r3307 r3340  
    2929
    3030namespace HeuristicLab.Encodings.PermutationEncoding {
    31   [Item("PreventRemovalInversionMoveTabuChecker", "Prevents deleting of previously added edges.")]
     31  [Item("InversionMoveHardTabuCriterion", @"For relative postion encoded permutations it prevents readding of previously deleted edges as well as deleting previously added edges.
     32  For absolute position encoded permutations it prevents moving a number if it was previously moved.
     33
     34If the aspiration condition is activated, a move will not be considered tabu against a move in the tabu list if it leads to a better solution than the quality recorded with the move in the tabu list.")]
    3235  [StorableClass]
    33   public class PreventRemovalInversionMoveTabuChecker : SingleSuccessorOperator, IPermutationInversionMoveOperator, ITabuChecker {
     36  public class InversionMoveHardTabuCriterion : SingleSuccessorOperator, IPermutationInversionMoveOperator, ITabuChecker {
    3437    public override bool CanChangeName {
    3538      get { return false; }
     
    4750      get { return (ILookupParameter<BoolValue>)Parameters["MoveTabu"]; }
    4851    }
    49     private ScopeParameter CurrentScopeParameter {
    50       get { return (ScopeParameter)Parameters["CurrentScope"]; }
     52    public IValueLookupParameter<BoolValue> MaximizationParameter {
     53      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
     54    }
     55    public ILookupParameter<DoubleValue> MoveQualityParameter {
     56      get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
     57    }
     58    public ValueParameter<BoolValue> UseAspirationCriterionParameter {
     59      get { return (ValueParameter<BoolValue>)Parameters["UseAspirationCriterion"]; }
    5160    }
    5261
    53     public PreventRemovalInversionMoveTabuChecker()
     62    public BoolValue UseAspirationCriterion {
     63      get { return UseAspirationCriterionParameter.Value; }
     64      set { UseAspirationCriterionParameter.Value = value; }
     65    }
     66
     67    public InversionMoveHardTabuCriterion()
    5468      : base() {
    5569      Parameters.Add(new LookupParameter<InversionMove>("InversionMove", "The move to evaluate."));
     
    5771      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
    5872      Parameters.Add(new LookupParameter<ItemList<IItem>>("TabuList", "The tabu list."));
    59       Parameters.Add(new ScopeParameter("CurrentScope", "The current scope."));
     73      Parameters.Add(new ValueParameter<BoolValue>("UseAspirationCriterion", "Whether to use the aspiration criterion or not.", new BoolValue(true)));
     74      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, else if it is a minimization problem."));
     75      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The quality of the current move."));
    6076    }
    6177
     
    6581      Permutation permutation = PermutationParameter.ActualValue;
    6682      int length = permutation.Length;
     83      double moveQuality = MoveQualityParameter.ActualValue.Value;
     84      bool maximization = MaximizationParameter.ActualValue.Value;
     85      bool useAspiration = UseAspirationCriterion.Value;
    6786      bool isTabu = false;
     87
    6888      foreach (IItem tabuMove in tabuList) {
    69         switch (permutation.PermutationType) {
    70           case PermutationTypes.RelativeUndirected: {
    71               int E1S = permutation.GetCircular(move.Index1 - 1);
    72               int E1T = permutation[move.Index1];
    73               int E2S = permutation[move.Index2];
    74               int E2T = permutation.GetCircular(move.Index2 + 1);
    75               InversionMoveRelativeAttribute relAttrib = (tabuMove as InversionMoveRelativeAttribute);
    76               if (relAttrib != null) {
    77                 if (relAttrib.Edge1Source == E1S && relAttrib.Edge2Source == E1T || relAttrib.Edge1Source == E1T && relAttrib.Edge2Source == E1S
    78                   || relAttrib.Edge1Source == E2S && relAttrib.Edge2Source == E2T || relAttrib.Edge1Source == E2T && relAttrib.Edge2Source == E2S
    79                   // if previously added Edge1Target-Edge2Target is deleted
    80                   || relAttrib.Edge1Target == E2S && relAttrib.Edge2Target == E2T || relAttrib.Edge1Target == E2T && relAttrib.Edge2Target == E2S
    81                   || relAttrib.Edge1Target == E1S && relAttrib.Edge2Target == E1T || relAttrib.Edge1Target == E1T && relAttrib.Edge2Target == E1S) {
    82                   isTabu = true;
     89        PermutationMoveAttribute attrib = (tabuMove as PermutationMoveAttribute);
     90        if (!useAspiration
     91          || maximization && moveQuality <= attrib.MoveQuality
     92          || !maximization && moveQuality >= attrib.MoveQuality) {
     93          switch (permutation.PermutationType) {
     94            case PermutationTypes.RelativeUndirected: {
     95                int E1S = permutation.GetCircular(move.Index1 - 1);
     96                int E1T = permutation[move.Index1];
     97                int E2S = permutation[move.Index2];
     98                int E2T = permutation.GetCircular(move.Index2 + 1);
     99                InversionMoveRelativeAttribute relAttrib = (attrib as InversionMoveRelativeAttribute);
     100                if (relAttrib != null) {
     101                  if (relAttrib.Edge1Source == E1S && relAttrib.Edge2Source == E1T || relAttrib.Edge1Source == E1T && relAttrib.Edge2Source == E1S
     102                    || relAttrib.Edge1Source == E2S && relAttrib.Edge2Source == E2T || relAttrib.Edge1Source == E2T && relAttrib.Edge2Source == E2S
     103                    // if previously added Edge1Target-Edge2Target is deleted
     104                    || relAttrib.Edge1Target == E2S && relAttrib.Edge2Target == E2T || relAttrib.Edge1Target == E2T && relAttrib.Edge2Target == E2S
     105                    || relAttrib.Edge1Target == E1S && relAttrib.Edge2Target == E1T || relAttrib.Edge1Target == E1T && relAttrib.Edge2Target == E1S) {
     106                    isTabu = true;
     107                  }
    83108                }
    84109              }
    85             }
    86             break;
    87           case PermutationTypes.RelativeDirected: {
    88               int E1S = permutation.GetCircular(move.Index1 - 1);
    89               int E1T = permutation[move.Index1];
    90               int E2S = permutation[move.Index2];
    91               int E2T = permutation.GetCircular(move.Index2 + 1);
    92               InversionMoveRelativeAttribute relAttrib = (tabuMove as InversionMoveRelativeAttribute);
    93               if (relAttrib != null) {
    94                 if (relAttrib.Edge1Source == E1S && relAttrib.Edge2Source == E1T
    95                   || relAttrib.Edge1Source == E2S && relAttrib.Edge2Source == E2T
    96                   // if previously added Edge1Target-Edge2Target is deleted
    97                   || relAttrib.Edge1Target == E2S && relAttrib.Edge2Target == E2T
    98                   || relAttrib.Edge1Target == E1S && relAttrib.Edge2Target == E1T) {
    99                   isTabu = true;
     110              break;
     111            case PermutationTypes.RelativeDirected: {
     112                int E1S = permutation.GetCircular(move.Index1 - 1);
     113                int E1T = permutation[move.Index1];
     114                int E2S = permutation[move.Index2];
     115                int E2T = permutation.GetCircular(move.Index2 + 1);
     116                InversionMoveRelativeAttribute relAttrib = (attrib as InversionMoveRelativeAttribute);
     117                if (relAttrib != null) {
     118                  if (relAttrib.Edge1Source == E1S && relAttrib.Edge2Source == E1T
     119                    || relAttrib.Edge1Source == E2S && relAttrib.Edge2Source == E2T
     120                    // if previously added Edge1Target-Edge2Target is deleted
     121                    || relAttrib.Edge1Target == E2S && relAttrib.Edge2Target == E2T
     122                    || relAttrib.Edge1Target == E1S && relAttrib.Edge2Target == E1T) {
     123                    isTabu = true;
     124                  }
    100125                }
    101126              }
    102             }
    103             break;
    104           case PermutationTypes.Absolute: {
    105               int i1 = move.Index1;
    106               int n1 = permutation[move.Index1];
    107               int i2 = move.Index2;
    108               int n2 = permutation[move.Index2];
    109               InversionMoveAbsoluteAttribute absAttrib = (tabuMove as InversionMoveAbsoluteAttribute);
    110               if (absAttrib != null) {
    111                 if (absAttrib.Number1 == n1 || absAttrib.Number1 == n2
    112                   || absAttrib.Number2 == n2 || absAttrib.Number2 == n1)
    113                   isTabu = true;
     127              break;
     128            case PermutationTypes.Absolute: {
     129                int i1 = move.Index1;
     130                int n1 = permutation[move.Index1];
     131                int i2 = move.Index2;
     132                int n2 = permutation[move.Index2];
     133                InversionMoveAbsoluteAttribute absAttrib = (attrib as InversionMoveAbsoluteAttribute);
     134                if (absAttrib != null) {
     135                  if (absAttrib.Number1 == n1 || absAttrib.Number1 == n2
     136                    || absAttrib.Number2 == n2 || absAttrib.Number2 == n1)
     137                    isTabu = true;
    114138
     139                }
    115140              }
    116             }
    117             break;
    118           default: {
    119               throw new InvalidOperationException(Name + ": Unknown permutation type.");
    120             }
     141              break;
     142            default: {
     143                throw new InvalidOperationException(Name + ": Unknown permutation type.");
     144              }
     145          }
    121146        }
    122147        if (isTabu) break;
  • trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveRelativeAttribute.cs

    r3233 r3340  
    2626  [Item("InversionMoveRelativeAttribute", "Specifies the tabu attributes for an inversion move (2-opt) on a relative position permutation.")]
    2727  [StorableClass]
    28   public class InversionMoveRelativeAttribute : Item {
     28  public class InversionMoveRelativeAttribute : PermutationMoveAttribute {
    2929    [Storable]
    3030    public int Edge1Source { get; private set; }
     
    4242
    4343    public InversionMoveRelativeAttribute()
    44       : this(-1, -1, -1, -1) { }
     44      : this(-1, -1, -1, -1, -1) { }
    4545
    46     public InversionMoveRelativeAttribute(int edge1Source, int edge1Target, int edge2Source, int edge2Target)
    47       : base() {
     46    public InversionMoveRelativeAttribute(int edge1Source, int edge1Target, int edge2Source, int edge2Target, double moveQuality)
     47      : base(moveQuality) {
    4848      Edge1Source = edge1Source;
    4949      Edge1Target = edge1Target;
  • trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveSoftTabuCriterion.cs

    r3307 r3340  
    2929
    3030namespace HeuristicLab.Encodings.PermutationEncoding {
    31   [Item("PreventReaddInversionMoveTabuChecker", "Prevents readding of previously deleted edges, but allows deleting previously added edges.")]
     31  [Item("InversionMoveSoftTabuCriterion", @"For relative postion encoded permutations it just prevents readding of previously deleted edges, but allows deleting previously added edges.
     32  For absolute position encoded permutations it prevents moving a number to a position it has previously occupied.
     33
     34If the aspiration condition is activated, a move will not be considered tabu against a move in the tabu list if it leads to a better solution than the quality recorded with the move in the tabu list.")]
    3235  [StorableClass]
    33   public class PreventReaddInversionMoveTabuChecker : SingleSuccessorOperator, IPermutationInversionMoveOperator, ITabuChecker {
     36  public class InversionMoveSoftTabuCriterion : SingleSuccessorOperator, IPermutationInversionMoveOperator, ITabuChecker {
    3437    public override bool CanChangeName {
    3538      get { return false; }
     
    4750      get { return (ILookupParameter<BoolValue>)Parameters["MoveTabu"]; }
    4851    }
    49     private ScopeParameter CurrentScopeParameter {
    50       get { return (ScopeParameter)Parameters["CurrentScope"]; }
     52    public IValueLookupParameter<BoolValue> MaximizationParameter {
     53      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
     54    }
     55    public ILookupParameter<DoubleValue> MoveQualityParameter {
     56      get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
     57    }
     58    public ValueParameter<BoolValue> UseAspirationCriterionParameter {
     59      get { return (ValueParameter<BoolValue>)Parameters["UseAspirationCriterion"]; }
    5160    }
    5261
    53     public PreventReaddInversionMoveTabuChecker()
     62    public BoolValue UseAspirationCriterion {
     63      get { return UseAspirationCriterionParameter.Value; }
     64      set { UseAspirationCriterionParameter.Value = value; }
     65    }
     66
     67    public InversionMoveSoftTabuCriterion()
    5468      : base() {
    5569      Parameters.Add(new LookupParameter<InversionMove>("InversionMove", "The move to evaluate."));
     
    5771      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
    5872      Parameters.Add(new LookupParameter<ItemList<IItem>>("TabuList", "The tabu list."));
    59       Parameters.Add(new ScopeParameter("CurrentScope", "The current scope."));
     73      Parameters.Add(new ValueParameter<BoolValue>("UseAspirationCriterion", "Whether to use the aspiration criterion or not.", new BoolValue(true)));
     74      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, else if it is a minimization problem."));
     75      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The quality of the current move."));
    6076    }
    6177
     
    6581      Permutation permutation = PermutationParameter.ActualValue;
    6682      int length = permutation.Length;
     83      double moveQuality = MoveQualityParameter.ActualValue.Value;
     84      bool maximization = MaximizationParameter.ActualValue.Value;
     85      bool useAspiration = UseAspirationCriterion.Value;
    6786      bool isTabu = false;
     87
    6888      foreach (IItem tabuMove in tabuList) {
    69         switch (permutation.PermutationType) {
    70           case PermutationTypes.RelativeUndirected: {
    71               int E1S = permutation.GetCircular(move.Index1 - 1);
    72               int E1T = permutation[move.Index1];
    73               int E2S = permutation[move.Index2];
    74               int E2T = permutation.GetCircular(move.Index2 + 1);
    75               InversionMoveRelativeAttribute relAttrib = (tabuMove as InversionMoveRelativeAttribute);
    76               if (relAttrib != null) {
    77                 // if previously deleted Edge1Source-Target is readded
    78                 if (relAttrib.Edge1Source == E1S && relAttrib.Edge1Target == E2S || relAttrib.Edge1Source == E2S && relAttrib.Edge1Target == E1S
    79                   || relAttrib.Edge1Source == E1T && relAttrib.Edge1Target == E2T || relAttrib.Edge1Source == E2T && relAttrib.Edge1Target == E1T
    80                   // if previously deleted Edge2Source-Target is readded
    81                   || relAttrib.Edge2Source == E1T && relAttrib.Edge2Target == E2T || relAttrib.Edge2Source == E2T && relAttrib.Edge2Target == E1T
    82                   || relAttrib.Edge2Source == E1S && relAttrib.Edge2Target == E2S || relAttrib.Edge2Source == E2S && relAttrib.Edge2Target == E1S) {
    83                   isTabu = true;
     89        PermutationMoveAttribute attrib = (tabuMove as PermutationMoveAttribute);
     90        if (!useAspiration
     91          || maximization && moveQuality <= attrib.MoveQuality
     92          || !maximization && moveQuality >= attrib.MoveQuality) {
     93          switch (permutation.PermutationType) {
     94            case PermutationTypes.RelativeUndirected: {
     95                int E1S = permutation.GetCircular(move.Index1 - 1);
     96                int E1T = permutation[move.Index1];
     97                int E2S = permutation[move.Index2];
     98                int E2T = permutation.GetCircular(move.Index2 + 1);
     99                InversionMoveRelativeAttribute relAttrib = (attrib as InversionMoveRelativeAttribute);
     100                if (relAttrib != null) {
     101                  // if previously deleted Edge1Source-Target is readded
     102                  if (relAttrib.Edge1Source == E1S && relAttrib.Edge1Target == E2S || relAttrib.Edge1Source == E2S && relAttrib.Edge1Target == E1S
     103                    || relAttrib.Edge1Source == E1T && relAttrib.Edge1Target == E2T || relAttrib.Edge1Source == E2T && relAttrib.Edge1Target == E1T
     104                    // if previously deleted Edge2Source-Target is readded
     105                    || relAttrib.Edge2Source == E1T && relAttrib.Edge2Target == E2T || relAttrib.Edge2Source == E2T && relAttrib.Edge2Target == E1T
     106                    || relAttrib.Edge2Source == E1S && relAttrib.Edge2Target == E2S || relAttrib.Edge2Source == E2S && relAttrib.Edge2Target == E1S) {
     107                    isTabu = true;
     108                  }
    84109                }
    85110              }
    86             }
    87             break;
    88           case PermutationTypes.RelativeDirected: {
    89               int E1S = permutation.GetCircular(move.Index1 - 1);
    90               int E1T = permutation[move.Index1];
    91               int E2S = permutation[move.Index2];
    92               int E2T = permutation.GetCircular(move.Index2 + 1);
    93               InversionMoveRelativeAttribute relAttrib = (tabuMove as InversionMoveRelativeAttribute);
    94               if (relAttrib != null) {
    95                 if (relAttrib.Edge1Source == E1S && relAttrib.Edge1Target == E2S
    96                   || relAttrib.Edge1Source == E1T && relAttrib.Edge1Target == E2T
    97                   // if previously deleted Edge2Source-Target is readded
    98                   || relAttrib.Edge2Source == E1T && relAttrib.Edge2Target == E2T
    99                   || relAttrib.Edge2Source == E1S && relAttrib.Edge2Target == E2S) {
    100                   isTabu = true;
     111              break;
     112            case PermutationTypes.RelativeDirected: {
     113                int E1S = permutation.GetCircular(move.Index1 - 1);
     114                int E1T = permutation[move.Index1];
     115                int E2S = permutation[move.Index2];
     116                int E2T = permutation.GetCircular(move.Index2 + 1);
     117                InversionMoveRelativeAttribute relAttrib = (attrib as InversionMoveRelativeAttribute);
     118                if (relAttrib != null) {
     119                  if (relAttrib.Edge1Source == E1S && relAttrib.Edge1Target == E2S
     120                    || relAttrib.Edge1Source == E1T && relAttrib.Edge1Target == E2T
     121                    // if previously deleted Edge2Source-Target is readded
     122                    || relAttrib.Edge2Source == E1T && relAttrib.Edge2Target == E2T
     123                    || relAttrib.Edge2Source == E1S && relAttrib.Edge2Target == E2S) {
     124                    isTabu = true;
     125                  }
    101126                }
    102127              }
    103             }
    104             break;
    105           case PermutationTypes.Absolute: {
    106               int i1 = move.Index1;
    107               int n1 = permutation[move.Index1];
    108               int i2 = move.Index2;
    109               int n2 = permutation[move.Index2];
    110               InversionMoveAbsoluteAttribute absAttrib = (tabuMove as InversionMoveAbsoluteAttribute);
    111               if (absAttrib != null) {
    112                 if ((absAttrib.Index1 == i1 || absAttrib.Index1 == i2) && (absAttrib.Number1 == n1 || absAttrib.Number1 == n2)
    113                   || (absAttrib.Index2 == i2 || absAttrib.Index2 == i1) && (absAttrib.Number2 == n2 || absAttrib.Number2 == n1))
    114                   isTabu = true;
     128              break;
     129            case PermutationTypes.Absolute: {
     130                int i1 = move.Index1;
     131                int n1 = permutation[move.Index1];
     132                int i2 = move.Index2;
     133                int n2 = permutation[move.Index2];
     134                InversionMoveAbsoluteAttribute absAttrib = (attrib as InversionMoveAbsoluteAttribute);
     135                if (absAttrib != null) {
     136                  if ((absAttrib.Index1 == i1 || absAttrib.Index1 == i2) && (absAttrib.Number1 == n1 || absAttrib.Number1 == n2)
     137                    || (absAttrib.Index2 == i2 || absAttrib.Index2 == i1) && (absAttrib.Number2 == n2 || absAttrib.Number2 == n1))
     138                    isTabu = true;
    115139
     140                }
    116141              }
    117             }
    118             break;
    119           default: {
    120               throw new InvalidOperationException(Name + ": Unknown permutation type.");
    121             }
     142              break;
     143            default: {
     144                throw new InvalidOperationException(Name + ": Unknown permutation type.");
     145              }
     146          }
    122147        }
    123148        if (isTabu) break;
  • trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveTabuMaker.cs

    r3233 r3340  
    2929
    3030namespace HeuristicLab.Encodings.PermutationEncoding {
    31   [Item("InversionMoveTabuMaker", "Declares a given inversion move (2-opt) as tabu, by adding its attributes to the tabu list.")]
     31  [Item("InversionMoveTabuMaker", "Declares a given inversion move (2-opt) as tabu, by adding its attributes to the tabu list and also store the solution quality or the move quality (whichever is better).")]
    3232  [StorableClass]
    3333  public class InversionMoveTabuMaker : TabuMaker, IPermutationInversionMoveOperator {
     
    4848    }
    4949
    50     protected override IItem GetTabuAttribute() {
     50    protected override IItem GetTabuAttribute(bool maximization, double quality, double moveQuality) {
    5151      InversionMove move = InversionMoveParameter.ActualValue;
    5252      Permutation permutation = PermutationParameter.ActualValue;
     53      double baseQuality = moveQuality;
     54      if (maximization && quality > moveQuality || !maximization && quality < moveQuality) baseQuality = quality; // we make an uphill move, the lower bound is the solution quality
    5355      if (permutation.PermutationType == PermutationTypes.Absolute)
    54         return new InversionMoveAbsoluteAttribute(move.Index1, permutation[move.Index1], move.Index2, permutation[move.Index2]);
     56        return new InversionMoveAbsoluteAttribute(move.Index1, permutation[move.Index1], move.Index2, permutation[move.Index2], baseQuality);
    5557      else
    5658        return new InversionMoveRelativeAttribute(permutation.GetCircular(move.Index1 - 1),
    5759          permutation[move.Index1],
    5860          permutation[move.Index2],
    59           permutation.GetCircular(move.Index2 + 1));
     61          permutation.GetCircular(move.Index2 + 1),
     62          baseQuality);
    6063    }
    6164  }
Note: See TracChangeset for help on using the changeset viewer.