LotSizingDataModel.Core 2.0.1
Core domain model, shared abstractions and XML-serializable entities.
Loading...
Searching...
No Matches
ProductionSchedulingProfile.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Xml.Serialization;
6
8
9/// <summary>
10/// Scheduling semantics attached to one production work center.
11/// </summary>
12[Serializable]
13[XmlType(TypeName = "productionSchedulingProfile")]
14public sealed class ProductionSchedulingProfile :
17{
18 private SchedulingBucketMode _bucketMode;
19 private SmallBucketProductionMode _smallBucketProductionMode;
20 private MicroPeriodLengthMode _microPeriodLengthMode;
21 private MicroPeriodAssignmentMode _microPeriodAssignmentMode;
22 private SetupCarryOverPolicy _setupCarryOverPolicy;
23 private int _initialSetupItemId;
24
25 [XmlAttribute("bucketMode")]
27 {
28 get => _bucketMode;
29 set => SetProperty(ref _bucketMode, value);
30 }
31
32 [XmlAttribute("smallBucketProductionMode")]
34 {
35 get => _smallBucketProductionMode;
36 set => SetProperty(
37 ref _smallBucketProductionMode,
38 value);
39 }
40
41 [XmlAttribute("microPeriodLengthMode")]
43 {
44 get => _microPeriodLengthMode;
45 set => SetProperty(ref _microPeriodLengthMode, value);
46 }
47
48 [XmlAttribute("microPeriodAssignmentMode")]
50 {
51 get => _microPeriodAssignmentMode;
52 set => SetProperty(ref _microPeriodAssignmentMode, value);
53 }
54
55 [XmlAttribute("setupCarryOverPolicy")]
57 {
58 get => _setupCarryOverPolicy;
59 set => SetProperty(ref _setupCarryOverPolicy, value);
60 }
61
62 /// <summary>
63 /// Item whose setup state is present before the first modeled bucket.
64 /// Zero means that no initial setup state is declared.
65 /// </summary>
66 [XmlAttribute("initialSetupItemId")]
68 {
69 get => _initialSetupItemId;
70 set
71 {
72 if (value < 0)
73 {
74 throw new ArgumentOutOfRangeException(
75 nameof(value),
76 value,
77 "The initial setup item identifier cannot be negative.");
78 }
79
80 SetProperty(ref _initialSetupItemId, value);
81 }
82 }
83
84 [XmlElement("microPeriodCount")]
86 {
87 get;
88 set;
89 }
90
91 [XmlElement("maximumSetupCount")]
93 {
94 get;
95 set;
96 }
97
98 [XmlElement("maximumProducedItemCount")]
100 {
101 get;
102 set;
103 }
104
105 [XmlArray("changeovers")]
106 [XmlArrayItem("changeover")]
107 public List<ProductionChangeover> Changeovers
108 {
109 get;
110 } = new();
111
112 [XmlIgnore]
113 public bool HasInitialSetupState =>
115
116 [XmlIgnore]
117 public bool HasSetupCarryOver =>
119 SetupCarryOverPolicy.Allowed;
120
121 [XmlIgnore]
123 Changeovers.Any(
124 changeover =>
125 changeover.ChangeoverTime is not null);
126
127 [XmlIgnore]
129 Changeovers.Any(
130 changeover =>
131 changeover.ChangeoverCost is not null);
132
133 [XmlIgnore]
135 MaximumProducedItemCount is not null;
136
137 [XmlIgnore]
140 MicroPeriodCount is not null &&
142
143 [XmlIgnore]
145 MicroPeriodCount is null
146 ? 0
147 : Enumerable
148 .Range(1, MicroPeriodCount.PlanningHorizon)
149 .Sum(period => MicroPeriodCount.GetCount(period));
150
151 [XmlIgnore]
153 GetMaximumValue(
155 parameter => parameter.GetCount);
156
157 [XmlIgnore]
159 MicroPeriodCount is not null &&
161 Enumerable
162 .Range(1, MicroPeriodCount.PlanningHorizon)
163 .Select(period => MicroPeriodCount.GetCount(period))
164 .Distinct()
165 .Take(2)
166 .Count() > 1;
167
168 [XmlIgnore]
171
172 [XmlIgnore]
175
176 [XmlIgnore]
178 GetMaximumValue(
180 parameter =>
181 parameter.GetCount);
182
183 [XmlIgnore]
185 GetMaximumValue(
187 parameter =>
188 parameter.GetCount);
189
190 [XmlIgnore]
192 {
193 get
194 {
195 if (MicroPeriodCount is not null)
196 {
197 return MicroPeriodCount.PlanningHorizon;
198 }
199
200 if (MaximumSetupCount is not null)
201 {
202 return MaximumSetupCount.PlanningHorizon;
203 }
204
205 if (MaximumProducedItemCount is not null)
206 {
207 return MaximumProducedItemCount.PlanningHorizon;
208 }
209
210 ProductionChangeover? first =
211 Changeovers.FirstOrDefault(
212 changeover =>
213 changeover.PlanningHorizon > 0);
214
215 return first?.PlanningHorizon ?? 0;
216 }
217 }
218
219 [XmlIgnore]
221 {
222 get
223 {
224 int[] horizons =
225 EnumeratePlanningHorizons()
226 .Where(value => value > 0)
227 .Distinct()
228 .ToArray();
229
230 return
231 horizons.Length <= 1 &&
232 Changeovers.All(
233 changeover =>
234 changeover.HasConsistentPlanningHorizon);
235 }
236 }
237
238 public void ResizeTimeSeries(int periodCount)
239 {
240 if (periodCount < 0)
241 {
242 throw new ArgumentOutOfRangeException(
243 nameof(periodCount),
244 periodCount,
245 "The planning horizon cannot be negative.");
246 }
247
248 MicroPeriodCount?.ResizeTimeSeries(periodCount);
249 MaximumSetupCount?.ResizeTimeSeries(periodCount);
250 MaximumProducedItemCount?.ResizeTimeSeries(periodCount);
251
252 foreach (
253 ProductionChangeover changeover
254 in Changeovers)
255 {
256 changeover.ResizeTimeSeries(periodCount);
257 }
258
261 }
262
263 public IEnumerable<ProductionMicroPeriodReference>
265 {
266 if (MicroPeriodCount is null)
267 {
268 yield break;
269 }
270
271 for (int macroPeriod = 1;
272 macroPeriod <= MicroPeriodCount.PlanningHorizon;
273 macroPeriod++)
274 {
275 int count =
276 MicroPeriodCount.GetCount(macroPeriod);
277
278 for (int microPeriodIndex = 1;
279 microPeriodIndex <= count;
280 microPeriodIndex++)
281 {
282 yield return
284 macroPeriod,
285 microPeriodIndex);
286 }
287 }
288 }
289
290 private static int GetMaximumValue<T>(
291 T? parameter,
292 Func<T, Func<int, int>> accessorFactory)
293 where T : class, IPlanningHorizonAware
294 {
295 if (
296 parameter is null ||
297 parameter.PlanningHorizon <= 0)
298 {
299 return 0;
300 }
301
302 Func<int, int> accessor =
303 accessorFactory(parameter);
304
305 return Enumerable
306 .Range(
307 1,
308 parameter.PlanningHorizon)
309 .Max(accessor);
310 }
311
312 private IEnumerable<int> EnumeratePlanningHorizons()
313 {
314 if (MicroPeriodCount is not null)
315 {
317 }
318
319 if (MaximumSetupCount is not null)
320 {
322 }
323
324 if (MaximumProducedItemCount is not null)
325 {
327 }
328
329 foreach (
330 ProductionChangeover changeover
331 in Changeovers)
332 {
333 if (changeover.PlanningHorizon > 0)
334 {
335 yield return changeover.PlanningHorizon;
336 }
337 }
338 }
339}
Base class for model objects that notify listeners when one of their properties changes.
virtual void OnPropertyChanged([CallerMemberName] string? propertyName=null)
Raises the PropertyChanged event.
int PlanningHorizon
Gets the number of planning periods represented by this parameter.
int PlanningHorizon
Gets the number of planning periods currently represented by the object's time-dependent data.
void ResizeTimeSeries(int periodCount)
Resizes every time-dependent series contained in the object.
int InitialSetupItemId
Item whose setup state is present before the first modeled bucket. Zero means that no initial setup s...
int PlanningHorizon
Gets the number of planning periods currently represented by the object's time-dependent data.
void ResizeTimeSeries(int periodCount)
Resizes every time-dependent series contained in the object.
Defines a model object containing data indexed by planning period.
int PlanningHorizon
Gets the number of planning periods currently represented by the object's time-dependent data.
SchedulingBucketMode
Time-bucket structure used by an integrated lot-sizing and scheduling description.
@ MacroMicro
Each planning macro-period is subdivided into explicit micro-periods, as in GLSP-style time structure...