#region License Information /* HeuristicLab * Copyright (C) 2002-2014 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.Optimization; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; namespace HeuristicLab.Problems.Programmable { [Item("Multi-objective Problem Definition Script", "Script that defines the parameter vector and evaluates the solution for a programmable problem.")] [StorableClass] public class MultiObjectiveProblemScript : ProblemScript, IMultiObjectiveProblemDefinition, IStorableContent { public string Filename { get; set; } protected override string CodeTemplate { get { return @"using System; using System.Linq; using System.Collections.Generic; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Encodings.PermutationEncoding; using HeuristicLab.Optimization; using HeuristicLab.Problems.Programmable; public class CustomProblemDefinition : ProblemScriptBase, IMultiObjectiveProblemDefinition { public bool[] Maximization { get { return new [] { false, false }; } } public CustomProblemDefinition() { // Define the solution encoding which can also consist of multiple vectors, examples below // Encoding = new BinaryEncoding(""b"", length: 5); // Encoding = new IntegerEncoding(""i"", lenght: 5, min: 2, max: 14, step: 4); // Encoding = new RealEncoding(""r"", length: 5, min: -1.0, max: 1.0); // Encoding = new PermutationEncoding(""P"", length: 5, type: PermutationTypes.Absolute); // Encoding = new MultiEncoding() // .AddBinaryVector(""b"", length: 5) // .AddIntegerVector(""i"", length: 5, min: 2, max: 14, step: 4) // .AddRealVector(""r"", length: 5, min: -1.0, max: 1.0) // .AddPermutation(""P"", length: 5, type: PermutationTypes.Absolute) ; } public override void Initialize() { // when the definition is created here you can initialize variables in the variable store } public double[] Evaluate(IRandom random, Individual individual) { var qualities = new [] { 0.0, 0.0 }; // use vars.yourVariable to access variables in the variable store i.e. yourVariable // qualities = new [] { individual.RealVector(""r"").Sum(x => x * x), individual.RealVector(""r"").Sum(x => x * x * x) }; return qualities; } public void Analyze(Individual[] individuals, double[][] qualities, ResultCollection results) { // write or update results given the range of vectors and resulting qualities // use e.g. vars.yourVariable to access variables in the variable store i.e. yourVariable } public override IEnumerable GetNeighbors(IRandom random, Individual individual) { // Create new vectors, based on the given one that represent small changes // This method is only called from move-based algorithms (LocalSearch, SimulatedAnnealing, etc.) while (true) { // this is not an infinite loop as only a finite amount of samples will be drawn // it is possible to return a concrete amount of neighbors also var neighbor = (Individual)individual.Clone(); //e.g. make a bit flip in a binary parameter //var bIndex = random.Next(neighbor.BinaryVector(""b"").Length); //neighbor.BinaryVector(""b"")[bIndex] = !neighbor.BinaryVector(""b"")[bIndex]; yield return neighbor; } } // implement further classes and methods }"; } } [StorableConstructor] protected MultiObjectiveProblemScript(bool deserializing) : base(deserializing) { } protected MultiObjectiveProblemScript(MultiObjectiveProblemScript original, Cloner cloner) : base(original, cloner) { } public MultiObjectiveProblemScript() { Code = CodeTemplate; } public override IDeepCloneable Clone(Cloner cloner) { return new MultiObjectiveProblemScript(this, cloner); } public new IMultiObjectiveProblemDefinition Instance { get { return (IMultiObjectiveProblemDefinition)base.Instance; } protected set { base.Instance = value; } } protected override void OnInstanceChanged() { OnProblemDefinitionChanged(); base.OnInstanceChanged(); } bool[] IMultiObjectiveProblemDefinition.Maximization { get { return Instance != null ? Instance.Maximization : new bool[0]; } } IEncoding IProblemDefinition.Encoding { get { return Instance != null ? Instance.Encoding : null; } } double[] IMultiObjectiveProblemDefinition.Evaluate(IRandom random, Individual individual) { return Instance.Evaluate(random, individual); } void IMultiObjectiveProblemDefinition.Analyze(Individual[] individuals, double[][] qualities, ResultCollection results) { Instance.Analyze(individuals, qualities, results); } IEnumerable IProblemDefinition.GetNeighbors(IRandom random, Individual individual) { return Instance.GetNeighbors(random, individual); } public event EventHandler ProblemDefinitionChanged; private void OnProblemDefinitionChanged() { var handler = ProblemDefinitionChanged; if (handler != null) handler(this, EventArgs.Empty); } } }