Ignore:
Timestamp:
04/19/10 23:34:34 (12 years ago)
Author:
abeham
Message:

Changed MultiCrossover to StochasticMultiOperator
Derived StochasticMultiBranch from StochasticMultiOperator
Derived encoding specific mutation/crossover operators from StochasticMultiOperator
#976

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Operators/3.3/StochasticMultiBranch.cs

    r3418 r3425  
    2020#endregion
    2121
    22 using System;
    23 using System.Collections.Generic;
    24 using System.Collections.ObjectModel;
    25 using System.Linq;
    26 using HeuristicLab.Collections;
    27 using HeuristicLab.Common;
    2822using HeuristicLab.Core;
    29 using HeuristicLab.Data;
    30 using HeuristicLab.Parameters;
    3123using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    3224
     
    3729  [Item("StochasticMultiBranch", "Branch of operators that have different probabilities to get executed.")]
    3830  [StorableClass]
    39   public class StochasticMultiBranch : MultiOperator<IOperator> {
    40     public ValueLookupParameter<DoubleArray> ProbabilitiesParameter {
    41       get { return (ValueLookupParameter<DoubleArray>)Parameters["Probabilities"]; }
    42     }
    43     public ILookupParameter<IRandom> RandomParameter {
    44       get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
    45     }
    46 
    47     public DoubleArray Probabilities {
    48       get { return ProbabilitiesParameter.Value; }
    49       set { ProbabilitiesParameter.Value = value; }
    50     }
    51 
    52     [StorableConstructor]
    53     public StochasticMultiBranch(bool deserializing) : base() { }
    54     /// <summary>
    55     /// Initializes a new instance of <see cref="StochasticMultiBranch"/> with two parameters
    56     /// (<c>Probabilities</c> and <c>Random</c>).
    57     /// </summary>
    58     public StochasticMultiBranch()
    59       : base() {
    60       Parameters.Add(new ValueLookupParameter<DoubleArray>("Probabilities", "The array of relative probabilities for each operator.", new DoubleArray()));
    61       Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
    62       Initialize();
    63     }
    64 
    65     [StorableHook(HookType.AfterDeserialization)]
    66     private void Initialize() {
    67       Operators.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<IOperator>>(Operators_ItemsAdded);
    68       Operators.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<IOperator>>(Operators_ItemsRemoved);
    69       Operators.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<IOperator>>(Operators_ItemsMoved);
    70     }
    71 
    72     void Operators_ItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOperator>> e) {
    73       if (Probabilities != null) {
    74         DoubleArray oldProb = (DoubleArray)Probabilities.Clone();
    75         foreach (IndexedItem<IOperator> old in e.OldItems) {
    76           foreach (IndexedItem<IOperator> item in e.Items) {
    77             if (old.Value == item.Value && item.Index < Probabilities.Length && old.Index < oldProb.Length)
    78               Probabilities[item.Index] = oldProb[old.Index];
    79           }
    80         }
    81       }
    82     }
    83 
    84     void Operators_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOperator>> e) {
    85       if (Probabilities != null && Probabilities.Length > Operators.Count) {
    86         List<double> probs = new List<double>(Probabilities.Cast<DoubleValue>().Select(x => x.Value));
    87         var sorted = e.Items.OrderByDescending(x => x.Index);
    88         foreach (IndexedItem<IOperator> item in sorted)
    89           if (probs.Count > item.Index) probs.RemoveAt(item.Index);
    90         Probabilities = new DoubleArray(probs.ToArray());
    91       }
    92     }
    93 
    94     private void Operators_ItemsAdded(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IndexedItem<IOperator>> e) {
    95       if (Probabilities != null && Probabilities.Length < Operators.Count) {
    96         DoubleArray probs = new DoubleArray(Operators.Count);
    97         double avg = 0;
    98         if (Probabilities.Length > 0) {
    99           for (int i = 0; i < Probabilities.Length; i++)
    100             avg += Probabilities[i];
    101           avg /= (double)Probabilities.Length;
    102         } else avg = 1;
    103 
    104         var added = e.Items.OrderBy(x => x.Index).ToList();
    105         int insertCount = 0;
    106         for (int i = 0; i < Operators.Count; i++) {
    107           if (insertCount < added.Count && i == added[insertCount].Index) {
    108             probs[i] = avg;
    109             insertCount++;
    110           } else if (i - insertCount < Probabilities.Length) {
    111             probs[i] = Probabilities[i - insertCount];
    112           } else probs[i] = avg;
    113         }
    114         Probabilities = probs;
    115       }
    116     }
    117 
    118     /// <summary>
    119     /// Applies an operator of the branches to the current scope with a
    120     /// specific probability.
    121     /// </summary>
    122     /// <exception cref="InvalidOperationException">Thrown when the list of probabilites does not
    123     /// match the number of operators.</exception>
    124     /// <returns>A new operation with the operator that was selected followed by the current operator's successor.</returns>
    125     public override IOperation Apply() {
    126       IRandom random = RandomParameter.ActualValue;
    127       DoubleArray probabilities = ProbabilitiesParameter.ActualValue;
    128       if(probabilities.Length != Operators.Count) {
    129         throw new InvalidOperationException("StochasticMultiBranch: The list of probabilities has to match the number of operators");
    130       }
    131       double sum = 0;
    132       for (int i = 0; i < Operators.Count; i++) {
    133         sum += probabilities[i];
    134       }
    135       double r = random.NextDouble() * sum;
    136       sum = 0;
    137       IOperator successor = null;
    138       for(int i = 0; i < Operators.Count; i++) {
    139         sum += probabilities[i];
    140         if(sum > r) {
    141           successor = Operators[i];
    142           break;
    143         }
    144       }
    145       OperationCollection next = new OperationCollection(base.Apply());
    146       if (successor != null) {
    147         next.Insert(0, ExecutionContext.CreateOperation(successor));
    148       }
    149       return next;
     31  public class StochasticMultiBranch : StochasticMultiOperator<IOperator> {
     32    protected override bool CreateChildOperation {
     33      get { return false; }
    15034    }
    15135  }
Note: See TracChangeset for help on using the changeset viewer.