source: branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost/3.3/Operators/Mutation/DistanceBasedIntegerVectorMutator.cs @ 13069

Last change on this file since 13069 was 13069, checked in by gkronber, 7 years ago

#2499: imported source code for HeuristicLab.BioBoost from private repository with some changes

File size: 5.9 KB
Line 
1using HeuristicLab.BioBoost.ProblemDescription;
2using HeuristicLab.Common;
3using HeuristicLab.Core;
4using HeuristicLab.Data;
5using HeuristicLab.Encodings.IntegerVectorEncoding;
6using HeuristicLab.Parameters;
7using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
8using System;
9using System.Linq;
10
11namespace HeuristicLab.BioBoost.Operators.Mutation {
12  [StorableClass]
13  public class DistanceBasedIntegerVectorMutator : IntegerVectorManipulator {
14
15
16    #region Parameters
17    public LookupParameter<DistanceMatrix> DistanceMatrixParameter { get { return (LookupParameter<DistanceMatrix>) Parameters["DistanceMatrix"]; } }
18    public ValueParameter<BoolValue> DistanceMatrixInProblemDataParameter { get { return (ValueParameter<BoolValue>) Parameters["DistanceMatrixInProblemData"]; } }
19    public ILookupParameter<BioBoostProblemData> ProblemDataParameter { get { return (ILookupParameter<BioBoostProblemData>) Parameters["ProblemData"]; } }
20    public ILookupParameter<IntArray> ViableSourcesParameter { get { return (ILookupParameter<IntArray>) Parameters["ViableSources"]; } }
21    public ILookupParameter<IntArray> ViableTargetsParameter { get { return (ILookupParameter<IntArray>) Parameters["ViableTargets"]; } }
22    public IValueLookupParameter<DoubleValue> MaximumDistanceParameter { get { return (IValueLookupParameter<DoubleValue>) Parameters["MaximumDistance"]; } }
23
24    #endregion
25
26    #region Parameter Values
27    public DistanceMatrix DistanceMatrix {
28      get {
29        if (DistanceMatrixInProblemData) {
30          return ((IValueParameter<DistanceMatrix>) ProblemData.Parameters[DistanceMatrixParameter.ActualName]).Value;
31        } else {
32          return DistanceMatrixParameter.ActualValue;
33        }
34      }
35    }
36    public bool DistanceMatrixInProblemData { get { return DistanceMatrixInProblemDataParameter.Value.Value; } }
37    public BioBoostProblemData ProblemData { get { return ProblemDataParameter.ActualValue; } }
38    public IntArray ViableSources { get { return ViableSourcesParameter.ActualValue; } }
39    public IntArray ViableTargets { get { return ViableTargetsParameter.ActualValue; } }
40    public double MaximumDistance { get { return MaximumDistanceParameter.ActualValue.Value;  } }
41    #endregion
42
43    #region Construction & Cloning
44    [StorableConstructor]
45    protected DistanceBasedIntegerVectorMutator(bool isDeserializing) : base(isDeserializing) {}
46    protected DistanceBasedIntegerVectorMutator(DistanceBasedIntegerVectorMutator orig, Cloner cloner) : base(orig, cloner) {}
47    public DistanceBasedIntegerVectorMutator() {
48      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The distance matrix to use", "StreetDistanceMatrix")); // TODO: check this
49      Parameters.Add(new ValueParameter<BoolValue>("DistanceMatrixInProblemData", "Whether to look for the distance matrix in problem data or in scope.", new BoolValue(true)));
50      Parameters.Add(new LookupParameter<BioBoostProblemData>("ProblemData", "Contains fixed values describing the problem."));
51      Parameters.Add(new LookupParameter<IntArray>("ViableSources", "A list with all indices of viable source regions."));
52      Parameters.Add(new LookupParameter<IntArray>("ViableTargets", "A list with all indices of viable target regions."));
53      Parameters.Add(new ValueLookupParameter<DoubleValue>("MaximumDistance", "the maximum distance from source to target allowed for mutation", new DoubleValue(Double.MaxValue)));
54    }
55    public override IDeepCloneable Clone(Cloner cloner) {
56      return new DistanceBasedIntegerVectorMutator(this, cloner);
57    }
58
59    [StorableHook(HookType.AfterDeserialization)]
60    private void AfterDeserialization() {
61      if (!Parameters.ContainsKey("ViableSources"))
62        Parameters.Add(new LookupParameter<IntArray>("ViableSources", "A list with all indices of viable source regions."));
63      if (!Parameters.ContainsKey("ViableTargets"))
64        Parameters.Add(new LookupParameter<IntArray>("ViableTargets", "A list with all indices of viable target regions."));
65      if (!Parameters.ContainsKey("MaximumDistance"))
66        Parameters.Add(new ValueLookupParameter<DoubleValue>("MaximumDistance", "the maximum distance from source to target allowed for mutation", new DoubleValue(Double.MaxValue)));
67    }
68    #endregion
69
70    protected override void Manipulate(IRandom random, IntegerVector integerVector) {
71      var sources = ViableSources ?? new IntArray(Enumerable.Range(0, integerVector.Length).ToArray());
72      var targets = ViableTargets ?? new IntArray(Enumerable.Range(0, integerVector.Length).ToArray());
73      var source = random.Next(sources.Length);
74      var target = integerVector[sources[source]];
75      var neighborDistances = new double[0].Select((d, idx) => new {index = idx, distance = d}).ToList();
76      var distances = DistanceMatrix;
77      var maxDistance = 0d;
78      for (int j = 0; j < targets.Length; j++) {
79        if (distances[source, targets[j]] > MaximumDistance) continue;
80        var dist = distances[target, targets[j]];
81        neighborDistances.Add(new {index = targets[j], distance = dist});
82        maxDistance = Math.Max(dist, maxDistance);
83      }
84      neighborDistances = neighborDistances.Select(p => new {p.index, distance = maxDistance - p.distance}).ToList();
85      neighborDistances.Sort((a, b) => b.distance.CompareTo(a.distance));
86      var totalDistance = neighborDistances.Sum(p => p.distance);
87      var threshold = random.NextDouble()*totalDistance;
88      var sum = 0d;
89      var index = 0;
90      while (index < neighborDistances.Count && sum < threshold) {
91        sum += neighborDistances[index].distance;
92        index++;
93      }
94      if (index < 0 || index >= neighborDistances.Count) {
95        integerVector[sources[source]] = sources[source];  // reset to local transport if no choices exist
96      } else {
97        integerVector[sources[source]] = neighborDistances[index].index;
98      }
99    }
100
101  }
102}
Note: See TracBrowser for help on using the repository browser.