ULSAlgorithms 1.1.0-g3e5595996d
High-performance exact and heuristic algorithms for uncapacitated lot sizing
Loading...
Searching...
No Matches
AdaptiveExactUlsSolver.cs
Go to the documentation of this file.
7
9
10/// <summary>
11/// Selects and executes an efficient exact ULS algorithm from problem
12/// characteristics while preserving the common <see cref="IUlsSolver"/> contract.
13/// </summary>
14/// <remarks>
15/// <para>
16/// When <c>p[t] + h[t] &gt;= p[t+1]</c> for every adjacent period, the selector
17/// uses <see cref="WagnerWhitinSolver"/>, i.e. the linear-time specialization of
18/// Wagelmans, van Hoesel and Kolen (1992). Otherwise it uses a configurable
19/// general <c>O(n log n)</c> exact algorithm.
20/// </para>
21/// <para>
22/// The no-speculative-motive condition is cached by the immutable
23/// <see cref="UlsProblem"/> during construction. Adaptive selection therefore
24/// adds no extra <c>O(n)</c> applicability scan before invoking the selected
25/// exact solver.
26/// </para>
27/// <para>
28/// The default general fallback is <see cref="WagelmansGeneralSolver"/>. The
29/// alternative <see cref="FedergruenTzurSolver"/> remains selectable explicitly
30/// for reproducible research and benchmarking. The v0.24 calibration campaign
31/// recorded in the v0.25 engineering notes found no practical crossover on the
32/// measured horizons, so no empirical threshold is introduced.
33/// </para>
34/// <para>
35/// References: A. Wagelmans, S. van Hoesel and A. Kolen, Operations Research
36/// 40(S1), S145-S156, 1992, DOI: 10.1287/opre.40.1.S145; A. Federgruen and
37/// M. Tzur, Management Science 37(8), 909-925, 1991,
38/// DOI: 10.1287/mnsc.37.8.909.
39/// </para>
40/// </remarks>
42{
43 private readonly WagnerWhitinSolver _linearSolver = new();
44 private readonly IUlsSolver _generalSolver;
45
46 /// <summary>
47 /// Initializes a selector using the Wagelmans general algorithm as fallback.
48 /// </summary>
53
54 /// <summary>
55 /// Initializes a selector with an explicit general exact fallback.
56 /// </summary>
57 /// <param name="fallback">General exact algorithm to use outside the NSM case.</param>
59 {
60 Fallback = fallback;
61 _generalSolver = fallback switch
62 {
67 _ => throw new ArgumentOutOfRangeException(
68 nameof(fallback),
69 fallback,
70 "Unknown general exact fallback.")
71 };
72 }
73
74 /// <inheritdoc />
75 public string Name => "Adaptive exact ULS solver";
76
77 /// <inheritdoc />
79
80 /// <summary>
81 /// Gets the general exact fallback configured for this selector.
82 /// </summary>
84
85 /// <summary>
86 /// Selects the exact solver to use for the supplied problem.
87 /// </summary>
88 /// <param name="problem">The validated ULS problem.</param>
89 /// <returns>The selected exact strategy.</returns>
90 /// <remarks>
91 /// The applicability decision reuses the immutable profile cached by
92 /// <see cref="UlsProblem"/> and therefore does not rescan the horizon.
93 /// </remarks>
95 {
96 ArgumentNullException.ThrowIfNull(problem);
97
98 return problem.HasNoSpeculativeMotiveCosts
99 ? _linearSolver
100 : _generalSolver;
101 }
102
103 /// <summary>
104 /// Selects a solver from already-computed problem characteristics.
105 /// </summary>
106 /// <param name="problem">The validated ULS problem.</param>
107 /// <param name="characteristics">Characteristics computed for this problem.</param>
108 /// <returns>The selected exact strategy.</returns>
109 /// <exception cref="ArgumentException">
110 /// Thrown when the supplied characteristics are inconsistent with the
111 /// problem horizon or total demand.
112 /// </exception>
114 UlsProblem problem,
115 in UlsProblemCharacteristics characteristics)
116 {
117 ArgumentNullException.ThrowIfNull(problem);
118
119 if (characteristics.Horizon != problem.Horizon ||
120 characteristics.TotalDemand != problem.TotalDemand)
121 {
122 throw new ArgumentException(
123 "The supplied characteristics do not describe the supplied problem.",
124 nameof(characteristics));
125 }
126
127 return characteristics.HasNoSpeculativeMotiveCosts
128 ? _linearSolver
129 : _generalSolver;
130 }
131
132 /// <inheritdoc />
134 UlsProblem problem,
135 CancellationToken cancellationToken = default)
136 {
137 ArgumentNullException.ThrowIfNull(problem);
138 cancellationToken.ThrowIfCancellationRequested();
139
140 IUlsSolver selected =
141 SelectSolver(problem);
142
143 UlsSolveResult selectedResult =
144 selected.Solve(
145 problem,
146 cancellationToken);
147
148 string selectedAlgorithmId =
149 GetSelectedAlgorithmId(
150 selected);
151
153 Name,
154 selectedResult.Status,
155 selectedAlgorithmId,
156 selectedResult.SolverName,
157 selectedResult.Solution,
158 selectedResult.Message);
159 }
160
161 private string GetSelectedAlgorithmId(
162 IUlsSolver selected)
163 {
164 if (ReferenceEquals(
165 selected,
166 _linearSolver))
167 {
168 return "wagner-whitin-linear";
169 }
170
171 return Fallback switch
172 {
173 UlsGeneralExactFallback.WagelmansGeneral =>
174 "wagelmans-general",
175
176 UlsGeneralExactFallback.FedergruenTzurGeneral =>
177 "federgruen-tzur-general",
178
179 _ => throw new InvalidOperationException(
180 $"Unsupported adaptive exact fallback '{Fallback}'.")
181 };
182 }
183}
184
Implements the general forward Federgruen-Tzur dynamic lot-sizing algorithm.
Solves the general uncapacitated economic lot-sizing problem in O(n log n) time using the backward ge...
Solves ULS instances with Wagner-Whitin costs in linear time.
Represents a validated classical uncapacitated lot-sizing problem.
Definition UlsProblem.cs:23
double TotalDemand
Gets the total demand over the complete planning horizon.
Definition UlsProblem.cs:87
int Horizon
Gets the number of planning periods.
Definition UlsProblem.cs:82
Solve result returned by the adaptive exact strategy.
Represents the outcome returned by a ULS solution strategy.
string? Message
Gets an optional diagnostic message.
UlsSolveStatus Status
Gets the mathematical solve status.
UlsSolution? Solution
Gets the feasible solution, when one is available.
string SolverName
Gets the solver that produced the result.
string Name
Gets the stable human-readable name of the solver.
UlsSolverKind Kind
Gets the broad family of the solver.
AdaptiveExactUlsSolver(UlsGeneralExactFallback fallback)
Initializes a selector with an explicit general exact fallback.
UlsSolveResult Solve(UlsProblem problem, CancellationToken cancellationToken=default)
Solves an uncapacitated lot-sizing problem.The solve result.
AdaptiveExactUlsSolver()
Initializes a selector using the Wagelmans general algorithm as fallback.
IUlsSolver SelectSolver(UlsProblem problem, in UlsProblemCharacteristics characteristics)
Selects a solver from already-computed problem characteristics.
IUlsSolver SelectSolver(UlsProblem problem)
Selects the exact solver to use for the supplied problem.
UlsGeneralExactFallback Fallback
Gets the general exact fallback configured for this selector.
Defines the common strategy contract implemented by every ULS solver.
Definition IUlsSolver.cs:14
UlsSolveResult Solve(UlsProblem problem, CancellationToken cancellationToken=default)
Solves an uncapacitated lot-sizing problem.
UlsSolverKind
Identifies the broad family of a ULS solution strategy.
UlsGeneralExactFallback
Selects the general exact algorithm used when the linear-time Wagner-Whitin specialization is not app...
@ WagelmansGeneral
Uses the backward geometric Wagelmans-van Hoesel-Kolen algorithm.
@ FedergruenTzurGeneral
Uses the forward Federgruen-Tzur algorithm.
Describes inexpensive structural and cost characteristics used to select an exact ULS solution strate...