#region License Information
/* HeuristicLab
* Copyright (C) 2002-2008 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.Text;
using HeuristicLab.Core;
using HeuristicLab.Data;
namespace HeuristicLab.Evolutionary {
///
/// Adjusts the mutation strength based on the ratio of successful offsprings.
///
public class SuccessRuleMutationStrengthAdjuster : OperatorBase {
///
public override string Description {
get { return @"Adjusts the mutation strength based on the ratio of successful offsprings"; }
}
///
/// Initializes a new instance of with six variable
/// infos (ShakingFactor, SuccessfulChild, TargetSuccessProbability,
/// SuccessProbability, LearningRate and DampeningFactor).
///
public SuccessRuleMutationStrengthAdjuster() {
AddVariableInfo(new VariableInfo("ShakingFactor", "The mutation strength to adjust", typeof(DoubleData), VariableKind.In | VariableKind.Out));
AddVariableInfo(new VariableInfo("SuccessfulChild", "Variable that tells if a child has become better than its parent", typeof(BoolData), VariableKind.In | VariableKind.Deleted));
AddVariableInfo(new VariableInfo("TargetSuccessProbability", "The targeted probability to create a successful offsrping", typeof(DoubleData), VariableKind.In));
AddVariableInfo(new VariableInfo("SuccessProbability", "The measured probability to create a successful offspring", typeof(DoubleData), VariableKind.New | VariableKind.In | VariableKind.Out));
AddVariableInfo(new VariableInfo("LearningRate", "The speed at which the success probability changes", typeof(DoubleData), VariableKind.In));
AddVariableInfo(new VariableInfo("DampeningFactor", "Influences the strength of the adjustment to the mutation strength", typeof(DoubleData), VariableKind.In));
}
///
/// Adjusts the mutation strength based on the ratio of successful offsprings.
///
/// The current scope where to adjust the mutation strength.
/// null.
public override IOperation Apply(IScope scope) {
DoubleData shakingFactor = GetVariableValue("ShakingFactor", scope, true);
DoubleData targetSuccessProb = GetVariableValue("TargetSuccessProbability", scope, true);
DoubleData successProb = GetVariableValue("SuccessProbability", scope, true);
if (successProb == null) {
IVariableInfo successProbInfo = GetVariableInfo("SuccessProbability");
IVariable successProbVar;
if (successProbInfo.Local) {
successProbVar = new Variable(successProbInfo.ActualName, new DoubleData(targetSuccessProb.Data));
AddVariable(successProbVar);
} else {
successProbVar = new Variable(scope.TranslateName(successProbInfo.FormalName), new DoubleData(targetSuccessProb.Data));
scope.AddVariable(successProbVar);
}
successProb = (DoubleData)successProbVar.Value;
}
DoubleData learningRate = GetVariableValue("LearningRate", scope, true);
DoubleData dampeningFactor = GetVariableValue("DampeningFactor", scope, true);
double success = 0.0;
for (int i = 0 ; i < scope.SubScopes.Count ; i++) {
if (scope.SubScopes[i].GetVariableValue("SuccessfulChild", false).Data) {
success++;
}
scope.SubScopes[i].RemoveVariable(scope.SubScopes[i].TranslateName("SuccessfulChild"));
}
if (scope.SubScopes.Count > 0) success /= scope.SubScopes.Count;
successProb.Data = (1.0 - learningRate.Data) * successProb.Data + success * learningRate.Data;
shakingFactor.Data *= Math.Exp((successProb.Data - ((targetSuccessProb.Data * (1.0 - successProb.Data)) / (1.0 - targetSuccessProb.Data))) / dampeningFactor.Data);
return null;
}
}
}