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

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

#2267 added crossover selection operators

File size: 7.9 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> CrossoverParameter {
47      get { return (LookupParameter<IOperator>)Parameters["Crossover"]; }
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
60    public override IDeepCloneable Clone(Cloner cloner) {
61      return new ProbabilitiesGenerator(this, cloner);
62    }
63    [StorableConstructor]
64    private ProbabilitiesGenerator(bool deserializing) : base(deserializing) { }
65    private ProbabilitiesGenerator(ProbabilitiesGenerator original, Cloner cloner) : base(original, cloner) { }
66    public ProbabilitiesGenerator()
67      : base() {
68      Parameters.Add(new ValueParameter<StringValue>("SuccessfulOffspringFlag", "The name of the flag which indicates if the individual was successful.", new StringValue("SuccessfulOffspring")));
69      Parameters.Add(new ValueParameter<StringValue>("OperatorNameVariable", "The properties of the successful offspring that should be collected.", new StringValue("SelectedCrossoverOperator")));
70      Parameters.Add(new LookupParameter<DoubleArray>("Probabilities"));
71      Parameters.Add(new LookupParameter<IOperator>("Crossover"));
72      Parameters.Add(new ValueParameter<DoubleValue>("MinimumOperatorUsage", "Minimum percentage of operator usage. ", new DoubleValue(0.05)));
73      Parameters.Add(new LookupParameter<ItemList<IScope>>("GeneratedOffspring", "Temporary store of the offspring population."));
74    }
75
76    public override IOperation Apply() {
77      if (GeneratedOffspringParameter.ActualValue == null) {
78        GeneratedOffspringParameter.ActualValue = new ItemList<IScope>();
79      }
80
81      var offspring = GeneratedOffspringParameter.ActualValue;
82      string operatorName = OperatorNameVariableParameter.Value.Value;
83      string succssFlag = SuccessfulOffspringFlagParameter.Value.Value;
84      Dictionary<string, int> operatorCount = new Dictionary<string, int>();
85      Dictionary<string, int> successfulOperatorCount = new Dictionary<string, int>();
86
87      var crossover = CrossoverParameter.ActualValue;
88      if (crossover.GetType().GetInterfaces().Any(x => x.IsGenericType &&
89        x.GetGenericTypeDefinition() == typeof(ICheckedMultiOperator<>))) {
90
91        for (int i = 0; i < offspring.Count; i++) {
92          // fetch values from scopes
93          IVariable tmpVar;
94          if (!offspring[i].Variables.TryGetValue(succssFlag, out tmpVar))
95            throw new InvalidOperationException(Name + ": Could not determine if an offspring was successful or not.");
96          BoolValue success = (tmpVar.Value as BoolValue);
97          if (success == null) throw new InvalidOperationException(Name + ": The variable that indicates whether an offspring is successful or not must contain a BoolValue.");
98
99          if (!offspring[i].Variables.TryGetValue(operatorName, out tmpVar))
100            throw new InvalidOperationException(Name + ": Could not determine operator an offspring was created with.");
101          StringValue op = (tmpVar.Value as StringValue);
102          if (op == null) throw new InvalidOperationException(Name + ": The variable the contains the operator name must be a string.");
103
104          if (!operatorCount.ContainsKey(op.Value)) {
105            operatorCount.Add(op.Value, 1);
106          } else {
107            operatorCount[op.Value]++;
108          }
109
110          if (success.Value) {
111            if (!successfulOperatorCount.ContainsKey(op.Value)) {
112              successfulOperatorCount.Add(op.Value, 1);
113            } else {
114              successfulOperatorCount[op.Value]++;
115            }
116          }
117        }
118
119        dynamic opCrossover = (dynamic)crossover;
120        int crossoverCount = (int)opCrossover.Operators.Count;
121        int checkedCrossoverCount = Enumerable.Count(opCrossover.Operators.CheckedItems);
122        dynamic[] crossoverNames = new dynamic[checkedCrossoverCount];
123        dynamic checkedItemsArray = Enumerable.ToArray(opCrossover.Operators.CheckedItems);
124
125        for (int i = 0; i < checkedCrossoverCount; i++) {
126          crossoverNames[i] = checkedItemsArray[i];
127        }
128
129        //initialize probabilities vector
130        if (ProbablilitiesParameter.ActualValue == null) {
131          ProbablilitiesParameter.ActualValue = new DoubleArray(crossoverCount);
132          for (int i = 0; i < crossoverCount; i++) {
133            ProbablilitiesParameter.ActualValue[i] = 1.0;
134          }
135          return base.Apply();
136        }
137
138        //fill probabilities vector
139        for (int i = 0; i < crossoverCount; i++) {
140          var cxNames = Enumerable.Where(crossoverNames, x => x.Index == i);
141
142          if (Enumerable.Any(cxNames)) {
143            var cxName = (string)Enumerable.Single(cxNames).Value.ItemName;
144            if (operatorCount.Any(x => x.Key.Contains(cxName))) {
145              int overallCount = operatorCount.Single(x => x.Key.Contains(cxName)).Value;
146              int successCount = 0;
147
148              if (successfulOperatorCount.Any(x => x.Key.Contains(cxName))) {
149                successCount = successfulOperatorCount.Single(x => x.Key.Contains(cxName)).Value;
150              }
151
152              double ratio = successCount / (double)overallCount;
153              if (ratio < MinimumOperatorUsageParameter.Value.Value) {
154                ratio = MinimumOperatorUsageParameter.Value.Value;
155              }
156              ProbablilitiesParameter.ActualValue[i] = ratio;
157            } else {
158              ProbablilitiesParameter.ActualValue[i] = MinimumOperatorUsageParameter.Value.Value;
159            }
160          } else {
161            ProbablilitiesParameter.ActualValue[i] = 0.0;
162          }
163        }
164
165        GeneratedOffspringParameter.ActualValue.Clear();
166      }
167
168      return base.Apply();
169    }
170  }
171}
Note: See TracBrowser for help on using the repository browser.