source: trunk/sources/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/General/Manipulators/BiasedMultiVRPSolutionManipulator.cs @ 10474

Last change on this file since 10474 was 10474, checked in by gkronber, 6 years ago

#2119: using RandomEnumerable.SampleProportional in BiasedMultiVRPOperators.

File size: 7.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2013 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.Linq;
24using HeuristicLab.Analysis;
25using HeuristicLab.Collections;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Data;
29using HeuristicLab.Optimization;
30using HeuristicLab.Parameters;
31using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
32using HeuristicLab.Random;
33
34namespace HeuristicLab.Problems.VehicleRouting.Encodings.General {
35  [Item("BiasedMultiVRPSolutionManipulator", "Randomly selects and applies one of its crossovers every time it is called based on the success progress.")]
36  [StorableClass]
37  public class BiasedMultiVRPSolutionManipulator : MultiVRPSolutionManipulator {
38    public ValueLookupParameter<DoubleArray> ActualProbabilitiesParameter {
39      get { return (ValueLookupParameter<DoubleArray>)Parameters["ActualProbabilities"]; }
40    }
41
42    public ValueLookupParameter<StringValue> SuccessProgressAnalyisis {
43      get { return (ValueLookupParameter<StringValue>)Parameters["SuccessProgressAnalysis"]; }
44    }
45
46    public ValueLookupParameter<DoubleValue> Factor {
47      get { return (ValueLookupParameter<DoubleValue>)Parameters["Factor"]; }
48    }
49
50    public ValueParameter<DoubleValue> LowerBoundParameter {
51      get { return (ValueParameter<DoubleValue>)Parameters["LowerBound"]; }
52    }
53
54    public ValueParameter<IntValue> DepthParameter {
55      get { return (ValueParameter<IntValue>)Parameters["Depth"]; }
56    }
57
58    [StorableConstructor]
59    protected BiasedMultiVRPSolutionManipulator(bool deserializing) : base(deserializing) { }
60    protected BiasedMultiVRPSolutionManipulator(BiasedMultiVRPSolutionManipulator original, Cloner cloner) : base(original, cloner) { }
61    public BiasedMultiVRPSolutionManipulator()
62      : base() {
63      Parameters.Add(new ValueLookupParameter<DoubleArray>("ActualProbabilities", "The array of relative probabilities for each operator."));
64      Parameters.Add(new ValueLookupParameter<StringValue>("SuccessProgressAnalysis", "The success progress analyisis to be considered",
65        new StringValue("ExecutedMutationOperator")));
66
67      Parameters.Add(new ValueLookupParameter<DoubleValue>("Factor", "The factor with which the probabilities should be updated", new DoubleValue(0.2)));
68      Parameters.Add(new ValueParameter<DoubleValue>("LowerBound", "The depth of the individuals in the scope tree.", new DoubleValue(0.01)));
69      Parameters.Add(new ValueParameter<IntValue>("Depth", "The depth of the individuals in the scope tree.", new IntValue(1)));
70
71      SelectedOperatorParameter.ActualName = "SelectedManipulationOperator";
72    }
73
74    public override IDeepCloneable Clone(Cloner cloner) {
75      return new BiasedMultiVRPSolutionManipulator(this, cloner);
76    }
77
78    public override void InitializeState() {
79      base.InitializeState();
80
81      ActualProbabilitiesParameter.Value = null;
82    }
83
84    public override IOperation InstrumentedApply() {
85      IOperator successor = null;
86
87      if (ActualProbabilitiesParameter.ActualValue == null) {
88        ActualProbabilitiesParameter.Value = ProbabilitiesParameter.ActualValue.Clone() as DoubleArray;
89      } else {
90        String key = "SuccessfulOffspringAnalyzer Results";
91
92        ResultCollection results = null;
93        IScope scope = ExecutionContext.Parent.Scope;
94        int depth = 1;
95        while (scope != null && depth < DepthParameter.Value.Value) {
96          scope = scope.Parent;
97          depth++;
98        }
99        if (scope != null)
100          results = scope.Variables["Results"].Value as ResultCollection;
101
102        if (results != null && results.ContainsKey(key)) {
103          ResultCollection successProgressAnalysisResult = results[key].Value as ResultCollection;
104          key = SuccessProgressAnalyisis.Value.Value;
105
106          if (successProgressAnalysisResult.ContainsKey(key)) {
107            DataTable successProgressAnalysis = successProgressAnalysisResult[key].Value as DataTable;
108
109            for (int i = 0; i < Operators.Count; i++) {
110              IOperator current = Operators[i];
111
112              if (successProgressAnalysis.Rows.ContainsKey(current.Name)) {
113                DataRow row = successProgressAnalysis.Rows[current.Name];
114
115                double sum = 0.0;
116                ObservableList<double> usages = row.Values;
117
118                sum += usages.Last();
119
120                ActualProbabilitiesParameter.ActualValue[i] += (sum / ActualProbabilitiesParameter.ActualValue[i]) * Factor.Value.Value;
121              }
122            }
123          }
124        }
125
126        //normalize
127        double max = ActualProbabilitiesParameter.ActualValue.Max();
128        for (int i = 0; i < ActualProbabilitiesParameter.ActualValue.Length; i++) {
129          ActualProbabilitiesParameter.ActualValue[i] /= max;
130          ActualProbabilitiesParameter.ActualValue[i] =
131            Math.Max(LowerBoundParameter.Value.Value,
132            ActualProbabilitiesParameter.ActualValue[i]);
133        }
134      }
135
136      //////////////// code has to be duplicated since ActualProbabilitiesParameter.ActualValue are updated and used for operator selection
137      IRandom random = RandomParameter.ActualValue;
138      DoubleArray probabilities = ActualProbabilitiesParameter.ActualValue;
139      if (probabilities.Length != Operators.Count) {
140        throw new InvalidOperationException(Name + ": The list of probabilities has to match the number of operators");
141      }
142      var checkedOperators = Operators.CheckedItems;
143      if (checkedOperators.Count() > 0) {
144        // select a random operator from the checked operators
145        successor =
146          checkedOperators.SampleProportional(random, 1, probabilities, false, false).First().Value;
147      }
148
149      IOperation successorOp = null;
150      if (Successor != null)
151        successorOp = ExecutionContext.CreateOperation(Successor);
152      OperationCollection next = new OperationCollection(successorOp);
153      if (successor != null) {
154        SelectedOperatorParameter.ActualValue = new StringValue(successor.Name);
155
156        if (CreateChildOperation)
157          next.Insert(0, ExecutionContext.CreateChildOperation(successor));
158        else next.Insert(0, ExecutionContext.CreateOperation(successor));
159      } else {
160        SelectedOperatorParameter.ActualValue = new StringValue("");
161      }
162
163      return next;
164    }
165  }
166}
Note: See TracBrowser for help on using the repository browser.