ULSAlgorithms 1.1.0-g3e5595996d
High-performance exact and heuristic algorithms for uncapacitated lot sizing
Loading...
Searching...
No Matches
ZeroInventoryOrderSolutionBuilder.cs
Go to the documentation of this file.
3
5
6/// <summary>
7/// Reconstructs a zero-inventory-order ULS solution from shortest-path predecessors.
8/// </summary>
10{
11 public static UlsSolveResult Build(
12 UlsProblem problem,
13 ReadOnlySpan<int> predecessor,
14 string solverName,
15 CancellationToken cancellationToken)
16 {
17 ArgumentNullException.ThrowIfNull(problem);
18
19 var horizon = problem.Horizon;
20 if (predecessor.Length != horizon + 1)
21 {
22 throw new ArgumentException(
23 $"Predecessor vector must contain {horizon + 1} entries.",
24 nameof(predecessor));
25 }
26
27 var production = new double[horizon];
28 var inventory = new double[horizon];
29 var setup = new bool[horizon];
30
31 var demands = problem.Demands;
32
33 var end = horizon;
34 while (end > 0)
35 {
36 cancellationToken.ThrowIfCancellationRequested();
37
38 var start = predecessor[end];
39 if (start < 0 || start >= end)
40 {
41 throw new InvalidOperationException(
42 "The shortest-path predecessor chain is inconsistent.");
43 }
44
45 var quantity = 0.0;
46 for (var period = start; period < end; period++)
47 {
48 quantity = AddFinite(quantity, demands[period], "reconstructed production quantity");
49 }
50
51 if (quantity > 0.0)
52 {
53 production[start] = quantity;
54 setup[start] = true;
55 }
56
57 end = start;
58 }
59
60 var runningInventory = 0.0;
61 var setupCost = 0.0;
62 var productionCost = 0.0;
63 var holdingCost = 0.0;
64
65 var setupCosts = problem.SetupCosts;
66 var productionCosts = problem.UnitProductionCosts;
67 var holdingCosts = problem.HoldingCosts;
68
69 for (var period = 0; period < horizon; period++)
70 {
71 cancellationToken.ThrowIfCancellationRequested();
72
73 if (setup[period])
74 {
75 setupCost = AddFinite(
76 setupCost,
77 setupCosts[period],
78 "solution setup cost");
79 }
80
81 productionCost = AddFinite(
82 productionCost,
83 MultiplyFinite(
84 productionCosts[period],
85 production[period],
86 "solution production cost"),
87 "solution production cost");
88
89 runningInventory = AddFinite(
90 runningInventory,
91 production[period],
92 "inventory balance");
93
94 runningInventory -= demands[period];
95
96 var tolerance = 1e-10 * Math.Max(
97 1.0,
98 Math.Max(Math.Abs(runningInventory), Math.Abs(demands[period])));
99
100 if (runningInventory < -tolerance)
101 {
102 throw new InvalidOperationException(
103 $"Reconstructed solution has negative inventory at period {period}.");
104 }
105
106 if (runningInventory < 0.0)
107 {
108 runningInventory = 0.0;
109 }
110
111 inventory[period] = runningInventory;
112
113 holdingCost = AddFinite(
114 holdingCost,
115 MultiplyFinite(
116 holdingCosts[period],
117 inventory[period],
118 "solution holding cost"),
119 "solution holding cost");
120 }
121
122 var solution = UlsSolution.FromOwnedBuffers(
123 production,
124 inventory,
125 setup,
126 setupCost,
127 productionCost,
128 holdingCost);
129
130 return new UlsSolveResult(
131 solverName,
132 UlsSolveStatus.Optimal,
133 solution);
134 }
135
136 private static double AddFinite(
137 double left,
138 double right,
139 string operation)
140 {
141 var value = left + right;
142
143 if (!double.IsFinite(value))
144 {
145 throw new ArithmeticException(
146 $"Numerical overflow while computing {operation}.");
147 }
148
149 return value;
150 }
151
152 private static double MultiplyFinite(
153 double left,
154 double right,
155 string operation)
156 {
157 var value = left * right;
158
159 if (!double.IsFinite(value))
160 {
161 throw new ArithmeticException(
162 $"Numerical overflow while computing {operation}.");
163 }
164
165 return value;
166 }
167}
Reconstructs a zero-inventory-order ULS solution from shortest-path predecessors.
static UlsSolveResult Build(UlsProblem problem, ReadOnlySpan< int > predecessor, string solverName, CancellationToken cancellationToken)
Represents a validated classical uncapacitated lot-sizing problem.
Definition UlsProblem.cs:23
ReadOnlySpan< double > UnitProductionCosts
Gets unit production costs by period.
int Horizon
Gets the number of planning periods.
Definition UlsProblem.cs:82
ReadOnlySpan< double > HoldingCosts
Gets end-of-period unit holding costs by period.
ReadOnlySpan< double > Demands
Gets demand by period.
Definition UlsProblem.cs:92
ReadOnlySpan< double > SetupCosts
Gets fixed setup costs by period.
Definition UlsProblem.cs:97
Represents a feasible production plan for a ULS problem.
Definition UlsSolution.cs:7
static UlsSolution FromOwnedBuffers(double[] productionQuantities, double[] endingInventories, bool[] setupDecisions, double setupCost, double productionCost, double holdingCost)
Creates a solution while transferring ownership of already allocated solver buffers.
Represents the outcome returned by a ULS solution strategy.
UlsSolveStatus
Describes the mathematical status of a ULS solve.