Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2499: added license headers and removed unused usings

File size: 6.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.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 PlantMerger : 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    #endregion
47
48    #region Parameter Values
49    public BioBoostProblemData ProblemData { get { return ProblemDataParameter.ActualValue; } }
50    public IntMatrix RegionBounds { get { return RegionBoundsParameter.ActualValue; } }
51    public IRandom Random { get { return RandomParameter.ActualValue; } }
52    public bool DistanceMatrixInProblemData { get { return DistanceMatrixInProblemDataParameter.Value.Value; } }
53    public DistanceMatrix DistanceMatrix {
54      get {
55        if (DistanceMatrixInProblemData) {
56          return ((IValueParameter<DistanceMatrix>) ProblemData.Parameters[DistanceMatrixParameter.ActualName]).Value;
57        } else {
58          return DistanceMatrixParameter.ActualValue;
59        }
60      }
61    }
62    #endregion
63
64    #region Construction & Cloning
65    [StorableConstructor]
66    public PlantMerger(bool isDeserializing) {}
67    public PlantMerger(PlantMerger orig, Cloner cloner) : base(orig, cloner) {}
68
69    public PlantMerger() {
70      Parameters.Add(new LookupParameter<BioBoostProblemData>("ProblemData", "The data store of the detailed problem description."));
71      Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The distance matrix to use", "StreetDistanceMatrix")); // TODO: check this
72      Parameters.Add(new ValueParameter<BoolValue>("DistanceMatrixInProblemData", "Whether to look for the distance matrix in problem data or in scope.", new BoolValue(true)));
73      Parameters.Add(new ValueLookupParameter<IntMatrix>("RegionBounds", "The limits of valid region ids."));
74      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator."));
75    }
76
77    public override IDeepCloneable Clone(Cloner cloner) {
78      return new PlantMerger(this, cloner);
79    }
80    #endregion
81
82    public override IOperation Apply() {
83      var scope = ExecutionContext.Scope;
84      var dm = DistanceMatrix;
85      var feedstock =
86        ProblemData.TransportTargets.CheckedItems.ElementAt(
87          Random.Next(ProblemData.TransportTargets.CheckedItems.Count())).Value.Value;
88      string product = null;
89      var productLinks = ProblemData.ProductLinks;
90      for (int i = 0; i < productLinks.Rows; i++) {
91        if (productLinks[i, 0] == feedstock)
92          product = productLinks[i, 1];
93      }
94      var supplyTransports = scope.Variables[LayerDescriptor.TransportTargets.NameWithPrefix(feedstock)].Value as IntegerVector;
95      var productTransportName = LayerDescriptor.TransportTargets.NameWithPrefix(product);
96      var productTransports = product == null || !scope.Variables.ContainsKey(productTransportName) ? null
97        : scope.Variables[productTransportName].Value as IntegerVector;
98      if (supplyTransports != null) {
99        var plants = supplyTransports.Select((target, source) => new {target, source}).GroupBy(p => p.target).ToList();
100        var plant = plants.ElementAt(Random.Next(plants.Count));
101        var allowedRegions = new HashSet<int>(plants.Select(p => p.Key));
102        var newTarget = FindNewTarget(plant.Key, Random, dm, allowedRegions);
103        foreach (var supplier in plant) {
104          supplyTransports[supplier.source] = newTarget;
105        }
106        if (productTransports != null) {
107          var temp = productTransports[newTarget];
108          productTransports[newTarget] = productTransports[plant.Key];
109          productTransports[plant.Key] = temp;
110        }
111      }
112      return base.Apply();
113    }
114
115    private int FindNewTarget(int oldTarget, IRandom random, DistanceMatrix distances, IEnumerable<int> allowedRegions) {
116      var neighborDistances = new double[0].Select((d, idx) => new {index = idx, distance = d}).ToList();
117      var maxDistance = 0d;
118      foreach (int j in allowedRegions) {
119        var dist = distances[oldTarget, j];
120        neighborDistances.Add(new {index = j, distance = dist});
121        maxDistance = Math.Max(dist, maxDistance);
122      }
123      neighborDistances = neighborDistances.Select(p => new {p.index, distance = maxDistance - p.distance}).ToList();
124      neighborDistances.Sort((a, b) => b.distance.CompareTo(a.distance));
125      var totalDistance = neighborDistances.Sum(p => p.distance);
126      var threshold = random.NextDouble()*totalDistance;
127      var sum = 0d;
128      var index = 0;
129      while (index < neighborDistances.Count && sum < threshold) {
130        sum += neighborDistances[index].distance;
131        index++;
132      }
133      index = Math.Min(index, neighborDistances.Count - 1);
134      return neighborDistances[index].index;
135    }
136
137  }
138}
Note: See TracBrowser for help on using the repository browser.