16 LotSizingInstance instance,
19 ArgumentNullException.ThrowIfNull(
22 ArgumentNullException.ThrowIfNull(
25 if (instance.PlanningHorizon <= 0)
27 throw new NotSupportedException(
28 "ULSAlgorithms exact adapters require a positive planning horizon.");
31 if (instance.SupplyChain.Demands.Count != 1 ||
32 instance.SupplyChain.ProductionRoutings.Count != 1 ||
33 instance.SupplyChain.Inventories.Count != 1)
35 throw new NotSupportedException(
36 "ULSAlgorithms exact adapters require exactly one demand, one production routing and one inventory.");
40 instance.SupplyChain.ProductionRoutings[0];
43 instance.SupplyChain.Inventories[0];
45 if (routing.LeadTime != 0)
47 throw new NotSupportedException(
48 "The alpha.34 ULSAlgorithms bridge requires zero production lead time.");
51 if (Math.Abs(inventory.InitialInventory) >
54 throw new NotSupportedException(
55 "The alpha.34 ULSAlgorithms bridge requires fixed zero initial inventory.");
58 if (inventory.ScheduledReceipt is not
null)
61 period <= instance.PlanningHorizon;
65 inventory.ScheduledReceipt[period]) >
68 throw new NotSupportedException(
69 "Scheduled receipts are outside the alpha.34 canonical ULS contract.");
74 if (instance.SupplyChain.ComponentRequirements.Count != 0 ||
75 instance.SupplyChain.SupplierDeliveries.Count != 0 ||
76 instance.SupplyChain.TransportCharacteristics.Count != 0)
78 throw new NotSupportedException(
79 "BOM, procurement and transport extensions are outside the alpha.34 canonical ULS contract.");
85 throw new NotSupportedException(
86 "ULSAlgorithms exact adapters require a minimization objective.");
93 throw new NotSupportedException(
94 "The alpha.34 canonical ULS objective cannot contain an additive constant.");
97 AssertCanonicalConstraintShape(
101 instance.PlanningHorizon;
107 instance.SupplyChain.Demands[0];
113 demands[period - 1] =
118 double[] setupCosts =
121 double[] productionCosts =
124 double[] holdingCosts =
127 var coefficientByVariable =
129 term => term.VariableId,
130 term => term.Coefficient);
132 int[] productionCounts =
138 int[] inventoryCounts =
141 int[] deliveryCounts =
152 throw new NotSupportedException(
153 $
"Variable '{variable.Name}' has no canonical domain key.");
156 if (!key.TryGetInt32(
162 throw new NotSupportedException(
163 $
"Variable '{variable.Name}' has no valid canonical planning period.");
169 coefficientByVariable.TryGetValue(
171 out
double coefficient);
173 switch (key.Category)
176 productionCounts[index]++;
177 productionCosts[index] += coefficient;
181 setupCounts[index]++;
182 setupCosts[index] += coefficient;
186 inventoryCounts[index]++;
187 holdingCosts[index] += coefficient;
191 deliveryCounts[index]++;
193 if (Math.Abs(coefficient) >
196 throw new NotSupportedException(
197 "Delivery-cost terms are outside the alpha.34 canonical ULS objective.");
203 throw new NotSupportedException(
204 $
"Decision category '{key.Category}' is outside the alpha.34 canonical ULS model shape.");
212 if (productionCounts[index] != 1 ||
213 setupCounts[index] != 1 ||
214 inventoryCounts[index] != 1 ||
215 deliveryCounts[index] > 1)
217 throw new NotSupportedException(
218 $
"Period {index + 1} does not contain exactly one production/setup/inventory variable or contains multiple delivery variables.");