ULSAlgorithms 1.1.0-g3e5595996d
High-performance exact and heuristic algorithms for uncapacitated lot sizing
Loading...
Searching...
No Matches
FreelandColleySolver.cs
Go to the documentation of this file.
1using System.Buffers;
6
8
9/// <summary>
10/// Implements the Freeland-Colley incremental lot-sizing heuristic.
11/// </summary>
12/// <remarks>
13/// <para>
14/// Starting from a replenishment in period <c>s</c>, demand in a later period
15/// <c>t</c> is added while its local incremental holding cost
16/// <c>h * (t-s) * d[t]</c> does not exceed the setup cost.
17/// </para>
18/// <para>
19/// Reference:
20/// J. R. Freeland and J. L. Colley Jr.,
21/// "A Simple Heuristic Method for Lot-Sizing in a Time-Phased Reorder System",
22/// Production and Inventory Management 23(1), 15-22, 1982.
23/// </para>
24/// <para>
25/// Worst-case time is O(T); auxiliary working memory is O(T).
26/// </para>
27/// </remarks>
28public sealed class FreelandColleySolver : IUlsSolver
29{
30 public string Name => "Freeland-Colley";
31
32 public UlsSolverKind Kind => UlsSolverKind.Heuristic;
33
34 public static bool IsApplicable(UlsProblem problem) =>
36
38 UlsProblem problem,
39 CancellationToken cancellationToken = default)
40 {
41 ArgumentNullException.ThrowIfNull(problem);
42 cancellationToken.ThrowIfCancellationRequested();
43
45 problem,
46 Name);
47
48 var horizon = problem.Horizon;
49 var buffer = ArrayPool<int>.Shared.Rent(horizon);
50
51 try
52 {
53 var cycleEnds = buffer.AsSpan(0, horizon);
54 cycleEnds.Fill(-1);
55
56 var demands = problem.Demands;
57 var setupCost = problem.SetupCosts[0];
58
59 var holdingCost =
60 horizon > 1
61 ? problem.HoldingCosts[0]
62 : 0.0;
63
64 var start =
66 demands,
67 0);
68
69 while (start < horizon)
70 {
71 cancellationToken.ThrowIfCancellationRequested();
72
73 var end = start;
74
75 for (var candidate = start + 1;
76 candidate < horizon;
77 candidate++)
78 {
79 var incrementalHolding =
80 holdingCost *
81 (candidate - start) *
82 demands[candidate];
83
84 if (!double.IsFinite(incrementalHolding))
85 {
86 throw new ArithmeticException(
87 "Numerical overflow in the Freeland-Colley criterion.");
88 }
89
90 if (incrementalHolding > setupCost)
91 {
92 break;
93 }
94
95 end = candidate;
96 }
97
98 cycleEnds[start] = end;
99
100 start =
102 demands,
103 end + 1);
104 }
105
107 problem,
108 cycleEnds,
109 Name,
110 cancellationToken);
111 }
112 finally
113 {
114 ArrayPool<int>.Shared.Return(
115 buffer,
116 clearArray: false);
117 }
118 }
119}
Implements the Freeland-Colley incremental lot-sizing heuristic.
UlsSolverKind Kind
Gets the broad family of the solver.
UlsSolveResult Solve(UlsProblem problem, CancellationToken cancellationToken=default)
Solves an uncapacitated lot-sizing problem.
string Name
Gets the stable human-readable name of the solver.
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)
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.