Free cookie consent management tool by TermsFeed Policy Generator

source: branches/ProblemRefactoring/HeuristicLab.Encodings.ScheduleEncoding/3.3/JobSequenceMatrix/Decoder/JSMDecoder.cs @ 13469

Last change on this file since 13469 was 13469, checked in by mkommend, 8 years ago

#2521: Refactored problem base classes and adapted scheduling encoding, scheduling problem and unit tests.

File size: 8.3 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 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.Collections.Generic;
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.Random;
32
33namespace HeuristicLab.Encodings.ScheduleEncoding {
34  [Item("JobSequenceMatrixDecoder", "Applies the GifflerThompson algorithm to create an active schedule from a JobSequence Matrix.")]
35  [StorableClass]
36  public class JSMDecoder : ScheduleDecoder<JSMEncoding> {
37
38    public IFixedValueParameter<EnumValue<JSMDecodingErrorPolicy>> DecodingErrorPolicyParameter {
39      get { return (IFixedValueParameter<EnumValue<JSMDecodingErrorPolicy>>)Parameters["DecodingErrorPolicy"]; }
40    }
41    public IFixedValueParameter<EnumValue<JSMForcingStrategy>> ForcingStrategyParameter {
42      get { return (IFixedValueParameter<EnumValue<JSMForcingStrategy>>)Parameters["ForcingStrategy"]; }
43    }
44
45    private JSMDecodingErrorPolicy DecodingErrorPolicy {
46      get { return DecodingErrorPolicyParameter.Value.Value; }
47    }
48
49    private JSMForcingStrategy ForcingStrategy {
50      get { return ForcingStrategyParameter.Value.Value; }
51    }
52
53    [StorableConstructor]
54    protected JSMDecoder(bool deserializing) : base(deserializing) { }
55    protected JSMDecoder(JSMDecoder original, Cloner cloner) : base(original, cloner) { }
56    public override IDeepCloneable Clone(Cloner cloner) {
57      return new JSMDecoder(this, cloner);
58    }
59
60    public JSMDecoder()
61      : base() {
62      Parameters.Add(new FixedValueParameter<EnumValue<JSMDecodingErrorPolicy>>("DecodingErrorPolicy", "Specify the policy that should be used to handle decoding errors.", new EnumValue<JSMDecodingErrorPolicy>(JSMDecodingErrorPolicy.RandomPolicy)));
63      Parameters.Add(new FixedValueParameter<EnumValue<JSMForcingStrategy>>("ForcingStrategy", "Specifies a forcing strategy.", new EnumValue<JSMForcingStrategy>(JSMForcingStrategy.SwapForcing)));
64    }
65
66    private static Task SelectTaskFromConflictSet(JSMEncoding solution, JSMDecodingErrorPolicy decodingErrorPolicy, JSMForcingStrategy forcingStrategy, int conflictedResourceNr, int progressOnConflictedResource, ItemList<Task> conflictSet, IRandom random) {
67      if (conflictSet.Count == 1)
68        return conflictSet[0];
69
70      var jsm = solution.JobSequenceMatrix;
71
72      //get solutionCandidate from jobSequencingMatrix
73      int solutionCandidateJobNr = jsm[conflictedResourceNr][progressOnConflictedResource];
74
75      //scan conflictSet for given solutionCandidate, and return if found
76      foreach (Task t in conflictSet) {
77        if (t.JobNr == solutionCandidateJobNr)
78          return t;
79      }
80
81      //if solutionCandidate wasn't found in conflictSet apply DecodingErrorPolicy and ForcingPolicy
82      Task result = ApplyDecodingErrorPolicy(decodingErrorPolicy, conflictSet, jsm[conflictedResourceNr], progressOnConflictedResource, random);
83      int newResolutionIndex = 0;
84
85      while (newResolutionIndex < jsm[conflictedResourceNr].Length && jsm[conflictedResourceNr][newResolutionIndex] != result.JobNr)
86        newResolutionIndex++;
87      ApplyForcingStrategy(forcingStrategy, solution, conflictedResourceNr, newResolutionIndex, progressOnConflictedResource, result.JobNr);
88
89      return result;
90    }
91
92    private static Task ApplyDecodingErrorPolicy(JSMDecodingErrorPolicy decodingErrorPolicy, ItemList<Task> conflictSet, Permutation resource, int progress, IRandom random) {
93      if (decodingErrorPolicy == JSMDecodingErrorPolicy.RandomPolicy) {
94        //Random
95        return conflictSet[random.Next(conflictSet.Count - 1)];
96      } else {
97        //Guided
98        for (int i = progress; i < resource.Length; i++) {
99          int j = 0;
100          while (j < conflictSet.Count && conflictSet[j].JobNr != resource[i])
101            j++;
102
103          if (j < conflictSet.Count)
104            return (conflictSet[j]);
105        }
106        return conflictSet[random.Next(conflictSet.Count - 1)];
107      }
108    }
109
110    private static void ApplyForcingStrategy(JSMForcingStrategy forcingStrategy, JSMEncoding solution, int conflictedResource, int newResolutionIndex, int progressOnResource, int newResolution) {
111      var jsm = solution.JobSequenceMatrix;
112      if (forcingStrategy == JSMForcingStrategy.SwapForcing) {
113        //SwapForcing
114        jsm[conflictedResource][newResolutionIndex] = jsm[conflictedResource][progressOnResource];
115        jsm[conflictedResource][progressOnResource] = newResolution;
116      } else if (forcingStrategy == JSMForcingStrategy.ShiftForcing) {
117        //ShiftForcing
118        List<int> asList = jsm[conflictedResource].ToList<int>();
119        if (newResolutionIndex > progressOnResource) {
120          asList.RemoveAt(newResolutionIndex);
121          asList.Insert(progressOnResource, newResolution);
122        } else {
123          asList.Insert(progressOnResource, newResolution);
124          asList.RemoveAt(newResolutionIndex);
125        }
126        jsm[conflictedResource] = new Permutation(PermutationTypes.Absolute, asList.ToArray<int>());
127      } else {
128        throw new InvalidOperationException(string.Format("JSMDecoder encountered unknown forcing strategy {0}", forcingStrategy));
129      }
130    }
131
132    public override Schedule DecodeSchedule(JSMEncoding encoding, ItemList<Job> jobData) {
133      return Decode(encoding, jobData, DecodingErrorPolicy, ForcingStrategy);
134    }
135
136    public static Schedule Decode(JSMEncoding solution, ItemList<Job> jobData, JSMDecodingErrorPolicy decodingErrorPolicy, JSMForcingStrategy forcingStrategy) {
137      var random = new FastRandom(solution.RandomSeed);
138      var jobs = (ItemList<Job>)jobData.Clone();
139      var resultingSchedule = new Schedule(jobs[0].Tasks.Count);
140
141      //Reset scheduled tasks in result
142      foreach (Job j in jobs) {
143        foreach (Task t in j.Tasks) {
144          t.IsScheduled = false;
145        }
146      }
147
148      //GT-Algorithm
149      //STEP 0 - Compute a list of "earliest operations"
150      ItemList<Task> earliestTasksList = GTAlgorithmUtils.GetEarliestNotScheduledTasks(jobs);
151      while (earliestTasksList.Count > 0) {
152        //STEP 1 - Get earliest not scheduled operation with minimal earliest completing time
153        Task minimal = GTAlgorithmUtils.GetTaskWithMinimalEC(earliestTasksList, resultingSchedule);
154        int conflictedResourceNr = minimal.ResourceNr;
155        Resource conflictedResource = resultingSchedule.Resources[conflictedResourceNr];
156
157        //STEP 2 - Compute a conflict set of all operations that can be scheduled on the conflicted resource
158        ItemList<Task> conflictSet = GTAlgorithmUtils.GetConflictSetForTask(minimal, earliestTasksList, resultingSchedule);
159
160        //STEP 3 - Select a task from the conflict set
161        int progressOnResource = conflictedResource.Tasks.Count;
162        Task selectedTask = SelectTaskFromConflictSet(solution, decodingErrorPolicy, forcingStrategy, conflictedResourceNr, progressOnResource, conflictSet, random);
163
164        //STEP 4 - Add the selected task to the current schedule
165        selectedTask.IsScheduled = true;
166        double startTime = GTAlgorithmUtils.ComputeEarliestStartTime(selectedTask, resultingSchedule);
167        resultingSchedule.ScheduleTask(selectedTask.ResourceNr, startTime, selectedTask.Duration, selectedTask.JobNr);
168
169        //STEP 5 - Back to STEP 1
170        earliestTasksList = GTAlgorithmUtils.GetEarliestNotScheduledTasks(jobs);
171      }
172
173      return resultingSchedule;
174    }
175  }
176}
Note: See TracBrowser for help on using the repository browser.