#region License Information /* HeuristicLab * Copyright (C) 2002-2015 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 HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; namespace HeuristicLab.Optimization { [Item("ComparisonTerminator", "An termination criterion which compares two values.")] [StorableClass] public class ComparisonTerminator : ThresholdTerminator where T : class, IItem, IComparable, IStringConvertibleValue, new() { public ILookupParameter ComparisonValueParameter { get { return (ILookupParameter)Parameters["ComparisonValue"]; } } private IFixedValueParameter ComparisonParameter { get { return (IFixedValueParameter)Parameters["Comparison"]; } } public ComparisonType ComparisonType { get { return ComparisonParameter.Value.Value; } set { ComparisonParameter.Value.Value = value; } } [StorableConstructor] protected ComparisonTerminator(bool deserializing) : base(deserializing) { } [StorableHook(HookType.AfterDeserialization)] private void AfterDeserialization() { Initialize(); } protected ComparisonTerminator(ComparisonTerminator original, Cloner cloner) : base(original, cloner) { Initialize(); } public override IDeepCloneable Clone(Cloner cloner) { return new ComparisonTerminator(this, cloner); } public ComparisonTerminator() : this(new T()) { } public ComparisonTerminator(T threshold) : base(threshold) { Parameters.Add(new LookupParameter("ComparisonValue", "The left side value of the comparison.") { Hidden = false }); Parameters.Add(new FixedValueParameter("Comparison", "The type of comparison.")); Initialize(); } public ComparisonTerminator(string comparisonValueActualName, ComparisonType comparisonType, T threshold) : this(threshold) { ComparisonValueParameter.ActualName = comparisonValueActualName; ComparisonType = comparisonType; } public ComparisonTerminator(string comparisonValueActualName, ComparisonType comparisonType, IFixedValueParameter thresholdParameter) : this() { ComparisonValueParameter.ActualName = comparisonValueActualName; ComparisonType = comparisonType; ThresholdParameter = thresholdParameter; } protected override bool CheckContinueCriterion() { IComparable lhs = ComparisonValueParameter.ActualValue; IComparable rhs = ThresholdParameter.Value; return ComparisonType.Compare(lhs, rhs); } private void Initialize() { ComparisonParameter.Value.ValueChanged += new EventHandler(ComparisonType_ValueChanged); } private void ComparisonType_ValueChanged(object sender, EventArgs e) { OnComparisonTypeChanged(); } protected virtual void OnComparisonTypeChanged() { OnToStringChanged(); } public override void CollectParameterValues(IDictionary values) { base.CollectParameterValues(values); values.Add(ComparisonValueParameter.Name, new StringValue(ComparisonValueParameter.ActualName)); } public override string ToString() { if (Threshold == null) return Name; else return string.Format("{0} {1} {2}", Name, ComparisonType.ToSymbol(), ThresholdParameter.Value); } } internal static class ComparisonTypeHelper { public static bool Compare(this ComparisonType comparison, IComparable lhs, IComparable rhs) { int i = lhs.CompareTo(rhs); switch (comparison) { case ComparisonType.Less: return i < 0; case ComparisonType.LessOrEqual: return i <= 0; case ComparisonType.Equal: return i == 0; case ComparisonType.GreaterOrEqual: return i >= 0; case ComparisonType.Greater: return i > 0; case ComparisonType.NotEqual: return i != 0; default: throw new InvalidOperationException(comparison + " is not supported."); } } public static string ToSymbol(this ComparisonType comparison) { switch (comparison) { case ComparisonType.Less: return "<"; case ComparisonType.LessOrEqual: return "<="; case ComparisonType.Equal: return "="; case ComparisonType.GreaterOrEqual: return ">="; case ComparisonType.Greater: return ">"; case ComparisonType.NotEqual: return "!="; default: throw new InvalidOperationException(comparison + " is not supported."); } } } }