LotSizingDataModel.Instance 2.0.1
Lot-sizing instance representation, descriptors and problem characterization.
Loading...
Searching...
No Matches
SolutionMethodCatalogFactory.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
4using LotSizingDataModel.Solution.Common;
5
7
8/// <summary>
9/// Creates predefined catalogs of solution methods for
10/// lot-sizing problem instances.
11/// </summary>
12/// <remarks>
13/// The factory provides operational method definitions used
14/// by <see cref="SolutionMethodAdvisor"/>.
15///
16/// The catalog describes technical applicability. It does not
17/// claim that one method will systematically outperform
18/// another method in practice.
19///
20/// Method kinds are resolved dynamically from the members
21/// actually available in <see cref="SolutionMethodKind"/>.
22/// No specific enumeration member is required at compile time.
23/// </remarks>
25{
26 /// <summary>
27 /// Gets the name of the standard solution-method catalog.
28 /// </summary>
29 public const string StandardCatalogName =
30 "Standard lot-sizing solution-method catalog";
31
32 /// <summary>
33 /// Gets the current version of the standard
34 /// solution-method catalog.
35 /// </summary>
36 public const string StandardCatalogVersion =
37 "1.0";
38
39 /// <summary>
40 /// Gets the method code assigned to the Wagner-Whitin
41 /// dynamic-programming method.
42 /// </summary>
43 public const string WagnerWhitinMethodCode =
44 "WW-DP";
45
46 /// <summary>
47 /// Gets the method code assigned to the Silver-Meal
48 /// heuristic.
49 /// </summary>
50 public const string SilverMealMethodCode =
51 "SILVER-MEAL";
52
53 /// <summary>
54 /// Gets the method code assigned to the generic
55 /// mixed-integer linear programming formulation.
56 /// </summary>
57 public const string GenericMilpMethodCode =
58 "MILP-GENERIC";
59
60 /// <summary>
61 /// Gets the method code assigned to the production
62 /// capacity Lagrangian-relaxation approach.
63 /// </summary>
64 public const string LagrangianRelaxationMethodCode =
65 "LAGRANGIAN-CAPACITY";
66
67 /// <summary>
68 /// Gets the method code assigned to the generic
69 /// fix-and-optimize matheuristic.
70 /// </summary>
71 public const string FixAndOptimizeMethodCode =
72 "FIX-AND-OPTIMIZE";
73
74 /// <summary>
75 /// Creates the standard catalog of lot-sizing solution
76 /// methods.
77 /// </summary>
78 /// <returns>
79 /// A new, independent and structurally valid
80 /// solution-method catalog.
81 /// </returns>
82 /// <remarks>
83 /// The returned catalog contains:
84 /// <list type="bullet">
85 /// <item>
86 /// <description>
87 /// Wagner-Whitin dynamic programming for the classical
88 /// uncapacitated single-item problem;
89 /// </description>
90 /// </item>
91 /// <item>
92 /// <description>
93 /// the Silver-Meal single-item heuristic;
94 /// </description>
95 /// </item>
96 /// <item>
97 /// <description>
98 /// a generic mixed-integer linear formulation;
99 /// </description>
100 /// </item>
101 /// <item>
102 /// <description>
103 /// a production-capacity Lagrangian relaxation;
104 /// </description>
105 /// </item>
106 /// <item>
107 /// <description>
108 /// a generic fix-and-optimize matheuristic.
109 /// </description>
110 /// </item>
111 /// </list>
112 ///
113 /// Each call creates new method-definition objects.
114 /// Modifying one returned catalog therefore does not
115 /// affect catalogs created by later calls.
116 /// </remarks>
117 public static SolutionMethodCatalog
119 {
120 var catalog =
122 catalogName:
124
125 catalogVersion:
127 {
128 Description =
129 "Operational catalog of mathematical " +
130 "programming methods, dynamic-programming " +
131 "procedures, relaxations and heuristics " +
132 "for lot-sizing problem instances.",
133
134 AllowUnknownFeatureCodes =
135 false
136 };
137
138 catalog.AddMethod(
139 CreateWagnerWhitinDefinition());
140
141 catalog.AddMethod(
142 CreateGenericMilpDefinition());
143
144 catalog.AddMethod(
145 CreateLagrangianRelaxationDefinition());
146
147 catalog.AddMethod(
148 CreateFixAndOptimizeDefinition());
149
150 catalog.AddMethod(
151 CreateSilverMealDefinition());
152
153 catalog.EnsureValid();
154
155 return catalog;
156 }
157
158 private static SolutionMethodDefinition
159 CreateWagnerWhitinDefinition()
160 {
161 var definition =
163 methodCode:
165
166 name:
167 "Wagner-Whitin dynamic programming",
168
169 methodKind:
170 ResolveMethodKind(
171 fallback:
172 default,
173
174 "DynamicProgramming",
175 "Dynamic_Programming",
176 "Dynamic",
177 "Exact",
178 "Optimization",
179 "MathematicalProgramming",
180 "Other",
181 "Unknown",
182 "Unspecified"))
183 {
184 MethodVersion =
186
187 Description =
188 "Exact dynamic-programming method for " +
189 "the deterministic, uncapacitated, " +
190 "single-item and single-level " +
191 "lot-sizing problem.",
192
193 Priority =
194 300,
195
196 SupportsAnyProblemFamily =
197 false,
198
199 SupportsAnyProductStructure =
200 false,
201
202 SupportsUnclassifiedProblems =
203 false,
204
205 SupportsAmbiguousClassifications =
206 false,
207
208 SupportsCompleteProblems =
209 true,
210
211 SupportsRelaxations =
212 false,
213
214 SupportsSubproblems =
215 true,
216
217 CanProduceFeasibleSolution =
218 true,
219
220 CanProveOptimality =
221 true,
222
223 CanProvideLowerBound =
224 true,
225
226 CanProvideUpperBound =
227 true
228 };
229
231 new[]
232 {
233 "LS-U"
234 });
235
236 definition.ReplacePreferredProblemTypeCodes(
237 new[]
238 {
239 "LS-U"
240 });
241
242 definition.ReplaceSupportedProductStructureTypes(
243 new[]
244 {
246 });
247
248 definition.ReplaceSupportedFeatureCodes(
249 new[]
250 {
251 "HasSetupCosts",
252 "HasTimeVaryingDemand",
253 "HasInitialInventory"
254 });
255
256 definition.ReplacePreferredFeatureCodes(
257 new[]
258 {
259 "HasSetupCosts",
260 "HasTimeVaryingDemand"
261 });
262
263 definition.ReplaceUnsupportedFeatureCodes(
264 GetClassicalSingleItemUnsupportedFeatureCodes());
265
266 definition.Comment =
267 "This definition represents the standard direct " +
268 "application of the Wagner-Whitin method. " +
269 "Specialized variants supporting additional " +
270 "features should be represented by separate " +
271 "method definitions.";
272
273 return definition;
274 }
275
276 private static SolutionMethodDefinition
277 CreateSilverMealDefinition()
278 {
279 var definition =
280 new SolutionMethodDefinition(
281 methodCode:
283
284 name:
285 "Silver-Meal heuristic",
286
287 methodKind:
288 ResolveMethodKind(
289 fallback:
290 default,
291
292 "Heuristic",
293 "ConstructiveHeuristic",
294 "Constructive",
295 "Approximation",
296 "Metaheuristic",
297 "Other",
298 "Unknown",
299 "Unspecified"))
300 {
301 MethodVersion =
303
304 Description =
305 "Constructive heuristic for the " +
306 "deterministic, uncapacitated, " +
307 "single-item and single-level " +
308 "lot-sizing problem.",
309
310 Priority =
311 130,
312
313 SupportsAnyProblemFamily =
314 false,
315
316 SupportsAnyProductStructure =
317 false,
318
319 SupportsUnclassifiedProblems =
320 false,
321
322 SupportsAmbiguousClassifications =
323 false,
324
325 SupportsCompleteProblems =
326 true,
327
328 SupportsRelaxations =
329 false,
330
331 SupportsSubproblems =
332 true,
333
334 CanProduceFeasibleSolution =
335 true,
336
337 CanProveOptimality =
338 false,
339
340 CanProvideLowerBound =
341 false,
342
343 CanProvideUpperBound =
344 true
345 };
346
347 definition.ReplaceSupportedProblemTypeCodes(
348 new[]
349 {
350 "LS-U"
351 });
352
353 definition.ReplacePreferredProblemTypeCodes(
354 new[]
355 {
356 "LS-U"
357 });
358
359 definition.ReplaceSupportedProductStructureTypes(
360 new[]
361 {
362 ProductStructureType.IndependentItems
363 });
364
365 definition.ReplaceSupportedFeatureCodes(
366 new[]
367 {
368 "HasSetupCosts",
369 "HasTimeVaryingDemand",
370 "HasInitialInventory"
371 });
372
373 definition.ReplacePreferredFeatureCodes(
374 new[]
375 {
376 "HasTimeVaryingDemand"
377 });
378
379 definition.ReplaceUnsupportedFeatureCodes(
380 GetClassicalSingleItemUnsupportedFeatureCodes());
381
382 definition.Comment =
383 "The standard Silver-Meal heuristic does not " +
384 "provide an optimality proof. Adapted variants " +
385 "should be represented by separate method " +
386 "definitions.";
387
388 return definition;
389 }
390
391 private static SolutionMethodDefinition
392 CreateGenericMilpDefinition()
393 {
394 var definition =
395 new SolutionMethodDefinition(
396 methodCode:
398
399 name:
400 "Generic mixed-integer linear formulation",
401
402 methodKind:
403 ResolveMethodKind(
404 fallback:
405 default,
406
407 "MixedIntegerProgramming",
408 "MixedIntegerLinearProgramming",
409 "MathematicalProgramming",
410 "Exact",
411 "Optimization",
412 "Solver",
413 "Other",
414 "Unknown",
415 "Unspecified"))
416 {
417 MethodVersion =
419
420 Description =
421 "Generic mixed-integer linear formulation " +
422 "intended to represent single-level, " +
423 "multi-level, capacitated and " +
424 "supply-chain extensions when the " +
425 "corresponding variables and constraints " +
426 "are implemented.",
427
428 Priority =
429 200,
430
431 SupportsAnyProblemFamily =
432 true,
433
434 SupportsAnyProductStructure =
435 true,
436
437 SupportsUnclassifiedProblems =
438 true,
439
440 SupportsAmbiguousClassifications =
441 true,
442
443 SupportsCompleteProblems =
444 true,
445
446 SupportsRelaxations =
447 true,
448
449 SupportsSubproblems =
450 true,
451
452 CanProduceFeasibleSolution =
453 true,
454
455 CanProveOptimality =
456 true,
457
458 CanProvideLowerBound =
459 true,
460
461 CanProvideUpperBound =
462 true
463 };
464
465 definition.ReplaceSupportedFeatureCodes(
466 GetBroadlySupportedFeatureCodes());
467
468 definition.ReplacePreferredProblemTypeCodes(
469 new[]
470 {
471 "LS-C",
472 "CLSP",
473 "MLLP",
474 "MLCLSP"
475 });
476
477 definition.Comment =
478 "Practical tractability depends on the selected " +
479 "formulation, solver, parameterization, hardware " +
480 "and instance dimensions.";
481
482 return definition;
483 }
484
485 private static SolutionMethodDefinition
486 CreateLagrangianRelaxationDefinition()
487 {
488 var definition =
489 new SolutionMethodDefinition(
490 methodCode:
492
493 name:
494 "Production-capacity Lagrangian " +
495 "relaxation",
496
497 methodKind:
498 ResolveMethodKind(
499 fallback:
500 default,
501
502 "LagrangianRelaxation",
503 "Relaxation",
504 "Decomposition",
505 "Dual",
506 "Exact",
507 "Optimization",
508 "Other",
509 "Unknown",
510 "Unspecified"))
511 {
512 MethodVersion =
514
515 Description =
516 "Lagrangian-relaxation template that " +
517 "dualizes production-capacity coupling " +
518 "constraints and solves the resulting " +
519 "structured subproblems.",
520
521 Priority =
522 180,
523
524 SupportsAnyProblemFamily =
525 false,
526
527 SupportsAnyProductStructure =
528 true,
529
530 SupportsUnclassifiedProblems =
531 false,
532
533 SupportsAmbiguousClassifications =
534 true,
535
536 SupportsCompleteProblems =
537 false,
538
539 SupportsRelaxations =
540 true,
541
542 SupportsSubproblems =
543 true,
544
545 CanProduceFeasibleSolution =
546 false,
547
548 CanProveOptimality =
549 false,
550
551 CanProvideLowerBound =
552 true,
553
554 CanProvideUpperBound =
555 false
556 };
557
558 definition.ReplaceSupportedProblemTypeCodes(
559 new[]
560 {
561 "LS-C",
562 "CLSP",
563 "MLCLSP"
564 });
565
566 definition.ReplacePreferredProblemTypeCodes(
567 new[]
568 {
569 "CLSP",
570 "MLCLSP"
571 });
572
573 definition.ReplaceRequiredFeatureCodes(
574 new[]
575 {
576 "HasProductionCapacityConstraints"
577 });
578
579 definition.ReplaceSupportedFeatureCodes(
580 new[]
581 {
582 "HasSetupCosts",
583 "HasSetupTimes",
584 "HasProductionLeadTimes",
585 "HasMinimumLotSizes",
586 "HasLotSizeMultiples",
587 "HasSafetyStockRequirements",
588 "HasBacklogging",
589 "HasTimeVaryingDemand",
590 "HasTimeVaryingProductionCapacity",
591 "HasSharedProductionCapacity"
592 });
593
594 definition.ReplacePreferredFeatureCodes(
595 new[]
596 {
597 "HasSharedProductionCapacity",
598 "HasTimeVaryingProductionCapacity"
599 });
600
601 definition.ReplacePartiallySupportedFeatureCodes(
602 new[]
603 {
604 "IsMultiSite",
605 "HasPurchasing",
606 "HasSupplierCapacityConstraints",
607 "HasSupplierLeadTimes",
608 "HasTransportation",
609 "HasTransportCapacityConstraints",
610 "HasTransportLeadTimes",
611 "HasWarehouseCapacityConstraints",
612 "HasAdditionalCapacity"
613 });
614
615 definition.ReplaceUnsupportedFeatureCodes(
616 new[]
617 {
618 "HasLostSales",
619 "HasStartUpCosts",
620 "HasFinancialConstraints",
621 "HasMultipleObjectives"
622 });
623
624 definition.Comment =
625 "A complete algorithm normally requires a dual " +
626 "optimization procedure and, when a feasible " +
627 "solution is required, a primal recovery method.";
628
629 return definition;
630 }
631
632 private static SolutionMethodDefinition
633 CreateFixAndOptimizeDefinition()
634 {
635 var definition =
636 new SolutionMethodDefinition(
637 methodCode:
639
640 name:
641 "Generic fix-and-optimize matheuristic",
642
643 methodKind:
644 ResolveMethodKind(
645 fallback:
646 default,
647
648 "Matheuristic",
649 "Hybrid",
650 "Heuristic",
651 "Metaheuristic",
652 "NeighborhoodSearch",
653 "Optimization",
654 "Other",
655 "Unknown",
656 "Unspecified"))
657 {
658 MethodVersion =
660
661 Description =
662 "Matheuristic that repeatedly fixes part " +
663 "of a mixed-integer solution and " +
664 "reoptimizes selected neighborhoods.",
665
666 Priority =
667 150,
668
669 SupportsAnyProblemFamily =
670 true,
671
672 SupportsAnyProductStructure =
673 true,
674
675 SupportsUnclassifiedProblems =
676 true,
677
678 SupportsAmbiguousClassifications =
679 true,
680
681 SupportsCompleteProblems =
682 true,
683
684 SupportsRelaxations =
685 false,
686
687 SupportsSubproblems =
688 true,
689
690 CanProduceFeasibleSolution =
691 true,
692
693 CanProveOptimality =
694 false,
695
696 CanProvideLowerBound =
697 false,
698
699 CanProvideUpperBound =
700 true
701 };
702
703 definition.ReplaceSupportedFeatureCodes(
704 GetBroadlySupportedFeatureCodes());
705
706 definition.ReplacePreferredProblemTypeCodes(
707 new[]
708 {
709 "CLSP",
710 "MLLP",
711 "MLCLSP"
712 });
713
714 definition.ReplacePreferredFeatureCodes(
715 new[]
716 {
717 "IsMultiItem",
718 "IsMultiLevel",
719 "HasProductionCapacityConstraints",
720 "HasSharedProductionCapacity"
721 });
722
723 definition.Comment =
724 "Compatibility assumes that a valid MILP " +
725 "formulation and an initial feasible solution or " +
726 "solution-construction procedure are available.";
727
728 return definition;
729 }
730
731 private static IReadOnlyList<string>
732 GetClassicalSingleItemUnsupportedFeatureCodes()
733 {
734 return new[]
735 {
736 "HasProductionCapacityConstraints",
737 "HasSharedProductionCapacity",
738 "HasTimeVaryingProductionCapacity",
739 "HasSafetyStockRequirements",
740 "HasBacklogging",
741 "HasLostSales",
742 "HasProductionLeadTimes",
743 "HasMinimumLotSizes",
744 "HasMaximumLotSizes",
745 "HasLotSizeMultiples",
746 "HasSetupTimes",
747 "HasStartUpCosts",
748 "HasAdditionalCapacity",
749 "HasPurchasing",
750 "HasSupplierCapacityConstraints",
751 "HasSupplierLeadTimes",
752 "HasTransportation",
753 "HasTransportCapacityConstraints",
754 "HasTransportLeadTimes",
755 "HasWarehouseCapacityConstraints",
756 "IsMultiSite",
757 "HasFinancialConstraints",
758 "HasMultipleObjectives"
759 };
760 }
761
762 private static IReadOnlyList<string>
763 GetBroadlySupportedFeatureCodes()
764 {
765 return new[]
766 {
767 "HasDemand",
768 "HasDeterministicDemand",
769 "HasTimeVaryingDemand",
770 "HasInitialInventory",
771 "HasSafetyStockRequirements",
772 "HasBacklogging",
773 "HasLostSales",
774 "HasProduction",
775 "HasProductionCapacityConstraints",
776 "HasSharedProductionCapacity",
777 "HasTimeVaryingProductionCapacity",
778 "HasSetupCosts",
779 "HasSetupTimes",
780 "HasStartUpCosts",
781 "HasProductionLeadTimes",
782 "HasMinimumLotSizes",
783 "HasMaximumLotSizes",
784 "HasLotSizeMultiples",
785 "HasAdditionalCapacity",
786 "HasPurchasing",
787 "HasSupplierCapacityConstraints",
788 "HasSupplierLeadTimes",
789 "HasTransportation",
790 "HasTransportCapacityConstraints",
791 "HasTransportLeadTimes",
792 "HasWarehouseCapacityConstraints",
793 "IsMultiSite",
794 "HasFinancialConstraints",
795 "HasMultipleObjectives",
796 "IsSingleItem",
797 "IsMultiItem",
798 "IsSingleLevel",
799 "IsMultiLevel",
800 "IsCapacitated"
801 };
802 }
803
804 private static SolutionMethodKind ResolveMethodKind(
805 SolutionMethodKind fallback,
806 params string[] candidateNames)
807 {
808 ArgumentNullException.ThrowIfNull(
809 candidateNames);
810
811 foreach (string candidateName in candidateNames)
812 {
813 if (string.IsNullOrWhiteSpace(
814 candidateName))
815 {
816 continue;
817 }
818
819 if (Enum.TryParse(
820 candidateName.Trim(),
821 ignoreCase:
822 true,
823 out SolutionMethodKind parsedValue) &&
824 Enum.IsDefined(
825 typeof(SolutionMethodKind),
826 parsedValue))
827 {
828 return parsedValue;
829 }
830 }
831
832 return fallback;
833 }
834}
Creates predefined catalogs of solution methods for lot-sizing problem instances.
const string WagnerWhitinMethodCode
Gets the method code assigned to the Wagner-Whitin dynamic-programming method.
const string GenericMilpMethodCode
Gets the method code assigned to the generic mixed-integer linear programming formulation.
const string StandardCatalogVersion
Gets the current version of the standard solution-method catalog.
const string LagrangianRelaxationMethodCode
Gets the method code assigned to the production capacity Lagrangian-relaxation approach.
const string StandardCatalogName
Gets the name of the standard solution-method catalog.
const string FixAndOptimizeMethodCode
Gets the method code assigned to the generic fix-and-optimize matheuristic.
static SolutionMethodCatalog CreateStandardCatalog()
Creates the standard catalog of lot-sizing solution methods.
const string SilverMealMethodCode
Gets the method code assigned to the Silver-Meal heuristic.
Represents an extensible catalog of solution methods that may be evaluated for lot-sizing problem ins...
void AddMethod(SolutionMethodDefinition method)
Adds a solution-method definition to the catalog.
Describes the applicability, capabilities and limitations of a solution method for lot-sizing problem...
void ReplaceSupportedProblemTypeCodes(IEnumerable< string > problemTypeCodes)
Replaces the supported problem-family codes.
@ IndependentItems
The instance contains no component-to-parent bill-of-materials relationship.