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

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

#2267 added OSGA source from r11490

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