LotSizingDataModel.Instance 2.0.1
Lot-sizing instance representation, descriptors and problem characterization.
Loading...
Searching...
No Matches
InstanceModelChecker.cs
Go to the documentation of this file.
1using LotSizingDataModel.Core.Validation;
2
4
5/// <summary>
6/// Checks whether a <see cref="LotSizingInstance"/> represents
7/// a structurally valid and semantically meaningful lot-sizing
8/// model.
9/// </summary>
10/// <remarks>
11/// Structural and referential validation remains owned by
12/// <see cref="SupplyChainValidator"/>. This checker composes those
13/// results and adds instance-level semantic diagnostics.
14///
15/// This service does not solve the mathematical model and does not
16/// determine exact feasibility. Those concerns belong to a separate
17/// feasibility analyzer.
18/// </remarks>
19public sealed class InstanceModelChecker
20{
21 private readonly SupplyChainValidator _structuralValidator;
22
23 /// <summary>
24 /// Initializes a checker using the canonical Core structural
25 /// validator.
26 /// </summary>
28 : this(new SupplyChainValidator())
29 {
30 }
31
32 /// <summary>
33 /// Initializes a checker with an explicit structural validator.
34 /// </summary>
36 SupplyChainValidator structuralValidator)
37 {
38 _structuralValidator =
39 structuralValidator ??
40 throw new ArgumentNullException(
41 nameof(structuralValidator));
42 }
43
44 /// <summary>
45 /// Checks one lot-sizing instance.
46 /// </summary>
48 LotSizingInstance instance)
49 {
50 ArgumentNullException.ThrowIfNull(instance);
51
52 var diagnostics =
53 new List<InstanceDiagnostic>();
54
55 AppendStructuralDiagnostics(
56 instance,
57 diagnostics);
58
59 AppendInstanceIdentityDiagnostics(
60 instance,
61 diagnostics);
62
63 AppendDemandDiagnostics(
64 instance,
65 diagnostics);
66
67 AppendKnownResultDiagnostics(
68 instance,
69 diagnostics);
70
71 return new InstanceModelCheckResult(
72 diagnostics);
73 }
74
75 private void AppendStructuralDiagnostics(
76 LotSizingInstance instance,
77 ICollection<InstanceDiagnostic> diagnostics)
78 {
79 IReadOnlyList<
80 SupplyChainValidator.ValidationIssue> issues =
81 _structuralValidator.Validate(
82 instance.SupplyChain);
83
84 foreach (
85 SupplyChainValidator.ValidationIssue issue
86 in issues)
87 {
89 issue.Severity ==
90 SupplyChainValidator.ValidationSeverity.Error
93
94 diagnostics.Add(
96 code: issue.Code,
97 severity: severity,
98 path:
99 "instance." +
100 issue.Path,
101 message: issue.Message,
102 suggestedAction:
103 "Correct the underlying supply-chain data " +
104 "before classification or solving."));
105 }
106 }
107
108 private static void AppendInstanceIdentityDiagnostics(
109 LotSizingInstance instance,
110 ICollection<InstanceDiagnostic> diagnostics)
111 {
112 if (instance.HasInstanceId)
113 {
114 return;
115 }
116
117 diagnostics.Add(
118 new InstanceDiagnostic(
119 code: "LSDM-SEM-001",
120 severity:
122 path: "instance.instanceId",
123 message:
124 "The instance has no stable identifier.",
125 suggestedAction:
126 "Assign a stable instance identifier before " +
127 "publishing or exchanging the instance."));
128 }
129
130 private static void AppendDemandDiagnostics(
131 LotSizingInstance instance,
132 ICollection<InstanceDiagnostic> diagnostics)
133 {
134 if (instance.SupplyChain.Demands.Count == 0)
135 {
136 diagnostics.Add(
137 new InstanceDiagnostic(
138 code: "LSDM-SEM-010",
139 severity:
141 path: "instance.supplyChain.demands",
142 message:
143 "The instance contains no external demand record.",
144 suggestedAction:
145 "Confirm that a demand-free planning problem is " +
146 "intentional."));
147 return;
148 }
149
150 bool hasPositiveDemand = false;
151
152 foreach (var demand in instance.SupplyChain.Demands)
153 {
154 for (
155 int period = 1;
156 period <= demand.PlanningHorizon;
157 period++)
158 {
159 if (demand.GetQuantity(period) > 0.0)
160 {
161 hasPositiveDemand = true;
162 break;
163 }
164 }
165
166 if (hasPositiveDemand)
167 {
168 break;
169 }
170 }
171
172 if (!hasPositiveDemand)
173 {
174 diagnostics.Add(
175 new InstanceDiagnostic(
176 code: "LSDM-SEM-011",
177 severity:
179 path: "instance.supplyChain.demands",
180 message:
181 "Demand records exist but all demand quantities " +
182 "are zero.",
183 suggestedAction:
184 "Confirm that the zero-demand instance is " +
185 "intentional."));
186 }
187 }
188
189 private static void AppendKnownResultDiagnostics(
190 LotSizingInstance instance,
191 ICollection<InstanceDiagnostic> diagnostics)
192 {
193 if (!instance.HasBestKnownResultId ||
194 instance.HasBestKnownResult)
195 {
196 return;
197 }
198
199 diagnostics.Add(
200 new InstanceDiagnostic(
201 code: "LSDM-SEM-020",
202 severity:
204 path: "instance.bestKnownResultId",
205 message:
206 "The selected best-known-result identifier does not " +
207 "refer to an existing known result.",
208 values:
209 new Dictionary<string, string>(
210 StringComparer.Ordinal)
211 {
212 ["bestKnownResultId"] =
213 instance.BestKnownResultId
214 },
215 suggestedAction:
216 "Select an existing known result or clear the " +
217 "best-known-result identifier."));
218 }
219}
Adds explicit closed-loop return streams to a lot-sizing instance without changing the historical Sup...
SupplyChain SupplyChain
Gets or sets the supply-chain model represented by the instance.
Represents one structured diagnostic produced while checking the semantic validity of a lot-sizing in...
Represents the complete result of semantic instance validation.
InstanceModelCheckResult Check(LotSizingInstance instance)
Checks one lot-sizing instance.
InstanceModelChecker(SupplyChainValidator structuralValidator)
Initializes a checker with an explicit structural validator.
InstanceModelChecker()
Initializes a checker using the canonical Core structural validator.
InstanceDiagnosticSeverity
Indicates the severity of one semantic instance diagnostic.
@ Error
Blocking issue that prevents the instance from being considered semantically valid.