#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.Drawing; 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.Problems.Instances; using HeuristicLab.Optimization; using System.Collections.Generic; namespace HeuristicLab.Problems.PFSP { [Item("Permutation Flowshop Scheduling Problem (PFSP)", "Represents a Permutation Flowshop Scheduling Problem")] [Creatable(CreatableAttribute.Categories.CombinatorialProblems, Priority = 999)] [StorableClass] public sealed class PermutationFlowshopSchedulingProblem : SingleObjectiveHeuristicOptimizationProblem, IProblemInstanceConsumer, IProblemInstanceExporter, IStorableContent { #region Default Instance private static readonly FSSPData DefaultInstance = new FSSPData() { Name = "Permutation Flowshop Scheduling Problem (PFSP)", Description = "The default instance of the PFSP problem in HeuristicLab", Jobs = 4, Machines = 4, //BestKnownQuality = 328, ProcessingTimes = new double[,] { {5 ,3, 6 ,6 }, {2 ,4, 8 ,4}, {4 ,2, 7 ,4}, {5 ,3, 8 ,6} } }; #endregion public string Filename { get; set; } #region Parameter Properties public OptionalValueParameter BestKnownSolutionParameter { get { return (OptionalValueParameter)Parameters["BestKnownSolution"]; } } public OptionalValueParameter JobMatrixParameter { get { return (OptionalValueParameter)Parameters["JobMatrix"]; } } #endregion #region Properties public Permutation BestKnownSolution { get { return BestKnownSolutionParameter.Value; } set { BestKnownSolutionParameter.Value = value; if (BestKnownSolutionChanged != null) { OnBestKnownSolutionChanged(); } } } public JobMatrix JobMatrix { get { return JobMatrixParameter.Value; } set { JobMatrixParameter.Value = value; } } #endregion public event EventHandler BestKnownSolutionChanged; private void OnBestKnownSolutionChanged() { var changed = BestKnownSolutionChanged; if (changed != null) changed(this, EventArgs.Empty); } [StorableConstructor] private PermutationFlowshopSchedulingProblem(bool deserializing) : base(deserializing) { } private PermutationFlowshopSchedulingProblem(PermutationFlowshopSchedulingProblem original, Cloner cloner) : base(original, cloner) { } public PermutationFlowshopSchedulingProblem() : base(new CmaxMakeSpanEvaluator(), new RandomPermutationCreator()) { Parameters.Add(new OptionalValueParameter("BestKnownSolution", "The best known solution of this FSSP instance.")); Parameters.Add(new OptionalValueParameter("JobMatrix", "The matrix which contains the jobs,machines and duration.")); Load(DefaultInstance); EvaluatorParameter.GetsCollected = false; EvaluatorParameter.Hidden = true; Maximization.Value = false; MaximizationParameter.Hidden = true; SolutionCreator.PermutationParameter.ActualName = "PFSPOrder"; Evaluator.QualityParameter.ActualName = "Makespan"; ParameterizeSolutionCreator(); ParameterizeEvaluator(); InitializeOperators(); } public override IDeepCloneable Clone(Cloner cloner) { return new PermutationFlowshopSchedulingProblem(this, cloner); } [StorableHook(HookType.AfterDeserialization)] private void AfterDeserialization() { } #region Problem Instance Handling public void Load(FSSPData data) { BestKnownQuality = data.BestKnownQuality.HasValue ? new DoubleValue(data.BestKnownQuality.Value) : null; Name = data.Name; Description = data.Description; JobMatrix = new JobMatrix(data.ProcessingTimes); if (data.BestKnownSchedule != null) { int[] permut = data.BestKnownSchedule; //Clean up if the first index = 1 if (!permut.Contains(0)) { permut = permut.Select(v => v - 1).ToArray(); } double bestKnownQuality = MakeSpanEvaluator.Apply( new CmaxMakeSpanEvaluator(), new DoubleMatrix(data.ProcessingTimes), new Permutation(PermutationTypes.Absolute, permut) ); BestKnownSolution = new Permutation(PermutationTypes.Absolute, data.BestKnownSchedule); BestKnownQuality = new DoubleValue(bestKnownQuality); } ParameterizeSolutionCreator(); } public FSSPData Export() { var result = new FSSPData { Name = Name, Description = Description, ProcessingTimes = new double[JobMatrix.Rows, JobMatrix.Columns] }; if (BestKnownQuality != null) { result.BestKnownQuality = BestKnownQuality.Value; } if (JobMatrix != null) { result.Jobs = JobMatrix.Rows; result.Machines = JobMatrix.Columns; } for (int i = 0; i < JobMatrix.Rows; i++) { for (int j = 0; j < JobMatrix.Columns; j++) { result.ProcessingTimes[i, j] = JobMatrix[i, j]; } } result.BestKnownSchedule = BestKnownSolution != null ? (BestKnownSolution as IntArray).ToArray() : null; return result; } #endregion #region Helpers private void InitializeOperators() { Operators.AddRange(ApplicationManager.Manager.GetInstances()); ParameterizeOperators(); } 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; } } private void ParameterizeSolutionCreator() { SolutionCreator.LengthParameter.Value = new IntValue(JobMatrix.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 CmaxMakeSpanEvaluator) { IMakespanEvaluator evaluator = (IMakespanEvaluator)Evaluator; evaluator.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName; evaluator.PermutationParameter.Hidden = true; } } #endregion } }