LotSizingDataModel.Solver 2.0.1
Solver-independent modeling, execution, monitoring and adapter infrastructure.
Loading...
Searching...
No Matches
WorkCenterCapacityConstraintFamilyBuilder.cs
Go to the documentation of this file.
1using System;
2using System.Linq;
3using System.Threading;
4using System.Threading.Tasks;
5using LotSizingDataModel.Core.PhysicalModel;
6using LotSizingDataModel.Core.Querying;
7using LotSizingDataModel.Core.Relationships;
8using LotSizingDataModel.Instance;
12
14
15/// <summary>
16/// Builds global work-center capacity constraints.
17/// </summary>
20{
21 /// <summary>
22 /// Gets the unique constraint-family identifier.
23 /// </summary>
24 public override string ConstraintFamilyId =>
25 "workCenterCapacity";
26
27 /// <summary>
28 /// Determines whether at least one work center is
29 /// capacitated.
30 /// </summary>
31 public override bool IsEnabled(
32 LotSizingInstance instance,
34 {
35 ArgumentNullException.ThrowIfNull(instance);
36 ArgumentNullException.ThrowIfNull(options);
37
39 .EnumerateWorkCenters(instance.SupplyChain)
40 .Any(
41 entry =>
42 entry.WorkCenter.CapacityConstraint is not null);
43 }
44
45 /// <summary>
46 /// Builds global work-center capacity constraints.
47 /// </summary>
48 protected override ValueTask BuildConstraintsAsync(
49 LotSizingInstance instance,
52 CancellationToken cancellationToken)
53 {
54 var queries =
55 new SupplyChainQueries(
56 instance.SupplyChain);
57
58 foreach (var entry in StandardFormulationResourceEnumerator
59 .EnumerateWorkCenters(instance.SupplyChain))
60 {
61 WorkCenter workCenter =
62 entry.WorkCenter;
63
64 if (workCenter.CapacityConstraint is null)
65 {
66 continue;
67 }
68
69 var reference =
70 new WorkCenterReference
71 {
72 PlantId =
73 entry.PlantId,
74
75 WorkCenterId =
76 workCenter.Id
77 };
78
79 foreach (int period in Enumerable.Range(
80 1,
81 instance.PlanningHorizon))
82 {
83 cancellationToken.ThrowIfCancellationRequested();
84
85 var expression =
87
88 foreach (ProductionRouting routing
89 in instance.SupplyChain.ProductionRoutings)
90 {
91 if (!routing.WorkCenters.Any(
92 candidate =>
93 candidate.PlantId ==
94 reference.PlantId &&
95 candidate.WorkCenterId ==
96 reference.WorkCenterId))
97 {
98 continue;
99 }
100
101 ProductionCharacteristic characteristic =
102 queries.GetRequiredProductionCharacteristic(
103 routing.ItemId,
104 reference);
105
106 string productionKey =
109 .Add(
111 routing.Id)
112 .Add(
114 period)
115 .Build();
116
117 expression.Add(
118 context.GetVariable(productionKey),
119 characteristic.UnitCapacityConsumption?[period] ??
120 1.0);
121
122 double setupTime =
123 characteristic.SetupTime?[period] ??
124 0.0;
125
126 if (setupTime > 0.0)
127 {
128 string setupKey =
131 .Add(
133 routing.Id)
134 .Add(
136 period)
137 .Build();
138
139 if (context.VariableRegistry.TryGet(
140 setupKey,
141 out MathematicalVariable? setupVariable) &&
142 setupVariable is not null)
143 {
144 expression.Add(
145 setupVariable,
146 setupTime);
147 }
148 }
149 }
150
151 foreach (ProductionSetupFamily family in
152 instance.SupplyChain.ProductionSetupFamilies.Where(
153 family =>
154 family.WorkCenter.PlantId == entry.PlantId &&
155 family.WorkCenter.WorkCenterId == workCenter.Id &&
156 family.SetupTime is not null))
157 {
158 double familySetupTime =
159 family.SetupTime?[period] ?? 0.0;
160
161 if (familySetupTime <= 0.0)
162 {
163 continue;
164 }
165
166 string familySetupKey =
169 .AuxiliaryProductionFamilySetup)
170 .Add(
172 family.Id)
173 .Add(
175 period)
176 .Build();
177
178 expression.Add(
179 context.GetVariable(familySetupKey),
180 familySetupTime);
181 }
182
183 string additionalKey =
186 .WorkCenterAdditionalCapacity)
187 .Add(
189 entry.PlantId)
190 .Add(
192 workCenter.Id)
193 .Add(
195 period)
196 .Build();
197
198 if (context.VariableRegistry.TryGet(
199 additionalKey,
200 out MathematicalVariable? additionalVariable) &&
201 additionalVariable is not null)
202 {
203 expression.Subtract(
204 additionalVariable);
205 }
206
208 context,
209 $"workCenterCapacity_p{entry.PlantId}" +
210 $"_w{workCenter.Id}_t{period}",
211 expression.Build(),
212 MathematicalConstraintSense.LessThanOrEqual,
213 workCenter.CapacityConstraint[period],
214 description:
215 "Global work-center capacity constraint.");
216 }
217 }
218
219 return ValueTask.CompletedTask;
220 }
221}
Provides a fluent builder for linear expressions.
Builds stable business-domain keys for mathematical variables and constraints.
MathematicalDomainKeyBuilder Add(string name, string value)
Adds a text segment.
Provides the shared state required while constructing a solver-independent mathematical model.
Enumerates physical resources together with the canonical references required by the mathematical for...
static IEnumerable<(int PlantId, WorkCenter WorkCenter)> EnumerateWorkCenters(SupplyChain supplyChain)
Enumerates every work center with its containing plant identifier.
Provides common validation and helper methods for one constraint family of the standard lot-sizing fo...
static void AddConstraint(MathematicalModelBuildContext context, string name, LinearExpression expression, MathematicalConstraintSense sense, double rightHandSide, string domainKey="", string description="")
Adds one linear constraint to the mathematical model.
Configures the standard solver-independent mixed-integer lot-sizing formulation.
override ValueTask BuildConstraintsAsync(LotSizingInstance instance, MathematicalModelBuildContext context, StandardLotSizingFormulationOptions options, CancellationToken cancellationToken)
Builds global work-center capacity constraints.
override bool IsEnabled(LotSizingInstance instance, StandardLotSizingFormulationOptions options)
Determines whether at least one work center is capacitated.
Provides the canonical mathematical domain-key categories used to identify lot-sizing decision famili...
const string Production
Identifies production-quantity decision variables.
const string Setup
Identifies production setup decision variables.
Provides the canonical mathematical domain-key segment names used by lot-sizing variables and constra...
Represents one decision variable in a mathematical optimization model.
MathematicalConstraintSense
Identifies the relational sense of a mathematical constraint.