#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 HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; namespace HeuristicLab.Encodings.VariableVector { [StorableClass] [Item(Name = "IntVariable", Description = "")] public class IntVariable : Variable, IActionVariable { public override int VirtualLength { get { return 1; } } [Storable] public bool Wildcard { get; set; } [Storable] protected IEnumerable possibleFeatures; public IEnumerable PossibleFeatures { get { return possibleFeatures; } } [Storable] protected int currentValue; public int CurrentValue { get { return currentValue; } set { if (!possibleFeatures.Contains(value)) { throw new ArgumentException("Value is not a possible feature of this variable."); } currentValue = value; } } [StorableConstructor] protected IntVariable(bool deserializing) : base(deserializing) { } protected IntVariable(IntVariable original, Cloner cloner) : base(original, cloner) { this.possibleFeatures = new List(original.possibleFeatures); this.Wildcard = original.Wildcard; this.currentValue = original.currentValue; } public IntVariable() : base() { Wildcard = false; } public IntVariable(string variableName, IEnumerable variableValues) : base(variableName) { if (variableValues.Count() > 0 && variableValues.Count() != variableValues.Distinct().Count()) { throw new ArgumentException("variableValues have to be distinct and there has to be at least one value."); } possibleFeatures = variableValues; Wildcard = false; currentValue = possibleFeatures.First(); } public IntVariable(string variableName, IEnumerable variableValues, int currentValue) : this(variableName, variableValues) { CurrentValue = currentValue; } public override IDeepCloneable Clone(Cloner cloner) { return new IntVariable(this, cloner); } public override string ToString() { return Wildcard ? "#" : currentValue.ToString(); } public override bool MatchInput(string target) { return Match(int.Parse(target)); } public override bool Match(int target) { return Wildcard || CurrentValue == target; } public override bool MatchVariable(IVariable target) { var targetCast = target as IntVariable; return targetCast != null && this.variableName.Equals(targetCast.VariableName) && Match(targetCast.CurrentValue); } public override IVariable GetEmptyCopy() { return new IntVariable(variableName, possibleFeatures); } public override IVariable GetSetCopy() { IntVariable copy = (IntVariable)GetEmptyCopy(); copy.Wildcard = this.Wildcard; copy.CurrentValue = this.CurrentValue; return copy; } IActionVariable IActionVariable.GetEmptyCopy() { return (IntVariable)GetEmptyCopy(); } IActionVariable IActionVariable.GetSetCopy() { return (IntVariable)GetSetCopy(); } public void RandomizeAction(IRandom random) { int index = random.Next(possibleFeatures.Count()); currentValue = possibleFeatures.ElementAt(index); } public override void Randomize(IRandom random, double changeSymbolProbability) { Wildcard = random.NextDouble() < changeSymbolProbability; int index = random.Next(possibleFeatures.Count()); currentValue = possibleFeatures.ElementAt(index); } public override bool Identical(IVariable target) { var targetCast = target as IntVariable; if (targetCast == null) { return false; } if (variableName != targetCast.variableName || Wildcard != targetCast.Wildcard || currentValue != targetCast.currentValue) { return false; } var thisEnumerator = possibleFeatures.GetEnumerator(); var castEnumerator = targetCast.possibleFeatures.GetEnumerator(); while (thisEnumerator.MoveNext() && castEnumerator.MoveNext()) { if (thisEnumerator.Current != castEnumerator.Current) return false; } return !thisEnumerator.MoveNext() && !castEnumerator.MoveNext(); } public override double GetGenerality() { return Wildcard ? 1 : 0; } public override bool IsGreaterThanOrEquallyGeneral(IVariable target) { var targetCast = target as IntVariable; if (targetCast == null) { return false; } return Wildcard || currentValue == targetCast.currentValue; } public override IVariable CrossParentsAtPosition(IVariable parent2, int pos) { var parent2Cast = parent2 as IntVariable; if (parent2Cast == null) { throw new ArgumentException("Argument is not of the correct type."); } if (pos != 0) { throw new ArgumentOutOfRangeException(); } return (IntVariable)parent2.GetSetCopy(); } public override void Manipulate(IRandom random, string stringValue, int pos, double spreadPercentage) { Manipulate(random, stringValue, pos); } public override void Manipulate(IRandom random, string stringValue, int pos) { if (pos != 0) { throw new ArgumentOutOfRangeException(); } Wildcard = !Wildcard; if (!Wildcard) { currentValue = int.Parse(stringValue); } } public override void Cover(IRandom random, string stringValue, double changeSymbolProbability) { Wildcard = random.NextDouble() < changeSymbolProbability; if (!Wildcard) { currentValue = int.Parse(stringValue); } } public override int GetHashCode() { int result = 1; int wildcardInt = Wildcard ? 1 : 0; result = 37 * result + wildcardInt; result = 37 * result + currentValue; foreach (var feature in possibleFeatures) { result = 37 * result + feature; } return result; } #region IActionVariable Members public void SetTo(string value) { currentValue = int.Parse(value); } public IEnumerable GetAllPossibleActions() { return possibleFeatures.Select(x => x.ToString()); } #endregion } }