Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2306 fixed typos and some cosmetic changes

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