using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using HeuristicLab.Common; using HeuristicLab.Common.Resources; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Encodings.BinaryVectorEncoding; using HeuristicLab.Optimization; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.PluginInfrastructure; using HeuristicLab.Random; using HeuristicLab.Problems.NK.WeightInitializers; namespace HeuristicLab.Problems.NK { [Item("NK Landscape", "Represents an NK landscape optimization problem.")] [Creatable("Problems")] [StorableClass] public sealed class NKLandscape : ParameterizedNamedItem, ISingleObjectiveHeuristicOptimizationProblem, IStorableContent { public string Filename { get; set; } public override Image ItemImage { get { return VSImageLibrary.Type; } } #region Parameter Properties public ValueParameter MaximizationParameter { get { return (ValueParameter)Parameters["Maximization"]; } } IParameter ISingleObjectiveHeuristicOptimizationProblem.MaximizationParameter { get { return MaximizationParameter; } } public ValueParameter LengthParameter { get { return (ValueParameter)Parameters["Length"]; } } public ValueParameter SolutionCreatorParameter { get { return (ValueParameter)Parameters["SolutionCreator"]; } } IParameter IHeuristicOptimizationProblem.SolutionCreatorParameter { get { return SolutionCreatorParameter; } } public ValueParameter EvaluatorParameter { get { return (ValueParameter)Parameters["Evaluator"]; } } IParameter IHeuristicOptimizationProblem.EvaluatorParameter { get { return EvaluatorParameter; } } public ValueParameter BestKnownQualityParameter { get { return (ValueParameter)Parameters["BestKnownQuality"]; } } IParameter ISingleObjectiveHeuristicOptimizationProblem.BestKnownQualityParameter { get { return BestKnownQualityParameter; } } public ValueParameter GeneInteractionsParameter { get { return (ValueParameter)Parameters["GeneInteractions"]; } } public ValueParameter InteractionSeedParameter { get { return (ValueParameter)Parameters["InteractionSeed"]; } } public ValueParameter NrOfInteractionsParameter { get { return (ValueParameter)Parameters["NrOfInteractions"]; } } public ValueParameter NrOfFitnessComponentsParameter { get { return (ValueParameter)Parameters["NrOfFitnessComponents"]; } } public ValueParameter WeightsParameter { get { return (ValueParameter)Parameters["Weights"]; } } public OptionalConstrainedValueParameter InteractionInitializerParameter { get { return (OptionalConstrainedValueParameter)Parameters["InteractionInitializer"]; } } public OptionalConstrainedValueParameter WeightsInitializerParameter { get { return (OptionalConstrainedValueParameter)Parameters["WeightsInitializer"]; } } #endregion #region Properties public IntValue Length { get { return LengthParameter.Value; } set { LengthParameter.Value = value; } } public IBinaryVectorCreator SolutionCreator { get { return SolutionCreatorParameter.Value; } set { SolutionCreatorParameter.Value = value; } } ISolutionCreator IHeuristicOptimizationProblem.SolutionCreator { get { return SolutionCreatorParameter.Value; } } public INKEvaluator Evaluator { get { return EvaluatorParameter.Value; } set { EvaluatorParameter.Value = value; } } ISingleObjectiveEvaluator ISingleObjectiveHeuristicOptimizationProblem.Evaluator { get { return EvaluatorParameter.Value; } } IEvaluator IHeuristicOptimizationProblem.Evaluator { get { return EvaluatorParameter.Value; } } public DoubleValue BestKnownQuality { get { return BestKnownQualityParameter.Value; } } public IEnumerable Operators { get { return operators.Cast(); } } public IInteractionInitializer InteractionInitializer { get { return InteractionInitializerParameter.Value; } } //private BestOneMaxSolutionAnalyzer BestOneMaxSolutionAnalyzer { //get { return operators.OfType().FirstOrDefault(); } //} #endregion private static MersenneTwister random = new MersenneTwister(); [Storable] private List operators; [StorableConstructor] private NKLandscape(bool deserializing) : base(deserializing) { } private NKLandscape(NKLandscape original, Cloner cloner) : base(original, cloner) { operators = original.operators.Select(x => (IOperator)cloner.Clone(x)).ToList(); AttachEventHandlers(); } public NKLandscape() : base() { RandomBinaryVectorCreator creator = new RandomBinaryVectorCreator(); INKEvaluator evaluator = new NKEvaluator(); Parameters.Add(new ValueParameter("Maximization", "Set to true as the OneMax Problem is a maximization problem.", new BoolValue(true))); Parameters.Add(new ValueParameter("Length", "The length of the BinaryVector.", new IntValue(10))); Parameters.Add(new ValueParameter("SolutionCreator", "The operator which should be used to create new OneMax solutions.", creator)); Parameters.Add(new ValueParameter("Evaluator", "The operator which should be used to evaluate NK landscape solutions.", evaluator)); Parameters.Add(new ValueParameter("BestKnownQuality", "The quality of the best known solution of this OneMax instance.", new DoubleValue(0))); Parameters.Add(new ValueParameter("GeneInteractions", "Every column gives the participating genes for each fitness component")); Parameters.Add(new ValueParameter("InteractionSeed", "The seed used for the hash function to generate interaction tables.", new IntValue(random.Next()))); Parameters.Add(new ValueParameter("NrOfFitnessComponents", "Number of fitness component functions. (nr of columns in the interaction column)", new IntValue(10))); Parameters.Add(new ValueParameter("NrOfInteractions", "Number of genes interacting with each other. (nr of True values per column in the interaction matrix)", new IntValue(3))); Parameters.Add(new ValueParameter("Weights", "The weights for the component functions. If shorted, will be repeated.", new DoubleArray(new[] { 1.0 }))); Parameters.Add(new OptionalConstrainedValueParameter("InteractionInitializer", "Initialize interactions within the component functions.")); Parameters.Add(new OptionalConstrainedValueParameter("WeightsInitializer", "Operator to initialize weights distribution")); InitializeInteractionInitializerParameter(); InitializeWeightsInitializerParameter(); ParameterizeSolutionCreator(); ParameterizeEvaluator(); InitializeOperators(); AttachEventHandlers(); InitializeInteractions(); } private void InitializeInteractionInitializerParameter() { foreach (var initializer in ApplicationManager.Manager.GetInstances()) InteractionInitializerParameter.ValidValues.Add(initializer); InteractionInitializerParameter.Value = InteractionInitializerParameter.ValidValues.First(v => v is RandomInteractionsInitializer); } private void InitializeWeightsInitializerParameter() { foreach (var initializer in ApplicationManager.Manager.GetInstances()) WeightsInitializerParameter.ValidValues.Add(initializer); WeightsInitializerParameter.Value = WeightsInitializerParameter.ValidValues.First(v => v is EqualWeightsInitializer); } public override IDeepCloneable Clone(Cloner cloner) { return new NKLandscape(this, cloner); } #region Events public event EventHandler SolutionCreatorChanged; private void OnSolutionCreatorChanged() { EventHandler handler = SolutionCreatorChanged; if (handler != null) handler(this, EventArgs.Empty); } public event EventHandler EvaluatorChanged; private void OnEvaluatorChanged() { EventHandler handler = EvaluatorChanged; if (handler != null) handler(this, EventArgs.Empty); } public event EventHandler OperatorsChanged; private void OnOperatorsChanged() { EventHandler handler = OperatorsChanged; if (handler != null) handler(this, EventArgs.Empty); } public event EventHandler Reset; private void OnReset() { EventHandler handler = Reset; if (handler != null) handler(this, EventArgs.Empty); } private void SolutionCreatorParameter_ValueChanged(object sender, EventArgs e) { SolutionCreator.BinaryVectorParameter.ActualNameChanged += new EventHandler(SolutionCreator_BinaryVectorParameter_ActualNameChanged); ParameterizeSolutionCreator(); ParameterizeEvaluator(); ParameterizeAnalyzer(); ParameterizeOperators(); OnSolutionCreatorChanged(); } private void SolutionCreator_BinaryVectorParameter_ActualNameChanged(object sender, EventArgs e) { ParameterizeEvaluator(); ParameterizeAnalyzer(); ParameterizeOperators(); } private void EvaluatorParameter_ValueChanged(object sender, EventArgs e) { ParameterizeEvaluator(); ParameterizeAnalyzer(); OnEvaluatorChanged(); } void LengthParameter_ValueChanged(object sender, EventArgs e) { ParameterizeSolutionCreator(); LengthParameter.Value.ValueChanged += new EventHandler(Length_ValueChanged); BestKnownQualityParameter.Value.Value = Length.Value; } void Length_ValueChanged(object sender, EventArgs e) { NrOfFitnessComponentsParameter.Value = new IntValue(Length.Value); } void BestKnownQualityParameter_ValueChanged(object sender, EventArgs e) { //BestKnownQualityParameter.Value.Value = Length.Value; } void OneBitflipMoveParameter_ActualNameChanged(object sender, EventArgs e) { string name = ((ILookupParameter)sender).ActualName; foreach (IOneBitflipMoveOperator op in Operators.OfType()) { op.OneBitflipMoveParameter.ActualName = name; } } #endregion #region Helpers [StorableHook(HookType.AfterDeserialization)] private void AfterDeserialization() { if (!Parameters.ContainsKey("InteractionInitializer")) { Parameters.Add(new OptionalConstrainedValueParameter("InteractionInitializer", "Initialized the interaction between bits and fitness components")); InitializeInteractionInitializerParameter(); } if (!Parameters.ContainsKey("WeightsInitializer")) { Parameters.Add(new OptionalConstrainedValueParameter("WeightsInitializer", "Operator to initialize weights distribution")); InitializeWeightsInitializerParameter(); } AttachEventHandlers(); } private void AttachEventHandlers() { SolutionCreatorParameter.ValueChanged += new EventHandler(SolutionCreatorParameter_ValueChanged); SolutionCreator.BinaryVectorParameter.ActualNameChanged += new EventHandler(SolutionCreator_BinaryVectorParameter_ActualNameChanged); BestKnownQualityParameter.ValueChanged += new EventHandler(BestKnownQualityParameter_ValueChanged); EvaluatorParameter.ValueChanged += new EventHandler(EvaluatorParameter_ValueChanged); LengthParameter.ValueChanged += new EventHandler(LengthParameter_ValueChanged); LengthParameter.Value.ValueChanged += new EventHandler(Length_ValueChanged); NrOfInteractionsParameter.ValueChanged += InteractionParameterChanged; NrOfInteractionsParameter.Value.ValueChanged += InteractionParameterChanged; NrOfFitnessComponentsParameter.ValueChanged += InteractionParameterChanged; NrOfFitnessComponentsParameter.Value.ValueChanged += InteractionParameterChanged; InteractionInitializerParameter.ValueChanged += new EventHandler(InteractionInitializerParameter_ValueChanged); WeightsInitializerParameter.ValueChanged += new EventHandler(WeightsInitializerParameter_ValueChanged); } void WeightsInitializerParameter_ValueChanged(object sender, EventArgs e) { InitializeWeights(); } void InteractionInitializerParameter_ValueChanged(object sender, EventArgs e) { InitializeInteractions(); } private void InteractionParameterChanged(object sender, EventArgs e) { InitializeInteractions(); } private void ParameterizeSolutionCreator() { SolutionCreator.LengthParameter.ActualName = LengthParameter.Name; } private void ParameterizeEvaluator() { if (Evaluator is NKEvaluator) ((NKEvaluator)Evaluator).BinaryVectorParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName; } private void ParameterizeAnalyzer() { //BestOneMaxSolutionAnalyzer.MaximizationParameter.ActualName = MaximizationParameter.Name; //BestOneMaxSolutionAnalyzer.BestKnownQualityParameter.ActualName = BestKnownQualityParameter.Name; //BestOneMaxSolutionAnalyzer.BinaryVectorParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName; //BestOneMaxSolutionAnalyzer.ResultsParameter.ActualName = "Results"; } private void InitializeOperators() { operators = new List(); //operators.Add(new BestOneMaxSolutionAnalyzer()); ParameterizeAnalyzer(); foreach (IBinaryVectorOperator op in ApplicationManager.Manager.GetInstances()) { if (!(op is ISingleObjectiveMoveEvaluator) || (op is INKMoveEvaluator)) { operators.Add(op); } } ParameterizeOperators(); InitializeMoveGenerators(); } private void InitializeMoveGenerators() { foreach (IOneBitflipMoveOperator op in Operators.OfType()) { if (op is IMoveGenerator) { op.OneBitflipMoveParameter.ActualNameChanged += new EventHandler(OneBitflipMoveParameter_ActualNameChanged); } } } private void ParameterizeOperators() { foreach (IBinaryVectorCrossover op in Operators.OfType()) { op.ParentsParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName; op.ChildParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName; } foreach (IBinaryVectorManipulator op in Operators.OfType()) { op.BinaryVectorParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName; } foreach (IBinaryVectorMoveOperator op in Operators.OfType()) { op.BinaryVectorParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName; } } private void InitializeInteractions() { if (InteractionInitializer != null) GeneInteractionsParameter.Value = InteractionInitializer.InitializeInterations( Length.Value, NrOfFitnessComponentsParameter.Value.Value, NrOfInteractionsParameter.Value.Value, random); } private void InitializeWeights() { if (WeightsInitializerParameter.Value != null) WeightsParameter.Value = new DoubleArray( WeightsInitializerParameter.Value.GetWeights(NrOfFitnessComponentsParameter.Value.Value) .ToArray()); } #endregion } }