Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost/3.3/Operators/Mutation/PlantMover.cs @ 13071

Last change on this file since 13071 was 13071, checked in by gkronber, 9 years ago

#2499: added license headers and removed unused usings

File size: 8.3 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.Collections.Generic;
24using System.Linq;
25using HeuristicLab.BioBoost.ProblemDescription;
26using HeuristicLab.BioBoost.Representation;
27using HeuristicLab.Common;
28using HeuristicLab.Core;
29using HeuristicLab.Data;
30using HeuristicLab.Encodings.IntegerVectorEncoding;
31using HeuristicLab.Operators;
32using HeuristicLab.Optimization;
33using HeuristicLab.Parameters;
34using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
35
36namespace HeuristicLab.BioBoost.Operators.Mutation {
37
38  public class PlantMover : SingleSuccessorOperator, IManipulator, IStochasticOperator {
39
40    #region Parameters
41    public LookupParameter<BioBoostProblemData> ProblemDataParameter { get { return (LookupParameter<BioBoostProblemData>) Parameters["ProblemData"]; } }
42    public LookupParameter<DistanceMatrix> DistanceMatrixParameter { get { return (LookupParameter<DistanceMatrix>) Parameters["DistanceMatrix"]; } }
43    public ValueParameter<BoolValue> DistanceMatrixInProblemDataParameter { get { return (ValueParameter<BoolValue>) Parameters["DistanceMatrixInProblemData"]; } }
44    public ValueLookupParameter<IntMatrix> RegionBoundsParameter { get { return (ValueLookupParameter<IntMatrix>) Parameters["RegionBounds"]; } }
45    public ILookupParameter<IRandom> RandomParameter { get { return (ILookupParameter<IRandom>) Parameters["Random"]; } }
46    public IValueLookupParameter<PercentValue> MergeAvoidanceProbabilityParameter { get { return (IValueLookupParameter<PercentValue>) Parameters["MergeAvoidanceProbability"]; } }
47    public IValueLookupParameter<PercentValue> SplitProbabilityParameter { get { return (IValueLookupParameter<PercentValue>) Parameters["SplitProbability"]; } }
48    public IValueLookupParameter<PercentValue> MovePercentageParameter { get { return (IValueLookupParameter<PercentValue>) Parameters["MovePercentage"]; } }
49    #endregion
50
51
52
53    #region Parameter Values
54    public BioBoostProblemData ProblemData { get { return ProblemDataParameter.ActualValue; } }
55    public IntMatrix RegionBounds { get { return RegionBoundsParameter.ActualValue; } }
56    public IRandom Random { get { return RandomParameter.ActualValue; } }
57    public bool DistanceMatrixInProblemData { get { return DistanceMatrixInProblemDataParameter.Value.Value; } }
58    public DistanceMatrix DistanceMatrix {
59      get {
60        if (DistanceMatrixInProblemData) {
61          return ((IValueParameter<DistanceMatrix>) ProblemData.Parameters[DistanceMatrixParameter.ActualName]).Value;
62        } else {
63          return DistanceMatrixParameter.ActualValue;
64        }
65      }
66    }
67    public double MergeAvoidanceProbability { get { return MergeAvoidanceProbabilityParameter.Value.Value; } }
68    public double SplitProbability { get { return SplitProbabilityParameter.Value.Value; } }
69    public double MovePercentage { get { return MovePercentageParameter.Value.Value; } }
70    #endregion
71
72    #region Construction & Cloning
73    [StorableConstructor]
74    public PlantMover(bool isDeserializing) {}
75    public PlantMover(PlantMover orig, Cloner cloner) : base(orig, cloner) {}
76
77    public PlantMover() {
78      Parameters.Add(new LookupParameter<BioBoostProblemData>("ProblemData", "The data store of the detailed problem description."));
79      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The distance matrix to use", "StreetDistanceMatrix")); // TODO: check this
80      Parameters.Add(new ValueParameter<BoolValue>("DistanceMatrixInProblemData", "Whether to look for the distance matrix in problem data or in scope.", new BoolValue(true)));
81      Parameters.Add(new ValueLookupParameter<IntMatrix>("RegionBounds", "The limits of valid region ids."));
82      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator."));
83      Parameters.Add(new ValueLookupParameter<PercentValue>("MergeAvoidanceProbability", "Probability that a moved plant will avoid existing plant locations.", new PercentValue(1)));
84      Parameters.Add(new ValueLookupParameter<PercentValue>("SplitProbability", "Probability that only part of the suppliers will follow to the new location.", new PercentValue(0)));
85      Parameters.Add(new ValueLookupParameter<PercentValue>("MovePercentage", "In case a plant is split, the percentage of suppliers that will move.", new PercentValue(0.5)));
86    }
87
88    public override IDeepCloneable Clone(Cloner cloner) {
89      return new PlantMover(this, cloner);
90    }
91    #endregion
92
93    public override IOperation Apply() {
94      var scope = ExecutionContext.Scope;
95      var dm = DistanceMatrix;
96      var feedstock =
97        ProblemData.TransportTargets.CheckedItems.ElementAt(
98          Random.Next(ProblemData.TransportTargets.CheckedItems.Count())).Value.Value;
99      string product = null;
100      var productLinks = ProblemData.ProductLinks;
101      for (int i = 0; i < productLinks.Rows; i++) {
102        if (productLinks[i, 0] == feedstock)
103          product = productLinks[i, 1];
104      }
105      var supplyTransports = scope.Variables[LayerDescriptor.TransportTargets.NameWithPrefix(feedstock)].Value as IntegerVector;
106      var productTransportName = LayerDescriptor.TransportTargets.NameWithPrefix(product);
107      var productTransports = product == null || !scope.Variables.ContainsKey(productTransportName) ? null
108        : scope.Variables[productTransportName].Value as IntegerVector;
109      if (supplyTransports != null) {
110        var plants = supplyTransports.Select((target, source) => new {target, source}).GroupBy(p => p.target).ToList();
111        var plant = plants.ElementAt(Random.Next(plants.Count));
112        var forbiddenRegions = new HashSet<int>();
113        if (Random.NextDouble() > MergeAvoidanceProbability) {
114          forbiddenRegions = new HashSet<int>(plants.Select(p => p.Key));
115        }
116        var newTarget = FindNewTarget(plant.Key, Random, dm, forbiddenRegions);
117        bool split = Random.NextDouble() < SplitProbability;
118        foreach (var supplier in plant) {
119          if (!split || Random.NextDouble() <= MovePercentage) {
120            supplyTransports[supplier.source] = newTarget;
121          }
122        }
123        if (productTransports != null) {
124          var temp = productTransports[newTarget];
125          productTransports[newTarget] = productTransports[plant.Key];
126          productTransports[plant.Key] = temp;
127        }
128      }
129      return base.Apply();
130    }
131
132    private int FindNewTarget(int oldTarget, IRandom random, DistanceMatrix distances, HashSet<int> forbiddenRegions) {
133      var neighborDistances = new double[0].Select((d, idx) => new {index = idx, distance = d}).ToList();
134      var maxDistance = 0d;
135      for (int j = 0; j < distances.Columns; j++) {
136        if (forbiddenRegions.Contains(j)) continue;
137        var dist = distances[oldTarget, j];
138        neighborDistances.Add(new {index = j, distance = dist});
139        maxDistance = Math.Max(dist, maxDistance);
140      }
141      neighborDistances = neighborDistances.Select(p => new {p.index, distance = maxDistance - p.distance}).ToList();
142      neighborDistances.Sort((a, b) => b.distance.CompareTo(a.distance));
143      var totalDistance = neighborDistances.Sum(p => p.distance);
144      var threshold = random.NextDouble()*totalDistance;
145      var sum = 0d;
146      var index = 0;
147      while (index < neighborDistances.Count && sum < threshold) {
148        sum += neighborDistances[index].distance;
149        index++;
150      }
151      index = Math.Min(index, neighborDistances.Count - 1);
152      return neighborDistances[index].index;
153    }
154
155  }
156}
Note: See TracBrowser for help on using the repository browser.