Free cookie consent management tool by TermsFeed Policy Generator

source: branches/CFSAP/HeuristicLab.Problems.Scheduling.CFSAP/3.3/CFSAPSequenceOnly.cs @ 14757

Last change on this file since 14757 was 14757, checked in by abeham, 7 years ago

#2747: Added CFSAP with optimal (polynomial) assignment algorithm

File size: 9.2 KB
Line 
1#region License Information
2
3/* HeuristicLab
4 * Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
5 *
6 * This file is part of HeuristicLab.
7 *
8 * HeuristicLab is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * HeuristicLab is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#endregion
23
24using System;
25using System.Linq;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Data;
29using HeuristicLab.Encodings.PermutationEncoding;
30using HeuristicLab.Optimization;
31using HeuristicLab.Parameters;
32using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
33using HeuristicLab.Problems.Instances;
34
35namespace HeuristicLab.Problems.Scheduling.CFSAP {
36  [Item("Cyclic Flow Shop with two machine nests (CFSAP) sequence only", "Non-permutational cyclic flow shop scheduling problem with two machine nests from W. Bozejko.")]
37  [Creatable(CreatableAttribute.Categories.CombinatorialProblems)]
38  [StorableClass]
39  public class CFSAPSequenceOnly : SingleObjectiveBasicProblem<PermutationEncoding>, IProblemInstanceConsumer<CFSAPData> {
40    public override bool Maximization { get { return false; } }
41
42    public IValueParameter<IntMatrix> ProcessingTimesParameter {
43      get { return (IValueParameter<IntMatrix>)Parameters["ProcessingTimes"]; }
44    }
45
46    public IValueParameter<ItemList<IntMatrix>> SetupTimesParameter {
47      get { return (IValueParameter<ItemList<IntMatrix>>)Parameters["SetupTimes"]; }
48    }
49
50    [StorableConstructor]
51    protected CFSAPSequenceOnly(bool deserializing) : base(deserializing) {}
52    protected CFSAPSequenceOnly(CFSAPSequenceOnly original, Cloner cloner)
53      : base(original, cloner) {}
54    public CFSAPSequenceOnly() {
55      Parameters.Add(new ValueParameter<IntMatrix>("ProcessingTimes", "The processing times of each job for each machine nest."));
56      Parameters.Add(new ValueParameter<ItemList<IntMatrix>>("SetupTimes", "The sequence dependent set up times among all jobs for each machine nest."));
57
58      ProcessingTimesParameter.Value = new IntMatrix(new int[,] {
59        { 5, 4, 3, 2, 1 },
60        { 1, 2, 3, 4, 5 }
61      });
62
63      SetupTimesParameter.Value = new ItemList<IntMatrix>(2);
64      SetupTimesParameter.Value.Add(new IntMatrix(new int[,] {
65        { 3, 4, 5, 4, 3 },
66        { 3, 4, 5, 4, 3 },
67        { 3, 4, 5, 4, 3 },
68        { 3, 4, 5, 4, 3 },
69        { 3, 4, 5, 4, 3 },
70      }));
71      SetupTimesParameter.Value.Add(new IntMatrix(new int[,] {
72        { 5, 4, 3, 4, 5 },
73        { 5, 4, 3, 4, 5 },
74        { 5, 4, 3, 4, 5 },
75        { 5, 4, 3, 4, 5 },
76        { 5, 4, 3, 4, 5 },
77      }));
78
79      Encoding.Length = 5;
80
81      Operators.RemoveAll(x => x is SingleObjectiveMoveGenerator);
82      Operators.RemoveAll(x => x is SingleObjectiveMoveEvaluator);
83      Operators.RemoveAll(x => x is SingleObjectiveMoveMaker);
84    }
85
86    public override IDeepCloneable Clone(Cloner cloner) {
87      return new CFSAPSequenceOnly(this, cloner);
88    }
89
90    public override double Evaluate(Individual individual, IRandom random) {
91      var order = individual.Permutation(Encoding.Name);
92      var N = order.Length;
93      var processingTimes = ProcessingTimesParameter.Value;
94      var setupTimes = SetupTimesParameter.Value;
95
96      int[,,] weights = new int[2, 2 * N, 2 * N];
97      int[,] graph = new int[2, N];
98      int[,] prevPath = new int[2, N + 1];                     //Only for optimal assignment evaluation
99      int[] optimalAssignment = new int[N];                //Only for optimal assignment evaluation
100
101      //Calculate weights in the graph
102      for (int S = 0; S < N; S++) { //Starting point of the arc
103        for (int sM = 0; sM < 2; sM++) {    //Starting point machine
104          int eM = sM == 0 ? 1 : 0;
105          weights[sM, S, S + 1] = 0;
106
107          for (int E = S + 2; E < S + N; E++)
108            weights[sM, S, E] =
109              weights[sM, S, E - 1] +
110              processingTimes[eM, order[(E - 1) % N]] +
111              setupTimes[eM][order[(E - 1) % N], order[E % N]];
112
113          for (int E = S + 1; E < S + N; E++)
114            weights[sM, S, E] += (
115              processingTimes[sM, order[S % N]] +
116              setupTimes[sM][order[S % N], order[(E + 1) % N]]
117            );
118        }
119      }
120
121      //Determine the shortest path in the graph
122      int T = int.MaxValue / 2;
123      for (int S = 0; S < N - 1; S++)      //Start node in graph          O(N)
124        for (int SM = 0; SM < 2; SM++) {   //Start node machine in graph  O(1)
125          graph[SM, S] = 0;
126          graph[SM == 0 ? 1 : 0, S] = int.MaxValue / 2;
127          prevPath[SM, 0] = -1;
128          for (int E = S + 1; E < N; E++)      //Currently calculated node          O(N)
129            for (int EM = 0; EM < 2; EM++) {   //Currently calculated node machine  O(1)
130              graph[EM, E] = int.MaxValue / 2;
131              for (int EC = S; EC < E; EC++) { //Nodes connected to node E          O(N)
132                int newWeight = graph[EM == 0 ? 1 : 0, EC] + weights[EM == 0 ? 1 : 0, EC, E];
133                if (newWeight < graph[EM, E]) {
134                  graph[EM, E] = newWeight;
135                  prevPath[EM, E] = EC;
136                }
137              }
138            }
139
140          int EP = S + N; //End point.
141          int newT = int.MaxValue / 2;
142          for (int EC = S + 1; EC < N; EC++) { //Nodes connected to EP O(N)
143            int newWeight = graph[SM == 0 ? 1 : 0, EC] + weights[SM == 0 ? 1 : 0, EC, EP];
144            if (newWeight < newT) {
145              newT = newWeight;
146              prevPath[SM, S] = EC;
147            }
148          }
149
150          if (newT < T) {
151            T = newT;
152            optimalAssignment = MakeAssignement(S, SM, prevPath, order);
153          }
154        }
155
156      //Omitted solutions
157      for (int machine = 0; machine < 2; machine++) {
158        int[] assignment = Enumerable.Repeat(machine, N).ToArray();
159        int newT = EvaluateAssignement(order, assignment, processingTimes, setupTimes);
160        if (newT < T) { //New best solution has been found
161          T = newT;
162          assignment.CopyTo(optimalAssignment, N);
163        }
164      }
165
166      return T;
167    }
168
169    //Function to evaluate individual with the specified assignment
170    public static int EvaluateAssignement(Permutation order, int[] assignment, IntMatrix processingTimes, ItemList<IntMatrix> setupTimes) {
171      var N = order.Length;
172      int T = 0;
173
174      for (int i = 0; i < N; i++) {
175        int operation = order[i];
176        int machine = assignment[operation];
177        T += processingTimes[machine, operation];
178      }
179
180      for (int machine = 0; machine < 2; machine++) {
181        int first = -1;
182        int last = -1;
183        for (int i = 0; i < N; i++) {
184          int operation = order[i];
185          if (assignment[operation] == machine) {
186            if (first == -1)
187              first = operation;
188            else
189              T += setupTimes[machine][last, operation];
190            last = operation;
191          }
192        }
193        if (last != -1 && first != -1)
194          T += setupTimes[machine][last, first];
195      }
196
197      return T;
198    }
199
200    private int[] MakeAssignement(int start, int startMach, int[,] prevPath, Permutation order) {
201      var N = order.Length;
202      int[] assignment = Enumerable.Repeat(-1, N).ToArray();
203      var inverseOrder = new int[N];
204
205      for (int i = 0; i < N; i++)
206        inverseOrder[order[i]] = i;
207
208      int end = start + N;
209
210      int currMach = startMach;
211      int currNode = start;
212      while (true) {
213        assignment[inverseOrder[currNode]] = currMach;
214        currNode = prevPath[currMach, currNode];
215        currMach = currMach == 0 ? 1 : 0;
216        if (currNode == start)
217          break;
218      }
219
220      currMach = startMach;
221      for (int i = 0; i < N; i++) {
222        if (assignment[inverseOrder[i]] != -1)
223          currMach = currMach == 0 ? 1 : 0;
224        else
225          assignment[inverseOrder[i]] = currMach;
226      }
227
228      return assignment;
229    }
230
231    public void Load(CFSAPData data) {
232      if (data.MachineNests != 2) throw new ArgumentException("Currently only two machine nests are supported.");
233      ProcessingTimesParameter.Value = new IntMatrix(data.ProcessingTimes);
234      var setups = new ItemList<IntMatrix>(data.MachineNests);
235      for (var m = 0; m < data.SetupTimes.GetLength(0); m++) {
236        var setupTimes = new int[data.Jobs, data.Jobs];
237        for (var i = 0; i < data.Jobs; i++)
238        for (var j = 0; j < data.Jobs; j++)
239          setupTimes[i, j] = data.SetupTimes[m, i, j];
240        setups.Add(new IntMatrix(setupTimes));
241      }
242      SetupTimesParameter.Value = setups;
243      Encoding.Length = data.Jobs;
244      Name = data.Name;
245      Description = data.Description;
246    }
247  }
248}
Note: See TracBrowser for help on using the repository browser.