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
pymoo/core/infill.py ADDED
@@ -0,0 +1,64 @@
1
+ from pymoo.core.duplicate import NoDuplicateElimination
2
+ from pymoo.core.population import Population
3
+ from pymoo.core.repair import NoRepair
4
+
5
+
6
+ class InfillCriterion:
7
+
8
+ def __init__(self,
9
+ repair=None,
10
+ eliminate_duplicates=None,
11
+ n_max_iterations=100,
12
+ **kwargs):
13
+
14
+ super().__init__()
15
+ self.n_max_iterations = n_max_iterations
16
+ self.eliminate_duplicates = eliminate_duplicates if eliminate_duplicates is not None else NoDuplicateElimination()
17
+ self.repair = repair if repair is not None else NoRepair()
18
+
19
+ def __call__(self, problem, pop, n_offsprings, **kwargs):
20
+ return self.do(problem, pop, n_offsprings, **kwargs)
21
+
22
+ def do(self, problem, pop, n_offsprings, **kwargs):
23
+ n_max_iterations = kwargs.get("n_max_iterations", self.n_max_iterations)
24
+
25
+ # the population object to be used
26
+ off = Population.create()
27
+
28
+ # infill counter - counts how often the mating needs to be done to fill up n_offsprings
29
+ n_infills = 0
30
+
31
+ # iterate until enough offsprings are created
32
+ while len(off) < n_offsprings:
33
+
34
+ # how many offsprings are remaining to be created
35
+ n_remaining = n_offsprings - len(off)
36
+
37
+ # do the mating
38
+ _off = self._do(problem, pop, n_remaining, **kwargs)
39
+
40
+ # repair the individuals if necessary - disabled if repair is NoRepair
41
+ _off = self.repair(problem, _off, **kwargs)
42
+
43
+ # eliminate the duplicates
44
+ _off = self.eliminate_duplicates.do(_off, pop, off)
45
+
46
+ # if more offsprings than necessary - truncate them randomly
47
+ if len(off) + len(_off) > n_offsprings:
48
+
49
+ # IMPORTANT: Interestingly, this makes a difference in performance for some algorithms
50
+ n_remaining = n_offsprings - len(off)
51
+ _off = _off[:n_remaining]
52
+
53
+ # add to the offsprings and increase the mating counter
54
+ off = Population.merge(off, _off)
55
+ n_infills += 1
56
+
57
+ # if no new offsprings can be generated within a pre-specified number of generations
58
+ if n_infills >= n_max_iterations:
59
+ break
60
+
61
+ return off
62
+
63
+ def _do(self, problem, pop, n_offsprings, **kwargs):
64
+ pass
@@ -0,0 +1,42 @@
1
+ import numpy as np
2
+
3
+ from pymoo.core.duplicate import NoDuplicateElimination
4
+ from pymoo.core.population import Population
5
+ from pymoo.core.repair import NoRepair
6
+ from pymoo.util.misc import at_least_2d_array
7
+
8
+
9
+ class Initialization:
10
+
11
+ def __init__(self,
12
+ sampling,
13
+ repair=None,
14
+ eliminate_duplicates=None) -> None:
15
+
16
+ super().__init__()
17
+ self.sampling = sampling
18
+ self.eliminate_duplicates = eliminate_duplicates if eliminate_duplicates else NoDuplicateElimination()
19
+ self.repair = repair if repair is not None else NoRepair()
20
+
21
+ def do(self, problem, n_samples, **kwargs):
22
+
23
+ # provide a whole population object - (individuals might be already evaluated)
24
+ if isinstance(self.sampling, Population):
25
+ pop = self.sampling
26
+
27
+ else:
28
+ if isinstance(self.sampling, np.ndarray):
29
+ sampling = at_least_2d_array(self.sampling)
30
+ pop = Population.new(X=sampling)
31
+ else:
32
+ pop = self.sampling(problem, n_samples, **kwargs)
33
+
34
+ # repair all solutions that are not already evaluated
35
+ not_eval_yet = [k for k in range(len(pop)) if len(pop[k].evaluated) == 0]
36
+ if len(not_eval_yet) > 0:
37
+ pop[not_eval_yet] = self.repair(problem, pop[not_eval_yet], **kwargs)
38
+
39
+ # filter duplicate in the population
40
+ pop = self.eliminate_duplicates.do(pop)
41
+
42
+ return pop
pymoo/core/mating.py ADDED
@@ -0,0 +1,39 @@
1
+ import math
2
+
3
+ from pymoo.core.infill import InfillCriterion
4
+
5
+
6
+ class Mating(InfillCriterion):
7
+
8
+ def __init__(self,
9
+ selection,
10
+ crossover,
11
+ mutation,
12
+ **kwargs):
13
+
14
+ super().__init__(**kwargs)
15
+ self.selection = selection
16
+ self.crossover = crossover
17
+ self.mutation = mutation
18
+
19
+ def _do(self, problem, pop, n_offsprings, parents=None, **kwargs):
20
+
21
+ # how many parents need to be select for the mating - depending on number of offsprings remaining
22
+ n_matings = math.ceil(n_offsprings / self.crossover.n_offsprings)
23
+
24
+ # if the parents for the mating are not provided directly - usually selection will be used
25
+ if parents is None:
26
+
27
+ # select the parents for the mating - just an index array
28
+ parents = self.selection(problem, pop, n_matings, n_parents=self.crossover.n_parents, **kwargs)
29
+
30
+ # do the crossover using the parents index and the population - additional data provided if necessary
31
+ off = self.crossover(problem, parents, **kwargs)
32
+
33
+ # do the mutation on the offsprings created through crossover
34
+ off = self.mutation(problem, off, **kwargs)
35
+
36
+ return off
37
+
38
+
39
+
pymoo/core/meta.py ADDED
@@ -0,0 +1,21 @@
1
+ from copy import deepcopy
2
+
3
+
4
+ class Meta(object):
5
+
6
+ def __init__(self, object, copy=True, clazz=None):
7
+ if clazz is None:
8
+ clazz = self.__class__
9
+
10
+ wrapped = object
11
+ if copy:
12
+ wrapped = deepcopy(wrapped)
13
+
14
+ self.__class__ = type(clazz.__name__,
15
+ tuple([clazz] + wrapped.__class__.mro()),
16
+ {})
17
+
18
+ self.__dict__ = wrapped.__dict__
19
+ self.__object__ = object
20
+ self.__super__ = wrapped
21
+
pymoo/core/mixed.py ADDED
@@ -0,0 +1,165 @@
1
+ import math
2
+ from copy import deepcopy
3
+
4
+ import numpy as np
5
+
6
+ from pymoo.algorithms.base.genetic import GeneticAlgorithm
7
+ from pymoo.algorithms.soo.nonconvex.ga import FitnessSurvival
8
+ from pymoo.core.duplicate import ElementwiseDuplicateElimination
9
+ from pymoo.core.individual import Individual
10
+ from pymoo.core.infill import InfillCriterion
11
+ from pymoo.core.population import Population
12
+ from pymoo.core.problem import Problem
13
+ from pymoo.core.sampling import Sampling
14
+ from pymoo.core.variable import Choice, Real, Integer, Binary, BoundedVariable
15
+ from pymoo.operators.crossover.sbx import SBX
16
+ from pymoo.operators.crossover.ux import UX
17
+ from pymoo.operators.mutation.bitflip import BFM
18
+ from pymoo.operators.mutation.pm import PM
19
+ from pymoo.operators.mutation.rm import ChoiceRandomMutation
20
+ from pymoo.operators.repair.rounding import RoundingRepair
21
+ from pymoo.operators.selection.rnd import RandomSelection
22
+ from pymoo.util.display.single import SingleObjectiveOutput
23
+
24
+
25
+ class MixedVariableMating(InfillCriterion):
26
+
27
+ def __init__(self,
28
+ selection=RandomSelection(),
29
+ crossover=None,
30
+ mutation=None,
31
+ repair=None,
32
+ eliminate_duplicates=True,
33
+ n_max_iterations=100,
34
+ **kwargs):
35
+
36
+ super().__init__(repair, eliminate_duplicates, n_max_iterations, **kwargs)
37
+
38
+ if crossover is None:
39
+ crossover = {
40
+ Binary: UX(),
41
+ Real: SBX(),
42
+ Integer: SBX(vtype=float, repair=RoundingRepair()),
43
+ Choice: UX(),
44
+ }
45
+
46
+ if mutation is None:
47
+ mutation = {
48
+ Binary: BFM(),
49
+ Real: PM(),
50
+ Integer: PM(vtype=float, repair=RoundingRepair()),
51
+ Choice: ChoiceRandomMutation(),
52
+ }
53
+
54
+ self.selection = selection
55
+ self.crossover = crossover
56
+ self.mutation = mutation
57
+
58
+ def _do(self, problem, pop, n_offsprings, parents=False, **kwargs):
59
+
60
+ # So far we assume all crossover need the same amount of parents and create the same number of offsprings
61
+ XOVER_N_PARENTS = 2
62
+ XOVER_N_OFFSPRINGS = 2
63
+
64
+ # the variables with the concrete information
65
+ vars = problem.vars
66
+
67
+ # group all the variables by their types
68
+ vars_by_type = {}
69
+ for k, v in vars.items():
70
+ clazz = type(v)
71
+
72
+ if clazz not in vars_by_type:
73
+ vars_by_type[clazz] = []
74
+ vars_by_type[clazz].append(k)
75
+
76
+ # # all different recombinations (the choices need to be split because of data types)
77
+ recomb = []
78
+ for clazz, list_of_vars in vars_by_type.items():
79
+ if clazz == Choice:
80
+ for e in list_of_vars:
81
+ recomb.append((clazz, [e]))
82
+ else:
83
+ recomb.append((clazz, list_of_vars))
84
+
85
+ # create an empty population that will be set in each iteration
86
+ off = Population.new(X=[{} for _ in range(n_offsprings)])
87
+
88
+ if not parents:
89
+ n_select = math.ceil(n_offsprings / XOVER_N_OFFSPRINGS)
90
+ pop = self.selection(problem, pop, n_select, XOVER_N_PARENTS, **kwargs)
91
+
92
+ for clazz, list_of_vars in recomb:
93
+
94
+ crossover = self.crossover[clazz]
95
+ assert crossover.n_parents == XOVER_N_PARENTS and crossover.n_offsprings == XOVER_N_OFFSPRINGS
96
+
97
+ _parents = [
98
+ [Individual(X=np.array([parent.X[var] for var in list_of_vars], dtype="O" if clazz is Choice else None))
99
+ for parent in parents]
100
+ for parents in pop
101
+ ]
102
+
103
+ _vars = {e: vars[e] for e in list_of_vars}
104
+ _xl = np.array([vars[e].lb if hasattr(vars[e], "lb") else None for e in list_of_vars])
105
+ _xu = np.array([vars[e].ub if hasattr(vars[e], "ub") else None for e in list_of_vars])
106
+ _problem = Problem(vars=_vars, xl=_xl, xu=_xu)
107
+
108
+ _off = crossover(_problem, _parents, **kwargs)
109
+
110
+ mutation = self.mutation[clazz]
111
+ _off = mutation(_problem, _off, **kwargs)
112
+
113
+ for k in range(n_offsprings):
114
+ for i, name in enumerate(list_of_vars):
115
+ off[k].X[name] = _off[k].X[i]
116
+
117
+ return off
118
+
119
+
120
+ class MixedVariableSampling(Sampling):
121
+
122
+ def _do(self, problem, n_samples, **kwargs):
123
+ V = {name: var.sample(n_samples) for name, var in problem.vars.items()}
124
+
125
+ X = []
126
+ for k in range(n_samples):
127
+ X.append({name: V[name][k] for name in problem.vars.keys()})
128
+
129
+ return X
130
+
131
+
132
+ class MixedVariableDuplicateElimination(ElementwiseDuplicateElimination):
133
+
134
+ def is_equal(self, a, b):
135
+ a, b = a.X, b.X
136
+ for k, v in a.items():
137
+ if k not in b or b[k] != v:
138
+ return False
139
+ return True
140
+
141
+
142
+ def groups_of_vars(vars):
143
+ ret = {}
144
+ for name, var in vars.items():
145
+ if var.__class__ not in ret:
146
+ ret[var.__class__] = []
147
+
148
+ ret[var.__class__].append((name, var))
149
+
150
+ return ret
151
+
152
+
153
+ class MixedVariableGA(GeneticAlgorithm):
154
+
155
+ def __init__(self,
156
+ pop_size=50,
157
+ n_offsprings=None,
158
+ output=SingleObjectiveOutput(),
159
+ sampling=MixedVariableSampling(),
160
+ mating=MixedVariableMating(eliminate_duplicates=MixedVariableDuplicateElimination()),
161
+ eliminate_duplicates=MixedVariableDuplicateElimination(),
162
+ survival=FitnessSurvival(),
163
+ **kwargs):
164
+ super().__init__(pop_size=pop_size, n_offsprings=n_offsprings, sampling=sampling, mating=mating,
165
+ eliminate_duplicates=eliminate_duplicates, output=output, survival=survival, **kwargs)
pymoo/core/mutation.py ADDED
@@ -0,0 +1,44 @@
1
+ from copy import deepcopy
2
+
3
+ import numpy as np
4
+
5
+ from pymoo.core.operator import Operator
6
+ from pymoo.core.variable import Real, get
7
+
8
+
9
+ class Mutation(Operator):
10
+
11
+ def __init__(self, prob=1.0, prob_var=None, **kwargs) -> None:
12
+ super().__init__(**kwargs)
13
+ self.prob = Real(prob, bounds=(0.7, 1.0), strict=(0.0, 1.0))
14
+ self.prob_var = Real(prob_var, bounds=(0.0, 0.25), strict=(0.0, 1.0)) if prob_var is not None else None
15
+
16
+ def do(self, problem, pop, inplace=True, **kwargs):
17
+
18
+ # if not inplace copy the population first
19
+ if not inplace:
20
+ pop = deepcopy(pop)
21
+
22
+ n_mut = len(pop)
23
+
24
+ # get the variables to be mutated
25
+ X = pop.get("X")
26
+
27
+ # retrieve the mutation variables
28
+ Xp = self._do(problem, X, **kwargs)
29
+
30
+ # the likelihood for a mutation on the individuals
31
+ prob = get(self.prob, size=n_mut)
32
+ mut = np.random.random(size=n_mut) <= prob
33
+
34
+ # store the mutated individual back to the population
35
+ pop[mut].set("X", Xp[mut])
36
+
37
+ return pop
38
+
39
+ def _do(self, problem, X, **kwargs):
40
+ return X
41
+
42
+ def get_prob_var(self, problem, **kwargs):
43
+ prob_var = self.prob_var if self.prob_var is not None else min(0.5, 1 / problem.n_var)
44
+ return get(prob_var, **kwargs)
pymoo/core/operator.py ADDED
@@ -0,0 +1,40 @@
1
+ import abc
2
+
3
+ import numpy as np
4
+
5
+
6
+ class Operator:
7
+
8
+ def __init__(self,
9
+ name=None,
10
+ vtype=None,
11
+ repair=None) -> None:
12
+
13
+ super().__init__()
14
+
15
+ if name is None:
16
+ name = self.__class__.__name__
17
+
18
+ self.name = name
19
+ self.vtype = vtype
20
+ self.repair = repair
21
+
22
+ @abc.abstractmethod
23
+ def do(self, problem, elem, *args, **kwargs):
24
+ pass
25
+
26
+ def __call__(self, problem, elem, *args, to_numpy=False, **kwargs):
27
+ out = self.do(problem, elem, *args, **kwargs)
28
+
29
+ if self.vtype is not None:
30
+ for ind in out:
31
+ ind.X = ind.X.astype(self.vtype)
32
+
33
+ # allow to have a built-in repair (can be useful to customize standard crossover)
34
+ if self.repair is not None:
35
+ self.repair.do(problem, out)
36
+
37
+ if to_numpy:
38
+ out = np.array([ind.X for ind in out])
39
+
40
+ return out
@@ -0,0 +1,134 @@
1
+ from pymoo.core.variable import Variable
2
+
3
+
4
+ # ---------------------------------------------------------------------------------------------------------
5
+ # Functions
6
+ # ---------------------------------------------------------------------------------------------------------
7
+
8
+ def get_data(obj):
9
+ if not isinstance(obj, dict):
10
+ if hasattr(obj, "__dict__"):
11
+ return obj.__dict__
12
+ else:
13
+ return {}
14
+ else:
15
+ return obj
16
+
17
+
18
+ def get_params(obj, flag="default", only_active=True):
19
+ return get_params_bfs(obj, flag, only_active)
20
+
21
+
22
+ def get_params_bfs(obj, flag, only_active):
23
+ ret = {}
24
+
25
+ q = [(None, obj)]
26
+
27
+ visited = set()
28
+
29
+ while len(q) > 0:
30
+
31
+ prefix, obj = q.pop()
32
+
33
+ if isinstance(obj, Variable):
34
+
35
+ if obj not in visited and obj.flag == flag and (not only_active or obj.active):
36
+
37
+ # find the right spot in the ret dictionary
38
+ e = ret
39
+
40
+ for name in prefix[:-1]:
41
+ if name not in e:
42
+ e[name] = {}
43
+ e = e[name]
44
+
45
+ # set it so the value
46
+ e[prefix[-1]] = obj
47
+
48
+ # add it to have been visited
49
+ visited.add(obj)
50
+
51
+ else:
52
+ data = get_data(obj)
53
+ for key in data:
54
+ new_prefix = [key] if prefix is None else prefix + [key]
55
+ entry = (new_prefix, data[key])
56
+ q.append(entry)
57
+
58
+ return ret
59
+
60
+
61
+ def get_params_rec(obj, visited, flag, only_active):
62
+ data = get_data(obj)
63
+
64
+ ret = {}
65
+ for k, v in data.items():
66
+ if isinstance(v, Variable):
67
+
68
+ if v not in visited and v.flag == flag and (not only_active or v.active):
69
+ ret[k] = v
70
+
71
+ visited.add(v)
72
+
73
+ else:
74
+ entry = get_params_rec(v, visited, flag, only_active)
75
+ if entry is not None and len(entry) > 0:
76
+ ret[k] = entry
77
+ return ret
78
+
79
+
80
+ def apply_to_params(obj, func_apply):
81
+ for _, v in flatten_rec(get_params(obj)):
82
+ func_apply(v)
83
+
84
+
85
+ def deactivate_params(obj):
86
+ def func(param):
87
+ param.active = False
88
+
89
+ apply_to_params(obj, func)
90
+
91
+
92
+ def set_params(obj, params, as_value=True):
93
+ data = get_data(obj)
94
+
95
+ for k, v in params.items():
96
+ if isinstance(v, dict):
97
+ set_params(data[k], v)
98
+ else:
99
+ if as_value:
100
+ data[k].set(v)
101
+ else:
102
+ data[k] = v
103
+
104
+
105
+ def flatten(params):
106
+ return {k: v for k, v in flatten_rec(params)}
107
+
108
+
109
+ def flatten_rec(params, prefix=None):
110
+ if hasattr(params, "items"):
111
+ for k, v in params.items():
112
+ yield from flatten_rec(v, prefix=f"{prefix}.{k}" if prefix is not None else k)
113
+ else:
114
+ yield prefix, params
115
+
116
+
117
+ def hierarchical(data):
118
+ ret = {}
119
+
120
+ groups = {}
121
+ for k, v in data.items():
122
+ a = k.split(".")
123
+ if len(a) > 1:
124
+ prefix = a[0]
125
+ if prefix not in groups:
126
+ groups[prefix] = {}
127
+ groups[prefix][".".join(a[1:])] = v
128
+ else:
129
+ ret[k] = v
130
+
131
+ for name, group in groups.items():
132
+ ret[name] = hierarchical(group)
133
+
134
+ return ret