LotSizingDataModel.Instance 2.0.1
Lot-sizing instance representation, descriptors and problem characterization.
Loading...
Searching...
No Matches
ClosedLoopReturnStream.cs
Go to the documentation of this file.
1using System;
2using System.Xml.Serialization;
3using LotSizingDataModel.Core.Common;
4using LotSizingDataModel.Core.PhysicalModel;
5
7
8/// <summary>
9/// Describes one exogenous stream of returned units and its
10/// recovery/disposal alternatives.
11/// </summary>
12[Serializable]
13[XmlType(TypeName = "closedLoopReturnStream")]
14public sealed class ClosedLoopReturnStream :
15 ModelObject,
16 IPlanningHorizonAware
17{
18 private int _id;
19 private int _itemId;
20 private int _distributionCenterId;
21 private WarehouseReference _recoveryWarehouse =
22 new();
23 private double _recoveryYield = 1.0;
24 private ClosedLoopTimeSeriesParameter _returnQuantity =
25 new();
26 private ClosedLoopTimeSeriesParameter? _recoveryCapacity;
27 private ClosedLoopTimeSeriesParameter _collectionUnitCost =
28 new();
29 private ClosedLoopTimeSeriesParameter _recoveryUnitCost =
30 new();
31 private ClosedLoopTimeSeriesParameter _disposalUnitCost =
32 new();
33
35 {
36 }
37
39 int id,
40 int itemId,
41 int distributionCenterId,
42 WarehouseReference recoveryWarehouse,
43 int planningHorizon)
44 {
45 Id =
46 id;
47
48 ItemId =
49 itemId;
50
52 distributionCenterId;
53
55 recoveryWarehouse;
56
58 planningHorizon);
59 }
60
61 [XmlAttribute("id")]
62 public int Id
63 {
64 get => _id;
65 set
66 {
67 if (value < 0)
68 {
69 throw new ArgumentOutOfRangeException(
70 nameof(value));
71 }
72
73 SetProperty(
74 ref _id,
75 value);
76 }
77 }
78
79 [XmlAttribute("itemId")]
80 public int ItemId
81 {
82 get => _itemId;
83 set
84 {
85 if (value < 0)
86 {
87 throw new ArgumentOutOfRangeException(
88 nameof(value));
89 }
90
91 SetProperty(
92 ref _itemId,
93 value);
94 }
95 }
96
97 [XmlAttribute("distributionCenterId")]
99 {
100 get => _distributionCenterId;
101 set
102 {
103 if (value < 0)
104 {
105 throw new ArgumentOutOfRangeException(
106 nameof(value));
107 }
108
109 SetProperty(
110 ref _distributionCenterId,
111 value);
112 }
113 }
114
115 [XmlElement("recoveryWarehouse")]
116 public WarehouseReference RecoveryWarehouse
117 {
118 get => _recoveryWarehouse;
119 set =>
120 SetProperty(
121 ref _recoveryWarehouse,
122 value ??
123 new WarehouseReference());
124 }
125
126 [XmlAttribute("recoveryYield")]
127 public double RecoveryYield
128 {
129 get => _recoveryYield;
130 set
131 {
132 if (!double.IsFinite(value) ||
133 value <= 0.0 ||
134 value > 1.0)
135 {
136 throw new ArgumentOutOfRangeException(
137 nameof(value),
138 value,
139 "Recovery yield must belong to ]0,1].");
140 }
141
142 SetProperty(
143 ref _recoveryYield,
144 value);
145 }
146 }
147
148 [XmlElement("returnQuantity")]
150 {
151 get => _returnQuantity;
152 set =>
153 SetProperty(
154 ref _returnQuantity,
155 value ??
157 }
158
159 [XmlElement("recoveryCapacity", IsNullable = true)]
161 {
162 get => _recoveryCapacity;
163 set =>
164 SetProperty(
165 ref _recoveryCapacity,
166 value);
167 }
168
169 [XmlElement("collectionUnitCost")]
171 {
172 get => _collectionUnitCost;
173 set =>
174 SetProperty(
175 ref _collectionUnitCost,
176 value ??
178 }
179
180 [XmlElement("recoveryUnitCost")]
182 {
183 get => _recoveryUnitCost;
184 set =>
185 SetProperty(
186 ref _recoveryUnitCost,
187 value ??
189 }
190
191 [XmlElement("disposalUnitCost")]
193 {
194 get => _disposalUnitCost;
195 set =>
196 SetProperty(
197 ref _disposalUnitCost,
198 value ??
200 }
201
202 [XmlIgnore]
203 public int PlanningHorizon =>
204 ReturnQuantity.PlanningHorizon;
205
206 [XmlIgnore]
208 {
209 get
210 {
211 int expected =
212 ReturnQuantity.PlanningHorizon;
213
214 if (CollectionUnitCost.PlanningHorizon != expected ||
215 RecoveryUnitCost.PlanningHorizon != expected ||
216 DisposalUnitCost.PlanningHorizon != expected)
217 {
218 return false;
219 }
220
221 return RecoveryCapacity is null ||
222 RecoveryCapacity.PlanningHorizon ==
223 expected;
224 }
225 }
226
227 public void ResizeTimeSeries(
228 int periodCount)
229 {
230 if (periodCount < 0)
231 {
232 throw new ArgumentOutOfRangeException(
233 nameof(periodCount));
234 }
235
236 ReturnQuantity.ResizeTimeSeries(
237 periodCount);
238
239 CollectionUnitCost.ResizeTimeSeries(
240 periodCount);
241
242 RecoveryUnitCost.ResizeTimeSeries(
243 periodCount);
244
245 DisposalUnitCost.ResizeTimeSeries(
246 periodCount);
247
248 RecoveryCapacity?.ResizeTimeSeries(
249 periodCount);
250
251 OnPropertyChanged(
252 nameof(PlanningHorizon));
253
254 OnPropertyChanged(
256 }
257
258 public void EnsureValid()
259 {
260 if (Id <= 0)
261 {
262 throw new InvalidOperationException(
263 "A closed-loop return stream requires a strictly positive identifier.");
264 }
265
266 if (ItemId <= 0)
267 {
268 throw new InvalidOperationException(
269 "A closed-loop return stream requires a strictly positive item identifier.");
270 }
271
272 if (DistributionCenterId <= 0)
273 {
274 throw new InvalidOperationException(
275 "A closed-loop return stream requires a strictly positive distribution-center identifier.");
276 }
277
278 if (RecoveryWarehouse.ReferenceId <= 0)
279 {
280 throw new InvalidOperationException(
281 "A closed-loop return stream requires a valid recovery warehouse.");
282 }
283
284 if (!double.IsFinite(RecoveryYield) ||
285 RecoveryYield <= 0.0 ||
286 RecoveryYield > 1.0)
287 {
288 throw new InvalidOperationException(
289 "Recovery yield must belong to ]0,1].");
290 }
291
293 {
294 throw new InvalidOperationException(
295 "All closed-loop return-stream time series must use one planning horizon.");
296 }
297 }
298}
ClosedLoopReturnStream(int id, int itemId, int distributionCenterId, WarehouseReference recoveryWarehouse, int planningHorizon)
Non-negative period-dependent quantity or unit-cost series used by the closed-loop instance extension...