desdeo 1.2__py3-none-any.whl → 2.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. desdeo/__init__.py +8 -8
  2. desdeo/adm/ADMAfsar.py +551 -0
  3. desdeo/adm/ADMChen.py +414 -0
  4. desdeo/adm/BaseADM.py +119 -0
  5. desdeo/adm/__init__.py +11 -0
  6. desdeo/api/README.md +73 -0
  7. desdeo/api/__init__.py +15 -0
  8. desdeo/api/app.py +50 -0
  9. desdeo/api/config.py +90 -0
  10. desdeo/api/config.toml +64 -0
  11. desdeo/api/db.py +27 -0
  12. desdeo/api/db_init.py +85 -0
  13. desdeo/api/db_models.py +164 -0
  14. desdeo/api/malaga_db_init.py +27 -0
  15. desdeo/api/models/__init__.py +266 -0
  16. desdeo/api/models/archive.py +23 -0
  17. desdeo/api/models/emo.py +128 -0
  18. desdeo/api/models/enautilus.py +69 -0
  19. desdeo/api/models/gdm/gdm_aggregate.py +139 -0
  20. desdeo/api/models/gdm/gdm_base.py +69 -0
  21. desdeo/api/models/gdm/gdm_score_bands.py +114 -0
  22. desdeo/api/models/gdm/gnimbus.py +138 -0
  23. desdeo/api/models/generic.py +104 -0
  24. desdeo/api/models/generic_states.py +401 -0
  25. desdeo/api/models/nimbus.py +158 -0
  26. desdeo/api/models/preference.py +128 -0
  27. desdeo/api/models/problem.py +717 -0
  28. desdeo/api/models/reference_point_method.py +18 -0
  29. desdeo/api/models/session.py +49 -0
  30. desdeo/api/models/state.py +463 -0
  31. desdeo/api/models/user.py +52 -0
  32. desdeo/api/models/utopia.py +25 -0
  33. desdeo/api/routers/_EMO.backup +309 -0
  34. desdeo/api/routers/_NAUTILUS.py +245 -0
  35. desdeo/api/routers/_NAUTILUS_navigator.py +233 -0
  36. desdeo/api/routers/_NIMBUS.py +765 -0
  37. desdeo/api/routers/__init__.py +5 -0
  38. desdeo/api/routers/emo.py +497 -0
  39. desdeo/api/routers/enautilus.py +237 -0
  40. desdeo/api/routers/gdm/gdm_aggregate.py +234 -0
  41. desdeo/api/routers/gdm/gdm_base.py +420 -0
  42. desdeo/api/routers/gdm/gdm_score_bands/gdm_score_bands_manager.py +398 -0
  43. desdeo/api/routers/gdm/gdm_score_bands/gdm_score_bands_routers.py +377 -0
  44. desdeo/api/routers/gdm/gnimbus/gnimbus_manager.py +698 -0
  45. desdeo/api/routers/gdm/gnimbus/gnimbus_routers.py +591 -0
  46. desdeo/api/routers/generic.py +233 -0
  47. desdeo/api/routers/nimbus.py +705 -0
  48. desdeo/api/routers/problem.py +307 -0
  49. desdeo/api/routers/reference_point_method.py +93 -0
  50. desdeo/api/routers/session.py +100 -0
  51. desdeo/api/routers/test.py +16 -0
  52. desdeo/api/routers/user_authentication.py +520 -0
  53. desdeo/api/routers/utils.py +187 -0
  54. desdeo/api/routers/utopia.py +230 -0
  55. desdeo/api/schema.py +100 -0
  56. desdeo/api/tests/__init__.py +0 -0
  57. desdeo/api/tests/conftest.py +151 -0
  58. desdeo/api/tests/test_enautilus.py +330 -0
  59. desdeo/api/tests/test_models.py +1179 -0
  60. desdeo/api/tests/test_routes.py +1075 -0
  61. desdeo/api/utils/_database.py +263 -0
  62. desdeo/api/utils/_logger.py +29 -0
  63. desdeo/api/utils/database.py +36 -0
  64. desdeo/api/utils/emo_database.py +40 -0
  65. desdeo/core.py +34 -0
  66. desdeo/emo/__init__.py +159 -0
  67. desdeo/emo/hooks/archivers.py +188 -0
  68. desdeo/emo/methods/EAs.py +541 -0
  69. desdeo/emo/methods/__init__.py +0 -0
  70. desdeo/emo/methods/bases.py +12 -0
  71. desdeo/emo/methods/templates.py +111 -0
  72. desdeo/emo/operators/__init__.py +1 -0
  73. desdeo/emo/operators/crossover.py +1282 -0
  74. desdeo/emo/operators/evaluator.py +114 -0
  75. desdeo/emo/operators/generator.py +459 -0
  76. desdeo/emo/operators/mutation.py +1224 -0
  77. desdeo/emo/operators/scalar_selection.py +202 -0
  78. desdeo/emo/operators/selection.py +1778 -0
  79. desdeo/emo/operators/termination.py +286 -0
  80. desdeo/emo/options/__init__.py +108 -0
  81. desdeo/emo/options/algorithms.py +435 -0
  82. desdeo/emo/options/crossover.py +164 -0
  83. desdeo/emo/options/generator.py +131 -0
  84. desdeo/emo/options/mutation.py +260 -0
  85. desdeo/emo/options/repair.py +61 -0
  86. desdeo/emo/options/scalar_selection.py +66 -0
  87. desdeo/emo/options/selection.py +127 -0
  88. desdeo/emo/options/templates.py +383 -0
  89. desdeo/emo/options/termination.py +143 -0
  90. desdeo/explanations/__init__.py +6 -0
  91. desdeo/explanations/explainer.py +100 -0
  92. desdeo/explanations/utils.py +90 -0
  93. desdeo/gdm/__init__.py +22 -0
  94. desdeo/gdm/gdmtools.py +45 -0
  95. desdeo/gdm/score_bands.py +114 -0
  96. desdeo/gdm/voting_rules.py +50 -0
  97. desdeo/mcdm/__init__.py +41 -0
  98. desdeo/mcdm/enautilus.py +338 -0
  99. desdeo/mcdm/gnimbus.py +484 -0
  100. desdeo/mcdm/nautili.py +345 -0
  101. desdeo/mcdm/nautilus.py +477 -0
  102. desdeo/mcdm/nautilus_navigator.py +656 -0
  103. desdeo/mcdm/nimbus.py +417 -0
  104. desdeo/mcdm/pareto_navigator.py +269 -0
  105. desdeo/mcdm/reference_point_method.py +186 -0
  106. desdeo/problem/__init__.py +83 -0
  107. desdeo/problem/evaluator.py +561 -0
  108. desdeo/problem/external/__init__.py +18 -0
  109. desdeo/problem/external/core.py +356 -0
  110. desdeo/problem/external/pymoo_provider.py +266 -0
  111. desdeo/problem/external/runtime.py +44 -0
  112. desdeo/problem/gurobipy_evaluator.py +562 -0
  113. desdeo/problem/infix_parser.py +341 -0
  114. desdeo/problem/json_parser.py +944 -0
  115. desdeo/problem/pyomo_evaluator.py +487 -0
  116. desdeo/problem/schema.py +1829 -0
  117. desdeo/problem/simulator_evaluator.py +348 -0
  118. desdeo/problem/sympy_evaluator.py +244 -0
  119. desdeo/problem/testproblems/__init__.py +88 -0
  120. desdeo/problem/testproblems/benchmarks_server.py +120 -0
  121. desdeo/problem/testproblems/binh_and_korn_problem.py +88 -0
  122. desdeo/problem/testproblems/cake_problem.py +185 -0
  123. desdeo/problem/testproblems/dmitry_forest_problem_discrete.py +71 -0
  124. desdeo/problem/testproblems/dtlz2_problem.py +102 -0
  125. desdeo/problem/testproblems/forest_problem.py +283 -0
  126. desdeo/problem/testproblems/knapsack_problem.py +163 -0
  127. desdeo/problem/testproblems/mcwb_problem.py +831 -0
  128. desdeo/problem/testproblems/mixed_variable_dimenrions_problem.py +83 -0
  129. desdeo/problem/testproblems/momip_problem.py +172 -0
  130. desdeo/problem/testproblems/multi_valued_constraints.py +119 -0
  131. desdeo/problem/testproblems/nimbus_problem.py +143 -0
  132. desdeo/problem/testproblems/pareto_navigator_problem.py +89 -0
  133. desdeo/problem/testproblems/re_problem.py +492 -0
  134. desdeo/problem/testproblems/river_pollution_problems.py +440 -0
  135. desdeo/problem/testproblems/rocket_injector_design_problem.py +140 -0
  136. desdeo/problem/testproblems/simple_problem.py +351 -0
  137. desdeo/problem/testproblems/simulator_problem.py +92 -0
  138. desdeo/problem/testproblems/single_objective.py +289 -0
  139. desdeo/problem/testproblems/spanish_sustainability_problem.py +945 -0
  140. desdeo/problem/testproblems/zdt_problem.py +274 -0
  141. desdeo/problem/utils.py +245 -0
  142. desdeo/tools/GenerateReferencePoints.py +181 -0
  143. desdeo/tools/__init__.py +120 -0
  144. desdeo/tools/desc_gen.py +22 -0
  145. desdeo/tools/generics.py +165 -0
  146. desdeo/tools/group_scalarization.py +3090 -0
  147. desdeo/tools/gurobipy_solver_interfaces.py +258 -0
  148. desdeo/tools/indicators_binary.py +117 -0
  149. desdeo/tools/indicators_unary.py +362 -0
  150. desdeo/tools/interaction_schema.py +38 -0
  151. desdeo/tools/intersection.py +54 -0
  152. desdeo/tools/iterative_pareto_representer.py +99 -0
  153. desdeo/tools/message.py +265 -0
  154. desdeo/tools/ng_solver_interfaces.py +199 -0
  155. desdeo/tools/non_dominated_sorting.py +134 -0
  156. desdeo/tools/patterns.py +283 -0
  157. desdeo/tools/proximal_solver.py +99 -0
  158. desdeo/tools/pyomo_solver_interfaces.py +477 -0
  159. desdeo/tools/reference_vectors.py +229 -0
  160. desdeo/tools/scalarization.py +2065 -0
  161. desdeo/tools/scipy_solver_interfaces.py +454 -0
  162. desdeo/tools/score_bands.py +627 -0
  163. desdeo/tools/utils.py +388 -0
  164. desdeo/tools/visualizations.py +67 -0
  165. desdeo/utopia_stuff/__init__.py +0 -0
  166. desdeo/utopia_stuff/data/1.json +15 -0
  167. desdeo/utopia_stuff/data/2.json +13 -0
  168. desdeo/utopia_stuff/data/3.json +15 -0
  169. desdeo/utopia_stuff/data/4.json +17 -0
  170. desdeo/utopia_stuff/data/5.json +15 -0
  171. desdeo/utopia_stuff/from_json.py +40 -0
  172. desdeo/utopia_stuff/reinit_user.py +38 -0
  173. desdeo/utopia_stuff/utopia_db_init.py +212 -0
  174. desdeo/utopia_stuff/utopia_problem.py +403 -0
  175. desdeo/utopia_stuff/utopia_problem_old.py +415 -0
  176. desdeo/utopia_stuff/utopia_reference_solutions.py +79 -0
  177. desdeo-2.1.0.dist-info/METADATA +186 -0
  178. desdeo-2.1.0.dist-info/RECORD +180 -0
  179. {desdeo-1.2.dist-info → desdeo-2.1.0.dist-info}/WHEEL +1 -1
  180. desdeo-2.1.0.dist-info/licenses/LICENSE +21 -0
  181. desdeo-1.2.dist-info/METADATA +0 -16
  182. desdeo-1.2.dist-info/RECORD +0 -4
@@ -0,0 +1,440 @@
1
+ """Variants of the river pollution problem are defined here."""
2
+
3
+ from pathlib import Path
4
+
5
+ import polars as pl
6
+
7
+ from desdeo.problem.schema import (
8
+ DiscreteRepresentation,
9
+ Objective,
10
+ ObjectiveTypeEnum,
11
+ Problem,
12
+ TensorConstant,
13
+ Variable,
14
+ VariableTypeEnum,
15
+ )
16
+
17
+
18
+ def river_pollution_problem(*, five_objective_variant: bool = True) -> Problem:
19
+ r"""Create a pydantic dataclass representation of the river pollution problem with either five or four variables.
20
+
21
+ The objective functions "DO city" ($f_1$), "DO municipality" ($f_2), and
22
+ "ROI fishery" ($f_3$) and "ROI city" ($f_4$) are to be
23
+ maximized. If the four variant problem is used, the the "BOD deviation" objective
24
+ function ($f_5$) is not present, but if it is, it is to be minimized.
25
+ The problem is defined as follows:
26
+
27
+ \begin{align*}
28
+ \max f_1(x) &= 4.07 + 2.27 x_1 \\
29
+ \max f_2(x) &= 2.60 + 0.03 x_1 + 0.02 x_2 + \frac{0.01}{1.39 - x_1^2} + \frac{0.30}{1.39 - x_2^2} \\
30
+ \max f_3(x) &= 8.21 - \frac{0.71}{1.09 - x_1^2} \\
31
+ \max f_4(x) &= 0.96 - \frac{0.96}{1.09 - x_2^2} \\
32
+ \min f_5(x) &= \max(|x_1 - 0.65|, |x_2 - 0.65|) \\
33
+ \text{s.t.}\quad & 0.3 \leq x_1 \leq 1.0,\\
34
+ & 0.3 \leq x_2 \leq 1.0,\\
35
+ \end{align*}
36
+
37
+ where the fifth objective is part of the problem definition only if
38
+ `five_objective_variant = True`.
39
+
40
+ Args:
41
+ five_objective_variant (bool, optional): Whether to use to five
42
+ objective function variant of the problem or not. Defaults to True.
43
+
44
+ Returns:
45
+ Problem: the river pollution problem.
46
+
47
+ References:
48
+ Narula, Subhash C., and HRoland Weistroffer. "A flexible method for
49
+ nonlinear multicriteria decision-making problems." IEEE Transactions on
50
+ Systems, Man, and Cybernetics 19.4 (1989): 883-887.
51
+
52
+ Miettinen, Kaisa, and Marko M. Mäkelä. "Interactive method NIMBUS for
53
+ nondifferentiable multiobjective optimization problems." Multicriteria
54
+ Analysis: Proceedings of the XIth International Conference on MCDM, 1-6
55
+ August 1994, Coimbra, Portugal. Berlin, Heidelberg: Springer Berlin
56
+ Heidelberg, 1997.
57
+ """
58
+ variable_1 = Variable(
59
+ name="BOD", symbol="x_1", variable_type="real", lowerbound=0.3, upperbound=1.0, initial_value=0.65
60
+ )
61
+ variable_2 = Variable(
62
+ name="DO", symbol="x_2", variable_type="real", lowerbound=0.3, upperbound=1.0, initial_value=0.65
63
+ )
64
+
65
+ f_1 = "4.07 + 2.27 * x_1"
66
+ f_2 = "2.60 + 0.03 * x_1 + 0.02 * x_2 + 0.01 / (1.39 - x_1**2) + 0.30 / (1.39 - x_2**2)"
67
+ f_3 = "8.21 - 0.71 / (1.09 - x_1**2)"
68
+ f_4 = "0.96 - 0.96 / (1.09 - x_2**2)"
69
+ f_5 = "Max(Abs(x_1 - 0.65), Abs(x_2 - 0.65))"
70
+
71
+ objective_1 = Objective(
72
+ name="DO city",
73
+ symbol="f_1",
74
+ func=f_1,
75
+ maximize=True,
76
+ ideal=6.34,
77
+ nadir=4.75,
78
+ is_convex=True,
79
+ is_linear=True,
80
+ is_twice_differentiable=True,
81
+ )
82
+ objective_2 = Objective(
83
+ name="DO municipality",
84
+ symbol="f_2",
85
+ func=f_2,
86
+ maximize=True,
87
+ ideal=3.44,
88
+ nadir=2.85,
89
+ is_convex=False,
90
+ is_linear=False,
91
+ is_twice_differentiable=True,
92
+ )
93
+ objective_3 = Objective(
94
+ name="ROI fishery",
95
+ symbol="f_3",
96
+ func=f_3,
97
+ maximize=True,
98
+ ideal=7.5,
99
+ nadir=0.32,
100
+ is_convex=True,
101
+ is_linear=False,
102
+ is_twice_differentiable=True,
103
+ )
104
+ objective_4 = Objective(
105
+ name="ROI city",
106
+ symbol="f_4",
107
+ func=f_4,
108
+ maximize=True,
109
+ ideal=0,
110
+ nadir=-9.70,
111
+ is_convex=True,
112
+ is_linear=False,
113
+ is_twice_differentiable=True,
114
+ )
115
+ objective_5 = Objective(
116
+ name="BOD deviation",
117
+ symbol="f_5",
118
+ func=f_5,
119
+ maximize=False,
120
+ ideal=0,
121
+ nadir=0.35,
122
+ is_convex=False,
123
+ is_linear=False,
124
+ is_twice_differentiable=False,
125
+ )
126
+
127
+ objectives = (
128
+ [objective_1, objective_2, objective_3, objective_4, objective_5]
129
+ if five_objective_variant
130
+ else [objective_1, objective_2, objective_3, objective_4]
131
+ )
132
+
133
+ return Problem(
134
+ name="The river pollution problem",
135
+ description="The river pollution problem to maximize return of investments (ROI) and dissolved oxygen (DO).",
136
+ variables=[variable_1, variable_2],
137
+ objectives=objectives,
138
+ )
139
+
140
+
141
+ def river_pollution_problem_discrete(*, five_objective_variant: bool = True) -> Problem:
142
+ """Create a pydantic dataclass representation of the river pollution problem with either five or four variables.
143
+
144
+ The objective functions "DO city" ($f_1$), "DO municipality" ($f_2), and
145
+ "ROI fishery" ($f_3$) and "ROI city" ($f_4$) are to be
146
+ maximized. If the four variant problem is used, the the "BOD deviation" objective
147
+ function ($f_5$) is not present, but if it is, it is to be minimized.
148
+ This version of the problem uses discrete representation of the variables and objectives and does not provide
149
+ the analytical functions for the objectives.
150
+
151
+ Args:
152
+ five_objective_variant (bool, optional): Whether to use to five
153
+ objective function variant of the problem or not. Defaults to True.
154
+
155
+ Returns:
156
+ Problem: the river pollution problem.
157
+
158
+ References:
159
+ Narula, Subhash C., and HRoland Weistroffer. "A flexible method for
160
+ nonlinear multicriteria decision-making problems." IEEE Transactions on
161
+ Systems, Man, and Cybernetics 19.4 (1989): 883-887.
162
+
163
+ Miettinen, Kaisa, and Marko M. Mäkelä. "Interactive method NIMBUS for
164
+ nondifferentiable multiobjective optimization problems." Multicriteria
165
+ Analysis: Proceedings of the XIth International Conference on MCDM, 1-6
166
+ August 1994, Coimbra, Portugal. Berlin, Heidelberg: Springer Berlin
167
+ Heidelberg, 1997.
168
+ """
169
+ filename = "datasets/river_poll_4_objs.csv"
170
+ true_var_names = {"x_1": "BOD", "x_2": "DO"}
171
+ true_obj_names = {"f1": "DO city", "f2": "DO municipality", "f3": "ROI fishery", "f4": "ROI city"}
172
+ if five_objective_variant:
173
+ filename = "datasets/river_poll_5_objs.csv"
174
+ true_obj_names["f5"] = "BOD deviation"
175
+
176
+ path = Path(__file__).parent.parent.parent.parent / filename
177
+ data = pl.read_csv(path, has_header=True)
178
+
179
+ variables = [
180
+ Variable(
181
+ name=true_var_names[varName],
182
+ symbol=varName,
183
+ variable_type=VariableTypeEnum.real,
184
+ lowerbound=0.3,
185
+ upperbound=1.0,
186
+ initial_value=0.65,
187
+ )
188
+ for varName in true_var_names
189
+ ]
190
+ maximize = {"f1": True, "f2": True, "f3": True, "f4": True, "f5": False}
191
+ ideal = {objName: (data[objName].max() if maximize[objName] else data[objName].min()) for objName in true_obj_names}
192
+ nadir = {objName: (data[objName].min() if maximize[objName] else data[objName].max()) for objName in true_obj_names}
193
+ units = {"f1": "mg/L", "f2": "mg/L", "f3": "%", "f4": "%", "f5": "mg/L"}
194
+
195
+ objectives = [
196
+ Objective(
197
+ name=true_obj_names[objName],
198
+ symbol=objName,
199
+ func=None,
200
+ unit=units[objName],
201
+ objective_type=ObjectiveTypeEnum.data_based,
202
+ maximize=maximize[objName],
203
+ ideal=ideal[objName],
204
+ nadir=nadir[objName],
205
+ )
206
+ for objName in true_obj_names
207
+ ]
208
+
209
+ discrete_def = DiscreteRepresentation(
210
+ variable_values=data[list(true_var_names.keys())].to_dict(),
211
+ objective_values=data[list(true_obj_names.keys())].to_dict(),
212
+ )
213
+
214
+ return Problem(
215
+ name="The river pollution problem (Discrete)",
216
+ description="The river pollution problem to maximize return of investments (ROI) and dissolved oxygen (DO).",
217
+ variables=variables,
218
+ objectives=objectives,
219
+ discrete_representation=discrete_def,
220
+ )
221
+
222
+
223
+ def river_pollution_scenario() -> Problem:
224
+ r"""Defines the scenario-based uncertain variant of the river pollution problem.
225
+
226
+ The river pollution problem considers a river close to a city.
227
+ There are two sources of pollution: industrial pollution from a
228
+ fishery and municipal waste from the city. Two treatment plants
229
+ (in the fishery and the city) are responsible for managing the pollution.
230
+ Pollution is reported in pounds of biochemical oxygen demanding material (BOD),
231
+ and water quality is measured in dissolved oxygen concentration (DO).
232
+
233
+ Cleaning water in the city increases the tax rate, and cleaning in the
234
+ fishery reduces the return on investment. The problem is to improve
235
+ the DO level in the city and at the municipality border (`f1` and `f2`, respectively),
236
+ while, at the same time, maximizing the percent return on investment at the fishery (`f3`)
237
+ and minimizing additions to the city tax (`f4`).
238
+
239
+ Decision variables are:
240
+
241
+ * `x1`: The proportional amount of BOD removed from water after the fishery (treatment plant 1).
242
+ * `x2`: The proportional amount of BOD removed from water after the city (treatment plant 2).
243
+
244
+ The original problem considered specific values for all parameters. However, in this formulation,
245
+ some parameters are deeply uncertain, and only a range of plausible values is known for each.
246
+ These deeply uncertain parameters are as follows:
247
+
248
+ * `α ∈ [3, 4.24]`: Water quality index after the fishery.
249
+ * `β ∈ [2.25, 2.4]`: BOD reduction rate at treatment plant 1 (after the fishery).
250
+ * `δ ∈ [0.075, 0.092]`: BOD reduction rate at treatment plant 2 (after the city).
251
+ * `ξ ∈ [0.067, 0.083]`: Effective rate of BOD reduction at treatment plant 1 after the city.
252
+ * `η ∈ [1.2, 1.50]`: Parameter used to calculate the effective BOD reduction rate at the second treatment plant.
253
+ * `r ∈ [5.1, 12.5]`: Investment return rate.
254
+
255
+ The uncertain version of the river problem is formulated as follows:
256
+
257
+ $$
258
+ \\begin{equation}
259
+ \\begin{array}{rll}
260
+ \\text{maximize} & f_1(\\mathbf{x}) = & \\alpha + \\left(\\log\\left(\\left(\\frac{\\beta}{2}
261
+ - 1.14\\right)^2\\right) + \\beta^3\\right) x_1 \\\\
262
+ \\text{maximize} & f_2(\\mathbf{x}) = & \\gamma + \\delta x_1 + \\xi x_2 + \\frac{0.01}{\\eta - x_1^2}
263
+ + \\frac{0.30}{\\eta - x_2^2} \\\\
264
+ \\text{maximize} & f_3(\\mathbf{x}) = & r - \\frac{0.71}{1.09 - x_1^2} \\\\
265
+ \\text{minimize} & f_4(\\mathbf{x}) = & -0.96 + \\frac{0.96}{1.09 - x_2^2} \\\\
266
+ \\text{subject to} & & 0.3 \\leq x_1, x_2 \\leq 1.0.
267
+ \\end{array}
268
+ \\end{equation}
269
+ $$
270
+
271
+ where $\\gamma = \\log\\left(\\frac{\\alpha}{2} - 1\\right) + \\frac{\\alpha}{2} + 1.5$.
272
+
273
+ Returns:
274
+ Problem: the scenario-based river pollution problem.
275
+
276
+ References:
277
+ Narula, Subhash C., and HRoland Weistroffer. "A flexible method for
278
+ nonlinear multicriteria decision-making problems." IEEE Transactions on
279
+ Systems, Man, and Cybernetics 19.4 (1989): 883-887.
280
+
281
+ Miettinen, Kaisa, and Marko M. Mäkelä. "Interactive method NIMBUS for
282
+ nondifferentiable multiobjective optimization problems." Multicriteria
283
+ Analysis: Proceedings of the XIth International Conference on MCDM, 1-6
284
+ August 1994, Coimbra, Portugal. Berlin, Heidelberg: Springer Berlin
285
+ Heidelberg, 1997.
286
+ """ # noqa: RUF002
287
+ num_scenarios = 6
288
+ scenario_key_stub = "scenario"
289
+
290
+ # defining scenario parameters
291
+ alpha_values = [4.070, 3.868, 3.620, 3.372, 3.124, 4.116]
292
+ beta_values = [2.270, 2.262, 2.278, 2.254, 2.270, 2.286]
293
+ delta_values = [0.0800, 0.0869, 0.0835, 0.0903, 0.0801, 0.0767]
294
+ xi_values = [0.0750, 0.0782, 0.0750, 0.0814, 0.0686, 0.0718]
295
+ eta_values = [1.39, 1.47, 1.23, 1.35, 1.29, 1.41]
296
+ r_values = [8.21, 10.28, 5.84, 11.76, 7.32, 8.80]
297
+
298
+ # each scenario parameter is defined as its own tensor constant
299
+ alpha_constant = TensorConstant(
300
+ name="Water quality index after fishery", symbol="alpha", shape=[num_scenarios], values=alpha_values
301
+ )
302
+ beta_constant = TensorConstant(
303
+ name="BOD reduction rate at treatment plant 1 (after the fishery)",
304
+ symbol="beta",
305
+ shape=[num_scenarios],
306
+ values=beta_values,
307
+ )
308
+ delta_constant = TensorConstant(
309
+ name="BOD reduction rate at treatment plant 2 (after the city)",
310
+ symbol="delta",
311
+ shape=[num_scenarios],
312
+ values=delta_values,
313
+ )
314
+ xi_constant = TensorConstant(
315
+ name="The effective rate of BOD reduction at treatment plant 1 (after the city)",
316
+ symbol="xi",
317
+ shape=[num_scenarios],
318
+ values=xi_values,
319
+ )
320
+ eta_constant = TensorConstant(
321
+ name="The effective rate of BOD reduction rate at plant 2 (after the fishery)",
322
+ symbol="eta",
323
+ shape=[num_scenarios],
324
+ values=eta_values,
325
+ )
326
+ r_constant = TensorConstant(
327
+ name="Investment return rate",
328
+ symbol="r",
329
+ shape=[num_scenarios],
330
+ values=r_values,
331
+ )
332
+
333
+ constants = [alpha_constant, beta_constant, delta_constant, xi_constant, eta_constant, r_constant]
334
+
335
+ # define variables
336
+ x1 = Variable(
337
+ name="BOD removed after fishery",
338
+ symbol="x_1",
339
+ variable_type=VariableTypeEnum.real,
340
+ lowerbound=0.3,
341
+ upperbound=1.0,
342
+ )
343
+
344
+ x2 = Variable(
345
+ name="BOD removed after city",
346
+ symbol="x_2",
347
+ variable_type=VariableTypeEnum.real,
348
+ lowerbound=0.3,
349
+ upperbound=1.0,
350
+ )
351
+
352
+ variables = [x1, x2]
353
+
354
+ # define objectives for each scenario
355
+ objectives = []
356
+ scenario_keys = []
357
+
358
+ for i in range(num_scenarios):
359
+ scenario_key = f"{scenario_key_stub}_{i + 1}"
360
+ scenario_keys.append(scenario_key)
361
+
362
+ gamma_expr = f"Ln(alpha[{i + 1}]/2 - 1) + alpha[{i + 1}]/2 + 1.5"
363
+
364
+ f1_expr = f"alpha[{i + 1}] + (Ln((beta[{i + 1}]/2 - 1.14)**2) + beta[{i + 1}]**3)*x_1"
365
+ f2_expr = (
366
+ f"{gamma_expr} + delta[{i + 1}]*x_1 + xi[{i + 1}]*x_2 + 0.01/(eta[{i + 1}] - x_1**2) "
367
+ f"+ 0.3/(eta[{i + 1}] - x_2**2)"
368
+ )
369
+ f3_expr = f"r[{i + 1}] - 0.71/(1.09 - x_1**2)"
370
+
371
+ # f1
372
+ objectives.append(
373
+ Objective(
374
+ name="DO level city",
375
+ symbol=f"f1_{i + 1}",
376
+ scenario_keys=[scenario_key],
377
+ func=f1_expr,
378
+ objective_type=ObjectiveTypeEnum.analytical,
379
+ maximize=True,
380
+ is_linear=False,
381
+ is_convex=False,
382
+ is_twice_differentiable=True,
383
+ )
384
+ )
385
+
386
+ # f2
387
+ objectives.append(
388
+ Objective(
389
+ name="DO level fishery",
390
+ symbol=f"f2_{i + 1}",
391
+ scenario_keys=[scenario_key],
392
+ func=f2_expr,
393
+ objective_type=ObjectiveTypeEnum.analytical,
394
+ maximize=True,
395
+ is_linear=False,
396
+ is_convex=False,
397
+ is_twice_differentiable=True,
398
+ )
399
+ )
400
+
401
+ # f3
402
+ objectives.append(
403
+ Objective(
404
+ name="Return of investment",
405
+ symbol=f"f3_{i + 1}",
406
+ scenario_keys=[scenario_key],
407
+ func=f3_expr,
408
+ objective_type=ObjectiveTypeEnum.analytical,
409
+ maximize=True,
410
+ is_linear=False,
411
+ is_convex=False,
412
+ is_twice_differentiable=True,
413
+ )
414
+ )
415
+
416
+ f4_expr = "-0.96 + 0.96/(1.09 - x_2**2)"
417
+
418
+ # f4, by setting the scenario_key to None, the objective function is assumed to be part of all the scenarios.
419
+ objectives.append(
420
+ Objective(
421
+ name="Addition to city tax",
422
+ symbol="f4",
423
+ scenario_keys=None,
424
+ func=f4_expr,
425
+ objective_type=ObjectiveTypeEnum.analytical,
426
+ maximize=False,
427
+ is_linear=False,
428
+ is_convex=False,
429
+ is_twice_differentiable=True,
430
+ )
431
+ )
432
+
433
+ return Problem(
434
+ name="Scenario-based river pollution problem",
435
+ description="The scenario-based river pollution problem",
436
+ constants=constants,
437
+ variables=variables,
438
+ objectives=objectives,
439
+ scenario_keys=scenario_keys,
440
+ )
@@ -0,0 +1,140 @@
1
+ from desdeo.problem.schema import (
2
+ Constant,
3
+ Constraint,
4
+ ConstraintTypeEnum,
5
+ DiscreteRepresentation,
6
+ ExtraFunction,
7
+ Objective,
8
+ ObjectiveTypeEnum,
9
+ Problem,
10
+ Variable,
11
+ VariableTypeEnum,
12
+ )
13
+
14
+ def rocket_injector_design(original_version=False) -> Problem:
15
+ """The rocekt injector design problem as published in Vaidyanathan, et al. (2003).
16
+
17
+ The original version of the problem has 4 objectives. In Goel et al. (2007), the TW4 objective is dropped
18
+ due to high correlation with one of the other objectives. Hence, the default version of the problem is the
19
+ modified version with 3 objectives.
20
+
21
+ Args:
22
+ original_version (bool): If True, the original version of the problem with 4 objectives is returned.
23
+
24
+ References:
25
+ R. Vaidyanathan, K. Tucker, N. Papila, W. Shyy, CFD-Based Design Optimization For Single Element Rocket
26
+ Injector, in: AIAA Aerospace Sciences Meeting, 2003, pp. 1-21.
27
+
28
+ Goel, T., Vaidyanathan, R., Haftka, R. T., Shyy, W., Queipo, N. V., & Tucker, K. (2007).
29
+ Response surface approximation of Pareto optimal front in multi-objective optimization.
30
+ Computer methods in applied mechanics and engineering, 196(4-6), 879-893.
31
+
32
+ Returns:
33
+ Problem: The rocket injector design problem.
34
+ """
35
+ # Variables
36
+ alpha = Variable(name="alpha", symbol="a", variable_type=VariableTypeEnum.real, lowerbound=0.0, upperbound=1.0)
37
+
38
+ deltaHA = Variable(
39
+ name="deltaHA", symbol="DHA", variable_type=VariableTypeEnum.real, lowerbound=0.0, upperbound=1.0
40
+ )
41
+
42
+ deltaOA = Variable(
43
+ name="deltaOA", symbol="DOA", variable_type=VariableTypeEnum.real, lowerbound=0.0, upperbound=1.0
44
+ )
45
+
46
+ OPTT = Variable(name="OPTT", symbol="OPTT", variable_type=VariableTypeEnum.real, lowerbound=0.0, upperbound=1.0)
47
+
48
+ # Objectives
49
+
50
+ tfmax_eqn = """
51
+ 0.692+ 0.477 * a- 0.687 * DHA- 0.080 * DOA- 0.0650 * OPTT- 0.167 * a * a- 0.0129 * DHA * a
52
+ + 0.0796 * DHA * DHA- 0.0634 * DOA * a- 0.0257 * DOA * DHA+ 0.0877 * DOA * DOA- 0.0521 * OPTT * a
53
+ + 0.00156 * OPTT * DHA+ 0.00198 * OPTT * DOA+ 0.0184 * OPTT * OPTT
54
+ """
55
+
56
+ xccmax_eqn = """
57
+ 0.153- 0.322 * a+ 0.396 * DHA+ 0.424 * DOA+ 0.0226 * OPTT+ 0.175 * a * a
58
+ + 0.0185 * DHA * a- 0.0701 * DHA * DHA- 0.251 * DOA * a+ 0.179 * DOA * DHA+ 0.0150 * DOA * DOA
59
+ + 0.0134 * OPTT * a+ 0.0296 * OPTT * DHA+ 0.0752 * OPTT * DOA+ 0.0192 * OPTT * OPTT
60
+ """
61
+
62
+ ttmax_eqn = """
63
+ 0.370- 0.205 * a+ 0.0307 * DHA+ 0.108 * DOA+ 1.019 * OPTT- 0.135 * a * a+ 0.0141 * DHA * a
64
+ + 0.0998 * DHA * DHA+ 0.208 * DOA * a- 0.0301 * DOA * DHA- 0.226 * DOA * DOA+ 0.353 * OPTT * a
65
+ - 0.0497 * OPTT * DOA- 0.423 * OPTT * OPTT+ 0.202 * DHA * a * a- 0.281 * DOA * a * a
66
+ - 0.342 * DHA * DHA * a- 0.245 * DHA * DHA * DOA+ 0.281 * DOA * DOA * DHA- 0.184 * OPTT * OPTT * a
67
+ - 0.281 * DHA * a * DOA
68
+ """
69
+
70
+ tw4_eqn = """
71
+ 0.758 + 0.358 * a - 0.807 * DHA + 0.0925 * DOA - 0.0468 * OPTT
72
+ - 0.172 * a * a + 0.0106 * DHA * a + 0.0697 * DHA * DHA
73
+ - 0.146 * DOA * a - 0.0416 * DOA * DHA + 0.102 * DOA * DOA
74
+ - 0.0694 * OPTT * a - 0.00503 * OPTT * DHA + 0.0151 * OPTT * DOA
75
+ + 0.0173 * OPTT * OPTT
76
+ """
77
+
78
+ # The ideal and nadir values are estimates. If you get a better estimate, feel free to update them.
79
+ tf_max = Objective(
80
+ name="TF_max",
81
+ symbol="TF_max",
82
+ func=tfmax_eqn,
83
+ maximize=False,
84
+ is_linear=False,
85
+ is_convex=False,
86
+ is_twice_differentiable=True,
87
+ ideal=-0.008907,
88
+ nadir=1.002000,
89
+ )
90
+
91
+ xcc_max = Objective(
92
+ name="Xcc_max",
93
+ symbol="Xcc_max",
94
+ func=xccmax_eqn,
95
+ maximize=False,
96
+ is_linear=False,
97
+ is_convex=False,
98
+ is_twice_differentiable=True,
99
+ ideal=0.004883,
100
+ nadir=1.075655,
101
+ )
102
+
103
+ tt_max = Objective(
104
+ name="TT_max",
105
+ symbol="TT_max",
106
+ func=ttmax_eqn,
107
+ maximize=False,
108
+ is_linear=False,
109
+ is_convex=False,
110
+ is_twice_differentiable=True,
111
+ ideal=-0.419077,
112
+ nadir=1.092842,
113
+ )
114
+
115
+ tw4 = Objective(
116
+ name="TW4",
117
+ symbol="TW4",
118
+ func=tw4_eqn,
119
+ maximize=False,
120
+ is_linear=False,
121
+ is_convex=False,
122
+ is_twice_differentiable=True,
123
+ ideal=-0.013602,
124
+ nadir=0.244688,
125
+ )
126
+
127
+ if original_version: # NOQA:SIM108
128
+ objectives = [tf_max, tw4, tt_max, xcc_max]
129
+ else:
130
+ objectives = [tf_max, tt_max, xcc_max]
131
+
132
+ return Problem(
133
+ name="Rocket Injector Design Problem",
134
+ description=(
135
+ "R. Vaidyanathan, K. Tucker, N. Papila, W. Shyy, CFD-Based Design Optimization For Single Element"
136
+ " Rocket Injector, in: AIAA Aerospace Sciences Meeting, 2003, pp. 1-21."
137
+ ),
138
+ variables=[alpha, deltaHA, deltaOA, OPTT],
139
+ objectives=objectives,
140
+ )