ULSAlgorithms 1.1.0-g3e5595996d
High-performance exact and heuristic algorithms for uncapacitated lot sizing
Loading...
Searching...
No Matches
UlsSolverDescriptor.cs
Go to the documentation of this file.
2
4
5/// <summary>
6/// Immutable metadata and construction entry for one public ULS strategy.
7/// </summary>
8public sealed class UlsSolverDescriptor
9{
10 private readonly Func<IUlsSolver> _factory;
11 private readonly Func<UlsSolverCreationOptions, IUlsSolver>? _configuredFactory;
12
14 string id,
15 string name,
16 UlsSolverCategory category,
17 string family,
18 string timeComplexity,
19 string spaceComplexity,
20 string applicability,
21 string scientificReference,
22 string doi,
23 string implementation,
24 string sourcePath,
25 Type implementationType,
26 Func<IUlsSolver> factory,
27 UlsSolverConfigurationCapabilities configurationCapabilities =
29 Func<UlsSolverCreationOptions, IUlsSolver>? configuredFactory = null)
30 {
31 ArgumentException.ThrowIfNullOrWhiteSpace(id);
32 ArgumentException.ThrowIfNullOrWhiteSpace(name);
33 ArgumentException.ThrowIfNullOrWhiteSpace(family);
34 ArgumentException.ThrowIfNullOrWhiteSpace(timeComplexity);
35 ArgumentException.ThrowIfNullOrWhiteSpace(spaceComplexity);
36 ArgumentException.ThrowIfNullOrWhiteSpace(applicability);
37 ArgumentException.ThrowIfNullOrWhiteSpace(scientificReference);
38 ArgumentException.ThrowIfNullOrWhiteSpace(implementation);
39 ArgumentException.ThrowIfNullOrWhiteSpace(sourcePath);
40 ArgumentNullException.ThrowIfNull(implementationType);
41 ArgumentNullException.ThrowIfNull(factory);
42
43 ValidateStableId(id);
44 ValidateConfigurationFactory(
45 configurationCapabilities,
46 configuredFactory);
47
48 if (!typeof(IUlsSolver).IsAssignableFrom(implementationType))
49 {
50 throw new ArgumentException(
51 $"Type '{implementationType.FullName}' does not implement IUlsSolver.",
52 nameof(implementationType));
53 }
54
55 Id = id;
56 Name = name;
57 Category = category;
60 : UlsSolverKind.Exact;
61 Family = family;
62 TimeComplexity = timeComplexity;
63 SpaceComplexity = spaceComplexity;
64 Applicability = applicability;
65 ScientificReference = scientificReference;
66 Doi = doi ?? string.Empty;
67 Implementation = implementation;
68 SourcePath = sourcePath;
69 ImplementationType = implementationType;
72 or UlsSolverCategory.CuttingPlane;
73 ConfigurationCapabilities = configurationCapabilities;
74 _factory = factory;
75 _configuredFactory = configuredFactory;
76 }
77
78 /// <summary>
79 /// Gets the stable lower-kebab-case identifier used by
80 /// <see cref="UlsSolverFactory"/>.
81 /// </summary>
82 public string Id { get; }
83
84 /// <summary>Gets the human-readable strategy name.</summary>
85 public string Name { get; }
86
87 /// <summary>Gets the exact/heuristic strategy kind.</summary>
88 public UlsSolverKind Kind { get; }
89
90 /// <summary>Gets the operational strategy category.</summary>
92
93 /// <summary>Gets the literature/implementation family.</summary>
94 public string Family { get; }
95
96 /// <summary>Gets the documented asymptotic time complexity.</summary>
97 public string TimeComplexity { get; }
98
99 /// <summary>Gets the documented auxiliary/model memory complexity.</summary>
100 public string SpaceComplexity { get; }
101
102 /// <summary>Gets the documented applicability conditions.</summary>
103 public string Applicability { get; }
104
105 /// <summary>
106 /// Gets whether solving requires an external mathematical-programming engine.
107 /// </summary>
108 public bool RequiresExternalSolver { get; }
109
110 /// <summary>Gets the primary scientific or historical reference.</summary>
111 public string ScientificReference { get; }
112
113 /// <summary>Gets the primary DOI when one is recorded, otherwise an empty string.</summary>
114 public string Doi { get; }
115
116 /// <summary>Gets the implementation note exposed by the public catalog.</summary>
117 public string Implementation { get; }
118
119 /// <summary>Gets the repository-relative implementation source path.</summary>
120 public string SourcePath { get; }
121
122 /// <summary>Gets the concrete public strategy type.</summary>
123 public Type ImplementationType { get; }
124
125 /// <summary>
126 /// Gets the constructor-level settings supported by the configurable
127 /// factory for this strategy.
128 /// </summary>
130
131 /// <summary>
132 /// Gets whether this strategy exposes at least one configurable factory
133 /// setting.
134 /// </summary>
138
139 /// <summary>
140 /// Creates a new solver instance using the strategy's default constructor
141 /// policy.
142 /// </summary>
143 /// <returns>A fresh public solver instance.</returns>
144 public IUlsSolver Create() =>
145 ValidateCreatedSolver(
146 _factory());
147
148 /// <summary>
149 /// Creates a new solver instance using explicit constructor-level
150 /// configuration.
151 /// </summary>
152 /// <param name="options">Composed factory options.</param>
153 /// <returns>A fresh configured solver instance.</returns>
154 /// <remarks>
155 /// An empty option set is equivalent to <see cref="Create()"/>.
156 /// Unsupported non-empty options are rejected.
157 /// </remarks>
159 {
160 ArgumentNullException.ThrowIfNull(options);
161
162 if (options.IsEmpty)
163 {
164 return Create();
165 }
166
167 options.EnsureValidFor(this);
168
169 if (_configuredFactory is null)
170 {
171 throw new InvalidOperationException(
172 $"Solver '{Id}' does not expose configurable construction.");
173 }
174
175 return ValidateCreatedSolver(
176 _configuredFactory(options));
177 }
178
179 private IUlsSolver ValidateCreatedSolver(IUlsSolver solver)
180 {
181 ArgumentNullException.ThrowIfNull(solver);
182
183 if (solver.GetType() != ImplementationType)
184 {
185 throw new InvalidOperationException(
186 $"Catalog factory for '{Id}' returned '{solver.GetType().FullName}' " +
187 $"instead of '{ImplementationType.FullName}'.");
188 }
189
190 if (solver.Kind != Kind)
191 {
192 throw new InvalidOperationException(
193 $"Catalog kind mismatch for '{Id}'. Expected {Kind}, got {solver.Kind}.");
194 }
195
196 return solver;
197 }
198
199 private static void ValidateConfigurationFactory(
201 Func<UlsSolverCreationOptions, IUlsSolver>? configuredFactory)
202 {
203 if (capabilities == UlsSolverConfigurationCapabilities.None &&
204 configuredFactory is not null)
205 {
206 throw new ArgumentException(
207 "A configured factory requires at least one configuration capability.",
208 nameof(configuredFactory));
209 }
210
211 if (capabilities != UlsSolverConfigurationCapabilities.None &&
212 configuredFactory is null)
213 {
214 throw new ArgumentException(
215 "Configuration capabilities require a configured factory.",
216 nameof(configuredFactory));
217 }
218 }
219
220 private static void ValidateStableId(string id)
221 {
222 if (id[0] == '-' || id[^1] == '-')
223 {
224 throw new ArgumentException(
225 "A solver identifier cannot start or end with '-'.",
226 nameof(id));
227 }
228
229 var previousHyphen = false;
230
231 foreach (var character in id)
232 {
233 var valid =
234 character is >= 'a' and <= 'z' ||
235 character is >= '0' and <= '9' ||
236 character == '-';
237
238 if (!valid || (character == '-' && previousHyphen))
239 {
240 throw new ArgumentException(
241 "Solver identifiers must use normalized lower-kebab-case ASCII.",
242 nameof(id));
243 }
244
245 previousHyphen = character == '-';
246 }
247 }
248}
Composes the existing strategy-specific constructor options used by UlsSolverFactory.
void EnsureValidFor(UlsSolverDescriptor descriptor)
string Doi
Gets the primary DOI when one is recorded, otherwise an empty string.
UlsSolverKind Kind
Gets the exact/heuristic strategy kind.
UlsSolverConfigurationCapabilities ConfigurationCapabilities
Gets the constructor-level settings supported by the configurable factory for this strategy.
string Applicability
Gets the documented applicability conditions.
Type ImplementationType
Gets the concrete public strategy type.
string TimeComplexity
Gets the documented asymptotic time complexity.
string Family
Gets the literature/implementation family.
bool RequiresExternalSolver
Gets whether solving requires an external mathematical-programming engine.
string SourcePath
Gets the repository-relative implementation source path.
string SpaceComplexity
Gets the documented auxiliary/model memory complexity.
string Name
Gets the human-readable strategy name.
string ScientificReference
Gets the primary scientific or historical reference.
IUlsSolver Create()
Creates a new solver instance using the strategy's default constructor policy.
UlsSolverDescriptor(string id, string name, UlsSolverCategory category, string family, string timeComplexity, string spaceComplexity, string applicability, string scientificReference, string doi, string implementation, string sourcePath, Type implementationType, Func< IUlsSolver > factory, UlsSolverConfigurationCapabilities configurationCapabilities=UlsSolverConfigurationCapabilities.None, Func< UlsSolverCreationOptions, IUlsSolver >? configuredFactory=null)
bool SupportsConfiguration
Gets whether this strategy exposes at least one configurable factory setting.
string Implementation
Gets the implementation note exposed by the public catalog.
IUlsSolver Create(UlsSolverCreationOptions options)
Creates a new solver instance using explicit constructor-level configuration.
UlsSolverCategory Category
Gets the operational strategy category.
string Id
Gets the stable lower-kebab-case identifier used by UlsSolverFactory.
Defines the common strategy contract implemented by every ULS solver.
Definition IUlsSolver.cs:14
UlsSolverKind Kind
Gets the broad family of the solver.
Definition IUlsSolver.cs:23
UlsSolverKind
Identifies the broad family of a ULS solution strategy.
@ Heuristic
A heuristic algorithm that seeks a feasible solution without an optimality proof.
UlsSolverConfigurationCapabilities
Identifies the constructor-level settings that can be supplied through the configurable solver factor...
UlsSolverCategory
Identifies the operational category of a public ULS strategy.
@ OptimizationFormulation
Exact mathematical formulation solved through the portable external optimization layer.
@ Heuristic
Constructive or improvement heuristic without an optimality proof.