Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2747_CFSAP/HeuristicLab.Problems.Scheduling.CFSAP/3.3/CFSAPSequenceOnly.cs @ 17639

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

#2747: worked on the CFSAP

  • Added problem definition that defines both sequence and assignment for a single nest
  • Added problem definition that would optimizes both sequence and assignment for multiple nests
  • Added interface
  • Added solving strategy that would use multiple instances of a template algorithm to optimize the worst nest
  • Fixed bug in parser regarding setup times
File size: 9.8 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 machines and a single nest (CFSAP) sequencing problem", "Non-permutational cyclic flow shop scheduling problem with a single nest of two machine 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 IntMatrix ProcessingTimes {
47      get { return ProcessingTimesParameter.Value; }
48      set { ProcessingTimesParameter.Value = value; }
49    }
50
51    public IValueParameter<ItemList<IntMatrix>> SetupTimesParameter {
52      get { return (IValueParameter<ItemList<IntMatrix>>)Parameters["SetupTimes"]; }
53    }
54
55    public ItemList<IntMatrix> SetupTimes {
56      get { return SetupTimesParameter.Value; }
57      set { SetupTimesParameter.Value = value; }
58    }
59
60    [StorableConstructor]
61    protected CFSAPSequenceOnly(bool deserializing) : base(deserializing) {}
62    protected CFSAPSequenceOnly(CFSAPSequenceOnly original, Cloner cloner)
63      : base(original, cloner) {}
64    public CFSAPSequenceOnly() {
65      Parameters.Add(new ValueParameter<IntMatrix>("ProcessingTimes", "The processing times of each job for each machine nest."));
66      Parameters.Add(new ValueParameter<ItemList<IntMatrix>>("SetupTimes", "The sequence dependent set up times among all jobs for each machine nest."));
67
68      ProcessingTimesParameter.Value = new IntMatrix(new int[,] {
69        { 5, 4, 3, 2, 1 },
70        { 1, 2, 3, 4, 5 }
71      });
72
73      SetupTimesParameter.Value = new ItemList<IntMatrix>(2);
74      SetupTimesParameter.Value.Add(new IntMatrix(new int[,] {
75        { 3, 4, 5, 4, 3 },
76        { 3, 4, 5, 4, 3 },
77        { 3, 4, 5, 4, 3 },
78        { 3, 4, 5, 4, 3 },
79        { 3, 4, 5, 4, 3 },
80      }));
81      SetupTimesParameter.Value.Add(new IntMatrix(new int[,] {
82        { 5, 4, 3, 4, 5 },
83        { 5, 4, 3, 4, 5 },
84        { 5, 4, 3, 4, 5 },
85        { 5, 4, 3, 4, 5 },
86        { 5, 4, 3, 4, 5 },
87      }));
88
89      Encoding.Length = 5;
90
91      Operators.RemoveAll(x => x is SingleObjectiveMoveGenerator);
92      Operators.RemoveAll(x => x is SingleObjectiveMoveEvaluator);
93      Operators.RemoveAll(x => x is SingleObjectiveMoveMaker);
94    }
95
96    public override IDeepCloneable Clone(Cloner cloner) {
97      return new CFSAPSequenceOnly(this, cloner);
98    }
99
100    public override double Evaluate(Individual individual, IRandom random) {
101      var order = individual.Permutation(Encoding.Name);
102      int T = EvaluateSequence(order);
103      return T;
104    }
105
106    public int EvaluateSequence(Permutation order) {
107      var N = order.Length;
108      var processingTimes = ProcessingTimesParameter.Value;
109      var setupTimes = SetupTimesParameter.Value;
110
111      int[,,] weights = new int[2, 2 * N, 2 * N];
112      int[,] graph = new int[2, N];
113      int[,] prevPath = new int[2, N + 1];                     //Only for optimal assignment evaluation
114      int[] optimalAssignment = new int[N];                //Only for optimal assignment evaluation
115
116      //Calculate weights in the graph
117      for (int S = 0; S < N; S++) { //Starting point of the arc
118        for (int sM = 0; sM < 2; sM++) {    //Starting point machine
119          int eM = sM == 0 ? 1 : 0;
120          weights[sM, S, S + 1] = 0;
121
122          for (int E = S + 2; E < S + N; E++)
123            weights[sM, S, E] =
124              weights[sM, S, E - 1] +
125              processingTimes[eM, order[(E - 1) % N]] +
126              setupTimes[eM][order[(E - 1) % N], order[E % N]];
127
128          for (int E = S + 1; E < S + N; E++)
129            weights[sM, S, E] += (
130              processingTimes[sM, order[S % N]] +
131              setupTimes[sM][order[S % N], order[(E + 1) % N]]
132            );
133        }
134      }
135
136      //Determine the shortest path in the graph
137      int T = int.MaxValue / 2;
138      for (int S = 0; S < N - 1; S++)      //Start node in graph          O(N)
139        for (int SM = 0; SM < 2; SM++) {   //Start node machine in graph  O(1)
140          graph[SM, S] = 0;
141          graph[SM == 0 ? 1 : 0, S] = int.MaxValue / 2;
142          prevPath[SM, 0] = -1;
143          for (int E = S + 1; E < N; E++)      //Currently calculated node          O(N)
144            for (int EM = 0; EM < 2; EM++) {   //Currently calculated node machine  O(1)
145              graph[EM, E] = int.MaxValue / 2;
146              for (int EC = S; EC < E; EC++) { //Nodes connected to node E          O(N)
147                int newWeight = graph[EM == 0 ? 1 : 0, EC] + weights[EM == 0 ? 1 : 0, EC, E];
148                if (newWeight < graph[EM, E]) {
149                  graph[EM, E] = newWeight;
150                  prevPath[EM, E] = EC;
151                }
152              }
153            }
154
155          int EP = S + N; //End point.
156          int newT = int.MaxValue / 2;
157          for (int EC = S + 1; EC < N; EC++) { //Nodes connected to EP O(N)
158            int newWeight = graph[SM == 0 ? 1 : 0, EC] + weights[SM == 0 ? 1 : 0, EC, EP];
159            if (newWeight < newT) {
160              newT = newWeight;
161              prevPath[SM, S] = EC;
162            }
163          }
164
165          if (newT < T) {
166            T = newT;
167            optimalAssignment = MakeAssignement(S, SM, prevPath, order);
168          }
169        }
170
171      //Omitted solutions
172      for (int machine = 0; machine < 2; machine++) {
173        int[] assignment = Enumerable.Repeat(machine, N).ToArray();
174        int newT = CFSAP.EvaluateAssignement(order, assignment, processingTimes, setupTimes);
175        if (newT < T) { //New best solution has been found
176          T = newT;
177          optimalAssignment = assignment;
178        }
179      }
180
181      return T;
182    }
183
184    private int[] MakeAssignement(int start, int startMach, int[,] prevPath, Permutation order) {
185      var N = order.Length;
186      int[] assignment = Enumerable.Repeat(-1, N).ToArray();
187      var inverseOrder = new int[N];
188
189      for (int i = 0; i < N; i++)
190        inverseOrder[order[i]] = i;
191
192      int end = start + N;
193
194      int currMach = startMach;
195      int currNode = start;
196      while (true) {
197        assignment[inverseOrder[currNode]] = currMach;
198        currNode = prevPath[currMach, currNode];
199        currMach = currMach == 0 ? 1 : 0;
200        if (currNode == start)
201          break;
202      }
203
204      currMach = startMach;
205      for (int i = 0; i < N; i++) {
206        if (assignment[inverseOrder[i]] != -1)
207          currMach = currMach == 0 ? 1 : 0;
208        else
209          assignment[inverseOrder[i]] = currMach;
210      }
211
212      return assignment;
213    }
214
215    public void UpdateEncoding() {
216      Encoding.Length = ProcessingTimes.Columns;
217    }
218
219    /// <summary>
220    /// Imports the first nest (index 0) given in the CFSAPData.
221    /// This is the same as calling Load(data, 0).
222    /// </summary>
223    /// <param name="data">The data of all nests.</param>
224    public void Load(CFSAPData data) {
225      Load(data, 0);
226    }
227
228    /// <summary>
229    /// Imports a specific nest given in the CFSAPData.
230    /// </summary>
231    /// <param name="data">The data of all nests.</param>
232    /// <param name="nest">The zero-based index of the nest that should be imported.</param>
233    public void Load(CFSAPData data, int nest) {
234      if (data.Machines[nest] != 2) throw new ArgumentException("Currently only two machines per nest are supported.");
235      if (nest < 0 || nest >= data.Nests) throw new ArgumentException("Nest must be a zero-based index.");
236      var pr = new int[data.Machines[nest], data.Jobs];
237      for (var i = 0; i < data.Machines[nest]; i++)
238        for (var j = 0; j < data.Jobs; j++)
239          pr[i, j] = data.ProcessingTimes[nest][i][j];
240      ProcessingTimesParameter.Value = new IntMatrix(pr);
241      var setups = new ItemList<IntMatrix>(data.Machines[nest]);
242      for (var m = 0; m < data.SetupTimes[nest].GetLength(0); m++) {
243        var setupTimes = new int[data.Jobs, data.Jobs];
244        for (var i = 0; i < data.Jobs; i++)
245          for (var j = 0; j < data.Jobs; j++)
246            setupTimes[i, j] = data.SetupTimes[nest][m][i][j];
247        setups.Add(new IntMatrix(setupTimes));
248      }
249      SetupTimesParameter.Value = setups;
250      UpdateEncoding();
251      Name = data.Name + "-nest" + nest;
252      Description = data.Description;
253      if (data.BestKnownCycleTime.HasValue)
254        BestKnownQuality = data.BestKnownCycleTime.Value;
255      else BestKnownQualityParameter.Value = null;
256    }
257  }
258}
Note: See TracBrowser for help on using the repository browser.