ULSAlgorithms 1.1.0-g3e5595996d
High-performance exact and heuristic algorithms for uncapacitated lot sizing
Loading...
Searching...
No Matches
PartPeriodBalancingSolver.cs
Go to the documentation of this file.
1using System.Buffers;
6
8
9/// <summary>
10/// Implements classical nearest-EPP Part-Period Balancing (PPB).
11/// </summary>
12/// <remarks>
13/// <para>
14/// The candidate lot is selected so that accumulated part-periods are as close
15/// as possible to the Economic Part Period <c>A/h</c>, considering both the
16/// last point below and the first point at/above the target.
17/// </para>
18/// <para>
19/// This is intentionally distinct from <see cref="PartPeriodSimplifiedSolver"/>,
20/// which stops before the first EPP overshoot.
21/// </para>
22/// <para>
23/// Early primary reference for the part-period algorithm:
24/// J. J. DeMatteis, "An Economic Lot-Sizing Technique I: The Part-Period
25/// Algorithm", IBM Systems Journal 7(1), 30-38, 1968.
26/// The PPS/PPB distinction is summarized by Baciarello et al. (2013),
27/// DOI 10.5772/56004.
28/// </para>
29/// </remarks>
31{
32 public string Name => "Part-Period Balancing";
33
34 public UlsSolverKind Kind => UlsSolverKind.Heuristic;
35
36 public static bool IsApplicable(UlsProblem problem) =>
38
39 public static double GetEconomicPartPeriod(UlsProblem problem)
40 {
41 ArgumentNullException.ThrowIfNull(problem);
43 problem,
44 "Part-Period Balancing");
45
46 var holdingCost =
47 problem.Horizon > 1 ? problem.HoldingCosts[0] : 0.0;
48
49 return holdingCost == 0.0
50 ? double.PositiveInfinity
51 : problem.SetupCosts[0] / holdingCost;
52 }
53
55 UlsProblem problem,
56 CancellationToken cancellationToken = default)
57 {
58 ArgumentNullException.ThrowIfNull(problem);
59 cancellationToken.ThrowIfCancellationRequested();
61
62 var horizon = problem.Horizon;
63 var buffer = ArrayPool<int>.Shared.Rent(horizon);
64
65 try
66 {
67 var cycleEnds = buffer.AsSpan(0, horizon);
68 cycleEnds.Fill(-1);
69
70 var demands = problem.Demands;
71 var holdingCost =
72 horizon > 1 ? problem.HoldingCosts[0] : 0.0;
73
74 var epp = holdingCost == 0.0
75 ? double.PositiveInfinity
76 : problem.SetupCosts[0] / holdingCost;
77
78 var start =
80
81 while (start < horizon)
82 {
83 cancellationToken.ThrowIfCancellationRequested();
84
85 if (double.IsPositiveInfinity(epp))
86 {
87 cycleEnds[start] = horizon - 1;
88 break;
89 }
90
91 var bestEnd = start;
92 var partPeriods = 0.0;
93 var bestDifference = epp;
94
95 for (var end = start + 1; end < horizon; end++)
96 {
97 partPeriods +=
98 (end - start) *
99 demands[end];
100
101 var difference =
102 Math.Abs(epp - partPeriods);
103
104 if (difference < bestDifference ||
105 (difference == bestDifference &&
106 end > bestEnd))
107 {
108 bestDifference = difference;
109 bestEnd = end;
110 }
111
112 if (partPeriods >= epp)
113 {
114 break;
115 }
116 }
117
118 cycleEnds[start] = bestEnd;
119
121 demands,
122 bestEnd + 1);
123 }
124
126 problem,
127 cycleEnds,
128 Name,
129 cancellationToken);
130 }
131 finally
132 {
133 ArrayPool<int>.Shared.Return(buffer, clearArray: false);
134 }
135 }
136}
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 classical nearest-EPP Part-Period Balancing (PPB).
string Name
Gets the stable human-readable name of the solver.
UlsSolverKind Kind
Gets the broad family 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.