#region License Information /* HeuristicLab * Copyright (C) 2002-2016 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.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.PluginInfrastructure; using HeuristicLab.Optimization; using System.Collections.Generic; using HeuristicLab.Problems.Instances.Types; using HeuristicLab.Problems.Instances; namespace HeuristicLab.Problems.LinearOrdering { [Item("Linear Ordering Problem (LOP)", "Represents a Linear Ordering Problem")] [Creatable(CreatableAttribute.Categories.CombinatorialProblems, Priority = 999)] [StorableClass] public sealed class LinearOrderingProblem : SingleObjectiveHeuristicOptimizationProblem, IProblemInstanceConsumer, IProblemInstanceExporter, IStorableContent { #region Default Instance 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} } }; #endregion public string Filename { get; set; } #region Parameter Properties public OptionalValueParameter BestKnownSolutionParameter { get { return (OptionalValueParameter)Parameters["BestKnownSolution"]; } } public OptionalValueParameter MatrixParameter { get { return (OptionalValueParameter)Parameters["Matrix"]; } } #endregion #region Properties public Permutation BestKnownSolution { get { return BestKnownSolutionParameter.Value; } set { BestKnownSolutionParameter.Value = value; if (BestKnownSolutionChanged != null) { OnBestKnownSolutionChanged(); } } } public DoubleMatrix Matrix { get { return MatrixParameter.Value; } set { MatrixParameter.Value = value; } } #endregion public event EventHandler BestKnownSolutionChanged; private void OnBestKnownSolutionChanged() { var changed = BestKnownSolutionChanged; if (changed != null) changed(this, EventArgs.Empty); } // BackwardsCompatibility3.3 #region Backwards compatible code, remove with 3.4 [Obsolete] [Storable(Name = "operators")] private IEnumerable oldOperators { get { return null; } set { if (value != null && value.Any()) Operators.AddRange(value); } } #endregion [StorableConstructor] private LinearOrderingProblem(bool deserializing) : base(deserializing) { } private LinearOrderingProblem(LinearOrderingProblem original, Cloner cloner) : base(original, cloner) { } public LinearOrderingProblem() : base(new SuperdiagonalMatrixTriangulationEvaluator(), new RandomPermutationCreator()) { Parameters.Add(new OptionalValueParameter("BestKnownSolution", "The best known solution of this LOP instance.")); Parameters.Add(new OptionalValueParameter("Matrix", "The matrix which contains the corresponding LOP-values")); Load(DefaultInstance); EvaluatorParameter.GetsCollected = false; EvaluatorParameter.Hidden = true; Maximization.Value = true; MaximizationParameter.Hidden = true; SolutionCreator.PermutationParameter.ActualName = "LOPOrder"; Evaluator.QualityParameter.ActualName = "SuperDiagonale"; ParameterizeSolutionCreator(); ParameterizeEvaluator(); InitializeOperators(); } public override IDeepCloneable Clone(Cloner cloner) { return new LinearOrderingProblem(this, cloner); } [StorableHook(HookType.AfterDeserialization)] private void AfterDeserialization() { } #region Problem Instance Handling public void Load(LOPData data) { BestKnownQuality = data.BestKnownQuality.HasValue ? new DoubleValue(data.BestKnownQuality.Value) : null; Name = data.Name; Description = data.Description; Matrix = new DoubleMatrix(data.Matrix); 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(); } double bestKnownQuality = MatrixTriangulationEvaluator.Apply( new SuperdiagonalMatrixTriangulationEvaluator(), new DoubleMatrix(data.Matrix), new Permutation(PermutationTypes.Absolute, permut) ); BestKnownSolution = new Permutation(PermutationTypes.Absolute, data.BestKnownPermutation); BestKnownQuality = new DoubleValue(bestKnownQuality); } ParameterizeSolutionCreator(); } public LOPData Export() { var result = new LOPData { Name = Name, Description = Description, BestKnownQuality = BestKnownQuality.Value, BestKnownPermutation = BestKnownSolution.ToArray(), Dimension = Matrix.Rows, Matrix = Matrix.CloneAsMatrix() }; return result; } #endregion #region Helpers private void InitializeOperators() { Operators.AddRange(ApplicationManager.Manager.GetInstances()); ParameterizeOperators(); UpdateMoveEvaluators(); } private void ParameterizeOperators() { foreach (IPermutationCrossover op in Operators.OfType()) { op.ParentsParameter.ActualName = SolutionCreator.PermutationParameter.ActualName; op.ParentsParameter.Hidden = true; op.ChildParameter.ActualName = SolutionCreator.PermutationParameter.ActualName; op.ChildParameter.Hidden = true; } foreach (IPermutationManipulator op in Operators.OfType()) { op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName; op.PermutationParameter.Hidden = true; } foreach (IPermutationMoveOperator op in Operators.OfType()) { op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName; op.PermutationParameter.Hidden = true; } foreach (IPermutationMultiNeighborhoodShakingOperator op in Operators.OfType()) { op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName; op.PermutationParameter.Hidden = true; } foreach (ISingleObjectiveImprovementOperator op in Operators.OfType()) { op.SolutionParameter.ActualName = SolutionCreator.PermutationParameter.ActualName; op.SolutionParameter.Hidden = true; } foreach (ISingleObjectivePathRelinker op in Operators.OfType()) { op.ParentsParameter.ActualName = SolutionCreator.PermutationParameter.ActualName; op.ParentsParameter.Hidden = true; } foreach (ISolutionSimilarityCalculator op in Operators.OfType()) { op.SolutionVariableName = SolutionCreator.PermutationParameter.ActualName; op.QualityVariableName = Evaluator.QualityParameter.ActualName; } } #endregion private void UpdateMoveEvaluators() { ParameterizeOperators(); OnOperatorsChanged(); } private void ParameterizeSolutionCreator() { SolutionCreator.LengthParameter.Value = new IntValue(Matrix.Columns); SolutionCreator.LengthParameter.Hidden = SolutionCreator.LengthParameter.Value != null; SolutionCreator.PermutationTypeParameter.Value = new PermutationType(PermutationTypes.RelativeUndirected); SolutionCreator.PermutationTypeParameter.Hidden = true; } private void ParameterizeEvaluator() { if (Evaluator is IMatrixTriangulationEvaluator) { IMatrixTriangulationEvaluator evaluator = (IMatrixTriangulationEvaluator)Evaluator; evaluator.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName; evaluator.PermutationParameter.Hidden = true; } } } }