#region License Information /* HeuristicLab * Copyright (C) 2002-2018 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.Linq; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Encodings.PermutationEncoding; using HeuristicLab.Optimization; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Problems.Instances; namespace HeuristicLab.Problems.PermutationProblems { [Item("Linear Ordering Problem (LOP)", "Represents a Linear Ordering Problem")] [Creatable(CreatableAttribute.Categories.CombinatorialProblems)] [StorableClass] public sealed class LinearOrderingProblem : SingleObjectiveBasicProblem, IProblemInstanceConsumer, IProblemInstanceExporter, IStorableContent { private static readonly LOPData DefaultInstance = new LOPData() { Name = "Linaer Ordering Problem (LOP)", Description = "The default instance of the LOP in HeuristicLab", Dimension = 4, Matrix = new double[,] { {0 ,3, 6 ,6}, {2 ,0, 8 ,4}, {4 ,2, 0 ,4}, {5 ,3, 8 ,0} } }; public OptionalValueParameter BestKnownSolutionParameter { get { return (OptionalValueParameter)Parameters["BestKnownSolution"]; } } public Permutation BestKnownSolution { get { return BestKnownSolutionParameter.Value; } set { BestKnownSolutionParameter.Value = value; } } public ValueParameter MatrixParameter { get { return (ValueParameter)Parameters["Matrix"]; } } public DoubleMatrix Matrix { get { return MatrixParameter.Value; } set { MatrixParameter.Value = value; } } public override bool Maximization { get { return true; } } [StorableConstructor] private LinearOrderingProblem(bool deserializing) : base(deserializing) { } private LinearOrderingProblem(LinearOrderingProblem original, Cloner cloner) : base(original, cloner) { } public LinearOrderingProblem() { Parameters.Add(new OptionalValueParameter("BestKnownSolution", "The best known solution of this LOP instance.")); Parameters.Add(new ValueParameter("Matrix", "The matrix which contains the corresponding LOP-values")); Load(DefaultInstance); EvaluatorParameter.GetsCollected = false; EvaluatorParameter.Hidden = true; Evaluator.QualityParameter.ActualName = "Superdiagonal"; } public override IDeepCloneable Clone(Cloner cloner) { return new LinearOrderingProblem(this, cloner); } public void Load(LOPData data) { if (data.Matrix.GetLength(0) != data.Matrix.GetLength(1)) { throw new ArgumentException("Matrix must be square"); } if (data.BestKnownQuality.HasValue) { BestKnownQuality = data.BestKnownQuality.Value; } Name = data.Name; Description = data.Description; Matrix = new DoubleMatrix(data.Matrix); Encoding.Length = Matrix.Columns; if (data.BestKnownPermutation != null) { int[] permut = data.BestKnownPermutation; //Clean up if the first index = 1 if (!permut.Contains(0)) { permut = permut.Select(v => v - 1).ToArray(); } BestKnownSolution = new Permutation(PermutationTypes.Absolute, permut); BestKnownQuality = Evaluate(new Permutation(PermutationTypes.Absolute, permut), Matrix); } } public LOPData Export() { var result = new LOPData { Name = Name, Description = Description, BestKnownQuality = BestKnownQuality, BestKnownPermutation = BestKnownSolution.ToArray(), Dimension = Matrix.Rows, Matrix = Matrix.CloneAsMatrix() }; return result; } public override double Evaluate(Individual individual, IRandom random) { return Evaluate(individual.Permutation(), Matrix); } private double Evaluate(Permutation permutation, DoubleMatrix matrix) { double sum = 0; for (int i = 1; i < matrix.Columns; i++) { for (int j = 0; j < i; j++) { sum += matrix[permutation[j], permutation[i]]; } } return sum; } } }