source: branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost/3.3/Operators/Mutation/MultiMutator.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: 7.5 KB
Line 
1using System.Reflection;
2using HeuristicLab.Collections;
3using HeuristicLab.Common;
4using HeuristicLab.Core;
5using HeuristicLab.Data;
6using HeuristicLab.Encodings.IntegerVectorEncoding;
7using HeuristicLab.Operators;
8using HeuristicLab.Optimization;
9using HeuristicLab.Parameters;
10using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
11using HeuristicLab.PluginInfrastructure;
12using System;
13using System.Collections.Generic;
14using System.Linq;
15using NetTopologySuite.Triangulate;
16
17namespace HeuristicLab.BioBoost.Operators.Mutation {
18  [StorableClass]
19  public class MultiMutator : StochasticMultiBranch<IManipulator>, IManipulator, IStochasticOperator {
20
21    public override bool CanChangeName { get { return false; } }
22
23    protected override bool CreateChildOperation { get { return true; } }
24
25    public IValueLookupParameter<IntValue> SeriesLengthParameter { get { return (IValueLookupParameter<IntValue>)Parameters["SeriesLength"]; } }
26    public ValueParameter<PercentArray> MinGenerationPercentagesParameter { get { return (ValueParameter<PercentArray>)Parameters["MinGenerationPercentages"]; } }
27    public ILookupParameter<IntValue> GenerationsParameter { get { return (ILookupParameter<IntValue>)Parameters["Generations"]; } }
28    public ILookupParameter<IntValue> MaxGenerationsParameter { get { return (ILookupParameter<IntValue>)Parameters["MaximumGenerations"]; } }
29    public PercentArray MinGenerationPercentages {
30      get { return MinGenerationPercentagesParameter.Value; }
31      set { MinGenerationPercentagesParameter.Value = value; }
32    }
33
34    public int SeriesLength { get { return SeriesLengthParameter.ActualValue.Value; } }
35
36    #region Construction & Cloning
37    [StorableConstructor]
38    protected MultiMutator(bool isDeserializing) : base(isDeserializing) { }
39    protected MultiMutator(MultiMutator orig, Cloner cloner) : base(orig, cloner) { }
40    public MultiMutator() {
41      Parameters.Add(new ValueLookupParameter<IntValue>("SeriesLength", "The number of manipulations to perform at once", new IntValue(1)));
42      Parameters.Add(new ValueParameter<PercentArray>("MinGenerationPercentages", "Relative number of generations before the respetive mutation becomes active.", new PercentArray(0)));
43      Parameters.Add(new LookupParameter<IntValue>("Generations", "Current number of generations/iterations."));
44      Parameters.Add(new LookupParameter<IntValue>("MaximumGenerations", "Maximum number of generations/iterations."));
45      foreach (var t in ApplicationManager.Manager.GetTypes(typeof(IManipulator), Assembly.GetExecutingAssembly())) {
46        if (t == this.GetType() || typeof(IIntegerVectorManipulator).IsAssignableFrom(t)) continue;
47        IManipulator instance = null;
48        try {
49          instance = Activator.CreateInstance(t) as IManipulator;
50        } catch { }
51        if (instance != null) Operators.Add(instance);
52      }
53      for (int i = 0; i < Operators.Count; i++) {
54        if (Operators[i] is CompoundMutator ||
55            Operators[i] is PlantMerger ||
56            Operators[i] is PlantSplitter ||
57            Operators[i] is PlantMover) {
58          // everything is fine
59        } else if (Operators[i] is PlantSupplierToggler ||
60                   Operators[i] is PlantSupplierUtilizationExchanger ||
61                   Operators[i] is PlantSupplierEqualizer ||
62                   Operators[i] is PlantSupplierRandomizer ||
63                   Operators[i] is PlantScalingMutator) {
64          MinGenerationPercentages[i] = 0.5;
65        } else if (Operators[i] is EmptyMutator) {
66          MinGenerationPercentages[i] = 0.8;
67        } else if (Operators[i] is PlantKiller) {
68          MinGenerationPercentages[i] = 0.9;
69        } else {
70          Operators.SetItemCheckedState(Operators[i], false);
71        }
72      }
73    }
74    public override IDeepCloneable Clone(Cloner cloner) {
75      return new MultiMutator(this, cloner);
76    }
77
78    [StorableHook(HookType.AfterDeserialization)]
79    private void AfterDeserialization() {
80      if (!Parameters.ContainsKey("MinGenerationPercentages")) {
81        Parameters.Add(new ValueParameter<PercentArray>("MinGenerationPercentages", "Relative number of generations before the respetive mutation becomes active.", new PercentArray(Operators.Count)));
82      }
83      if (!Parameters.ContainsKey("Generations"))
84        Parameters.Add(new LookupParameter<IntValue>("Generations", "Current number of generations/iterations."));
85      if (!Parameters.ContainsKey("MaximumGenerations"))
86        Parameters.Add(new LookupParameter<IntValue>("MaximumGenerations", "Maximum number of generations/iterations."));
87      if (!Parameters.ContainsKey("SeriesLength"))
88        Parameters.Add(new ValueLookupParameter<IntValue>("SeriesLength", "The number of manipulations to perform at once", new IntValue(1)));
89    }
90    #endregion
91
92    protected override void Operators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IManipulator>> e) {
93      base.Operators_ItemsAdded(sender, e);
94      if (MinGenerationPercentages.Length >= Operators.Count) return;
95      var added = e.Items.OrderBy(x => x.Index).ToList();
96      int insertCount = 0;
97      var percentages = new PercentArray(Operators.Count);
98      for (int i = 0; i < Operators.Count; i++) {
99        if (insertCount < added.Count && i == added[insertCount].Index) {
100          percentages[i] = 0;
101          insertCount++;
102        } else if (i - insertCount < MinGenerationPercentages.Length) {
103          percentages[i] = MinGenerationPercentages[i - insertCount];
104        } else percentages[i] = 0;
105      }
106      MinGenerationPercentages = percentages;
107    }
108
109    protected override void Operators_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IManipulator>> e) {
110      base.Operators_ItemsRemoved(sender, e);
111      if (MinGenerationPercentages.Length <= Operators.Count) return;
112      var percentages = new List<double>(MinGenerationPercentages);
113      var sorted = e.Items.OrderByDescending(x => x.Index);
114      foreach (var item in sorted)
115        if (percentages.Count > item.Index) percentages.RemoveAt(item.Index);
116      MinGenerationPercentages = new PercentArray(percentages.ToArray());
117    }
118
119    public override IOperation InstrumentedApply() {
120      if (Operators.Count == 0) throw new InvalidOperationException(Name + ": Please add at least one manipulator to choose from.");
121      if (MaxGenerationsParameter.ActualValue == null || GenerationsParameter.ActualValue == null || MinGenerationPercentages.Max() == 0)
122        return base.InstrumentedApply();
123      DoubleArray probability = null;
124      try {
125        var generationPercentage = 1.0 * GenerationsParameter.ActualValue.Value / MaxGenerationsParameter.ActualValue.Value;
126        for (int i = 0; i < Probabilities.Length; i++) {
127          if (MinGenerationPercentages[i] > generationPercentage) {
128            if (probability == null) probability = (DoubleArray)Probabilities.Clone(); // backup old probabilities
129            Probabilities[i] = 0;
130          }
131        }
132        if (SeriesLength == 1) {
133          return base.InstrumentedApply();
134        } else {
135          var operations = new OperationCollection();
136          for (var i = 0; i < SeriesLength; i++) {
137            operations.Add(base.InstrumentedApply());
138          }
139          return operations;
140        }
141      } finally {
142        // restore old probabilities
143        if (probability != null)
144          Probabilities = probability;
145      }
146    }
147  }
148}
Note: See TracBrowser for help on using the repository browser.