#region License Information /* HeuristicLab * Copyright (C) 2002-2012 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.Common; using HeuristicLab.Core; using HeuristicLab.Optimization.Operators.LCS; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; namespace HeuristicLab.Encodings.DecisionList { [StorableClass] [Item("Rule", "")] public class Rule : Item { [Storable] private IDictionary variables; public IDictionary Variables { get { return variables; } } [Storable] private IAction action; public IAction Action { get { return action; } } public double Length { get { return variables.Values.Sum(x => x.Length); } } [StorableConstructor] protected Rule(bool deserializing) : base(deserializing) { } protected Rule(Rule original, Cloner cloner) : base(original, cloner) { variables = new Dictionary(original.variables.Count); foreach (var item in original.variables) { variables.Add(item.Key, cloner.Clone(item.Value)); } action = (IAction)original.action.Clone(); } public Rule() : base() { variables = new Dictionary(); } public Rule(IEnumerable condition, IAction action) : this() { foreach (var variable in condition) { variables.Add(variable.VariableName, variable); } this.action = action; } public override IDeepCloneable Clone(Cloner cloner) { return new Rule(this, cloner); } public override string ToString() { StringBuilder sb = new StringBuilder(); foreach (var variable in Variables) { sb.Append(variable.Value + "|"); } sb.Append("|" + Action); return sb.ToString(); } public void Randomize(IRandom random, double oneProbability, IEnumerable discretizers, IEnumerable exceptActions = null) { foreach (var variable in variables.Values) { variable.Randomize(random, oneProbability, discretizers); } if (exceptActions == null) { action.Randomize(random); } else { action.Randomize(random, exceptActions); } } public void SetToMatchInput(IGAssistInput input) { foreach (var variable in variables) { if (!input.VariableNames.Contains(variable.Key)) { throw new ArgumentException("input does not contain variable name of rule"); } variable.Value.SetToMatch(input.GetVariableValue(variable.Key)); } } public double ComputeTheoryLength() { return variables.Sum(x => x.Value.ComputeTheoryLength()); } public bool MatchInput(IGAssistInput target) { foreach (var variable in variables) { if (!target.VariableNames.Contains(variable.Key)) { throw new ArgumentException("Input doesn't contain variable"); } if (!variable.Value.Match(target.GetVariableValue(variable.Key))) { return false; } } return true; } public Rule Crossover(Rule rule, IRandom random) { //variables and rule.Variables have to be the same int cutpoint = random.Next(0, Variables.Count); var crossedVariables = new List(variables.Count); var variableNames = variables.Keys.ToList(); for (int i = 0; i < cutpoint; i++) { crossedVariables.Add(this.Variables[variableNames[i]]); } for (int i = cutpoint; i < variables.Count; i++) { crossedVariables.Add(rule.Variables[variableNames[i]]); } IAction action = random.Next(0, 2) == 0 ? this.action : rule.action; return new Rule(crossedVariables, action); } public void ApplySplit(IRandom random, double probability) { foreach (var variable in variables.Values) { if (random.NextDouble() < probability) variable.Split(random); } } public void ApplyMerge(IRandom random, double probability) { foreach (var variable in variables.Values) { if (random.NextDouble() < probability) variable.Merge(random); } } public void ApplyReinitialize(IRandom random, double probability, double oneProbability, IEnumerable discretizers) { foreach (var variable in variables.Values) { if (random.NextDouble() < probability) variable.Reinitialize(random, oneProbability, discretizers); } } } }