pymoo 0.6.1.5.dev0__cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.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.

Potentially problematic release.


This version of pymoo might be problematic. Click here for more details.

Files changed (328) hide show
  1. pymoo/__init__.py +3 -0
  2. pymoo/algorithms/__init__.py +0 -0
  3. pymoo/algorithms/base/__init__.py +0 -0
  4. pymoo/algorithms/base/bracket.py +38 -0
  5. pymoo/algorithms/base/genetic.py +109 -0
  6. pymoo/algorithms/base/line.py +62 -0
  7. pymoo/algorithms/base/local.py +39 -0
  8. pymoo/algorithms/base/meta.py +79 -0
  9. pymoo/algorithms/hyperparameters.py +89 -0
  10. pymoo/algorithms/moo/__init__.py +0 -0
  11. pymoo/algorithms/moo/age.py +310 -0
  12. pymoo/algorithms/moo/age2.py +194 -0
  13. pymoo/algorithms/moo/ctaea.py +298 -0
  14. pymoo/algorithms/moo/dnsga2.py +76 -0
  15. pymoo/algorithms/moo/kgb.py +446 -0
  16. pymoo/algorithms/moo/moead.py +183 -0
  17. pymoo/algorithms/moo/nsga2.py +113 -0
  18. pymoo/algorithms/moo/nsga3.py +358 -0
  19. pymoo/algorithms/moo/pinsga2.py +370 -0
  20. pymoo/algorithms/moo/rnsga2.py +188 -0
  21. pymoo/algorithms/moo/rnsga3.py +246 -0
  22. pymoo/algorithms/moo/rvea.py +214 -0
  23. pymoo/algorithms/moo/sms.py +195 -0
  24. pymoo/algorithms/moo/spea2.py +190 -0
  25. pymoo/algorithms/moo/unsga3.py +47 -0
  26. pymoo/algorithms/soo/__init__.py +0 -0
  27. pymoo/algorithms/soo/convex/__init__.py +0 -0
  28. pymoo/algorithms/soo/nonconvex/__init__.py +0 -0
  29. pymoo/algorithms/soo/nonconvex/brkga.py +161 -0
  30. pymoo/algorithms/soo/nonconvex/cmaes.py +554 -0
  31. pymoo/algorithms/soo/nonconvex/de.py +279 -0
  32. pymoo/algorithms/soo/nonconvex/direct.py +149 -0
  33. pymoo/algorithms/soo/nonconvex/es.py +203 -0
  34. pymoo/algorithms/soo/nonconvex/g3pcx.py +94 -0
  35. pymoo/algorithms/soo/nonconvex/ga.py +93 -0
  36. pymoo/algorithms/soo/nonconvex/ga_niching.py +223 -0
  37. pymoo/algorithms/soo/nonconvex/isres.py +74 -0
  38. pymoo/algorithms/soo/nonconvex/nelder.py +251 -0
  39. pymoo/algorithms/soo/nonconvex/optuna.py +80 -0
  40. pymoo/algorithms/soo/nonconvex/pattern.py +183 -0
  41. pymoo/algorithms/soo/nonconvex/pso.py +399 -0
  42. pymoo/algorithms/soo/nonconvex/pso_ep.py +297 -0
  43. pymoo/algorithms/soo/nonconvex/random_search.py +25 -0
  44. pymoo/algorithms/soo/nonconvex/sres.py +56 -0
  45. pymoo/algorithms/soo/univariate/__init__.py +0 -0
  46. pymoo/algorithms/soo/univariate/backtracking.py +59 -0
  47. pymoo/algorithms/soo/univariate/exp.py +46 -0
  48. pymoo/algorithms/soo/univariate/golden.py +65 -0
  49. pymoo/algorithms/soo/univariate/quadr_interp.py +81 -0
  50. pymoo/algorithms/soo/univariate/wolfe.py +163 -0
  51. pymoo/config.py +33 -0
  52. pymoo/constraints/__init__.py +3 -0
  53. pymoo/constraints/adaptive.py +62 -0
  54. pymoo/constraints/as_obj.py +56 -0
  55. pymoo/constraints/as_penalty.py +41 -0
  56. pymoo/constraints/eps.py +26 -0
  57. pymoo/constraints/from_bounds.py +36 -0
  58. pymoo/core/__init__.py +0 -0
  59. pymoo/core/algorithm.py +394 -0
  60. pymoo/core/callback.py +38 -0
  61. pymoo/core/crossover.py +77 -0
  62. pymoo/core/decision_making.py +102 -0
  63. pymoo/core/decomposition.py +76 -0
  64. pymoo/core/duplicate.py +163 -0
  65. pymoo/core/evaluator.py +116 -0
  66. pymoo/core/indicator.py +34 -0
  67. pymoo/core/individual.py +784 -0
  68. pymoo/core/infill.py +64 -0
  69. pymoo/core/initialization.py +42 -0
  70. pymoo/core/mating.py +39 -0
  71. pymoo/core/meta.py +21 -0
  72. pymoo/core/mixed.py +165 -0
  73. pymoo/core/mutation.py +44 -0
  74. pymoo/core/operator.py +40 -0
  75. pymoo/core/parameters.py +134 -0
  76. pymoo/core/plot.py +210 -0
  77. pymoo/core/population.py +180 -0
  78. pymoo/core/problem.py +460 -0
  79. pymoo/core/recorder.py +99 -0
  80. pymoo/core/repair.py +23 -0
  81. pymoo/core/replacement.py +96 -0
  82. pymoo/core/result.py +52 -0
  83. pymoo/core/sampling.py +43 -0
  84. pymoo/core/selection.py +61 -0
  85. pymoo/core/solution.py +10 -0
  86. pymoo/core/survival.py +103 -0
  87. pymoo/core/termination.py +70 -0
  88. pymoo/core/variable.py +399 -0
  89. pymoo/cython/__init__.py +0 -0
  90. pymoo/cython/calc_perpendicular_distance.cpython-312-x86_64-linux-gnu.so +0 -0
  91. pymoo/cython/calc_perpendicular_distance.pyx +67 -0
  92. pymoo/cython/decomposition.cpython-312-x86_64-linux-gnu.so +0 -0
  93. pymoo/cython/decomposition.pyx +165 -0
  94. pymoo/cython/hv.cpython-312-x86_64-linux-gnu.so +0 -0
  95. pymoo/cython/hv.pyx +18 -0
  96. pymoo/cython/info.cpython-312-x86_64-linux-gnu.so +0 -0
  97. pymoo/cython/info.pyx +5 -0
  98. pymoo/cython/mnn.cpython-312-x86_64-linux-gnu.so +0 -0
  99. pymoo/cython/mnn.pyx +273 -0
  100. pymoo/cython/non_dominated_sorting.cpython-312-x86_64-linux-gnu.so +0 -0
  101. pymoo/cython/non_dominated_sorting.pyx +645 -0
  102. pymoo/cython/pruning_cd.cpython-312-x86_64-linux-gnu.so +0 -0
  103. pymoo/cython/pruning_cd.pyx +197 -0
  104. pymoo/cython/stochastic_ranking.cpython-312-x86_64-linux-gnu.so +0 -0
  105. pymoo/cython/stochastic_ranking.pyx +49 -0
  106. pymoo/cython/utils.pxd +129 -0
  107. pymoo/cython/vendor/__init__.py +0 -0
  108. pymoo/cython/vendor/hypervolume.cpp +1621 -0
  109. pymoo/cython/vendor/hypervolume.h +63 -0
  110. pymoo/decomposition/__init__.py +0 -0
  111. pymoo/decomposition/aasf.py +24 -0
  112. pymoo/decomposition/asf.py +10 -0
  113. pymoo/decomposition/pbi.py +13 -0
  114. pymoo/decomposition/perp_dist.py +13 -0
  115. pymoo/decomposition/tchebicheff.py +11 -0
  116. pymoo/decomposition/util.py +13 -0
  117. pymoo/decomposition/weighted_sum.py +8 -0
  118. pymoo/docs.py +187 -0
  119. pymoo/experimental/__init__.py +0 -0
  120. pymoo/experimental/algorithms/__init__.py +0 -0
  121. pymoo/experimental/algorithms/gde3.py +57 -0
  122. pymoo/gradient/__init__.py +21 -0
  123. pymoo/gradient/automatic.py +57 -0
  124. pymoo/gradient/grad_autograd.py +105 -0
  125. pymoo/gradient/grad_complex.py +35 -0
  126. pymoo/gradient/grad_jax.py +51 -0
  127. pymoo/gradient/toolbox/__init__.py +6 -0
  128. pymoo/indicators/__init__.py +0 -0
  129. pymoo/indicators/distance_indicator.py +55 -0
  130. pymoo/indicators/gd.py +7 -0
  131. pymoo/indicators/gd_plus.py +7 -0
  132. pymoo/indicators/hv/__init__.py +63 -0
  133. pymoo/indicators/hv/exact.py +71 -0
  134. pymoo/indicators/hv/exact_2d.py +102 -0
  135. pymoo/indicators/hv/monte_carlo.py +74 -0
  136. pymoo/indicators/igd.py +7 -0
  137. pymoo/indicators/igd_plus.py +7 -0
  138. pymoo/indicators/kktpm.py +151 -0
  139. pymoo/indicators/migd.py +55 -0
  140. pymoo/indicators/rmetric.py +203 -0
  141. pymoo/indicators/spacing.py +52 -0
  142. pymoo/mcdm/__init__.py +0 -0
  143. pymoo/mcdm/compromise_programming.py +19 -0
  144. pymoo/mcdm/high_tradeoff.py +40 -0
  145. pymoo/mcdm/pseudo_weights.py +32 -0
  146. pymoo/operators/__init__.py +0 -0
  147. pymoo/operators/control.py +187 -0
  148. pymoo/operators/crossover/__init__.py +0 -0
  149. pymoo/operators/crossover/binx.py +45 -0
  150. pymoo/operators/crossover/dex.py +122 -0
  151. pymoo/operators/crossover/erx.py +162 -0
  152. pymoo/operators/crossover/expx.py +51 -0
  153. pymoo/operators/crossover/hux.py +37 -0
  154. pymoo/operators/crossover/nox.py +13 -0
  155. pymoo/operators/crossover/ox.py +84 -0
  156. pymoo/operators/crossover/pcx.py +82 -0
  157. pymoo/operators/crossover/pntx.py +49 -0
  158. pymoo/operators/crossover/sbx.py +125 -0
  159. pymoo/operators/crossover/spx.py +5 -0
  160. pymoo/operators/crossover/ux.py +20 -0
  161. pymoo/operators/mutation/__init__.py +0 -0
  162. pymoo/operators/mutation/bitflip.py +17 -0
  163. pymoo/operators/mutation/gauss.py +58 -0
  164. pymoo/operators/mutation/inversion.py +42 -0
  165. pymoo/operators/mutation/nom.py +7 -0
  166. pymoo/operators/mutation/pm.py +94 -0
  167. pymoo/operators/mutation/rm.py +23 -0
  168. pymoo/operators/repair/__init__.py +0 -0
  169. pymoo/operators/repair/bounce_back.py +32 -0
  170. pymoo/operators/repair/bounds_repair.py +95 -0
  171. pymoo/operators/repair/inverse_penalty.py +89 -0
  172. pymoo/operators/repair/rounding.py +18 -0
  173. pymoo/operators/repair/to_bound.py +31 -0
  174. pymoo/operators/repair/vtype.py +11 -0
  175. pymoo/operators/sampling/__init__.py +0 -0
  176. pymoo/operators/sampling/lhs.py +73 -0
  177. pymoo/operators/sampling/rnd.py +50 -0
  178. pymoo/operators/selection/__init__.py +0 -0
  179. pymoo/operators/selection/rnd.py +72 -0
  180. pymoo/operators/selection/tournament.py +76 -0
  181. pymoo/operators/survival/__init__.py +0 -0
  182. pymoo/operators/survival/rank_and_crowding/__init__.py +1 -0
  183. pymoo/operators/survival/rank_and_crowding/classes.py +209 -0
  184. pymoo/operators/survival/rank_and_crowding/metrics.py +208 -0
  185. pymoo/optimize.py +72 -0
  186. pymoo/problems/__init__.py +157 -0
  187. pymoo/problems/dyn.py +47 -0
  188. pymoo/problems/dynamic/__init__.py +0 -0
  189. pymoo/problems/dynamic/cec2015.py +108 -0
  190. pymoo/problems/dynamic/df.py +452 -0
  191. pymoo/problems/dynamic/misc.py +167 -0
  192. pymoo/problems/functional.py +48 -0
  193. pymoo/problems/many/__init__.py +5 -0
  194. pymoo/problems/many/cdtlz.py +159 -0
  195. pymoo/problems/many/dcdtlz.py +88 -0
  196. pymoo/problems/many/dtlz.py +264 -0
  197. pymoo/problems/many/wfg.py +550 -0
  198. pymoo/problems/multi/__init__.py +14 -0
  199. pymoo/problems/multi/bnh.py +34 -0
  200. pymoo/problems/multi/carside.py +48 -0
  201. pymoo/problems/multi/clutch.py +104 -0
  202. pymoo/problems/multi/csi.py +55 -0
  203. pymoo/problems/multi/ctp.py +198 -0
  204. pymoo/problems/multi/dascmop.py +213 -0
  205. pymoo/problems/multi/kursawe.py +25 -0
  206. pymoo/problems/multi/modact.py +68 -0
  207. pymoo/problems/multi/mw.py +400 -0
  208. pymoo/problems/multi/omnitest.py +48 -0
  209. pymoo/problems/multi/osy.py +32 -0
  210. pymoo/problems/multi/srn.py +28 -0
  211. pymoo/problems/multi/sympart.py +94 -0
  212. pymoo/problems/multi/tnk.py +24 -0
  213. pymoo/problems/multi/truss2d.py +83 -0
  214. pymoo/problems/multi/welded_beam.py +41 -0
  215. pymoo/problems/multi/wrm.py +36 -0
  216. pymoo/problems/multi/zdt.py +151 -0
  217. pymoo/problems/multi_to_single.py +22 -0
  218. pymoo/problems/single/__init__.py +12 -0
  219. pymoo/problems/single/ackley.py +24 -0
  220. pymoo/problems/single/cantilevered_beam.py +34 -0
  221. pymoo/problems/single/flowshop_scheduling.py +112 -0
  222. pymoo/problems/single/g.py +874 -0
  223. pymoo/problems/single/griewank.py +18 -0
  224. pymoo/problems/single/himmelblau.py +15 -0
  225. pymoo/problems/single/knapsack.py +48 -0
  226. pymoo/problems/single/mopta08.py +26 -0
  227. pymoo/problems/single/multimodal.py +20 -0
  228. pymoo/problems/single/pressure_vessel.py +30 -0
  229. pymoo/problems/single/rastrigin.py +20 -0
  230. pymoo/problems/single/rosenbrock.py +22 -0
  231. pymoo/problems/single/schwefel.py +18 -0
  232. pymoo/problems/single/simple.py +13 -0
  233. pymoo/problems/single/sphere.py +19 -0
  234. pymoo/problems/single/traveling_salesman.py +79 -0
  235. pymoo/problems/single/zakharov.py +19 -0
  236. pymoo/problems/static.py +14 -0
  237. pymoo/problems/util.py +42 -0
  238. pymoo/problems/zero_to_one.py +27 -0
  239. pymoo/termination/__init__.py +23 -0
  240. pymoo/termination/collection.py +12 -0
  241. pymoo/termination/cv.py +48 -0
  242. pymoo/termination/default.py +45 -0
  243. pymoo/termination/delta.py +64 -0
  244. pymoo/termination/fmin.py +16 -0
  245. pymoo/termination/ftol.py +144 -0
  246. pymoo/termination/indicator.py +49 -0
  247. pymoo/termination/max_eval.py +14 -0
  248. pymoo/termination/max_gen.py +15 -0
  249. pymoo/termination/max_time.py +20 -0
  250. pymoo/termination/robust.py +34 -0
  251. pymoo/termination/xtol.py +33 -0
  252. pymoo/util/__init__.py +0 -0
  253. pymoo/util/archive.py +150 -0
  254. pymoo/util/cache.py +29 -0
  255. pymoo/util/clearing.py +82 -0
  256. pymoo/util/display/__init__.py +0 -0
  257. pymoo/util/display/column.py +52 -0
  258. pymoo/util/display/display.py +34 -0
  259. pymoo/util/display/multi.py +96 -0
  260. pymoo/util/display/output.py +53 -0
  261. pymoo/util/display/progress.py +54 -0
  262. pymoo/util/display/single.py +67 -0
  263. pymoo/util/dominator.py +67 -0
  264. pymoo/util/function_loader.py +129 -0
  265. pymoo/util/hv.py +23 -0
  266. pymoo/util/matlab_engine.py +39 -0
  267. pymoo/util/misc.py +460 -0
  268. pymoo/util/mnn.py +70 -0
  269. pymoo/util/nds/__init__.py +0 -0
  270. pymoo/util/nds/dominance_degree_non_dominated_sort.py +159 -0
  271. pymoo/util/nds/efficient_non_dominated_sort.py +152 -0
  272. pymoo/util/nds/fast_non_dominated_sort.py +70 -0
  273. pymoo/util/nds/naive_non_dominated_sort.py +36 -0
  274. pymoo/util/nds/non_dominated_sorting.py +67 -0
  275. pymoo/util/nds/tree_based_non_dominated_sort.py +133 -0
  276. pymoo/util/normalization.py +312 -0
  277. pymoo/util/optimum.py +42 -0
  278. pymoo/util/plotting.py +177 -0
  279. pymoo/util/pruning_cd.py +89 -0
  280. pymoo/util/randomized_argsort.py +60 -0
  281. pymoo/util/ref_dirs/__init__.py +24 -0
  282. pymoo/util/ref_dirs/construction.py +88 -0
  283. pymoo/util/ref_dirs/das_dennis.py +52 -0
  284. pymoo/util/ref_dirs/energy.py +319 -0
  285. pymoo/util/ref_dirs/energy_layer.py +119 -0
  286. pymoo/util/ref_dirs/genetic_algorithm.py +63 -0
  287. pymoo/util/ref_dirs/incremental.py +68 -0
  288. pymoo/util/ref_dirs/misc.py +128 -0
  289. pymoo/util/ref_dirs/optimizer.py +59 -0
  290. pymoo/util/ref_dirs/performance.py +162 -0
  291. pymoo/util/ref_dirs/reduction.py +85 -0
  292. pymoo/util/ref_dirs/sample_and_map.py +24 -0
  293. pymoo/util/reference_direction.py +260 -0
  294. pymoo/util/remote.py +55 -0
  295. pymoo/util/roulette.py +27 -0
  296. pymoo/util/running_metric.py +128 -0
  297. pymoo/util/sliding_window.py +25 -0
  298. pymoo/util/stochastic_ranking.py +32 -0
  299. pymoo/util/value_functions.py +719 -0
  300. pymoo/util/vectors.py +40 -0
  301. pymoo/util/vf_dominator.py +99 -0
  302. pymoo/vendor/__init__.py +0 -0
  303. pymoo/vendor/cec2018.py +398 -0
  304. pymoo/vendor/gta.py +617 -0
  305. pymoo/vendor/hv.py +267 -0
  306. pymoo/vendor/vendor_cmaes.py +412 -0
  307. pymoo/vendor/vendor_coco.py +81 -0
  308. pymoo/vendor/vendor_scipy.py +232 -0
  309. pymoo/version.py +1 -0
  310. pymoo/visualization/__init__.py +8 -0
  311. pymoo/visualization/fitness_landscape.py +127 -0
  312. pymoo/visualization/heatmap.py +123 -0
  313. pymoo/visualization/pcp.py +120 -0
  314. pymoo/visualization/petal.py +91 -0
  315. pymoo/visualization/radar.py +108 -0
  316. pymoo/visualization/radviz.py +68 -0
  317. pymoo/visualization/scatter.py +150 -0
  318. pymoo/visualization/star_coordinate.py +75 -0
  319. pymoo/visualization/util.py +123 -0
  320. pymoo/visualization/video/__init__.py +0 -0
  321. pymoo/visualization/video/callback_video.py +82 -0
  322. pymoo/visualization/video/one_var_one_obj.py +57 -0
  323. pymoo/visualization/video/two_var_one_obj.py +62 -0
  324. pymoo-0.6.1.5.dev0.dist-info/METADATA +187 -0
  325. pymoo-0.6.1.5.dev0.dist-info/RECORD +328 -0
  326. pymoo-0.6.1.5.dev0.dist-info/WHEEL +6 -0
  327. pymoo-0.6.1.5.dev0.dist-info/licenses/LICENSE +191 -0
  328. pymoo-0.6.1.5.dev0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,25 @@
1
+ from pymoo.core.algorithm import Algorithm
2
+ from pymoo.core.population import Population
3
+ from pymoo.operators.sampling.rnd import FloatRandomSampling
4
+ from pymoo.util.display.single import SingleObjectiveOutput
5
+
6
+
7
+ class RandomSearch(Algorithm):
8
+
9
+ def __init__(self,
10
+ n_points_per_iteration=100,
11
+ sampling=FloatRandomSampling(),
12
+ output=SingleObjectiveOutput(),
13
+ **kwargs):
14
+ super().__init__(output=output, **kwargs)
15
+ self.n_points_per_iteration = n_points_per_iteration
16
+ self.sampling = sampling
17
+
18
+ def _initialize_infill(self):
19
+ return self._infill()
20
+
21
+ def _infill(self):
22
+ return self.sampling.do(self.problem, self.n_points_per_iteration)
23
+
24
+ def _advance(self, infills=None, **kwargs):
25
+ self.pop = infills if self.opt is None else Population.merge(infills, self.opt)
@@ -0,0 +1,56 @@
1
+ import numpy as np
2
+
3
+ from pymoo.algorithms.soo.nonconvex.es import ES
4
+ from pymoo.core.population import Population, calc_cv
5
+ from pymoo.core.survival import Survival
6
+ from pymoo.docs import parse_doc_string
7
+ from pymoo.util.function_loader import load_function
8
+
9
+
10
+ class StochasticRankingSurvival(Survival):
11
+
12
+ def __init__(self, PR):
13
+ super().__init__(filter_infeasible=False)
14
+ self.PR = PR
15
+
16
+ def _do(self, problem, pop, *args, n_survive=None, tcv=None, **kwargs):
17
+ assert problem.n_obj == 1, "This stochastic ranking implementation only works for single-objective problems."
18
+
19
+ F, G = pop.get("F", "G")
20
+ f = F[:, 0]
21
+
22
+ if not problem.has_constraints():
23
+ I = f.argsort()
24
+
25
+ else:
26
+ phi = calc_cv(pop)
27
+ J = np.arange(len(phi))
28
+ I = load_function("stochastic_ranking")(f, phi, self.PR, J)
29
+
30
+ return pop[I][:n_survive]
31
+
32
+
33
+ class SRES(ES):
34
+
35
+ def __init__(self, PF=0.45, **kwargs):
36
+ """
37
+ Stochastic Ranking Evolutionary Strategy (SRES)
38
+
39
+ Parameters
40
+ ----------
41
+ PF: float
42
+ The stochastic ranking weight for choosing a random decision while doing the modified bubble sort.
43
+ """
44
+ super().__init__(survival=StochasticRankingSurvival(PF), **kwargs)
45
+ self.PF = PF
46
+
47
+ def _advance(self, infills=None, **kwargs):
48
+
49
+ # if not all solutions suggested by infill() are evaluated we create a more semi (mu+lambda) algorithm
50
+ if len(infills) < self.pop_size:
51
+ infills = Population.merge(infills, self.pop)
52
+
53
+ self.pop = self.survival.do(self.problem, infills, n_survive=self.pop_size)
54
+
55
+
56
+ parse_doc_string(SRES.__init__)
File without changes
@@ -0,0 +1,59 @@
1
+ from pymoo.algorithms.base.line import LineSearch
2
+ from pymoo.core.evaluator import Evaluator
3
+ from pymoo.core.solution import Solution, SolutionSet
4
+ from pymoo.core.termination import NoTermination
5
+ from pymoo.optimize import minimize
6
+ from pymoo.problems.single import Sphere
7
+
8
+
9
+ class BacktrackingLineSearch(LineSearch):
10
+
11
+ def __init__(self, alpha=0.1, beta=0.33, **kwargs):
12
+ super().__init__(**kwargs)
13
+ self.alpha = alpha
14
+ self.beta = beta
15
+ self.termination = NoTermination()
16
+
17
+ def _initialize_infill(self):
18
+ super()._initialize_infill()
19
+ self.t = 1.0
20
+ self.point.set("t", self.t)
21
+
22
+ # TODO: evaluate_values_of needs to be moved into evaluator to be more flexible
23
+ if self.point.get("dF") is None:
24
+ self.evaluator.eval(self.problem, self.point, evaluate_values_of=["dF"], algorithm=self)
25
+
26
+ def step(self):
27
+ t = self.t
28
+ x, f, df, p = self.point.X, self.point.F[0], self.point.get("dF")[0], self.direction
29
+
30
+ infill = Solution(X=x + t * p, t=t)
31
+ self.evaluator.eval(self.problem, infill, algorithm=self, evaluate_values_of=["F"])
32
+ _f = infill.F[0]
33
+
34
+ self.pop = SolutionSet.merge(self.pop, infill)
35
+ self.infill = infill
36
+
37
+ if _f < f + self.alpha * self.t * df.T @ p or self.t <= 1e-8:
38
+ self.termination.force_termination = True
39
+ else:
40
+ self.t = self.t * self.beta
41
+
42
+
43
+ if __name__ == '__main__':
44
+ import numpy as np
45
+
46
+ problem = Sphere()
47
+
48
+ X = np.array(np.random.random(problem.n_var))
49
+
50
+ point = Solution(X=X)
51
+ Evaluator(evaluate_values_of=["F", "dF"]).eval(problem, point)
52
+
53
+ direction = - point.get("dF")[0]
54
+
55
+ algorithm = BacktrackingLineSearch().setup(problem, point=point, direction=direction)._initialize()
56
+
57
+ res = minimize(problem, algorithm)
58
+
59
+ print(res.X)
@@ -0,0 +1,46 @@
1
+ import numpy as np
2
+
3
+ from pymoo.core.algorithm import Algorithm
4
+ from pymoo.core.individual import Individual
5
+ from pymoo.core.population import Population
6
+ from pymoo.core.replacement import is_better
7
+ from pymoo.termination.default import DefaultSingleObjectiveTermination
8
+
9
+
10
+ class ExponentialSearch(Algorithm):
11
+
12
+ def __init__(self, delta=0.05, **kwargs):
13
+ super().__init__(**kwargs)
14
+ self.termination = DefaultSingleObjectiveTermination()
15
+ self.alpha = delta
16
+ self.point = None
17
+
18
+ def _setup(self, problem, x0=None, **kwargs):
19
+ msg = "Only problems with one variable, one objective and no constraints can be solved!"
20
+ assert problem.n_var == 1 and not problem.has_constraints() and problem.n_obj == 1, msg
21
+ self.point = x0
22
+
23
+ def _initialize_infill(self):
24
+ self.step_size = self.alpha
25
+
26
+ if self.point is None:
27
+ return Population.new(X=np.copy(self.problem.xl[None, :]))
28
+ else:
29
+ return Population.create(self.point)
30
+
31
+ def step(self):
32
+ alpha, max_alpha = self.alpha, self.problem.xu[0]
33
+
34
+ if alpha > max_alpha:
35
+ alpha = max_alpha
36
+
37
+ infill = Individual(X=np.array([alpha]))
38
+ self.evaluator.eval(self.problem, infill)
39
+ self.pop = Population.merge(self.pop, infill)[-10:]
40
+
41
+ if is_better(self.point, infill, eps=0.0) or alpha == max_alpha:
42
+ self.termination.force_termination = True
43
+ return
44
+
45
+ self.point = infill
46
+ self.alpha *= 2
@@ -0,0 +1,65 @@
1
+ from pymoo.algorithms.base.bracket import BracketSearch
2
+ from pymoo.core.individual import Individual
3
+ from pymoo.core.population import Population
4
+
5
+
6
+ class GoldenSectionSearch(BracketSearch):
7
+
8
+ def __init__(self, **kwargs):
9
+ super().__init__(**kwargs)
10
+ self.left, self.right = None, None
11
+ self.R = (5 ** 0.5 - 1) / 2
12
+
13
+ def _initialize_infill(self):
14
+ super()._initialize_infill()
15
+ a, b = self.a, self.b
16
+
17
+ # the golden ratio (precomputed constant)
18
+ R = self.R
19
+
20
+ # create the left and right in the interval itself
21
+ c, d = Individual(X=b.X - R * (b.X - a.X)), Individual(X=a.X + R * (b.X - a.X))
22
+
23
+ # create a population with all four individuals
24
+ pop = Population.create(a, c, d, b)
25
+
26
+ self.pop, self.infills = pop, pop
27
+
28
+ return pop
29
+
30
+ def _advance(self, **kwargs):
31
+
32
+ # all the elements in the interval
33
+ a, c, d, b = self.pop
34
+
35
+ # the golden ratio (precomputed constant)
36
+ R = self.R
37
+
38
+ # if the left solution is better than the right
39
+ if c.F[0] < d.F[0]:
40
+
41
+ # make the right to be the new right bound and the left becomes the right
42
+ a, b = a, d
43
+ d = c
44
+
45
+ # create a new left individual and evaluate
46
+ c = Individual(X=b.X - R * (b.X - a.X))
47
+ self.evaluator.eval(self.problem, c, algorithm=self)
48
+ self.infills = c
49
+
50
+ # if the right solution is better than the left
51
+ else:
52
+
53
+ # make the left to be the new left bound and the right becomes the left
54
+ a, b = c, b
55
+ c = d
56
+
57
+ # create a new right individual and evaluate
58
+ d = Individual(X=a.X + R * (b.X - a.X))
59
+ self.evaluator.eval(self.problem, d, algorithm=self)
60
+ self.infills = d
61
+
62
+ # update the population with all the four individuals
63
+ self.pop = Population.create(a, c, d, b)
64
+
65
+
@@ -0,0 +1,81 @@
1
+ from pymoo.algorithms.base.bracket import BracketSearch
2
+ from pymoo.core.individual import Individual
3
+ from pymoo.core.population import Population
4
+
5
+
6
+ def quadr_interp_equ(xa, fa, xb, fb, xc, fc):
7
+ g1 = (fc - fa) / (xc - xa)
8
+ g2 = ((fb - fc) / (xb - xc) - g1) * (xb - xa)
9
+ xd = 0.5 * ((xa - xb) - g1 / g2)
10
+ return xd
11
+
12
+
13
+ def quadr_interp(a, b, c):
14
+ return Individual(X=quadr_interp_equ(a.X, a.F, b.X, b.F, c.X, c.F))
15
+
16
+
17
+ class QuadraticInterpolationSearch(BracketSearch):
18
+
19
+ def __init__(self, a=None, b=None, **kwargs):
20
+ """
21
+
22
+ 7.1.2 Quadratic Interpolation Search
23
+ http://www.mathcs.emory.edu/~haber/math315/chap7.pdf
24
+
25
+ Parameters
26
+ ----------
27
+ a
28
+ b
29
+ kwargs
30
+ """
31
+ super().__init__(a, b, **kwargs)
32
+
33
+ def _initialize_infill(self):
34
+ super()._initialize_infill()
35
+ a, b = self.a, self.b
36
+
37
+ # set c to be directly in the middle between the two brackets
38
+ c = Individual(X=(b.X - a.X) / 2)
39
+
40
+ # create a population with all three individuals
41
+ pop = Population.create(a, b, c)
42
+
43
+ return pop
44
+
45
+ def _advance(self, **kwargs):
46
+
47
+ # all the elements in the interval
48
+ a, b, c = self.pop
49
+
50
+ # if this is the case then the function is not convex (which means U shaped)
51
+ if c.F[0] >= a.F[0] or c.F[0] >= b.F[0]:
52
+
53
+ # choose the left side if a smaller than b, or the right side otherwise
54
+ if a.F[0] <= b.F[0]:
55
+ a = c
56
+ else:
57
+ b = c
58
+
59
+ c = Individual(X=(b.X - a.X) / 2)
60
+ self.evaluator.eval(self.problem, c, algorithm=self)
61
+ self.infills = c
62
+
63
+ else:
64
+
65
+ d = quadr_interp(a, b, c)
66
+ self.evaluator.eval(self.problem, d, algorithm=self)
67
+ self.infills = d
68
+
69
+ # swap c and d -> make sure d is always on the right of c -> a, c, d, b
70
+ if c.X[0] > d.X[0]:
71
+ c, d = d, c
72
+
73
+ # if c is better than d, then d becomes the new right bound
74
+ if c.F[0] <= d.F[0]:
75
+ b = d
76
+
77
+ # if d is better than c, then c becomes the new left bound and d the new right bound
78
+ else:
79
+ a, c = c, d
80
+
81
+ self.pop = Population.create(a, b, c)
@@ -0,0 +1,163 @@
1
+ import numpy as np
2
+
3
+ from pymoo.algorithms.base.line import LineSearchProblem
4
+ from pymoo.core.algorithm import Algorithm
5
+ from pymoo.core.evaluator import Evaluator
6
+ from pymoo.core.individual import Individual
7
+ from pymoo.core.solution import SolutionSet
8
+
9
+
10
+ class WolfeSearch(Algorithm):
11
+
12
+ def __init__(self, c1=1e-4, c2=0.9, max_iter=10, **kwargs):
13
+
14
+ super().__init__(**kwargs)
15
+ self.c1 = c1
16
+ self.c2 = c2
17
+ self.max_iter = max_iter
18
+
19
+ def _setup(self, problem, **kwargs):
20
+ assert isinstance(problem,
21
+ LineSearchProblem), "The wolfe search only purpose is to solve a line search problem!"
22
+ self.pop = SolutionSet.create(problem.point)
23
+ self.opt = self.pop
24
+
25
+ def _set_optimum(self, force=False):
26
+ pass
27
+
28
+ def step(self):
29
+ sol = self._infill()
30
+
31
+ self.opt = sol
32
+ self.termination.force_termination = True
33
+
34
+ def _infill(self):
35
+
36
+ problem, evaluator = self.problem, self.evaluator
37
+ evaluator.skip_already_evaluated = False
38
+
39
+ sol, direction = self.problem.point, self.problem.direction
40
+
41
+ # the function value and gradient of the initial solution
42
+ sol.set("alpha", 0.0)
43
+ sol_F, sol_dF = sol.F[0], sol.get("dF")[0]
44
+
45
+ def zoom(alpha_low, alpha_high, max_iter=100):
46
+
47
+ while True:
48
+
49
+ _alpha = (alpha_high.get("alpha") + alpha_low.get("alpha")) / 2
50
+ _point = Individual(X=_alpha)
51
+ evaluator.eval(problem, _point, evaluate_values_of=["F", "CV"])
52
+
53
+ if _point.F[0] > sol_F + self.c1 * _alpha * sol_dF @ direction or _point.F[0] > alpha_low.F[0]:
54
+ alpha_high = _point
55
+ else:
56
+ evaluator.eval(problem, _point, evaluate_values_of=["dF"])
57
+ point_dF = _point.get("dF")[0]
58
+
59
+ if np.abs(point_dF @ direction) <= -self.c2 * sol_dF @ direction:
60
+ return _point
61
+
62
+ if (point_dF @ direction) * (alpha_high.get("alpha") - alpha_low.get("alpha")) >= 0:
63
+ alpha_high = alpha_low
64
+
65
+ alpha_low = _point
66
+
67
+ last = sol
68
+
69
+ alpha = 1.0
70
+ current = Individual(X=alpha)
71
+
72
+ for i in range(1, self.max_iter + 1):
73
+
74
+ # evaluate the solutions
75
+ evaluator.eval(problem, current, evaluate_values_of=["F", "CV"])
76
+
77
+ # get the values from the solution to be used to evaluate the conditions
78
+ F, dF, _F = last.F[0], last.get("dF")[0], current.F[0]
79
+
80
+ # if the wolfe condition is violate we have found our upper bound
81
+ if _F > sol_F + self.c1 * sol_dF @ direction or (i > 1 and F >= _F):
82
+ return zoom(last, current)
83
+
84
+ # for the other condition we need the gradient information
85
+ evaluator.eval(problem, current, evaluate_values_of=["dF"])
86
+ _dF = current.get("dF")[0]
87
+
88
+ if np.abs(_dF @ direction) <= -self.c2 * sol_dF @ direction:
89
+ return current
90
+
91
+ if _dF @ direction >= 0:
92
+ return zoom(current, last)
93
+
94
+ alpha = 2 * alpha
95
+ last = current
96
+ current = Individual(X=alpha)
97
+
98
+ return current
99
+
100
+
101
+ def wolfe_line_search(problem, sol, direction, c1=1e-4, c2=0.9, max_iter=10, evaluator=None):
102
+ # initialize the evaluator to be used (this will make sure evaluations are counted)
103
+ evaluator = evaluator if evaluator is not None else Evaluator()
104
+ evaluator.skip_already_evaluated = False
105
+
106
+ # the function value and gradient of the initial solution
107
+ sol.set("alpha", 0.0)
108
+ sol_F, sol_dF = sol.F[0], sol.get("dF")[0]
109
+
110
+ def zoom(alpha_low, alpha_high, max_iter=100):
111
+
112
+ while True:
113
+
114
+ _alpha = (alpha_high.get("alpha") + alpha_low.get("alpha")) / 2
115
+ _point = Individual(X=sol.X + _alpha * direction, alpha=_alpha)
116
+ evaluator.eval(problem, _point, evaluate_values_of=["F", "CV"])
117
+
118
+ if _point.F[0] > sol_F + c1 * _alpha * sol_dF @ direction or _point.F[0] > alpha_low.F[0]:
119
+ alpha_high = _point
120
+ else:
121
+ evaluator.eval(problem, _point, evaluate_values_of=["dF"])
122
+ point_dF = _point.get("dF")[0]
123
+
124
+ if np.abs(point_dF @ direction) <= -c2 * sol_dF @ direction:
125
+ return _point
126
+
127
+ if (point_dF @ direction) * (alpha_high.get("alpha") - alpha_low.get("alpha")) >= 0:
128
+ alpha_high = alpha_low
129
+
130
+ alpha_low = _point
131
+
132
+ last = sol
133
+
134
+ alpha = 1.0
135
+ current = Individual(X=sol.X + alpha * direction, alpha=alpha)
136
+
137
+ for i in range(1, max_iter + 1):
138
+
139
+ # evaluate the solutions
140
+ evaluator.eval(problem, current, evaluate_values_of=["F", "CV"])
141
+
142
+ # get the values from the solution to be used to evaluate the conditions
143
+ F, dF, _F = last.F[0], last.get("dF")[0], current.F[0]
144
+
145
+ # if the wolfe condition is violate we have found our upper bound
146
+ if _F > sol_F + c1 * sol_dF @ direction or (i > 1 and F >= _F):
147
+ return zoom(last, current)
148
+
149
+ # for the other condition we need the gradient information
150
+ evaluator.eval(problem, current, evaluate_values_of=["dF"])
151
+ _dF = current.get("dF")[0]
152
+
153
+ if np.abs(_dF @ direction) <= -c2 * sol_dF @ direction:
154
+ return current
155
+
156
+ if _dF @ direction >= 0:
157
+ return zoom(current, last)
158
+
159
+ alpha = 2 * alpha
160
+ last = current
161
+ current = Individual(X=sol.X + alpha * direction, alpha=alpha)
162
+
163
+ return current
pymoo/config.py ADDED
@@ -0,0 +1,33 @@
1
+ from os.path import dirname, realpath
2
+
3
+ from pymoo.version import __version__
4
+
5
+
6
+ class Config:
7
+ """
8
+ The configuration of this package in general providing the place
9
+ for declaring global variables.
10
+ """
11
+
12
+ # the root directory where the package is located at
13
+ root = dirname(realpath(__file__))
14
+
15
+ warnings = {
16
+ "not_compiled": True
17
+ }
18
+
19
+ # whether a warning should be printed if compiled modules are not available
20
+ show_compile_hint = True
21
+
22
+ # whether when import a file the doc should be parsed - only activate when creating doc files
23
+ parse_custom_docs = False
24
+
25
+ # a method defining the endpoint to load data remotely - default from GitHub repo
26
+ @classmethod
27
+ def data(cls):
28
+ return f"https://raw.githubusercontent.com/anyoptimization/pymoo-data/main/"
29
+
30
+
31
+ # returns the directory to be used for imports
32
+ def get_pymoo():
33
+ return dirname(Config.root)
@@ -0,0 +1,3 @@
1
+
2
+
3
+
@@ -0,0 +1,62 @@
1
+ from copy import deepcopy
2
+
3
+ import numpy as np
4
+
5
+ from pymoo.core.algorithm import Algorithm
6
+ from pymoo.core.evaluator import Evaluator
7
+ from pymoo.core.individual import Individual
8
+ from pymoo.core.meta import Meta
9
+ from pymoo.core.population import Population
10
+ from pymoo.core.problem import Problem
11
+
12
+
13
+ class AttachConfigEvaluator(Meta, Evaluator):
14
+
15
+ def __init__(self, wrapped, config):
16
+ super().__init__(wrapped)
17
+ self.config = config
18
+
19
+ def eval(self, problem: Problem, pop: Population, **kwargs):
20
+ pop = super().eval(problem, pop, **kwargs)
21
+ pop.apply(lambda ind: ind.set("config", self.config))
22
+
23
+
24
+ def copy_to_dict(src, dest):
25
+ dest.clear()
26
+ dest.update(**src)
27
+
28
+
29
+ class AdaptiveConstraintHandling(Meta, Algorithm):
30
+
31
+ def __init__(self, algorithm):
32
+ super().__init__(algorithm)
33
+
34
+ self.config = Individual.default_config()
35
+ self.config["cache"] = False
36
+
37
+ self.default_config = deepcopy(self.config)
38
+ self.adapted_config = deepcopy(self.config)
39
+
40
+ def _setup(self, _, **kwargs):
41
+ self.evaluator = AttachConfigEvaluator(self.evaluator, self.config)
42
+
43
+ def _adapt_constraint_handling(self, config, infills=None, **kwargs):
44
+ pass
45
+
46
+ def _initialize_advance(self, infills=None, **kwargs):
47
+ copy_to_dict(self.adapted_config, self.config)
48
+ super()._initialize_advance(infills=infills, **kwargs)
49
+ copy_to_dict(self.default_config, self.config)
50
+
51
+ def _advance(self, infills=None, **kwargs):
52
+ copy_to_dict(self.adapted_config, self.config)
53
+ super()._advance(infills=infills, **kwargs)
54
+ copy_to_dict(self.default_config, self.config)
55
+
56
+ self._adapt_constraint_handling(self.adapted_config, infills=infills, **kwargs)
57
+
58
+ def _infill(self):
59
+ copy_to_dict(self.adapted_config, self.config)
60
+ pop = super()._infill()
61
+ copy_to_dict(self.default_config, self.config)
62
+ return pop
@@ -0,0 +1,56 @@
1
+ import pymoo.gradient.toolbox as anp
2
+ import numpy as np
3
+
4
+ from pymoo.core.individual import calc_cv
5
+ from pymoo.core.meta import Meta
6
+ from pymoo.core.problem import Problem
7
+ from pymoo.util.misc import from_dict
8
+
9
+
10
+ class ConstraintsAsObjective(Meta, Problem):
11
+
12
+ def __init__(self,
13
+ problem,
14
+ config=None,
15
+ append=True):
16
+
17
+ super().__init__(problem)
18
+ self.config = config
19
+ self.append = append
20
+
21
+ if append:
22
+ self.n_obj = problem.n_obj + 1
23
+ else:
24
+ self.n_obj = 1
25
+
26
+ self.n_ieq_constr = 0
27
+ self.n_eq_constr = 0
28
+
29
+ def do(self, X, return_values_of, *args, **kwargs):
30
+ out = self.__object__.do(X, return_values_of, *args, **kwargs)
31
+
32
+ # get at the values from the output
33
+ F, G, H = from_dict(out, "F", "G", "H")
34
+
35
+ # store a backup of the values in out
36
+ out["__F__"], out["__G__"], out["__H__"] = F, G, H
37
+
38
+ # calculate the total constraint violation (here normalization shall be already included)
39
+ CV = calc_cv(G=G, H=H, config=self.config)
40
+
41
+ # append the constraint violation as objective
42
+ if self.append:
43
+ out["F"] = anp.column_stack([CV, F])
44
+ else:
45
+ out["F"] = CV
46
+
47
+ del out["G"]
48
+ del out["H"]
49
+
50
+ return out
51
+
52
+ def pareto_front(self, *args, **kwargs):
53
+ pf = super().pareto_front(*args, **kwargs)
54
+ if pf is not None:
55
+ pf = np.column_stack([np.zeros(len(pf)), pf])
56
+ return pf