LotSizingDataModel.Solver 2.0.1
Solver-independent modeling, execution, monitoring and adapter infrastructure.
Loading...
Searching...
No Matches
TransportAdditionalCapacityDecisionMapper.cs
Go to the documentation of this file.
1using System;
2using System.Linq;
3using LotSizingDataModel.Core.PhysicalModel;
4using LotSizingDataModel.Solution;
5using LotSizingDataModel.Solution.Decisions;
7
9
10/// <summary>
11/// Maps mathematical item-specific additional transport-capacity
12/// values to transport decisions in a lot-sizing solution.
13/// </summary>
14/// <remarks>
15/// Expected canonical domain-key format:
16/// <code>
17/// transportAdditionalCapacity|item=&lt;id&gt;|transportResource=&lt;id&gt;|originWarehouse=&lt;id&gt;|destinationWarehouse=&lt;id&gt;|period=&lt;index&gt;
18/// </code>
19/// Origin and destination may alternatively be identified by
20/// <c>originPlant</c> and <c>destinationPlant</c>.
21/// Period numbers are one-based.
22/// </remarks>
25{
26 /// <summary>
27 /// Gets the mathematical domain-key category handled by this
28 /// mapper.
29 /// </summary>
30 public override string Category =>
32
33 /// <summary>
34 /// Maps one non-zero item-specific additional transport
35 /// capacity value.
36 /// </summary>
37 /// <param name="context">
38 /// Mathematical-solution mapping context.
39 /// </param>
40 /// <param name="solution">
41 /// Target lot-sizing solution.
42 /// </param>
43 /// <param name="domainKey">
44 /// Parsed additional transport-capacity domain key.
45 /// </param>
46 /// <param name="variableValue">
47 /// Additional transport-capacity value returned by the
48 /// solver.
49 /// </param>
50 protected override void MapValue(
52 LotSizingSolution solution,
53 MathematicalDomainKey domainKey,
54 MathematicalVariableValue variableValue)
55 {
56 ArgumentNullException.ThrowIfNull(
57 context);
58
59 ArgumentNullException.ThrowIfNull(
60 solution);
61
62 ArgumentNullException.ThrowIfNull(
63 domainKey);
64
65 ArgumentNullException.ThrowIfNull(
66 variableValue);
67
68 int itemId =
69 domainKey.GetRequiredInt32(
71
72 int transportResourceId =
73 domainKey.GetRequiredInt32(
75
76 int period =
77 domainKey.GetRequiredInt32(
79
80 WarehouseReference origin =
81 ResolveWarehouse(
82 domainKey,
85 "origin");
86
87 WarehouseReference destination =
88 ResolveWarehouse(
89 domainKey,
92 "destination");
93
94 TransportDecision? decision =
95 solution.TransportDecisions
96 .FirstOrDefault(
97 existing =>
98 existing.Matches(
99 itemId,
100 transportResourceId,
101 origin,
102 destination));
103
104 if (decision is null)
105 {
106 if (solution.PlanningHorizon <= 0)
107 {
108 throw new InvalidOperationException(
109 "The target lot-sizing solution must have a " +
110 "strictly positive planning horizon before " +
111 "transport decisions are mapped.");
112 }
113
114 decision =
115 new TransportDecision(
116 itemId,
117 transportResourceId,
118 origin,
119 destination,
120 solution.PlanningHorizon);
121
122 solution.AddTransportDecision(
123 decision);
124 }
125
126 decision.SetAdditionalCapacityUsed(
127 period,
128 variableValue.Value);
129 }
130
131 private static WarehouseReference ResolveWarehouse(
132 MathematicalDomainKey domainKey,
133 string warehouseSegment,
134 string plantSegment,
135 string role)
136 {
137 bool hasStandaloneWarehouse =
138 domainKey.TryGetInt32(
139 warehouseSegment,
140 out int warehouseId);
141
142 bool hasPlantWarehouse =
143 domainKey.TryGetInt32(
144 plantSegment,
145 out int plantId);
146
147 if (hasStandaloneWarehouse ==
148 hasPlantWarehouse)
149 {
150 throw new InvalidOperationException(
151 $"A transport additional-capacity domain key " +
152 $"must identify exactly one {role} warehouse " +
153 $"using either '{warehouseSegment}' or " +
154 $"'{plantSegment}'.");
155 }
156
157 if (hasStandaloneWarehouse)
158 {
159 return WarehouseReference
160 .ForStandaloneWarehouse(
161 warehouseId);
162 }
163
164 return WarehouseReference
165 .ForPlantWarehouse(
166 plantId);
167 }
168}
Stores the value returned by a solver for one mathematical decision variable.
double Value
Gets or sets the value returned by the solver.
Provides the canonical mathematical domain-key categories used to identify lot-sizing decision famili...
const string TransportAdditionalCapacity
Identifies item-specific additional transport-capacity decision variables.
Provides a reusable base implementation for mathematical decision mappers handling one domain-key cat...
Represents a parsed mathematical-model business-domain key.
int GetRequiredInt32(string name)
Gets a required integer segment.
bool TryGetInt32(string name, out int value)
Attempts to get an integer segment.
Provides the canonical mathematical domain-key segment names used by lot-sizing variables and constra...
const string TransportResource
Transport-resource identifier segment.
const string DestinationWarehouse
Standalone destination-warehouse identifier segment.
const string DestinationPlant
Destination-plant identifier segment.
const string OriginWarehouse
Standalone origin-warehouse identifier segment.
Provides the shared state and lookup services required while mapping a mathematical solver result bac...
Maps mathematical item-specific additional transport-capacity values to transport decisions in a lot-...
override string Category
Gets the mathematical domain-key category handled by this mapper.
override void MapValue(MathematicalSolutionMappingContext context, LotSizingSolution solution, MathematicalDomainKey domainKey, MathematicalVariableValue variableValue)
Maps one non-zero item-specific additional transport capacity value.