LotSizingDataModel.Solver 2.0.1
Solver-independent modeling, execution, monitoring and adapter infrastructure.
Loading...
Searching...
No Matches
MathematicalVariableRegistry.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
4
6
7/// <summary>
8/// Maintains the correspondence between business-domain keys
9/// and mathematical variables during model construction.
10/// </summary>
11/// <remarks>
12/// A domain key identifies one lot-sizing decision independently
13/// of the solver-specific variable object. Examples include:
14/// <code>
15/// production|item=1|plant=2|period=3
16/// inventory|item=1|warehouse=4|period=3
17/// setup|item=1|resource=5|period=3
18/// </code>
19/// </remarks>
21{
22 private readonly Dictionary<string, MathematicalVariable>
23 _variablesByDomainKey =
24 new(
25 StringComparer.Ordinal);
26
27 /// <summary>
28 /// Gets the number of registered variables.
29 /// </summary>
30 public int Count =>
31 _variablesByDomainKey.Count;
32
33 /// <summary>
34 /// Registers a mathematical variable using its domain key.
35 /// </summary>
36 /// <param name="variable">
37 /// Mathematical variable to register.
38 /// </param>
39 /// <exception cref="ArgumentNullException">
40 /// Thrown when <paramref name="variable"/> is
41 /// <see langword="null"/>.
42 /// </exception>
43 /// <exception cref="InvalidOperationException">
44 /// Thrown when the variable has no domain key or when the
45 /// domain key is already registered.
46 /// </exception>
47 public void Register(
48 MathematicalVariable variable)
49 {
50 ArgumentNullException.ThrowIfNull(
51 variable);
52
53 variable.EnsureValid();
54
55 string domainKey =
56 NormalizeDomainKey(
57 variable.DomainKey);
58
59 if (!_variablesByDomainKey.TryAdd(
60 domainKey,
61 variable))
62 {
63 throw new InvalidOperationException(
64 $"The mathematical variable domain key " +
65 $"'{domainKey}' is already registered.");
66 }
67 }
68
69 /// <summary>
70 /// Registers a mathematical variable with an explicit
71 /// domain key.
72 /// </summary>
73 /// <param name="domainKey">
74 /// Business-domain key.
75 /// </param>
76 /// <param name="variable">
77 /// Mathematical variable to register.
78 /// </param>
79 /// <exception cref="ArgumentNullException">
80 /// Thrown when <paramref name="variable"/> is
81 /// <see langword="null"/>.
82 /// </exception>
83 /// <exception cref="InvalidOperationException">
84 /// Thrown when the key conflicts with the variable domain key
85 /// or is already registered.
86 /// </exception>
87 public void Register(
88 string domainKey,
89 MathematicalVariable variable)
90 {
91 ArgumentNullException.ThrowIfNull(
92 variable);
93
94 variable.EnsureValid();
95
96 string normalizedDomainKey =
97 NormalizeDomainKey(
98 domainKey);
99
100 if (!string.IsNullOrWhiteSpace(
101 variable.DomainKey) &&
102 !string.Equals(
103 variable.DomainKey.Trim(),
104 normalizedDomainKey,
105 StringComparison.Ordinal))
106 {
107 throw new InvalidOperationException(
108 "The supplied domain key does not match the " +
109 "mathematical variable domain key.");
110 }
111
112 variable.DomainKey =
113 normalizedDomainKey;
114
115 Register(
116 variable);
117 }
118
119 /// <summary>
120 /// Determines whether a variable is registered for a domain
121 /// key.
122 /// </summary>
123 /// <param name="domainKey">
124 /// Business-domain key.
125 /// </param>
126 /// <returns>
127 /// <see langword="true"/> when a variable is registered;
128 /// otherwise, <see langword="false"/>.
129 /// </returns>
130 public bool Contains(
131 string domainKey)
132 {
133 string normalizedDomainKey =
134 NormalizeDomainKey(
135 domainKey);
136
137 return _variablesByDomainKey.ContainsKey(
138 normalizedDomainKey);
139 }
140
141 /// <summary>
142 /// Gets the variable registered for a domain key.
143 /// </summary>
144 /// <param name="domainKey">
145 /// Business-domain key.
146 /// </param>
147 /// <returns>
148 /// Registered mathematical variable.
149 /// </returns>
150 /// <exception cref="KeyNotFoundException">
151 /// Thrown when no variable is registered for the supplied
152 /// domain key.
153 /// </exception>
155 string domainKey)
156 {
157 string normalizedDomainKey =
158 NormalizeDomainKey(
159 domainKey);
160
161 if (_variablesByDomainKey.TryGetValue(
162 normalizedDomainKey,
163 out MathematicalVariable? variable))
164 {
165 return variable;
166 }
167
168 throw new KeyNotFoundException(
169 $"No mathematical variable is registered for domain " +
170 $"key '{normalizedDomainKey}'.");
171 }
172
173 /// <summary>
174 /// Attempts to get the variable registered for a domain key.
175 /// </summary>
176 /// <param name="domainKey">
177 /// Business-domain key.
178 /// </param>
179 /// <param name="variable">
180 /// Registered variable when the method succeeds.
181 /// </param>
182 /// <returns>
183 /// <see langword="true"/> when a variable is found;
184 /// otherwise, <see langword="false"/>.
185 /// </returns>
186 public bool TryGet(
187 string domainKey,
188 out MathematicalVariable? variable)
189 {
190 string normalizedDomainKey =
191 NormalizeDomainKey(
192 domainKey);
193
194 return _variablesByDomainKey.TryGetValue(
195 normalizedDomainKey,
196 out variable);
197 }
198
199 /// <summary>
200 /// Removes the variable registered for a domain key.
201 /// </summary>
202 /// <param name="domainKey">
203 /// Business-domain key.
204 /// </param>
205 /// <returns>
206 /// <see langword="true"/> when a variable was removed;
207 /// otherwise, <see langword="false"/>.
208 /// </returns>
209 public bool Remove(
210 string domainKey)
211 {
212 string normalizedDomainKey =
213 NormalizeDomainKey(
214 domainKey);
215
216 return _variablesByDomainKey.Remove(
217 normalizedDomainKey);
218 }
219
220 /// <summary>
221 /// Removes all registered variables.
222 /// </summary>
223 public void Clear()
224 {
225 _variablesByDomainKey.Clear();
226 }
227
228 /// <summary>
229 /// Returns a snapshot of all registered variables.
230 /// </summary>
231 /// <returns>
232 /// Read-only dictionary indexed by domain key.
233 /// </returns>
234 public IReadOnlyDictionary<string, MathematicalVariable>
236 {
237 return new Dictionary<string, MathematicalVariable>(
238 _variablesByDomainKey,
239 StringComparer.Ordinal);
240 }
241
242 private static string NormalizeDomainKey(
243 string domainKey)
244 {
245 if (string.IsNullOrWhiteSpace(
246 domainKey))
247 {
248 throw new InvalidOperationException(
249 "A mathematical variable domain key is required.");
250 }
251
252 return domainKey.Trim();
253 }
254}
Maintains the correspondence between business-domain keys and mathematical variables during model con...
bool Contains(string domainKey)
Determines whether a variable is registered for a domain key.
bool TryGet(string domainKey, out MathematicalVariable? variable)
Attempts to get the variable registered for a domain key.
void Register(MathematicalVariable variable)
Registers a mathematical variable using its domain key.
MathematicalVariable GetRequired(string domainKey)
Gets the variable registered for a domain key.
IReadOnlyDictionary< string, MathematicalVariable > GetSnapshot()
Returns a snapshot of all registered variables.
bool Remove(string domainKey)
Removes the variable registered for a domain key.
void Register(string domainKey, MathematicalVariable variable)
Registers a mathematical variable with an explicit domain key.
Represents one decision variable in a mathematical optimization model.
string DomainKey
Gets or sets an optional domain key used to map the mathematical variable back to a lot-sizing decisi...
void EnsureValid()
Validates the mathematical variable.