source: branches/2864_PermutationProblems/HeuristicLab.Problems.PFSP/3.3/PermutationFlowshopSchedulingProblem.cs @ 15521

Last change on this file since 15521 was 15521, checked in by fholzing, 22 months ago

#2864: First commit of new branch of Permutation based benchmark problems.

File size: 13.2 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Drawing;
24using System.Linq;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Encodings.PermutationEncoding;
29using HeuristicLab.Parameters;
30using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
31using HeuristicLab.PluginInfrastructure;
32using HeuristicLab.Problems.Instances;
33using HeuristicLab.Optimization;
34using System.Collections.Generic;
35
36namespace HeuristicLab.Problems.PFSP
37{
38    [Item("Permutation Flowshop Scheduling Problem (PFSP)", "Represents a Permutation Flowshop Scheduling Problem")]
39    [Creatable(CreatableAttribute.Categories.CombinatorialProblems, Priority = 999)]
40    [StorableClass]
41    public sealed class PermutationFlowshopSchedulingProblem : SingleObjectiveHeuristicOptimizationProblem<IPFSPEvaluator, IPermutationCreator>, IProblemInstanceConsumer<FSSPData>, IProblemInstanceExporter<FSSPData>, IStorableContent
42    {
43        #region Default Instance
44        private static readonly FSSPData DefaultInstance = new FSSPData()
45        {
46            Name = "Permutation Flowshop Scheduling Problem (PFSP)",
47            Description = "The default instance of the PFSP problem in HeuristicLab",
48            Jobs = 4,
49            Machines = 4,
50            //BestKnownQuality = 328,
51            ProcessingTimes = new double[,] {
52                {5 ,3, 6 ,6 },
53                {2 ,4, 8 ,4},
54                {4 ,2, 7 ,4},
55                {5 ,3, 8 ,6}
56            }
57        };
58        #endregion
59
60        public string Filename { get; set; }
61
62        #region Parameter Properties
63        public OptionalValueParameter<Permutation> BestKnownSolutionParameter
64        {
65            get { return (OptionalValueParameter<Permutation>)Parameters["BestKnownSolution"]; }
66        }
67
68        public OptionalValueParameter<JobMatrix> JobMatrixParameter
69        {
70            get { return (OptionalValueParameter<JobMatrix>)Parameters["JobMatrix"]; }
71        }
72        #endregion
73
74        #region Properties
75        public Permutation BestKnownSolution
76        {
77            get { return BestKnownSolutionParameter.Value; }
78            set
79            {
80                BestKnownSolutionParameter.Value = value;
81                if (BestKnownSolutionChanged != null) { OnBestKnownSolutionChanged(); }
82            }
83        }
84        public JobMatrix JobMatrix
85        {
86            get { return JobMatrixParameter.Value; }
87            set { JobMatrixParameter.Value = value; }
88        }
89        #endregion
90
91        public event EventHandler BestKnownSolutionChanged;
92        private void OnBestKnownSolutionChanged()
93        {
94            var changed = BestKnownSolutionChanged;
95            if (changed != null)
96                changed(this, EventArgs.Empty);
97        }
98
99        // BackwardsCompatibility3.3
100        #region Backwards compatible code, remove with 3.4
101        [Obsolete]
102        [Storable(Name = "operators")]
103        private IEnumerable<IOperator> oldOperators
104        {
105            get { return null; }
106            set
107            {
108                if (value != null && value.Any())
109                    Operators.AddRange(value);
110            }
111        }
112        #endregion
113
114        [StorableConstructor]
115        private PermutationFlowshopSchedulingProblem(bool deserializing) : base(deserializing) { }
116        private PermutationFlowshopSchedulingProblem(PermutationFlowshopSchedulingProblem original, Cloner cloner)
117          : base(original, cloner)
118        {
119            RegisterEventHandlers();
120        }
121        public PermutationFlowshopSchedulingProblem()
122          : base(new AwesomeMakeSpanEvaluator(), new RandomPermutationCreator())
123        {
124            Parameters.Add(new OptionalValueParameter<Permutation>("BestKnownSolution", "The best known solution of this FSSP instance."));
125            Parameters.Add(new OptionalValueParameter<JobMatrix>("JobMatrix", "The matrix which contains the jobs,machines and duration."));
126
127            Load(DefaultInstance);
128            EvaluatorParameter.GetsCollected = false;
129            EvaluatorParameter.Hidden = true;
130
131            Maximization.Value = false;
132            MaximizationParameter.Hidden = true;
133
134            SolutionCreator.PermutationParameter.ActualName = "PFSPOrder";
135            Evaluator.QualityParameter.ActualName = "Makespan";
136            ParameterizeSolutionCreator();
137            ParameterizeEvaluator();
138
139            InitializeOperators();
140            RegisterEventHandlers();
141        }
142
143        public override IDeepCloneable Clone(Cloner cloner)
144        {
145            return new PermutationFlowshopSchedulingProblem(this, cloner);
146        }
147
148        [StorableHook(HookType.AfterDeserialization)]
149        private void AfterDeserialization()
150        {
151            RegisterEventHandlers();
152        }
153
154        private void RegisterEventHandlers()
155        {
156            SolutionCreator.PermutationParameter.ActualNameChanged += new EventHandler(SolutionCreator_PermutationParameter_ActualNameChanged);
157            Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
158        }
159
160        private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e)
161        {
162            //Nothing to do  ParameterizeAnalyzers();
163        }
164
165        private void SolutionCreator_PermutationParameter_ActualNameChanged(object sender, EventArgs e)
166        {
167            ParameterizeEvaluator();
168            //ParameterizeAnalyzers();
169            ParameterizeOperators();
170        }
171
172        #region Events
173        private void ScheduleEvaluator_QualityParameter_ActualNameChanged(object sender, EventArgs eventArgs)
174        {
175            ParameterizeOperators();
176        }
177
178        private void SolutionCreator_SchedulingEncodingParameter_ActualNameChanged(object sender, EventArgs eventArgs)
179        {
180            ParameterizeOperators();
181        }
182
183        private void ScheduleDecoder_ScheduleParameter_ActualNameChanged(object sender, EventArgs eventArgs)
184        {
185            ParameterizeOperators();
186        }
187        #endregion
188
189        #region Problem Instance Handling
190        public void Load(FSSPData data)
191        {
192
193            BestKnownQuality = data.BestKnownQuality.HasValue ? new DoubleValue(data.BestKnownQuality.Value) : null;
194            Name = data.Name;
195            Description = data.Description;
196            JobMatrix = new JobMatrix(data.ProcessingTimes);
197
198            if (data.BestKnownSchedule != null)
199            {
200                int[] permut = data.BestKnownSchedule;
201                //Clean up if the first index = 1
202                if (!permut.Contains(0)) { permut = permut.Select(v => v - 1).ToArray(); }
203                double bestKnownQuality = MakeSpanEvaluator.Apply(
204                    new AwesomeMakeSpanEvaluator(),
205                    new DoubleMatrix(data.ProcessingTimes),
206                    new Permutation(PermutationTypes.Absolute, permut)
207                );
208
209                BestKnownSolution = new Permutation(PermutationTypes.Absolute, data.BestKnownSchedule);
210                BestKnownQuality = new DoubleValue(bestKnownQuality);
211            }
212
213            ParameterizeSolutionCreator();
214        }
215
216        public FSSPData Export()
217        {
218            var result = new FSSPData
219            {
220                Name = Name,
221                Description = Description,
222                ProcessingTimes = new double[JobMatrix.Rows, JobMatrix.Columns]
223            };
224
225            if (BestKnownQuality != null)
226            {
227                result.BestKnownQuality = BestKnownQuality.Value;
228            }
229
230            if (JobMatrix != null)
231            {
232                result.Jobs = JobMatrix.Rows;
233                result.Machines = JobMatrix.Columns;
234            }
235
236            for (int i = 0; i < JobMatrix.Rows; i++)
237            {
238                for (int j = 0; j < JobMatrix.Columns; j++)
239                {
240                    result.ProcessingTimes[i, j] = JobMatrix[i, j];
241                }
242            }
243
244            result.BestKnownSchedule = BestKnownSolution != null ? (BestKnownSolution as IntArray).ToArray() : null;
245
246            return result;
247        }
248        #endregion
249
250        #region Helpers
251        private void InitializeOperators()
252        {
253            var operators = new HashSet<IPermutationOperator>(new IPermutationOperator[] {
254                new OrderCrossover2(),
255                new InversionManipulator(),
256                new StochasticInversionMultiMoveGenerator()
257            }, new TypeEqualityComparer<IPermutationOperator>());
258
259            foreach (var op in ApplicationManager.Manager.GetInstances<IPermutationOperator>())
260                operators.Add(op);
261            Operators.AddRange(operators);
262            Operators.Add(new BestTSPSolutionAnalyzer());
263            ParameterizeOperators();
264            UpdateMoveEvaluators();
265        }
266
267
268        private void ParameterizeOperators()
269        {
270            foreach (IPermutationCrossover op in Operators.OfType<IPermutationCrossover>())
271            {
272                op.ParentsParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
273                op.ParentsParameter.Hidden = true;
274                op.ChildParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
275                op.ChildParameter.Hidden = true;
276            }
277            foreach (IPermutationManipulator op in Operators.OfType<IPermutationManipulator>())
278            {
279                op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
280                op.PermutationParameter.Hidden = true;
281            }
282            foreach (IPermutationMoveOperator op in Operators.OfType<IPermutationMoveOperator>())
283            {
284                op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
285                op.PermutationParameter.Hidden = true;
286            }
287            foreach (IPermutationMultiNeighborhoodShakingOperator op in Operators.OfType<IPermutationMultiNeighborhoodShakingOperator>())
288            {
289                op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
290                op.PermutationParameter.Hidden = true;
291            }
292            foreach (ISingleObjectiveImprovementOperator op in Operators.OfType<ISingleObjectiveImprovementOperator>())
293            {
294                op.SolutionParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
295                op.SolutionParameter.Hidden = true;
296            }
297            foreach (ISingleObjectivePathRelinker op in Operators.OfType<ISingleObjectivePathRelinker>())
298            {
299                op.ParentsParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
300                op.ParentsParameter.Hidden = true;
301            }
302            foreach (ISolutionSimilarityCalculator op in Operators.OfType<ISolutionSimilarityCalculator>())
303            {
304                op.SolutionVariableName = SolutionCreator.PermutationParameter.ActualName;
305                op.QualityVariableName = Evaluator.QualityParameter.ActualName;
306            }
307        }
308        #endregion
309
310        private void UpdateMoveEvaluators()
311        {
312            Operators.RemoveAll(x => x is ISingleObjectiveMoveEvaluator);
313            foreach (var op in ApplicationManager.Manager.GetInstances<ISingleObjectiveMoveEvaluator>())
314                Operators.Add(op);
315
316            ParameterizeOperators();
317            OnOperatorsChanged();
318        }
319
320        private void ParameterizeSolutionCreator()
321        {
322            SolutionCreator.LengthParameter.Value = new IntValue(JobMatrix.Columns); //Jobs
323
324            SolutionCreator.LengthParameter.Hidden = SolutionCreator.LengthParameter.Value != null;
325            SolutionCreator.PermutationTypeParameter.Value = new PermutationType(PermutationTypes.RelativeUndirected);
326            SolutionCreator.PermutationTypeParameter.Hidden = true;
327        }
328        private void ParameterizeEvaluator()
329        {
330            if (Evaluator is AwesomeMakeSpanEvaluator)
331            {
332                IMakespanEvaluator evaluator = (IMakespanEvaluator)Evaluator;
333                evaluator.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
334                evaluator.PermutationParameter.Hidden = true;
335            }
336        }
337    }
338}
Note: See TracBrowser for help on using the repository browser.