Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PTSP/HeuristicLab.Problems.PTSP/3.3/MoveGenerators/Exhaustive25MoveGenerator.cs @ 12272

Last change on this file since 12272 was 12272, checked in by apolidur, 9 years ago

#2221: Adding 2.5-opt-EEs operators to PTSP

File size: 2.7 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using HeuristicLab.Common;
5using HeuristicLab.Core;
6using HeuristicLab.Optimization;
7using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
8using HeuristicLab.Encodings.PermutationEncoding;
9using HeuristicLab.Parameters;
10using HeuristicLab.Operators;
11
12namespace HeuristicLab.Problems.PTSP {
13  [Item("Exhaustive25MoveGenerator", "Generates all possible inversion and shift moves (2.5-opt) from a given permutation.")]
14  [StorableClass]
15  class Exhaustive25MoveGenerator : TwoPointFiveMoveGenerator, IExhaustiveMoveGenerator {
16    public override bool CanChangeName {
17      get { return false; }
18    }
19
20    [StorableConstructor]
21    protected Exhaustive25MoveGenerator(bool deserializing) : base(deserializing) { }
22    protected Exhaustive25MoveGenerator(Exhaustive25MoveGenerator original, Cloner cloner) : base(original, cloner) { }
23    public Exhaustive25MoveGenerator()
24      : base() {
25    }
26
27    public override IDeepCloneable Clone(Cloner cloner) {
28      return new Exhaustive25MoveGenerator(this, cloner);
29    }
30   
31    public static TwoPointFiveMove[] Apply(Permutation permutation) {
32      return Generate(permutation).ToArray();
33    }
34
35    public static IEnumerable<TwoPointFiveMove> Generate(Permutation permutation) {
36      int length = permutation.Length;
37      if (length == 1) throw new ArgumentException("Exhaustive25MoveGenerator: There cannot be a 2.5 move given a permutation of length 1.", "permutation");
38      int totalMoves = (length) * (length - 1) / 2;
39
40      if (permutation.PermutationType == PermutationTypes.RelativeUndirected) {
41        if (totalMoves - 3 > 0) {
42          for (int i = 0; i < length - 1; i++) {
43            for (int j = i + 1; j < length; j++) {
44              // doesn't make sense to inverse the whole permutation or the whole but one in case of relative undirected permutations
45              if (j - i >= length - 2) continue;
46              yield return new TwoPointFiveMove(i, j,true);
47              yield return new TwoPointFiveMove(i, j, false);
48            }
49          }
50        } else { // when length is 3 or less, there's actually no difference, but for the sake of not crashing the algorithm create a dummy move
51          yield return new TwoPointFiveMove(0, 1,true);
52        }
53      } else {
54        for (int i = 0; i < length - 1; i++)
55          for (int j = i + 1; j < length; j++) {
56            yield return new TwoPointFiveMove(i, j,true);
57            yield return new TwoPointFiveMove(i, j, false);
58          }
59      }
60    }
61
62    protected override TwoPointFiveMove[] GenerateMoves(Permutation permutation) {
63      return Apply(permutation);
64    }
65  }
66}
Note: See TracBrowser for help on using the repository browser.