Free cookie consent management tool by TermsFeed Policy Generator

source: branches/FitnessLandscapeAnalysis/HeuristicLab.Analysis.FitnessLandscape/Exhaustive/PermutationEnumerationManipulator.cs @ 7590

Last change on this file since 7590 was 7128, checked in by epitzer, 13 years ago

#1696 Integrate fitness landscape analysis plugins from Heureka! repository.

File size: 4.2 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using HeuristicLab.Common;
24using HeuristicLab.Core;
25using HeuristicLab.Data;
26using HeuristicLab.Encodings.PermutationEncoding;
27using HeuristicLab.Parameters;
28using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
29
30namespace HeuristicLab.Analysis.FitnessLandscape {
31
32  [Item("PermutationEnumerationManipulator", "An operator that generates the next permutation based on lexicographic ordering.")]
33  [StorableClass]
34  public class PermutationEnumerationManipulator : PermutationManipulator {
35
36    public ValueLookupParameter<IntValue> NrOfStepsParameter {
37      get { return (ValueLookupParameter<IntValue>)Parameters["NrOfSteps"]; }
38    }
39
40    [StorableConstructor]
41    protected PermutationEnumerationManipulator(bool deserializing) : base(deserializing) { }
42    protected PermutationEnumerationManipulator(PermutationEnumerationManipulator original, Cloner cloner) : base(original, cloner) { }
43    public PermutationEnumerationManipulator() {
44      Parameters.Add(new ValueLookupParameter<IntValue>("NrOfSteps", "The number of steps to advance the permutation.", new IntValue(1)));
45    }
46    [StorableHook(HookType.AfterDeserialization)]
47    private void EnsureParameterExists() {
48      if (!Parameters.ContainsKey("NrOfSteps"))
49        Parameters.Add(new ValueLookupParameter<IntValue>("NrOfSteps", "The number of steps to advance the permutation.", new IntValue(1)));
50    }
51
52    public override IDeepCloneable Clone(Cloner cloner) {
53      return new PermutationEnumerationManipulator(this, cloner);
54    }
55
56    protected override void Manipulate(IRandom random, Permutation permutation) {
57      int steps = NrOfStepsParameter.ActualValue.Value;
58      if (steps < 0)
59        steps = random.Next(-steps)+1;
60      for (int i=0; i<steps; i++)
61        Advance(permutation);
62    }
63
64    public void Advance(Permutation p) {
65      Advance(p, 0, new bool[p.Length]);
66    }
67
68    public bool Advance(Permutation perm, int index, bool[] used) {
69      // cannot mutate length 1 permutations
70      if (index >= perm.Length)
71        return false;
72
73      // try to swap the last two positions
74      if (index == perm.Length - 2) {
75        if (perm[index] < perm[index + 1]) {
76          Swap(perm, index, index+1);
77          return true;
78        } else
79          return false;
80      }
81      used[perm[index]] = true;
82      if (Advance(perm, index + 1, used)) // try to advance later digits
83        return true;
84      used[perm[index]] = false;
85      for (int i = perm[index] + 1; i < perm.Length; i++) { // try to advance this digit
86        if (!used[i]) {
87          perm[index] = i;
88          used[i] = true;
89          Fill(perm, index + 1, used);
90          return true;
91        }
92      }
93      if (index == 0) { // wrap around
94        Fill(perm, 0, new bool[perm.Length]);
95        return true;
96      }
97      return false;
98    }
99
100    public static void Swap(Permutation p, int i, int j) {
101      int t = p[j];
102      p[j] = p[i];
103      p[i] = t;
104    }
105
106    private void Fill(Permutation perm, int startIndex, bool[] used) {
107      int j = 0;
108      for (int i = startIndex; i < perm.Length; i++) {
109        for (; j < used.Length; j++) {
110          if (!used[j]) {
111            perm[i] = j;
112            used[j] = true;
113            goto Done;
114          }
115        }
116        throw new InvalidOperationException("not enough elements left");
117      Done: ;
118      }
119    }
120  }
121}
Note: See TracBrowser for help on using the repository browser.