using System; using System.Security.Cryptography; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Encodings.BinaryVectorEncoding; using HeuristicLab.Operators; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using System.Threading; namespace HeuristicLab.Problems.NK { [Item("NK Landscape Evaluator", "Evaluates 'points' on an NK Landscape.")] [StorableClass] public class NKEvaluator : SingleSuccessorOperator, INKEvaluator { #region Parameters public ILookupParameter QualityParameter { get { return (ILookupParameter)Parameters["Quality"]; } } public LookupParameter F_iParameter { get { return (LookupParameter)Parameters["F_i"]; } } public ILookupParameter BinaryVectorParameter { get { return (ILookupParameter)Parameters["BinaryVector"]; } } public LookupParameter GeneInteractionsParameter { get { return (LookupParameter)Parameters["GeneInteractions"]; } } public LookupParameter InteractionSeedParameter { get { return (LookupParameter)Parameters["InteractionSeed"]; } } public LookupParameter WeightsParameter { get { return (LookupParameter)Parameters["Weights"]; } } public ValueLookupParameter StoreComponentsParameter { get { return (ValueLookupParameter)Parameters["StoreComponents"]; } } #endregion #region ParameterValues private double Quality { set { QualityParameter.ActualValue = new DoubleValue(value); } } private BinaryVector BinaryVector { get { return BinaryVectorParameter.ActualValue; } } private BoolMatrix GeneInteractions { get { return GeneInteractionsParameter.ActualValue; } } private int InteractionSeed { get { return InteractionSeedParameter.ActualValue.Value; } } private DoubleArray Weights { get { return WeightsParameter.ActualValue; } } private bool StoreComponents { get { IParameter param; return Parameters.TryGetValue("StoreComponents", out param) && ((ValueLookupParameter)param).ActualValue.Value == true; } } #endregion private ThreadLocal hashAlgorithm; [StorableConstructor] protected NKEvaluator(bool deserializing) : base(deserializing) { hashAlgorithm = new ThreadLocal(() => HashAlgorithm.Create("MD5")); } protected NKEvaluator(NKEvaluator original, Cloner cloner) : base(original, cloner) { hashAlgorithm = new ThreadLocal(() => HashAlgorithm.Create("MD5")); } public NKEvaluator() { Parameters.Add(new LookupParameter("Quality", "The evaluated quality of the OneMax solution.")); Parameters.Add(new LookupParameter("F_i", "Fitness component functions.")); Parameters.Add(new LookupParameter("BinaryVector", "The solution given in path representation which should be evaluated.")); Parameters.Add(new LookupParameter("GeneInteractions", "Matrix indicating gene interactions.")); Parameters.Add(new LookupParameter("InteractionSeed", "Seed used for randomly generting gene interactions.")); Parameters.Add(new LookupParameter("Weights", "The weights for the component functions. If shorter, will be repeated.")); Parameters.Add(new ValueLookupParameter("StoreComponents", "Inject values of component functions into the scope (F_i)", new BoolValue(false))); hashAlgorithm = new ThreadLocal(() => HashAlgorithm.Create("MD5")); } public override IDeepCloneable Clone(Cloner cloner) { return new NKEvaluator(this, cloner); } public long Hash(long x) { return BitConverter.ToInt64(hashAlgorithm.Value.ComputeHash(BitConverter.GetBytes(x), 0, 8), 0); } public double F_i(long x, long i, long g_i, long seed) { return Math.Abs((double)Hash((x & g_i) ^ Hash(g_i ^ Hash(i ^ seed))))/long.MaxValue; } public double F(long x, long[] g, double[] w, long seed, ref double[] f_i) { double value = 0; for (int i = 0; i