LotSizingDataModel.Solver 2.0.1
Solver-independent modeling, execution, monitoring and adapter infrastructure.
Loading...
Searching...
No Matches
StandardLotSizingFormulation.cs
Go to the documentation of this file.
1using System;
2using System.Linq;
3using System.Threading;
4using System.Threading.Tasks;
5using LotSizingDataModel.Instance;
7
9
10/// <summary>
11/// Provides the standard solver-independent mixed-integer
12/// lot-sizing formulation.
13/// </summary>
14/// <remarks>
15/// The formulation delegates variable, objective, and
16/// constraint construction to dedicated components. This keeps
17/// the formulation orchestration independent from any native
18/// solver API and allows the three construction stages to evolve
19/// independently.
20/// </remarks>
21public sealed class StandardLotSizingFormulation :
23{
24 /// <summary>
25 /// Canonical identifier of the standard lot-sizing
26 /// formulation.
27 /// </summary>
28 public const string StandardFormulationId =
29 "standard";
30
32 _variableBuilder;
33
35 _objectiveBuilder;
36
38 _constraintBuilder;
39
41 _options;
42
43 /// <summary>
44 /// Initializes the standard lot-sizing formulation.
45 /// </summary>
46 /// <param name="variableBuilder">
47 /// Component responsible for mathematical variable
48 /// construction.
49 /// </param>
50 /// <param name="objectiveBuilder">
51 /// Component responsible for objective construction.
52 /// </param>
53 /// <param name="constraintBuilder">
54 /// Component responsible for constraint construction.
55 /// </param>
56 /// <param name="options">
57 /// Standard formulation options.
58 /// </param>
59 /// <exception cref="ArgumentNullException">
60 /// Thrown when one of the supplied dependencies is
61 /// <see langword="null"/>.
62 /// </exception>
68 {
69 ArgumentNullException.ThrowIfNull(
70 variableBuilder);
71
72 ArgumentNullException.ThrowIfNull(
73 objectiveBuilder);
74
75 ArgumentNullException.ThrowIfNull(
76 constraintBuilder);
77
78 ArgumentNullException.ThrowIfNull(
79 options);
80
81 StandardLotSizingFormulationOptions normalizedOptions =
82 options.Clone();
83
84 normalizedOptions.EnsureValid();
85
86 _variableBuilder =
87 variableBuilder;
88
89 _objectiveBuilder =
90 objectiveBuilder;
91
92 _constraintBuilder =
93 constraintBuilder;
94
95 _options =
96 normalizedOptions;
97 }
98
99 /// <summary>
100 /// Gets the unique formulation identifier.
101 /// </summary>
102 public override string FormulationId =>
104
105 /// <summary>
106 /// Gets the human-readable formulation name.
107 /// </summary>
108 public override string Name =>
109 "Standard lot-sizing MILP formulation";
110
111 /// <summary>
112 /// Gets the formulation description.
113 /// </summary>
114 public override string Description =>
115 "Solver-independent mixed-integer linear formulation " +
116 "for normalized lot-sizing instances.";
117
118 /// <summary>
119 /// Gets an independent copy of the options used by this
120 /// formulation.
121 /// </summary>
123 _options.Clone();
124
125 /// <summary>
126 /// Determines whether the standard formulation can build a
127 /// mathematical model for the supplied instance.
128 /// </summary>
129 /// <param name="instance">
130 /// Lot-sizing instance to evaluate.
131 /// </param>
132 /// <returns>
133 /// <see langword="true"/> when the instance has a strictly
134 /// positive planning horizon; otherwise,
135 /// <see langword="false"/>.
136 /// </returns>
137 public override bool CanBuild(
138 LotSizingInstance instance)
139 {
140 if (instance is null)
141 {
142 return false;
143 }
144
145 return instance.PlanningHorizon > 0;
146 }
147
148 /// <summary>
149 /// Creates the mathematical model name.
150 /// </summary>
151 /// <param name="instance">
152 /// Lot-sizing instance being formulated.
153 /// </param>
154 /// <returns>
155 /// Human-readable mathematical model name.
156 /// </returns>
157 protected override string CreateModelName(
158 LotSizingInstance instance)
159 {
160 ArgumentNullException.ThrowIfNull(
161 instance);
162
163 if (!string.IsNullOrWhiteSpace(
164 instance.Name))
165 {
166 return
167 $"{instance.Name.Trim()} - {FormulationId}";
168 }
169
170 if (!string.IsNullOrWhiteSpace(
171 instance.InstanceId))
172 {
173 return
174 $"{instance.InstanceId.Trim()} - {FormulationId}";
175 }
176
177 return base.CreateModelName(
178 instance);
179 }
180
181 /// <summary>
182 /// Builds and registers all mathematical variables.
183 /// </summary>
184 /// <param name="instance">
185 /// Source lot-sizing instance.
186 /// </param>
187 /// <param name="context">
188 /// Mathematical-model build context.
189 /// </param>
190 /// <param name="cancellationToken">
191 /// Token used to cancel variable construction.
192 /// </param>
193 /// <returns>
194 /// Task representing variable construction.
195 /// </returns>
196 protected override ValueTask BuildVariablesAsync(
197 LotSizingInstance instance,
199 CancellationToken cancellationToken)
200 {
201 if (_options.IncludeTransport)
202 {
203 var transportErrors = new LotSizingDataModel.Core.Validation.SupplyChainValidator()
204 .Validate(instance.SupplyChain)
205 .Where(issue => issue.Severity == LotSizingDataModel.Core.Validation.SupplyChainValidator.ValidationSeverity.Error
206 && issue.Path.StartsWith("supplyChain.transport", StringComparison.Ordinal))
207 .ToArray();
208 if (transportErrors.Length > 0)
209 throw new InvalidOperationException("Invalid transport structure: " + string.Join("; ", transportErrors.Select(issue => issue.ToString())));
210 }
211
212 return _variableBuilder.BuildAsync(
213 instance,
214 context,
215 _options,
216 cancellationToken);
217 }
218
219 /// <summary>
220 /// Builds the mathematical objective.
221 /// </summary>
222 /// <param name="instance">
223 /// Source lot-sizing instance.
224 /// </param>
225 /// <param name="context">
226 /// Mathematical-model build context.
227 /// </param>
228 /// <param name="cancellationToken">
229 /// Token used to cancel objective construction.
230 /// </param>
231 /// <returns>
232 /// Task representing objective construction.
233 /// </returns>
234 protected override ValueTask BuildObjectiveAsync(
235 LotSizingInstance instance,
237 CancellationToken cancellationToken)
238 {
239 return _objectiveBuilder.BuildAsync(
240 instance,
241 context,
242 _options,
243 cancellationToken);
244 }
245
246 /// <summary>
247 /// Builds all mathematical constraints.
248 /// </summary>
249 /// <param name="instance">
250 /// Source lot-sizing instance.
251 /// </param>
252 /// <param name="context">
253 /// Mathematical-model build context.
254 /// </param>
255 /// <param name="cancellationToken">
256 /// Token used to cancel constraint construction.
257 /// </param>
258 /// <returns>
259 /// Task representing constraint construction.
260 /// </returns>
261 protected override ValueTask BuildConstraintsAsync(
262 LotSizingInstance instance,
264 CancellationToken cancellationToken)
265 {
266 return _constraintBuilder.BuildAsync(
267 instance,
268 context,
269 _options,
270 cancellationToken);
271 }
272}
Provides the shared state required while constructing a solver-independent mathematical model.
Provides a reusable base implementation for solver-independent lot-sizing formulations.
override string CreateModelName(LotSizingInstance instance)
Creates the mathematical model name.
override bool CanBuild(LotSizingInstance instance)
Determines whether the standard formulation can build a mathematical model for the supplied instance.
StandardLotSizingFormulationOptions Options
Gets an independent copy of the options used by this formulation.
override ValueTask BuildVariablesAsync(LotSizingInstance instance, MathematicalModelBuildContext context, CancellationToken cancellationToken)
Builds and registers all mathematical variables.
StandardLotSizingFormulation(IStandardLotSizingVariableBuilder variableBuilder, IStandardLotSizingObjectiveBuilder objectiveBuilder, IStandardLotSizingConstraintBuilder constraintBuilder, StandardLotSizingFormulationOptions options)
Initializes the standard lot-sizing formulation.
const string StandardFormulationId
Canonical identifier of the standard lot-sizing formulation.
override string FormulationId
Gets the unique formulation identifier.
override string Name
Gets the human-readable formulation name.
override ValueTask BuildObjectiveAsync(LotSizingInstance instance, MathematicalModelBuildContext context, CancellationToken cancellationToken)
Builds the mathematical objective.
override ValueTask BuildConstraintsAsync(LotSizingInstance instance, MathematicalModelBuildContext context, CancellationToken cancellationToken)
Builds all mathematical constraints.
Configures the standard solver-independent mixed-integer lot-sizing formulation.
StandardLotSizingFormulationOptions Clone()
Creates an independent copy.
Defines the constraint-construction component used by the standard solver-independent lot-sizing form...
Defines the objective-construction component used by the standard solver-independent lot-sizing formu...
Defines the variable-construction component used by the standard solver-independent lot-sizing formul...