Free cookie consent management tool by TermsFeed Policy Generator

source: branches/FitnessLandscapeAnalysis/HeuristicLab.Problems.NK/NKLandscape.cs @ 12565

Last change on this file since 12565 was 12565, checked in by ascheibe, 9 years ago

#2306 merged changes from copy of NK landscapes back into original plugin and deleted copy

File size: 9.6 KB
Line 
1using System;
2using System.Linq;
3using System.Security.Cryptography;
4using HeuristicLab.Common;
5using HeuristicLab.Core;
6using HeuristicLab.Data;
7using HeuristicLab.Encodings.BinaryVectorEncoding;
8using HeuristicLab.Parameters;
9using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
10using HeuristicLab.PluginInfrastructure;
11using HeuristicLab.Problems.Binary;
12using HeuristicLab.Problems.NK.WeightInitializers;
13using HeuristicLab.Random;
14
15namespace HeuristicLab.Problems.NK {
16
17  [Item("NK Landscape", "Represents an NK landscape optimization problem.")]
18  [Creatable("Problems")]
19  [StorableClass]
20  public sealed class NKLandscape : BinaryProblem {
21    public override bool Maximization {
22      get { return false; }
23    }
24
25    #region Parameters
26    public ValueParameter<BoolMatrix> GeneInteractionsParameter {
27      get { return (ValueParameter<BoolMatrix>)Parameters["GeneInteractions"]; }
28    }
29    public ValueParameter<IntValue> InteractionSeedParameter {
30      get { return (ValueParameter<IntValue>)Parameters["InteractionSeed"]; }
31    }
32    public ValueParameter<IntValue> NrOfInteractionsParameter {
33      get { return (ValueParameter<IntValue>)Parameters["NrOfInteractions"]; }
34    }
35    public ValueParameter<IntValue> NrOfFitnessComponentsParameter {
36      get { return (ValueParameter<IntValue>)Parameters["NrOfFitnessComponents"]; }
37    }
38    public ValueParameter<DoubleArray> WeightsParameter {
39      get { return (ValueParameter<DoubleArray>)Parameters["Weights"]; }
40    }
41    public IConstrainedValueParameter<IInteractionInitializer> InteractionInitializerParameter {
42      get { return (IConstrainedValueParameter<IInteractionInitializer>)Parameters["InteractionInitializer"]; }
43    }
44    public IConstrainedValueParameter<IWeightsInitializer> WeightsInitializerParameter {
45      get { return (IConstrainedValueParameter<IWeightsInitializer>)Parameters["WeightsInitializer"]; }
46    }
47    #endregion
48
49    #region Properties
50    public IInteractionInitializer InteractionInitializer {
51      get { return InteractionInitializerParameter.Value; }
52    }
53    public BoolMatrix GeneInteractions {
54      get { return GeneInteractionsParameter.Value; }
55    }
56    public DoubleArray Weights {
57      get { return WeightsParameter.Value; }
58    }
59    public IntValue InteractionSeed {
60      get { return InteractionSeedParameter.Value; }
61    }
62    #endregion
63
64    [ThreadStatic]
65    private static MersenneTwister random;
66    public static MersenneTwister Random {
67      get {
68        if (random == null) {
69          random = new MersenneTwister();
70        }
71        return random;
72      }
73    }
74
75    [ThreadStatic]
76    private static HashAlgorithm hashAlgorithm;
77
78    public static HashAlgorithm HashAlgorithm {
79      get {
80        if (hashAlgorithm == null) {
81          hashAlgorithm = HashAlgorithm.Create("MD5");
82        }
83        return hashAlgorithm;
84      }
85    }
86
87    [StorableConstructor]
88    private NKLandscape(bool deserializing) : base(deserializing) { }
89    private NKLandscape(NKLandscape original, Cloner cloner)
90      : base(original, cloner) {
91      RegisterEventHandlers();
92    }
93    public NKLandscape()
94      : base() {
95      Parameters.Add(new ValueParameter<BoolMatrix>("GeneInteractions", "Every column gives the participating genes for each fitness component"));
96      Parameters.Add(new ValueParameter<IntValue>("InteractionSeed", "The seed used for the hash function to generate interaction tables.", new IntValue(Random.Next())));
97      Parameters.Add(new ValueParameter<IntValue>("NrOfFitnessComponents", "Number of fitness component functions. (nr of columns in the interaction column)", new IntValue(10)));
98      Parameters.Add(new ValueParameter<IntValue>("NrOfInteractions", "Number of genes interacting with each other. (nr of True values per column in the interaction matrix)", new IntValue(3)));
99      Parameters.Add(new ValueParameter<DoubleArray>("Weights", "The weights for the component functions. If shorted, will be repeated.", new DoubleArray(new[] { 1.0 })));
100      Parameters.Add(new OptionalConstrainedValueParameter<IInteractionInitializer>("InteractionInitializer", "Initialize interactions within the component functions."));
101      Parameters.Add(new OptionalConstrainedValueParameter<IWeightsInitializer>("WeightsInitializer", "Operator to initialize weights distribution"));
102
103      InitializeInteractionInitializerParameter();
104      InitializeWeightsInitializerParameter();
105
106      InitializeOperators();
107      RegisterEventHandlers();
108      InitializeInteractions();
109    }
110
111    private void InitializeInteractionInitializerParameter() {
112      foreach (var initializer in ApplicationManager.Manager.GetInstances<IInteractionInitializer>())
113        InteractionInitializerParameter.ValidValues.Add(initializer);
114      InteractionInitializerParameter.Value = InteractionInitializerParameter.ValidValues.First(v => v is RandomInteractionsInitializer);
115    }
116
117    private void InitializeWeightsInitializerParameter() {
118      foreach (var initializer in ApplicationManager.Manager.GetInstances<IWeightsInitializer>())
119        WeightsInitializerParameter.ValidValues.Add(initializer);
120      WeightsInitializerParameter.Value = WeightsInitializerParameter.ValidValues.First(v => v is EqualWeightsInitializer);
121    }
122
123    public override IDeepCloneable Clone(Cloner cloner) {
124      return new NKLandscape(this, cloner);
125    }
126
127    #region Events
128    protected override void LengthParameter_ValueChanged(object sender, EventArgs e) {
129      BestKnownQualityParameter.Value = new DoubleValue(Length);
130      NrOfFitnessComponentsParameter.Value = new IntValue(Length);
131    }
132    #endregion
133
134    #region Helpers
135    [StorableHook(HookType.AfterDeserialization)]
136    private void AfterDeserialization() {
137      RegisterEventHandlers();
138    }
139
140    private void RegisterEventHandlers() {
141      NrOfInteractionsParameter.ValueChanged += InteractionParameterChanged;
142      NrOfInteractionsParameter.Value.ValueChanged += InteractionParameterChanged;
143      NrOfFitnessComponentsParameter.ValueChanged += InteractionParameterChanged;
144      NrOfFitnessComponentsParameter.Value.ValueChanged += InteractionParameterChanged;
145      InteractionInitializerParameter.ValueChanged += InteractionInitializerParameter_ValueChanged;
146      WeightsInitializerParameter.ValueChanged += WeightsInitializerParameter_ValueChanged;
147    }
148
149    void WeightsInitializerParameter_ValueChanged(object sender, EventArgs e) {
150      InitializeWeights();
151    }
152
153    void InteractionInitializerParameter_ValueChanged(object sender, EventArgs e) {
154      InitializeInteractions();
155    }
156
157    private void InteractionParameterChanged(object sender, EventArgs e) {
158      InitializeInteractions();
159    }
160
161    private void InitializeOperators() {
162      NKBitFlipMoveEvaluator nkEvaluator = new NKBitFlipMoveEvaluator();
163      Encoding.ConfigureOperator(nkEvaluator);
164      Operators.Add(nkEvaluator);
165    }
166
167    private void InitializeInteractions() {
168      if (InteractionInitializer != null)
169        GeneInteractionsParameter.Value = InteractionInitializer.InitializeInterations(
170          Length,
171          NrOfFitnessComponentsParameter.Value.Value,
172          NrOfInteractionsParameter.Value.Value, Random);
173    }
174
175    private void InitializeWeights() {
176      if (WeightsInitializerParameter.Value != null)
177        WeightsParameter.Value = new DoubleArray(
178          WeightsInitializerParameter.Value.GetWeights(NrOfFitnessComponentsParameter.Value.Value)
179          .ToArray());
180    }
181    #endregion
182
183    #region Evaluation function
184    public static long Hash(long x) {
185      return BitConverter.ToInt64(HashAlgorithm.ComputeHash(BitConverter.GetBytes(x), 0, 8), 0);
186    }
187
188    public static double F_i(long x, long i, long g_i, long seed) {
189      return Math.Abs((double)Hash((x & g_i) ^ Hash(g_i ^ Hash(i ^ seed)))) / long.MaxValue;
190    }
191
192    public static double F(long x, long[] g, double[] w, long seed, ref double[] f_i) {
193      double value = 0;
194      for (int i = 0; i < g.Length; i++) {
195        f_i[i] = F_i(x, i, g[i], seed);
196        value += w[i % w.Length] * f_i[i];
197      }
198      return value;
199    }
200
201    public static long Encode(BinaryVector v) {
202      long x = 0;
203      for (int i = 0; i < 64 && i < v.Length; i++) {
204        x |= (v[i] ? (long)1 : (long)0) << i;
205      }
206      return x;
207    }
208
209    public static long[] Encode(BoolMatrix m) {
210      long[] x = new long[m.Columns];
211      for (int c = 0; c < m.Columns; c++) {
212        x[c] = 0;
213        for (int r = 0; r < 64 && r < m.Rows; r++) {
214          x[c] |= (m[r, c] ? (long)1 : (long)0) << r;
215        }
216      }
217      return x;
218    }
219
220    public static double[] Normalize(DoubleArray weights) {
221      double sum = 0;
222      double[] w = new double[weights.Length];
223      foreach (var v in weights) {
224        sum += Math.Abs(v);
225      }
226      for (int i = 0; i < weights.Length; i++) {
227        w[i] = Math.Abs(weights[i]) / sum;
228      }
229      return w;
230    }
231
232    public static double Evaluate(BinaryVector vector, BoolMatrix interactions, DoubleArray weights, int seed, out double[] f_i) {
233      long x = Encode(vector);
234      long[] g = Encode(interactions);
235      double[] w = Normalize(weights);
236      f_i = new double[interactions.Columns];
237      return F(x, g, w, (long)seed, ref f_i);
238    }
239
240    public override double Evaluate(BinaryVector vector, IRandom random) {
241      double[] f_i;//not used atm
242      double quality = Evaluate(vector, GeneInteractions, Weights, InteractionSeed.Value, out f_i);
243      return quality;
244    }
245    #endregion
246  }
247}
Note: See TracBrowser for help on using the repository browser.