#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;
}
}
}
}