#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
}
}