LotSizingDataModel.Solver 2.0.1
Solver-independent modeling, execution, monitoring and adapter infrastructure.
Loading...
Searching...
No Matches
MultiObjectiveModelPlanner.cs
Go to the documentation of this file.
1using LotSizingDataModel.Core.DecisionModel.Objectives;
2using LotSizingDataModel.Instance;
4
6
7/// <summary>
8/// Resolves executable objective criteria and constructs weighted/lexicographic
9/// mathematical models.
10/// </summary>
11public static class MultiObjectiveModelPlanner
12{
13 public static IReadOnlyList<ExecutableObjectiveCriterion>
15 LotSizingInstance instance,
17 {
18 ArgumentNullException.ThrowIfNull(instance);
19 ArgumentNullException.ThrowIfNull(context);
20
21 OptimizationObjectivePolicy? policy =
22 instance.SupplyChain.ObjectivePolicy;
23
24 if (policy is null)
25 {
26 return
27 [
28 CreateCriterion(
29 OptimizationObjectiveKind.Economic,
30 1.0,
31 0,
32 0.0,
33 context)
34 ];
35 }
36
37 if (policy.AggregationMode ==
38 ObjectiveAggregationMode.Single)
39 {
40 return
41 [
42 CreateCriterion(
43 policy.PrimaryObjectiveKind,
44 1.0,
45 0,
46 0.0,
47 context)
48 ];
49 }
50
51 if (policy.AggregationMode is not
52 ObjectiveAggregationMode.WeightedSum and not
53 ObjectiveAggregationMode.Lexicographic)
54 {
55 throw new NotSupportedException(
56 $"Objective aggregation mode '{policy.AggregationMode}' is not executable.");
57 }
58
59 if (!policy.HasExecutableCriterionSpecifications)
60 {
61 throw new InvalidOperationException(
62 "WeightedSum/Lexicographic execution requires explicit ExecutionCriteria.");
63 }
64
65 if (!policy.HasUniqueExecutableCriterionKinds)
66 {
67 throw new InvalidOperationException(
68 "Executable objective criterion kinds must be unique.");
69 }
70
71 if (policy.AggregationMode ==
72 ObjectiveAggregationMode.Lexicographic &&
73 !policy.HasUniqueLexicographicPriorities)
74 {
75 throw new InvalidOperationException(
76 "Lexicographic objective priorities must be unique.");
77 }
78
79 IEnumerable<ObjectiveCriterionExecutionSpecification>
80 specifications =
81 policy.ExecutionCriteria;
82
83 if (policy.AggregationMode ==
84 ObjectiveAggregationMode.Lexicographic)
85 {
86 specifications =
87 specifications
88 .OrderBy(
89 specification =>
90 specification.Priority);
91 }
92
93 return specifications
94 .Select(
95 specification =>
96 CreateCriterion(
97 specification.Kind,
98 specification.Weight,
99 specification.Priority,
100 specification.AbsoluteTolerance,
101 context))
102 .ToArray();
103 }
104
107 IReadOnlyList<ExecutableObjectiveCriterion> criteria)
108 {
109 ArgumentNullException.ThrowIfNull(context);
110 ArgumentNullException.ThrowIfNull(criteria);
111
112 if (criteria.Count == 0)
113 {
114 throw new InvalidOperationException(
115 "WeightedSum requires at least one criterion.");
116 }
117
118 MathematicalModel model =
119 context.Model.Clone();
120
121 var weighted =
122 new LinearExpression();
123
124 foreach (ExecutableObjectiveCriterion criterion in criteria)
125 {
126 LinearExpression term =
127 criterion.Expression.Clone();
128
129 term.MultiplyBy(
130 criterion.Weight);
131
132 weighted.Add(term);
133 }
134
135 model.Objective =
137 "weightedSum",
138 ObjectiveSense.Minimize,
139 weighted)
140 {
141 Description =
142 "Explicit weighted sum of executable objective criteria."
143 };
144
145 model.EnsureValid();
146 return model;
147 }
148
152 IEnumerable<(ExecutableObjectiveCriterion Criterion, double Value)>
153 preserved)
154 {
155 ArgumentNullException.ThrowIfNull(context);
156 ArgumentNullException.ThrowIfNull(criterion);
157 ArgumentNullException.ThrowIfNull(preserved);
158
159 MathematicalModel model =
160 context.Model.Clone();
161
162 int nextConstraintId =
163 model.Constraints.Count == 0
164 ? 1
165 : model.Constraints.Max(constraint => constraint.Id) + 1;
166
167 foreach (var previous in preserved)
168 {
169 LinearExpression expression =
170 previous.Criterion.Expression.Clone();
171
172 double rhs =
173 previous.Value +
174 previous.Criterion.AbsoluteTolerance -
175 expression.Constant;
176
177 expression.Constant = 0.0;
178
179 model.AddConstraint(
181 nextConstraintId++,
182 $"lexicographicPreserve_{previous.Criterion.Kind}",
183 expression,
184 MathematicalConstraintSense.LessThanOrEqual,
185 rhs)
186 {
187 Description =
188 "Preserves an already optimized lexicographic criterion."
189 });
190 }
191
192 model.Objective =
194 $"lexicographic_{criterion.Kind}",
195 ObjectiveSense.Minimize,
196 criterion.Expression.Clone())
197 {
198 Description =
199 "One exact lexicographic optimization stage."
200 };
201
202 model.EnsureValid();
203 return model;
204 }
205
206 private static ExecutableObjectiveCriterion CreateCriterion(
207 OptimizationObjectiveKind kind,
208 double weight,
209 int priority,
210 double absoluteTolerance,
212 {
213 LinearExpression expression =
214 kind switch
215 {
216 OptimizationObjectiveKind.Economic =>
217 context.EconomicCriterion.Clone(),
218
219 OptimizationObjectiveKind.Financial
220 when context.FinancialCriterion is not null =>
221 context.FinancialCriterion.Clone(),
222
223 OptimizationObjectiveKind.Financial =>
224 throw new NotSupportedException(
225 "Financial objective requires CashFlowPolicy."),
226
227 OptimizationObjectiveKind.Sustainability =>
228 throw new NotSupportedException(
229 "Sustainability objective remains unsupported until real sustainability data and criterion semantics exist."),
230
231 _ =>
232 throw new NotSupportedException(
233 $"Objective kind '{kind}' is not executable.")
234 };
235
236 return new ExecutableObjectiveCriterion
237 {
238 Kind = kind,
239 Expression = expression,
240 Weight = weight,
241 Priority = priority,
242 AbsoluteTolerance = absoluteTolerance
243 };
244 }
245}
Resolves executable objective criteria and constructs weighted/lexicographic mathematical models.
static IReadOnlyList< ExecutableObjectiveCriterion > ResolveCriteria(LotSizingInstance instance, FinancialExecutionModelContext context)
static MathematicalModel CreateLexicographicStageModel(FinancialExecutionModelContext context, ExecutableObjectiveCriterion criterion, IEnumerable<(ExecutableObjectiveCriterion Criterion, double Value)> preserved)
static MathematicalModel CreateWeightedSumModel(FinancialExecutionModelContext context, IReadOnlyList< ExecutableObjectiveCriterion > criteria)
Represents one linear constraint in a mathematical optimization model.
Represents a linear expression composed of variable terms and a constant value.
void MultiplyBy(double factor)
Multiplies the entire expression by a scalar.
LinearExpression Clone()
Creates an independent copy of this expression.
double Constant
Gets or sets the constant value of the expression.
Represents a solver-independent mathematical optimization model.
MathematicalModel Clone()
Creates an independent copy of the mathematical model.
List< LinearConstraint > Constraints
Gets the linear constraints.
Represents the objective function of a mathematical optimization model.
void EnsureValid()
Validates the mathematical objective.
ObjectiveSense
Identifies the optimization direction of a mathematical objective.
MathematicalConstraintSense
Identifies the relational sense of a mathematical constraint.