source: branches/VOSGA/HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm/ProbabilitiesGenerator.cs @ 11518

Last change on this file since 11518 was 11518, checked in by ascheibe, 8 years ago

#2267 added probabilities to results

File size: 8.5 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2014 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.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Operators;
29using HeuristicLab.Optimization;
30using HeuristicLab.Parameters;
31using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
32
33namespace HeuristicLab.Algorithms.VOffspringSelectionGeneticAlgorithm {
34  [Item("ProbabilitiesGenerator", "An operator the generates the probability vector for Multi Crossovers/Mutators")]
35  [StorableClass]
36  public class ProbabilitiesGenerator : SingleSuccessorOperator, IAnalyzer {
37    public bool EnabledByDefault {
38      get { return false; }
39    }
40    public ValueParameter<StringValue> SuccessfulOffspringFlagParameter {
41      get { return (ValueParameter<StringValue>)Parameters["SuccessfulOffspringFlag"]; }
42    }
43    public ValueParameter<StringValue> OperatorNameVariableParameter {
44      get { return (ValueParameter<StringValue>)Parameters["OperatorNameVariable"]; }
45    }
46    public LookupParameter<IOperator> OperatorParameter {
47      get { return (LookupParameter<IOperator>)Parameters["Operator"]; }
48    }
49    public LookupParameter<DoubleArray> ProbablilitiesParameter {
50      get { return (LookupParameter<DoubleArray>)Parameters["Probabilities"]; }
51
52    }
53    public ValueParameter<DoubleValue> MinimumOperatorUsageParameter {
54      get { return (ValueParameter<DoubleValue>)Parameters["MinimumOperatorUsage"]; }
55    }
56    public LookupParameter<ItemList<IScope>> GeneratedOffspringParameter {
57      get { return (LookupParameter<ItemList<IScope>>)Parameters["GeneratedOffspring"]; }
58    }
59    public ValueLookupParameter<ResultCollection> ResultsParameter {
60      get { return (ValueLookupParameter<ResultCollection>)Parameters["Results"]; }
61    }
62    public override IDeepCloneable Clone(Cloner cloner) {
63      return new ProbabilitiesGenerator(this, cloner);
64    }
65    [StorableConstructor]
66    private ProbabilitiesGenerator(bool deserializing) : base(deserializing) { }
67    private ProbabilitiesGenerator(ProbabilitiesGenerator original, Cloner cloner) : base(original, cloner) { }
68    public ProbabilitiesGenerator()
69      : base() {
70      Parameters.Add(new ValueParameter<StringValue>("SuccessfulOffspringFlag", "The name of the flag which indicates if the individual was successful.", new StringValue("SuccessfulOffspring")));
71      Parameters.Add(new ValueParameter<StringValue>("OperatorNameVariable", "The properties of the successful offspring that should be collected.", new StringValue("SelectedCrossoverOperator")));
72      Parameters.Add(new LookupParameter<DoubleArray>("Probabilities", "The probability vector a multi crossover/mutator uses to decide which operator to use"));
73      Parameters.Add(new LookupParameter<IOperator>("Operator", "The multioperator that contains the list of used crossovers/mutators", "Crossover"));
74      Parameters.Add(new ValueParameter<DoubleValue>("MinimumOperatorUsage", "Minimum percentage of operator usage. ", new DoubleValue(0.05)));
75      Parameters.Add(new LookupParameter<ItemList<IScope>>("GeneratedOffspring", "Temporary store of the offspring population."));
76      Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The result collection where the population diversity analysis results should be stored."));
77
78    }
79
80    public override IOperation Apply() {
81      if (GeneratedOffspringParameter.ActualValue == null) {
82        GeneratedOffspringParameter.ActualValue = new ItemList<IScope>();
83      }
84
85      var offspring = GeneratedOffspringParameter.ActualValue;
86      string operatorName = OperatorNameVariableParameter.Value.Value;
87      string succssFlag = SuccessfulOffspringFlagParameter.Value.Value;
88      Dictionary<string, int> operatorCount = new Dictionary<string, int>();
89      Dictionary<string, int> successfulOperatorCount = new Dictionary<string, int>();
90
91      var crossover = OperatorParameter.ActualValue;
92      if (crossover.GetType().GetInterfaces().Any(x => x.IsGenericType &&
93        x.GetGenericTypeDefinition() == typeof(ICheckedMultiOperator<>))) {
94
95        for (int i = 0; i < offspring.Count; i++) {
96          // fetch values from scopes
97          IVariable tmpVar;
98          if (!offspring[i].Variables.TryGetValue(succssFlag, out tmpVar))
99            throw new InvalidOperationException(Name + ": Could not determine if an offspring was successful or not.");
100          BoolValue success = (tmpVar.Value as BoolValue);
101          if (success == null) throw new InvalidOperationException(Name + ": The variable that indicates whether an offspring is successful or not must contain a BoolValue.");
102
103          if (!offspring[i].Variables.TryGetValue(operatorName, out tmpVar))
104            throw new InvalidOperationException(Name + ": Could not determine operator an offspring was created with.");
105          StringValue op = (tmpVar.Value as StringValue);
106          if (op == null) throw new InvalidOperationException(Name + ": The variable the contains the operator name must be a string.");
107
108          if (!operatorCount.ContainsKey(op.Value)) {
109            operatorCount.Add(op.Value, 1);
110          } else {
111            operatorCount[op.Value]++;
112          }
113
114          if (success.Value) {
115            if (!successfulOperatorCount.ContainsKey(op.Value)) {
116              successfulOperatorCount.Add(op.Value, 1);
117            } else {
118              successfulOperatorCount[op.Value]++;
119            }
120          }
121        }
122
123        dynamic opCrossover = (dynamic)crossover;
124        int crossoverCount = (int)opCrossover.Operators.Count;
125        int checkedCrossoverCount = Enumerable.Count(opCrossover.Operators.CheckedItems);
126        dynamic[] crossoverNames = new dynamic[checkedCrossoverCount];
127        dynamic checkedItemsArray = Enumerable.ToArray(opCrossover.Operators.CheckedItems);
128
129        for (int i = 0; i < checkedCrossoverCount; i++) {
130          crossoverNames[i] = checkedItemsArray[i];
131        }
132
133        //initialize probabilities vector
134        if (ProbablilitiesParameter.ActualValue == null) {
135          ProbablilitiesParameter.ActualValue = new DoubleArray(crossoverCount);
136          ResultsParameter.ActualValue.Add(new Result("Probabilities", ProbablilitiesParameter.ActualValue));
137          for (int i = 0; i < crossoverCount; i++) {
138            ProbablilitiesParameter.ActualValue[i] = 1.0;
139          }
140          return base.Apply();
141        }
142
143        //fill probabilities vector
144        for (int i = 0; i < crossoverCount; i++) {
145          var cxNames = Enumerable.Where(crossoverNames, x => x.Index == i);
146
147          if (Enumerable.Any(cxNames)) {
148            var cxName = (string)Enumerable.Single(cxNames).Value.ItemName;
149            if (operatorCount.Any(x => x.Key.Contains(cxName))) {
150              int overallCount = operatorCount.Single(x => x.Key.Contains(cxName)).Value;
151              int successCount = 0;
152
153              if (successfulOperatorCount.Any(x => x.Key.Contains(cxName))) {
154                successCount = successfulOperatorCount.Single(x => x.Key.Contains(cxName)).Value;
155              }
156
157              double ratio = successCount / (double)overallCount;
158              if (ratio < MinimumOperatorUsageParameter.Value.Value) {
159                ratio = MinimumOperatorUsageParameter.Value.Value;
160              }
161              ProbablilitiesParameter.ActualValue[i] = ratio;
162            } else {
163              ProbablilitiesParameter.ActualValue[i] = MinimumOperatorUsageParameter.Value.Value;
164            }
165          } else {
166            ProbablilitiesParameter.ActualValue[i] = 0.0;
167          }
168        }
169
170        GeneratedOffspringParameter.ActualValue.Clear();
171      }
172
173      return base.Apply();
174    }
175  }
176}
Note: See TracBrowser for help on using the repository browser.