#region License Information /* HeuristicLab * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Linq; using System.Text; using HeuristicLab.Core; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Common; using HeuristicLab.Analysis; using HeuristicLab.Parameters; using HeuristicLab.Optimization; using HeuristicLab.Data; using HeuristicLab.Collections; namespace HeuristicLab.Problems.VehicleRouting.Encodings.General { [Item("BiasedMultiVRPSolutionManipulator", "Randomly selects and applies one of its crossovers every time it is called based on the success progress.")] [StorableClass] public class BiasedMultiVRPSolutionManipulator : MultiVRPSolutionManipulator { public ValueLookupParameter ActualProbabilitiesParameter { get { return (ValueLookupParameter)Parameters["ActualProbabilities"]; } } public ValueLookupParameter LastUpdateParameter { get { return (ValueLookupParameter)Parameters["LastUpdate"]; } } public ValueLookupParameter ResultsParameter { get { return (ValueLookupParameter)Parameters["Results"]; } } public ValueLookupParameter SuccessProgressAnalyisis { get { return (ValueLookupParameter)Parameters["SuccessProgressAnalysis"]; } } public ValueLookupParameter Interval { get { return (ValueLookupParameter)Parameters["Interval"]; } } public ValueLookupParameter Factor { get { return (ValueLookupParameter)Parameters["Factor"]; } } public LookupParameter Generations { get { return (LookupParameter)Parameters["Generations"]; } } [StorableConstructor] protected BiasedMultiVRPSolutionManipulator(bool deserializing) : base(deserializing) { } protected BiasedMultiVRPSolutionManipulator(BiasedMultiVRPSolutionManipulator original, Cloner cloner) : base(original, cloner) { } public BiasedMultiVRPSolutionManipulator() : base() { Parameters.Add(new ValueLookupParameter("ActualProbabilities", "The array of relative probabilities for each operator.")); Parameters.Add(new ValueLookupParameter("Results", "The result collection where the succedd progress analysis results should be stored.")); Parameters.Add(new ValueLookupParameter("SuccessProgressAnalysis", "The success progress analyisis to be considered", new StringValue("Success Progress ExecutedMutationOperator"))); Parameters.Add(new ValueLookupParameter("Interval", "The interval the probabilities should be updated", new IntValue(1))); Parameters.Add(new ValueLookupParameter("LastUpdate", "Specifies when the probabilities were last updated", new IntValue(0))); Parameters.Add(new ValueLookupParameter("Factor", "The factor with which the probabilities should be updated", new DoubleValue(35))); Parameters.Add(new LookupParameter("Generations", "The current number of generations.")); } public override IDeepCloneable Clone(Cloner cloner) { return new BiasedMultiVRPSolutionManipulator(this, cloner); } public override IOperation Apply() { int generations = Generations.ActualValue.Value; int interval = Interval.ActualValue.Value; if (generations == 0) { ActualProbabilitiesParameter.Value = ProbabilitiesParameter.ActualValue.Clone() as DoubleArray; LastUpdateParameter.Value = new IntValue(0); } else if (generations % interval == 0 && LastUpdateParameter.Value.Value != generations) { String key = SuccessProgressAnalyisis.ActualValue.Value; if (ResultsParameter.ActualValue != null && ResultsParameter.ActualValue.ContainsKey(key)) { DataTable successProgressAnalysis = ResultsParameter.ActualValue[key].Value as DataTable; for (int i = 0; i < Operators.Count; i++) { IOperator current = Operators[i]; if (successProgressAnalysis.Rows.ContainsKey(current.Name)) { DataRow row = successProgressAnalysis.Rows[current.Name]; double sum = 0.0; ObservableList usages = row.Values; int end = generations; int start = generations - interval; if (end - start > 0) { for (int j = start; j < end; j++) { sum += (double)usages[j]; } ActualProbabilitiesParameter.Value[i] += ((sum / (end - start)) / ActualProbabilitiesParameter.Value[i]) * Factor.Value.Value; } } } } //normalize double max = ActualProbabilitiesParameter.Value.Max(); for (int i = 0; i < ActualProbabilitiesParameter.Value.Length; i++) { ActualProbabilitiesParameter.Value[i] /= max; } LastUpdateParameter.Value.Value = generations; } //////////////// IRandom random = RandomParameter.ActualValue; DoubleArray probabilities = ActualProbabilitiesParameter.ActualValue; if (probabilities.Length != Operators.Count) { throw new InvalidOperationException(Name + ": The list of probabilities has to match the number of operators"); } IOperator successor = null; var checkedOperators = Operators.CheckedItems; if (checkedOperators.Count() > 0) { // select a random operator from the checked operators double sum = (from indexedItem in checkedOperators select probabilities[indexedItem.Index]).Sum(); if (sum == 0) throw new InvalidOperationException(Name + ": All selected operators have zero probability."); double r = random.NextDouble() * sum; sum = 0; foreach (var indexedItem in checkedOperators) { sum += probabilities[indexedItem.Index]; if (sum > r) { successor = indexedItem.Value; break; } } } IOperation successorOp = null; if (Successor != null) successorOp = ExecutionContext.CreateOperation(Successor); OperationCollection next = new OperationCollection(successorOp); if (successor != null) { ExecutedOperatorParameter.ActualValue = new StringValue(successor.GetType().Name); if (CreateChildOperation) next.Insert(0, ExecutionContext.CreateChildOperation(successor)); else next.Insert(0, ExecutionContext.CreateOperation(successor)); } else { ExecutedOperatorParameter.ActualValue = new StringValue(""); } return next; } } }