ULSAlgorithms 1.1.0-g3e5595996d
High-performance exact and heuristic algorithms for uncapacitated lot sizing
Loading...
Searching...
No Matches
SilverMealSolver.cs
Go to the documentation of this file.
1using System.Buffers;
6
8
9/// <summary>
10/// Implements the Silver-Meal least-cost-per-period heuristic.
11/// </summary>
12/// <remarks>
13/// Starting with the first uncovered positive demand, the candidate
14/// replenishment cycle is extended while the average setup-plus-holding cost
15/// per covered calendar period does not increase.
16/// <para>
17/// Reference: E. A. Silver and H. C. Meal,
18/// "A heuristic for selecting lot size quantities for the case of a
19/// deterministic time-varying demand rate and discrete opportunities for
20/// replenishment", Production and Inventory Management, 14(2), 64-74, 1973.
21/// </para>
22/// </remarks>
23public sealed class SilverMealSolver : IUlsSolver
24{
25 public string Name => "Silver-Meal";
26
27 public UlsSolverKind Kind => UlsSolverKind.Heuristic;
28
29 public static bool IsApplicable(UlsProblem problem) =>
31
33 UlsProblem problem,
34 CancellationToken cancellationToken = default)
35 {
36 ArgumentNullException.ThrowIfNull(problem);
37 cancellationToken.ThrowIfCancellationRequested();
39
40 var horizon = problem.Horizon;
41 var buffer = ArrayPool<int>.Shared.Rent(horizon);
42
43 try
44 {
45 var cycleEnds = buffer.AsSpan(0, horizon);
46 cycleEnds.Fill(-1);
47
48 var demands = problem.Demands;
49 var setupCost = problem.SetupCosts[0];
50 var holdingCost =
51 horizon > 1 ? problem.HoldingCosts[0] : 0.0;
52
53 var start =
55
56 while (start < horizon)
57 {
58 cancellationToken.ThrowIfCancellationRequested();
59
60 var bestEnd = start;
61 var accumulatedHolding = 0.0;
62 var previousAverage = setupCost;
63
64 for (var end = start + 1; end < horizon; end++)
65 {
66 accumulatedHolding +=
67 holdingCost *
68 (end - start) *
69 demands[end];
70
71 var average =
72 (setupCost + accumulatedHolding) /
73 (end - start + 1);
74
75 if (average > previousAverage)
76 {
77 break;
78 }
79
80 previousAverage = average;
81 bestEnd = end;
82 }
83
84 cycleEnds[start] = bestEnd;
85
87 demands,
88 bestEnd + 1);
89 }
90
92 problem,
93 cycleEnds,
94 Name,
95 cancellationToken);
96 }
97 finally
98 {
99 ArrayPool<int>.Shared.Return(buffer, clearArray: false);
100 }
101 }
102}
Shared applicability checks for classical stationary-cost lot-sizing heuristics.
static void ThrowIfNotStationary(UlsProblem problem, string solverName)
static int FindNextPositiveDemand(ReadOnlySpan< double > demands, int start)
Builds and validates a zero-backlogging heuristic solution from a set of replenishment cycles.
static UlsSolveResult Build(UlsProblem problem, ReadOnlySpan< int > cycleEnds, string solverName, CancellationToken cancellationToken)
Implements the Silver-Meal least-cost-per-period heuristic.
UlsSolverKind Kind
Gets the broad family of the solver.
static bool IsApplicable(UlsProblem problem)
string Name
Gets the stable human-readable name of the solver.
UlsSolveResult Solve(UlsProblem problem, CancellationToken cancellationToken=default)
Solves an uncapacitated lot-sizing problem.
Represents a validated classical uncapacitated lot-sizing problem.
Definition UlsProblem.cs:23
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 the outcome returned by a ULS solution strategy.
Defines the common strategy contract implemented by every ULS solver.
Definition IUlsSolver.cs:14
UlsSolverKind
Identifies the broad family of a ULS solution strategy.