Free cookie consent management tool by TermsFeed Policy Generator

source: addons/HeuristicLab.FitnessLandscapeAnalysis/HeuristicLab.Analysis.FitnessLandscape/NeutralSelector.cs @ 16573

Last change on this file since 16573 was 16573, checked in by gkronber, 5 years ago

#2520: changed HeuristicLab.FLA addon to compile with new HL.Persistence

File size: 11.4 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using HeuristicLab.Analysis.FitnessLandscape.DistanceCalculators;
5using HeuristicLab.Common;
6using HeuristicLab.Core;
7using HeuristicLab.Data;
8using HeuristicLab.Operators;
9using HeuristicLab.Optimization;
10using HeuristicLab.Parameters;
11using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
12using HeuristicLab.PluginInfrastructure;
13using HEAL.Attic;
14
15namespace HeuristicLab.Analysis.FitnessLandscape {
16  [Item("NeutralSelector", "A selection operator that explores neutral areas.")]
17  [StorableType("36A053AF-DA26-4878-ADA3-E61CD200D753")]
18  public class NeutralSelector : SingleSuccessorOperator, ISingleObjectiveSelector {
19
20    public override bool CanChangeName {
21      get { return false; }
22    }
23
24    #region Parameters
25    public ScopeParameter CurrentScopeParameter {
26      get { return (ScopeParameter)Parameters["CurrentScope"]; }
27    }
28    protected IValueParameter<BoolValue> CopySelectedParameter {
29      get { return (IValueParameter<BoolValue>)Parameters["CopySelected"]; }
30    }
31    public IValueLookupParameter<IntValue> NumberOfSelectedSubScopesParameter {
32      get { return (IValueLookupParameter<IntValue>)Parameters["NumberOfSelectedSubScopes"]; }
33    }
34    public IValueLookupParameter<BoolValue> MaximizationParameter {
35      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
36    }
37    public ILookupParameter<ItemArray<DoubleValue>> QualityParameter {
38      get { return (ILookupParameter<ItemArray<DoubleValue>>)Parameters["Quality"]; }
39    }
40    public ScopePathLookupParameter<DoubleValue> BaseQualityParameter {
41      get { return (ScopePathLookupParameter<DoubleValue>)Parameters["BaseQuality"]; }
42    }
43    public ScopePathLookupParameter<IItem> BaseSolutionParameter {
44      get { return (ScopePathLookupParameter<IItem>)Parameters["BaseSolution"]; }
45    }
46    public ScopePathLookupParameter<IItem> StartingPointParameter {
47      get { return (ScopePathLookupParameter<IItem>)Parameters["StartingPoint"]; }
48    }
49    public ILookupParameter<ItemArray<IItem>> SolutionParameter {
50      get { return (ILookupParameter<ItemArray<IItem>>)Parameters["Solution"]; }
51    }
52    public IConstrainedValueParameter<IItemDistanceCalculator> SolutionDistanceCalculatorParameter {
53      get { return (IConstrainedValueParameter<IItemDistanceCalculator>)Parameters["SolutionDistanceCalculator"]; }
54    }
55    public ValueLookupParameter<DoubleValue> EpsilonParameter {
56      get { return (ValueLookupParameter<DoubleValue>)Parameters["Epsilon"]; }
57    }
58    public ILookupParameter<DoubleValue> CurrentFractionOfNeutralNeighborsParameter {
59      get { return (LookupParameter<DoubleValue>)Parameters["CurrentFractionOfNeutralNeighbors"]; }
60    }
61    public LookupParameter<DoubleValue> CurrentNeutralDistanceParameter {
62      get { return (LookupParameter<DoubleValue>)Parameters["CurrentNeutralDistance"]; }
63    }
64    public LookupParameter<IRandom> RandomParameter {
65      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
66    }
67    #endregion
68
69    #region Parameter Values
70    protected IScope CurrentScope {
71      get { return CurrentScopeParameter.ActualValue; }
72    }
73    public BoolValue CopySelected {
74      get { return CopySelectedParameter.Value; }
75      set { CopySelectedParameter.Value = value; }
76    }
77    protected double CurrentNeutralDistance {
78      set {
79        if (CurrentNeutralDistanceParameter.ActualValue == null)
80          CurrentNeutralDistanceParameter.ActualValue = new DoubleValue(value);
81        else
82          CurrentNeutralDistanceParameter.ActualValue.Value = value;
83      }
84
85    }
86    protected double CurrentFractionOfNeutralNeighbors {
87      get { return CurrentFractionOfNeutralNeighborsParameter.ActualValue.Value; }
88      set {
89        if (CurrentFractionOfNeutralNeighborsParameter.ActualValue == null)
90          CurrentFractionOfNeutralNeighborsParameter.ActualValue = new DoubleValue(value);
91        else
92          CurrentFractionOfNeutralNeighborsParameter.ActualValue.Value = value;
93      }
94    }
95    #endregion
96
97    #region Construction & Cloning
98    [StorableConstructor]
99    protected NeutralSelector(StorableConstructorFlag _) : base(_) { }
100    protected NeutralSelector(NeutralSelector original, Cloner cloner) : base(original, cloner) { }
101    public NeutralSelector() {
102      Parameters.Add(new ScopeParameter("CurrentScope", "The current scope from which sub-scopes should be selected."));
103      Parameters.Add(new ValueParameter<BoolValue>("CopySelected", "True if the selected sub-scopes should be copied, otherwise false.", new BoolValue(true)));
104      Parameters.Add(new ValueLookupParameter<IntValue>("NumberOfSelectedSubScopes", "The number of sub-scopes which should be selected."));
105      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the current problem is a maximization problem, otherwise false."));
106      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The quality value contained in each sub-scope which is used for selection."));
107      Parameters.Add(new ScopePathLookupParameter<DoubleValue>("BaseQuality", "The base quality value to compare to. This is required to determine wheter a local optimum has been found and the direction should be reversed."));
108      Parameters.Add(new ValueLookupParameter<DoubleValue>("Epsilon", "Maximum delta accepted as neutral mutation.", new DoubleValue(0)));
109      Parameters.Add(new ScopePathLookupParameter<IItem>("BaseSolution", "Previous solution in neutral walk."));
110      Parameters.Add(new ScopePathLookupParameter<IItem>("StartingPoint", "Starting point of neutral walk (broken by non neutral transition through fallback selector)"));
111      Parameters.Add(new ScopeTreeLookupParameter<IItem>("Solution", "Current solution"));
112      Parameters.Add(new ConstrainedValueParameter<IItemDistanceCalculator>("SolutionDistanceCalculator", "Operator to calculate distances between the base item and the current item."));
113      Parameters.Add(new LookupParameter<DoubleValue>("CurrentNeutralDistance", "The distance of the current item to the starting point of the neutral (portion of the) walk."));
114      Parameters.Add(new LookupParameter<DoubleValue>("CurrentFractionOfNeutralNeighbors", "The fraction of examined neighbors that have the same fitness value (within epsilon)"));
115      Parameters.Add(new LookupParameter<IRandom>("Random", "Random number generator for breaking ties in the ordering."));
116      CopySelectedParameter.Hidden = true;
117      MaximizationParameter.Hidden = true;
118      NumberOfSelectedSubScopesParameter.Hidden = true;
119      BaseQualityParameter.Hidden = false;
120      QualityParameter.Hidden = false;
121      BaseSolutionParameter.Hidden = false;
122      StartingPointParameter.Hidden = true;
123      SolutionParameter.Hidden = false;
124      SolutionDistanceCalculatorParameter.Hidden = false;
125      StartingPointParameter.Hidden = false;
126      BaseQualityParameter.ActualName = "Quality";
127      BaseSolutionParameter.Path = "../Remaining/{0}";
128      BaseQualityParameter.Path = "../Remaining/{0}";
129      StartingPointParameter.Path = "..";
130      foreach (var v in ApplicationManager.Manager.GetInstances<IItemDistanceCalculator>())
131        SolutionDistanceCalculatorParameter.ValidValues.Add(v);
132    }
133    public override IDeepCloneable Clone(Cloner cloner) {
134      return new NeutralSelector(this, cloner);
135    }
136    [StorableHook(HookType.AfterDeserialization)]
137    private void AfterDeserialization() {
138      if (!Parameters.ContainsKey("CurrentFractionOfNeutralNeighbors"))
139        Parameters.Add(new LookupParameter<DoubleValue>("CurrentFractionOfNeutralNeighbors", "The fraction of examined neighbors that have the same fitness (within epsilon)"));
140    }
141    #endregion
142
143    private static double Squash(double d, double eps) {
144      return d <= eps ? 0 : d;
145    }
146
147    public sealed override IOperation Apply() {
148      var calc = (IItemDistanceCalculator)SolutionDistanceCalculatorParameter.ActualValue;
149      var baseQuality = BaseQualityParameter.ActualValue.Value;
150      var startingPoint = StartingPointParameter.ActualValue;
151      var baseSolution = BaseSolutionParameter.ActualValue;
152      var items = SolutionParameter.ActualValue;
153      var eps = EpsilonParameter.ActualValue.Value;
154      var random = RandomParameter.ActualValue;
155      double currentNeutralDistance;
156
157      if (startingPoint == null) {
158        currentNeutralDistance = 0;
159        CurrentNeutralDistance = 0;
160        startingPoint = baseSolution;
161        StartingPointParameter.ActualValue = (IItem)baseSolution.Clone();
162      } else {
163        currentNeutralDistance = calc.Distance(startingPoint, baseSolution);
164      }
165
166      var neighbors = QualityParameter.ActualValue
167        .Zip(items, (q, i) => new { Quality = q.Value, Item = i })
168        .Select((p, i) => new {
169          Idx = i,
170          Diff = Squash(Math.Abs(baseQuality - p.Quality), eps),
171          StartDist = calc.Distance(startingPoint, p.Item),
172          BaseDist = calc.Distance(baseSolution, p.Item)
173        })
174        .Where(n => n.BaseDist > 0)
175        .ToList();
176      if (neighbors.Count > 0) {
177        if (random != null)
178          neighbors.Shuffle(random);
179        var mostDistantNeutralNeighbor =
180          neighbors.Where(n => n.Diff == 0).OrderByDescending(n => n.StartDist).FirstOrDefault();
181        if (mostDistantNeutralNeighbor != null && mostDistantNeutralNeighbor.StartDist > currentNeutralDistance) {
182          if (currentNeutralDistance == 0) {
183            StartingPointParameter.ActualValue = (IItem)baseSolution.Clone();
184            CurrentNeutralDistance = mostDistantNeutralNeighbor.BaseDist;
185          } else {
186            CurrentNeutralDistance = mostDistantNeutralNeighbor.StartDist;
187          }
188          Select(mostDistantNeutralNeighbor.Idx);
189        } else {
190          var mostDistantNonNeutralNeighbor = neighbors.Where(n => n.Diff > 0).OrderByDescending(n => n.StartDist).FirstOrDefault();
191          if (mostDistantNonNeutralNeighbor != null) {
192            Select(mostDistantNonNeutralNeighbor.Idx);
193          } else {
194            var mostDistantNeighbor = neighbors.OrderByDescending(n => n.StartDist).FirstOrDefault();
195            Select(mostDistantNeighbor.Idx);
196          }
197          if (currentNeutralDistance > 0)
198            StartingPointParameter.ActualValue = (IItem)baseSolution.Clone();
199          CurrentNeutralDistance = 0;
200        }
201        CurrentFractionOfNeutralNeighbors = 1.0 * neighbors.Count(n => n.Diff == 0) / neighbors.Count;
202      }
203      return base.Apply();
204    }
205
206    private void Select(int i) {
207      List<IScope> scopes = new List<IScope>(CurrentScope.SubScopes);
208      bool copy = CopySelectedParameter.Value.Value;
209      bool maximization = MaximizationParameter.ActualValue.Value;
210      IScope[] selected = new IScope[1];
211      if (copy) {
212        selected[0] = (IScope)scopes[i].Clone();
213      } else {
214        selected[0] = scopes[i];
215        scopes[i] = null;
216        scopes.RemoveAll(x => x == null);
217      }
218      CurrentScope.SubScopes.Clear();
219      IScope remainingScope = new Scope("Remaining");
220      remainingScope.SubScopes.AddRange(scopes);
221      CurrentScope.SubScopes.Add(remainingScope);
222      IScope selectedScope = new Scope("Selected");
223      selectedScope.SubScopes.AddRange(selected);
224      CurrentScope.SubScopes.Add(selectedScope);
225    }
226  }
227}
Note: See TracBrowser for help on using the repository browser.