pymoo 0.6.1.6__cp312-cp312-macosx_10_13_universal2.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 (337) 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 +110 -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 +91 -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/cmopso.py +239 -0
  14. pymoo/algorithms/moo/ctaea.py +305 -0
  15. pymoo/algorithms/moo/dnsga2.py +80 -0
  16. pymoo/algorithms/moo/kgb.py +450 -0
  17. pymoo/algorithms/moo/moead.py +183 -0
  18. pymoo/algorithms/moo/mopso_cd.py +309 -0
  19. pymoo/algorithms/moo/nsga2.py +113 -0
  20. pymoo/algorithms/moo/nsga3.py +361 -0
  21. pymoo/algorithms/moo/pinsga2.py +370 -0
  22. pymoo/algorithms/moo/rnsga2.py +188 -0
  23. pymoo/algorithms/moo/rnsga3.py +246 -0
  24. pymoo/algorithms/moo/rvea.py +214 -0
  25. pymoo/algorithms/moo/sms.py +196 -0
  26. pymoo/algorithms/moo/spea2.py +191 -0
  27. pymoo/algorithms/moo/unsga3.py +49 -0
  28. pymoo/algorithms/soo/__init__.py +0 -0
  29. pymoo/algorithms/soo/convex/__init__.py +0 -0
  30. pymoo/algorithms/soo/nonconvex/__init__.py +0 -0
  31. pymoo/algorithms/soo/nonconvex/brkga.py +162 -0
  32. pymoo/algorithms/soo/nonconvex/cmaes.py +556 -0
  33. pymoo/algorithms/soo/nonconvex/de.py +283 -0
  34. pymoo/algorithms/soo/nonconvex/direct.py +148 -0
  35. pymoo/algorithms/soo/nonconvex/es.py +213 -0
  36. pymoo/algorithms/soo/nonconvex/g3pcx.py +94 -0
  37. pymoo/algorithms/soo/nonconvex/ga.py +95 -0
  38. pymoo/algorithms/soo/nonconvex/ga_niching.py +223 -0
  39. pymoo/algorithms/soo/nonconvex/isres.py +74 -0
  40. pymoo/algorithms/soo/nonconvex/nelder.py +251 -0
  41. pymoo/algorithms/soo/nonconvex/nrbo.py +191 -0
  42. pymoo/algorithms/soo/nonconvex/optuna.py +80 -0
  43. pymoo/algorithms/soo/nonconvex/pattern.py +185 -0
  44. pymoo/algorithms/soo/nonconvex/pso.py +337 -0
  45. pymoo/algorithms/soo/nonconvex/pso_ep.py +307 -0
  46. pymoo/algorithms/soo/nonconvex/random_search.py +25 -0
  47. pymoo/algorithms/soo/nonconvex/sres.py +56 -0
  48. pymoo/algorithms/soo/univariate/__init__.py +0 -0
  49. pymoo/algorithms/soo/univariate/exp.py +46 -0
  50. pymoo/algorithms/soo/univariate/golden.py +65 -0
  51. pymoo/algorithms/soo/univariate/quadr_interp.py +81 -0
  52. pymoo/algorithms/soo/univariate/wolfe.py +163 -0
  53. pymoo/config.py +33 -0
  54. pymoo/constraints/__init__.py +3 -0
  55. pymoo/constraints/adaptive.py +66 -0
  56. pymoo/constraints/as_obj.py +56 -0
  57. pymoo/constraints/as_penalty.py +41 -0
  58. pymoo/constraints/eps.py +34 -0
  59. pymoo/constraints/from_bounds.py +36 -0
  60. pymoo/core/__init__.py +0 -0
  61. pymoo/core/algorithm.py +408 -0
  62. pymoo/core/callback.py +38 -0
  63. pymoo/core/crossover.py +79 -0
  64. pymoo/core/decision_making.py +102 -0
  65. pymoo/core/decomposition.py +76 -0
  66. pymoo/core/duplicate.py +163 -0
  67. pymoo/core/evaluator.py +116 -0
  68. pymoo/core/indicator.py +34 -0
  69. pymoo/core/individual.py +784 -0
  70. pymoo/core/infill.py +65 -0
  71. pymoo/core/initialization.py +44 -0
  72. pymoo/core/mating.py +39 -0
  73. pymoo/core/meta.py +21 -0
  74. pymoo/core/mixed.py +164 -0
  75. pymoo/core/mutation.py +44 -0
  76. pymoo/core/operator.py +46 -0
  77. pymoo/core/parameters.py +134 -0
  78. pymoo/core/plot.py +208 -0
  79. pymoo/core/population.py +180 -0
  80. pymoo/core/problem.py +373 -0
  81. pymoo/core/recorder.py +99 -0
  82. pymoo/core/repair.py +23 -0
  83. pymoo/core/replacement.py +96 -0
  84. pymoo/core/result.py +52 -0
  85. pymoo/core/sampling.py +45 -0
  86. pymoo/core/selection.py +61 -0
  87. pymoo/core/solution.py +10 -0
  88. pymoo/core/survival.py +107 -0
  89. pymoo/core/termination.py +70 -0
  90. pymoo/core/variable.py +415 -0
  91. pymoo/decomposition/__init__.py +0 -0
  92. pymoo/decomposition/aasf.py +24 -0
  93. pymoo/decomposition/asf.py +10 -0
  94. pymoo/decomposition/pbi.py +13 -0
  95. pymoo/decomposition/perp_dist.py +13 -0
  96. pymoo/decomposition/tchebicheff.py +11 -0
  97. pymoo/decomposition/util.py +13 -0
  98. pymoo/decomposition/weighted_sum.py +8 -0
  99. pymoo/docs.py +187 -0
  100. pymoo/experimental/__init__.py +0 -0
  101. pymoo/experimental/algorithms/__init__.py +0 -0
  102. pymoo/experimental/algorithms/gde3.py +57 -0
  103. pymoo/functions/__init__.py +135 -0
  104. pymoo/functions/compiled/__init__.py +0 -0
  105. pymoo/functions/compiled/calc_perpendicular_distance.cpp +27464 -0
  106. pymoo/functions/compiled/calc_perpendicular_distance.cpython-312-darwin.so +0 -0
  107. pymoo/functions/compiled/decomposition.cpp +28853 -0
  108. pymoo/functions/compiled/decomposition.cpython-312-darwin.so +0 -0
  109. pymoo/functions/compiled/info.cpp +7058 -0
  110. pymoo/functions/compiled/info.cpython-312-darwin.so +0 -0
  111. pymoo/functions/compiled/mnn.cpp +30095 -0
  112. pymoo/functions/compiled/mnn.cpython-312-darwin.so +0 -0
  113. pymoo/functions/compiled/non_dominated_sorting.cpp +35692 -0
  114. pymoo/functions/compiled/non_dominated_sorting.cpython-312-darwin.so +0 -0
  115. pymoo/functions/compiled/pruning_cd.cpp +29248 -0
  116. pymoo/functions/compiled/pruning_cd.cpython-312-darwin.so +0 -0
  117. pymoo/functions/compiled/stochastic_ranking.cpp +28042 -0
  118. pymoo/functions/compiled/stochastic_ranking.cpython-312-darwin.so +0 -0
  119. pymoo/functions/standard/__init__.py +1 -0
  120. pymoo/functions/standard/calc_perpendicular_distance.py +20 -0
  121. pymoo/functions/standard/decomposition.py +18 -0
  122. pymoo/functions/standard/hv.py +5 -0
  123. pymoo/functions/standard/mnn.py +78 -0
  124. pymoo/functions/standard/non_dominated_sorting.py +474 -0
  125. pymoo/functions/standard/pruning_cd.py +93 -0
  126. pymoo/functions/standard/stochastic_ranking.py +42 -0
  127. pymoo/gradient/__init__.py +24 -0
  128. pymoo/gradient/automatic.py +85 -0
  129. pymoo/gradient/grad_autograd.py +105 -0
  130. pymoo/gradient/grad_complex.py +35 -0
  131. pymoo/gradient/grad_jax.py +51 -0
  132. pymoo/gradient/numpy.py +22 -0
  133. pymoo/gradient/toolbox/__init__.py +19 -0
  134. pymoo/indicators/__init__.py +0 -0
  135. pymoo/indicators/distance_indicator.py +55 -0
  136. pymoo/indicators/gd.py +7 -0
  137. pymoo/indicators/gd_plus.py +7 -0
  138. pymoo/indicators/hv/__init__.py +59 -0
  139. pymoo/indicators/hv/approximate.py +105 -0
  140. pymoo/indicators/hv/exact.py +68 -0
  141. pymoo/indicators/hv/exact_2d.py +102 -0
  142. pymoo/indicators/igd.py +7 -0
  143. pymoo/indicators/igd_plus.py +7 -0
  144. pymoo/indicators/kktpm.py +151 -0
  145. pymoo/indicators/migd.py +55 -0
  146. pymoo/indicators/rmetric.py +203 -0
  147. pymoo/indicators/spacing.py +52 -0
  148. pymoo/mcdm/__init__.py +0 -0
  149. pymoo/mcdm/compromise_programming.py +19 -0
  150. pymoo/mcdm/high_tradeoff.py +40 -0
  151. pymoo/mcdm/pseudo_weights.py +32 -0
  152. pymoo/operators/__init__.py +0 -0
  153. pymoo/operators/control.py +190 -0
  154. pymoo/operators/crossover/__init__.py +0 -0
  155. pymoo/operators/crossover/binx.py +47 -0
  156. pymoo/operators/crossover/dex.py +125 -0
  157. pymoo/operators/crossover/erx.py +164 -0
  158. pymoo/operators/crossover/expx.py +53 -0
  159. pymoo/operators/crossover/hux.py +37 -0
  160. pymoo/operators/crossover/nox.py +25 -0
  161. pymoo/operators/crossover/ox.py +88 -0
  162. pymoo/operators/crossover/pcx.py +84 -0
  163. pymoo/operators/crossover/pntx.py +49 -0
  164. pymoo/operators/crossover/sbx.py +137 -0
  165. pymoo/operators/crossover/spx.py +5 -0
  166. pymoo/operators/crossover/ux.py +20 -0
  167. pymoo/operators/mutation/__init__.py +0 -0
  168. pymoo/operators/mutation/bitflip.py +17 -0
  169. pymoo/operators/mutation/gauss.py +60 -0
  170. pymoo/operators/mutation/inversion.py +42 -0
  171. pymoo/operators/mutation/nom.py +7 -0
  172. pymoo/operators/mutation/pm.py +96 -0
  173. pymoo/operators/mutation/rm.py +23 -0
  174. pymoo/operators/repair/__init__.py +0 -0
  175. pymoo/operators/repair/bounce_back.py +32 -0
  176. pymoo/operators/repair/bounds_repair.py +97 -0
  177. pymoo/operators/repair/inverse_penalty.py +91 -0
  178. pymoo/operators/repair/rounding.py +18 -0
  179. pymoo/operators/repair/to_bound.py +31 -0
  180. pymoo/operators/repair/vtype.py +11 -0
  181. pymoo/operators/sampling/__init__.py +0 -0
  182. pymoo/operators/sampling/lhs.py +76 -0
  183. pymoo/operators/sampling/rnd.py +52 -0
  184. pymoo/operators/selection/__init__.py +0 -0
  185. pymoo/operators/selection/rnd.py +75 -0
  186. pymoo/operators/selection/tournament.py +78 -0
  187. pymoo/operators/survival/__init__.py +0 -0
  188. pymoo/operators/survival/rank_and_crowding/__init__.py +1 -0
  189. pymoo/operators/survival/rank_and_crowding/classes.py +212 -0
  190. pymoo/operators/survival/rank_and_crowding/metrics.py +208 -0
  191. pymoo/optimize.py +72 -0
  192. pymoo/parallelization/__init__.py +15 -0
  193. pymoo/parallelization/dask.py +25 -0
  194. pymoo/parallelization/joblib.py +28 -0
  195. pymoo/parallelization/ray.py +31 -0
  196. pymoo/parallelization/starmap.py +24 -0
  197. pymoo/problems/__init__.py +157 -0
  198. pymoo/problems/dyn.py +47 -0
  199. pymoo/problems/dynamic/__init__.py +0 -0
  200. pymoo/problems/dynamic/cec2015.py +108 -0
  201. pymoo/problems/dynamic/df.py +451 -0
  202. pymoo/problems/dynamic/misc.py +167 -0
  203. pymoo/problems/functional.py +48 -0
  204. pymoo/problems/many/__init__.py +5 -0
  205. pymoo/problems/many/cdtlz.py +159 -0
  206. pymoo/problems/many/dcdtlz.py +88 -0
  207. pymoo/problems/many/dtlz.py +264 -0
  208. pymoo/problems/many/wfg.py +553 -0
  209. pymoo/problems/multi/__init__.py +14 -0
  210. pymoo/problems/multi/bnh.py +34 -0
  211. pymoo/problems/multi/carside.py +48 -0
  212. pymoo/problems/multi/clutch.py +104 -0
  213. pymoo/problems/multi/csi.py +55 -0
  214. pymoo/problems/multi/ctp.py +198 -0
  215. pymoo/problems/multi/dascmop.py +213 -0
  216. pymoo/problems/multi/kursawe.py +25 -0
  217. pymoo/problems/multi/modact.py +68 -0
  218. pymoo/problems/multi/mw.py +400 -0
  219. pymoo/problems/multi/omnitest.py +48 -0
  220. pymoo/problems/multi/osy.py +32 -0
  221. pymoo/problems/multi/srn.py +28 -0
  222. pymoo/problems/multi/sympart.py +94 -0
  223. pymoo/problems/multi/tnk.py +24 -0
  224. pymoo/problems/multi/truss2d.py +83 -0
  225. pymoo/problems/multi/welded_beam.py +41 -0
  226. pymoo/problems/multi/wrm.py +36 -0
  227. pymoo/problems/multi/zdt.py +151 -0
  228. pymoo/problems/multi_to_single.py +22 -0
  229. pymoo/problems/single/__init__.py +12 -0
  230. pymoo/problems/single/ackley.py +24 -0
  231. pymoo/problems/single/cantilevered_beam.py +34 -0
  232. pymoo/problems/single/flowshop_scheduling.py +113 -0
  233. pymoo/problems/single/g.py +874 -0
  234. pymoo/problems/single/griewank.py +18 -0
  235. pymoo/problems/single/himmelblau.py +15 -0
  236. pymoo/problems/single/knapsack.py +49 -0
  237. pymoo/problems/single/mopta08.py +26 -0
  238. pymoo/problems/single/multimodal.py +20 -0
  239. pymoo/problems/single/pressure_vessel.py +30 -0
  240. pymoo/problems/single/rastrigin.py +20 -0
  241. pymoo/problems/single/rosenbrock.py +22 -0
  242. pymoo/problems/single/schwefel.py +18 -0
  243. pymoo/problems/single/simple.py +13 -0
  244. pymoo/problems/single/sphere.py +19 -0
  245. pymoo/problems/single/traveling_salesman.py +79 -0
  246. pymoo/problems/single/zakharov.py +19 -0
  247. pymoo/problems/static.py +14 -0
  248. pymoo/problems/util.py +42 -0
  249. pymoo/problems/zero_to_one.py +27 -0
  250. pymoo/termination/__init__.py +23 -0
  251. pymoo/termination/collection.py +12 -0
  252. pymoo/termination/cv.py +48 -0
  253. pymoo/termination/default.py +45 -0
  254. pymoo/termination/delta.py +64 -0
  255. pymoo/termination/fmin.py +16 -0
  256. pymoo/termination/ftol.py +144 -0
  257. pymoo/termination/indicator.py +49 -0
  258. pymoo/termination/max_eval.py +14 -0
  259. pymoo/termination/max_gen.py +15 -0
  260. pymoo/termination/max_time.py +20 -0
  261. pymoo/termination/robust.py +34 -0
  262. pymoo/termination/xtol.py +33 -0
  263. pymoo/util/__init__.py +33 -0
  264. pymoo/util/archive.py +152 -0
  265. pymoo/util/cache.py +29 -0
  266. pymoo/util/clearing.py +82 -0
  267. pymoo/util/display/__init__.py +0 -0
  268. pymoo/util/display/column.py +52 -0
  269. pymoo/util/display/display.py +34 -0
  270. pymoo/util/display/multi.py +100 -0
  271. pymoo/util/display/output.py +53 -0
  272. pymoo/util/display/progress.py +54 -0
  273. pymoo/util/display/single.py +67 -0
  274. pymoo/util/dominator.py +67 -0
  275. pymoo/util/hv.py +21 -0
  276. pymoo/util/matlab_engine.py +39 -0
  277. pymoo/util/misc.py +447 -0
  278. pymoo/util/nds/__init__.py +0 -0
  279. pymoo/util/nds/dominance_degree_non_dominated_sort.py +159 -0
  280. pymoo/util/nds/efficient_non_dominated_sort.py +152 -0
  281. pymoo/util/nds/fast_non_dominated_sort.py +70 -0
  282. pymoo/util/nds/find_non_dominated.py +54 -0
  283. pymoo/util/nds/naive_non_dominated_sort.py +36 -0
  284. pymoo/util/nds/non_dominated_sorting.py +94 -0
  285. pymoo/util/nds/tree_based_non_dominated_sort.py +133 -0
  286. pymoo/util/normalization.py +312 -0
  287. pymoo/util/optimum.py +42 -0
  288. pymoo/util/randomized_argsort.py +63 -0
  289. pymoo/util/ref_dirs/__init__.py +24 -0
  290. pymoo/util/ref_dirs/construction.py +89 -0
  291. pymoo/util/ref_dirs/das_dennis.py +52 -0
  292. pymoo/util/ref_dirs/energy.py +317 -0
  293. pymoo/util/ref_dirs/energy_layer.py +119 -0
  294. pymoo/util/ref_dirs/genetic_algorithm.py +64 -0
  295. pymoo/util/ref_dirs/incremental.py +69 -0
  296. pymoo/util/ref_dirs/misc.py +128 -0
  297. pymoo/util/ref_dirs/optimizer.py +59 -0
  298. pymoo/util/ref_dirs/performance.py +162 -0
  299. pymoo/util/ref_dirs/reduction.py +85 -0
  300. pymoo/util/ref_dirs/sample_and_map.py +24 -0
  301. pymoo/util/reference_direction.py +258 -0
  302. pymoo/util/remote.py +55 -0
  303. pymoo/util/roulette.py +29 -0
  304. pymoo/util/running_metric.py +128 -0
  305. pymoo/util/sliding_window.py +25 -0
  306. pymoo/util/value_functions.py +720 -0
  307. pymoo/util/vectors.py +40 -0
  308. pymoo/util/vf_dominator.py +102 -0
  309. pymoo/vendor/__init__.py +0 -0
  310. pymoo/vendor/cec2018.py +398 -0
  311. pymoo/vendor/gta.py +617 -0
  312. pymoo/vendor/vendor_cmaes.py +421 -0
  313. pymoo/vendor/vendor_coco.py +81 -0
  314. pymoo/vendor/vendor_scipy.py +232 -0
  315. pymoo/version.py +1 -0
  316. pymoo/visualization/__init__.py +21 -0
  317. pymoo/visualization/app/__init__.py +0 -0
  318. pymoo/visualization/app/pso.py +61 -0
  319. pymoo/visualization/fitness_landscape.py +128 -0
  320. pymoo/visualization/heatmap.py +123 -0
  321. pymoo/visualization/matplotlib.py +61 -0
  322. pymoo/visualization/pcp.py +121 -0
  323. pymoo/visualization/petal.py +91 -0
  324. pymoo/visualization/radar.py +108 -0
  325. pymoo/visualization/radviz.py +68 -0
  326. pymoo/visualization/scatter.py +150 -0
  327. pymoo/visualization/star_coordinate.py +75 -0
  328. pymoo/visualization/util.py +296 -0
  329. pymoo/visualization/video/__init__.py +0 -0
  330. pymoo/visualization/video/callback_video.py +82 -0
  331. pymoo/visualization/video/one_var_one_obj.py +57 -0
  332. pymoo/visualization/video/two_var_one_obj.py +62 -0
  333. pymoo-0.6.1.6.dist-info/METADATA +209 -0
  334. pymoo-0.6.1.6.dist-info/RECORD +337 -0
  335. pymoo-0.6.1.6.dist-info/WHEEL +6 -0
  336. pymoo-0.6.1.6.dist-info/licenses/LICENSE +191 -0
  337. pymoo-0.6.1.6.dist-info/top_level.txt +1 -0
@@ -0,0 +1,190 @@
1
+ import math
2
+ from abc import abstractmethod
3
+
4
+ import numpy as np
5
+
6
+ from pymoo.core.duplicate import NoDuplicateElimination
7
+ from pymoo.core.individual import Individual
8
+ from pymoo.core.infill import InfillCriterion
9
+ from pymoo.core.mixed import MixedVariableMating
10
+ from pymoo.core.parameters import get_params, flatten
11
+ from pymoo.core.problem import Problem
12
+ from pymoo.core.variable import Choice, Real, Integer, Binary
13
+ from pymoo.operators.crossover.sbx import SBX
14
+ from pymoo.operators.crossover.ux import UX
15
+ from pymoo.operators.mutation.bitflip import BFM
16
+ from pymoo.operators.mutation.pm import PM
17
+ from pymoo.operators.mutation.rm import ChoiceRandomMutation
18
+ from pymoo.operators.repair.rounding import RoundingRepair
19
+ from pymoo.operators.selection.tournament import TournamentSelection, compare
20
+ from pymoo.util import default_random_state
21
+
22
+
23
+ class ParameterControl:
24
+
25
+ def __init__(self, obj) -> None:
26
+ super().__init__()
27
+
28
+ self.data = None
29
+
30
+ params = flatten({"ParameterControl": get_params(obj)})
31
+ self.params = params
32
+
33
+ # print("PARAMETER CONTROL:", list(self.params))
34
+
35
+ @default_random_state
36
+ def do(self, N, set_to_params=True, random_state=None):
37
+ vals = self._do(N, random_state=random_state)
38
+ if set_to_params:
39
+ if vals is not None:
40
+ for k, v in vals.items():
41
+ self.params[k].set(v)
42
+ return vals
43
+
44
+ @abstractmethod
45
+ def _do(self, N, random_state=None):
46
+ pass
47
+
48
+ def tell(self, **kwargs):
49
+ self.data = dict(kwargs)
50
+
51
+ def advance(self, infills=None):
52
+ for k, v in self.params.items():
53
+ assert len(v.get()) == len(
54
+ infills), "Make sure that the infills and parameters asked for have the same size."
55
+ infills.set(k, v.get())
56
+
57
+
58
+ class NoParameterControl(ParameterControl):
59
+
60
+ def __init__(self, _) -> None:
61
+ super().__init__(None)
62
+
63
+ def _do(self, N, random_state=None):
64
+ return {}
65
+
66
+
67
+ class RandomParameterControl(ParameterControl):
68
+
69
+ def _do(self, N, random_state=None):
70
+ return {key: value.sample(N, random_state=random_state) for key, value in self.params.items()}
71
+
72
+
73
+ class EvolutionaryParameterControl(ParameterControl):
74
+
75
+ def __init__(self, obj) -> None:
76
+ super().__init__(obj)
77
+ self.eps = 0.05
78
+
79
+ def _do(self, N, random_state=None):
80
+ params = self.params
81
+ pop = self.data.get("pop")
82
+
83
+ # make sure that for each parameter a value exists - if not simply set it randomly
84
+ for name, param in params.items():
85
+ is_none = np.where(pop.get(name) == None)[0]
86
+ if len(is_none) > 0:
87
+ pop[is_none].set(name, param.sample(len(is_none), random_state=random_state))
88
+
89
+ selection = AgeBasedTournamentSelection()
90
+
91
+ crossover = {
92
+ Binary: UX(),
93
+ Real: SBX(),
94
+ Integer: SBX(vtype=float, repair=RoundingRepair()),
95
+ Choice: UX(),
96
+ }
97
+
98
+ mutation = {
99
+ Binary: BFM(),
100
+ Real: PM(),
101
+ Integer: PM(vtype=float, repair=RoundingRepair()),
102
+ Choice: ChoiceRandomMutation(),
103
+ }
104
+
105
+ mating = MixedVariableMating(
106
+ crossover=crossover,
107
+ mutation=mutation,
108
+ eliminate_duplicates=NoDuplicateElimination()
109
+ )
110
+
111
+ problem = Problem(vars=params)
112
+
113
+ parents = selection(problem, pop, N, n_parents=2, random_state=random_state)
114
+ parents = [[Individual(X={key: parent.get(key) for key in params}) for parent in mating] for mating in parents]
115
+
116
+ off = mating(problem, parents, N, parents=True, random_state=random_state)
117
+
118
+ Xp = off.get("X")
119
+ ret = {param: np.array([Xp[i][param] for i in range(len(Xp))]) for param in params}
120
+
121
+ return ret
122
+
123
+
124
+ class AgeBasedTournamentSelection(TournamentSelection):
125
+
126
+ def __init__(self, pressure=2):
127
+ super().__init__(age_binary_tournament, pressure)
128
+
129
+
130
+ def age_binary_tournament(pop, P, **kwargs):
131
+ n_tournaments, n_parents = P.shape
132
+
133
+ if n_parents != 2:
134
+ raise ValueError("Only implemented for binary tournament!")
135
+
136
+ S = np.full(n_tournaments, np.nan)
137
+ random_state = kwargs.get('random_state', None)
138
+
139
+ for i in range(n_tournaments):
140
+ a, b = P[i, 0], P[i, 1]
141
+ a_gen, b_gen = pop[a].get("n_gen"), pop[b].get("n_gen")
142
+ S[i] = compare(a, a_gen, b, b_gen, method='larger_is_better', return_random_if_equal=True, random_state=random_state)
143
+
144
+ return S[:, None].astype(int, copy=False)
145
+
146
+
147
+ class ParameterControlMating(InfillCriterion):
148
+
149
+ def __init__(self,
150
+ selection,
151
+ crossover,
152
+ mutation,
153
+ control=NoParameterControl,
154
+ **kwargs):
155
+ super().__init__(**kwargs)
156
+ self.selection = selection
157
+ self.crossover = crossover
158
+ self.mutation = mutation
159
+ self.control = control(self)
160
+
161
+ def _do(self, problem, pop, n_offsprings, parents=None, **kwargs):
162
+
163
+ # how many parents need to be select for the mating - depending on number of offsprings remaining
164
+ n_matings = math.ceil(n_offsprings / self.crossover.n_offsprings)
165
+
166
+ # do the parameter control for the mating
167
+ control = self.control
168
+ control.tell(pop=pop)
169
+ control.do(n_matings)
170
+
171
+ # if the parents for the mating are not provided directly - usually selection will be used
172
+ if parents is None:
173
+
174
+ # select the parents for the mating - just an index array
175
+ parents = self.selection.do(problem, pop, n_matings, n_parents=self.crossover.n_parents, **kwargs)
176
+
177
+ # do the crossover using the parents index and the population - additional data provided if necessary
178
+ off = self.crossover(problem, parents, **kwargs)
179
+
180
+ # now we have to consider during parameter control that a crossover can produce multiple offsprings
181
+ for name, param in control.params.items():
182
+ param.set(np.repeat(param.get(), self.crossover.n_offsprings))
183
+
184
+ # do the mutation on the offsprings created through crossover
185
+ off = self.mutation(problem, off, **kwargs)
186
+
187
+ # finally attach the parameters back to the offsprings
188
+ control.advance(off)
189
+
190
+ return off
File without changes
@@ -0,0 +1,47 @@
1
+ import numpy as np
2
+
3
+ from pymoo.core.crossover import Crossover
4
+ from pymoo.core.variable import Real, get
5
+ from pymoo.util import default_random_state
6
+ from pymoo.util.misc import row_at_least_once_true
7
+
8
+
9
+ @default_random_state
10
+ def mut_binomial(n, m, prob, at_least_once=True, random_state=None):
11
+ prob = np.ones(n) * prob
12
+ M = random_state.random((n, m)) < prob[:, None]
13
+
14
+ if at_least_once:
15
+ M = row_at_least_once_true(M, random_state=random_state)
16
+
17
+ return M
18
+
19
+
20
+ class BinomialCrossover(Crossover):
21
+
22
+ def __init__(self, bias=0.5, n_offsprings=2, **kwargs):
23
+ super().__init__(2, n_offsprings, **kwargs)
24
+ self.bias = Real(bias, bounds=(0.1, 0.9), strict=(0.0, 1.0))
25
+
26
+ def _do(self, problem, X, *args, random_state=None, **kwargs):
27
+ _, n_matings, n_var = X.shape
28
+
29
+ bias = get(self.bias, size=n_matings)
30
+ M = mut_binomial(n_matings, n_var, bias, at_least_once=True, random_state=random_state)
31
+
32
+ if self.n_offsprings == 1:
33
+ Xp = X[0].copy()
34
+ Xp[~M] = X[1][~M]
35
+ Xp = Xp[None, ...]
36
+ elif self.n_offsprings == 2:
37
+ Xp = np.copy(X)
38
+ Xp[0][~M] = X[1][~M]
39
+ Xp[1][~M] = X[0][~M]
40
+ else:
41
+ raise Exception
42
+
43
+ return Xp
44
+
45
+
46
+ class BX(BinomialCrossover):
47
+ pass
@@ -0,0 +1,125 @@
1
+ import numpy as np
2
+
3
+ from pymoo.core.crossover import Crossover
4
+ from pymoo.core.population import Population
5
+ from pymoo.operators.crossover.binx import mut_binomial
6
+ from pymoo.operators.crossover.expx import mut_exp
7
+ from pymoo.operators.repair.bounds_repair import is_out_of_bounds_by_problem, repair_random_init
8
+ from pymoo.util import default_random_state
9
+
10
+
11
+ @default_random_state
12
+ def de_differential(X, F, dither=None, jitter=True, gamma=0.0001, return_differentials=False, random_state=None):
13
+ n_parents, n_matings, n_var = X.shape
14
+ assert n_parents % 2 == 1, "For the differential an odd number of values need to be provided"
15
+
16
+ # make sure F is a one-dimensional vector
17
+ F = np.ones(n_matings) * F
18
+
19
+ # build the pairs for the differentials
20
+ pairs = (np.arange(n_parents - 1) + 1).reshape(-1, 2)
21
+
22
+ # the differentials from each pair subtraction
23
+ diffs = np.zeros((n_matings, n_var))
24
+
25
+ # for each difference
26
+ for i, j in pairs:
27
+
28
+ if dither == "vector":
29
+ F = (F + random_state.random(n_matings) * (1 - F))
30
+ elif dither == "scalar":
31
+ F = F + random_state.random() * (1 - F)
32
+
33
+ # http://www.cs.ndsu.nodak.edu/~siludwig/Publish/papers/SSCI20141.pdf
34
+ if jitter:
35
+ F = (F * (1 + gamma * (random_state.random(n_matings) - 0.5)))
36
+
37
+ # an add the difference to the first vector
38
+ diffs += F[:, None] * (X[i] - X[j])
39
+
40
+ # now add the differentials to the first parent
41
+ Xp = X[0] + diffs
42
+
43
+ if return_differentials:
44
+ return Xp, diffs
45
+ else:
46
+ return Xp
47
+
48
+
49
+ class DEX(Crossover):
50
+
51
+ def __init__(self,
52
+ F=None,
53
+ CR=0.7,
54
+ variant="bin",
55
+ dither=None,
56
+ jitter=False,
57
+ n_diffs=1,
58
+ n_iter=1,
59
+ at_least_once=True,
60
+ **kwargs):
61
+
62
+ super().__init__(1 + 2 * n_diffs, 1, **kwargs)
63
+ self.n_diffs = n_diffs
64
+ self.F = F
65
+ self.CR = CR
66
+ self.variant = variant
67
+ self.at_least_once = at_least_once
68
+ self.dither = dither
69
+ self.jitter = jitter
70
+ self.n_iter = n_iter
71
+
72
+ def do(self, problem, pop, parents=None, *args, random_state, **kwargs):
73
+
74
+ # if a parents with array with mating indices is provided -> transform the input first
75
+ if parents is not None:
76
+ pop = [pop[mating] for mating in parents]
77
+
78
+ # get the actual values from each of the parents
79
+ X = np.swapaxes(np.array([[parent.get("X") for parent in mating] for mating in pop]), 0, 1).copy()
80
+
81
+ n_parents, n_matings, n_var = X.shape
82
+
83
+ # a mask over matings that need to be repeated
84
+ m = np.arange(n_matings)
85
+
86
+ # if the user provides directly an F value to use
87
+ F = self.F if self.F is not None else rnd_F(m, random_state=random_state)
88
+
89
+ # prepare the out to be set
90
+ Xp = de_differential(X[:, m], F, random_state=random_state)
91
+
92
+ # if the problem has boundaries to be considered
93
+ if problem.has_bounds():
94
+
95
+ for k in range(self.n_iter):
96
+ # find the individuals which are still infeasible
97
+ m = is_out_of_bounds_by_problem(problem, Xp)
98
+
99
+ F = rnd_F(m, random_state=random_state)
100
+
101
+ # actually execute the differential equation
102
+ Xp[m] = de_differential(X[:, m], F, random_state=random_state)
103
+
104
+ # if still infeasible do a random initialization
105
+ Xp = repair_random_init(Xp, X[0], *problem.bounds())
106
+
107
+ if self.variant == "bin":
108
+ M = mut_binomial(n_matings, n_var, self.CR, at_least_once=self.at_least_once, random_state=random_state)
109
+ elif self.variant == "exp":
110
+ M = mut_exp(n_matings, n_var, self.CR, at_least_once=self.at_least_once, random_state=random_state)
111
+ else:
112
+ raise Exception(f"Unknown variant: {self.variant}")
113
+
114
+ # take the first parents (this is already a copy)
115
+ X = X[0]
116
+
117
+ # set the corresponding values from the donor vector
118
+ X[M] = Xp[M]
119
+
120
+ return Population.new("X", X)
121
+
122
+
123
+ @default_random_state
124
+ def rnd_F(m, random_state=None):
125
+ return 0.5 * (1 + random_state.uniform(size=len(m)))
@@ -0,0 +1,164 @@
1
+ import numpy as np
2
+
3
+ from pymoo.core.crossover import Crossover
4
+ from pymoo.util import default_random_state
5
+
6
+
7
+ def remove_from_adj_list(H, val):
8
+ for e in list(H[val]):
9
+ H[e].remove(val)
10
+ del H[val]
11
+
12
+
13
+ def has_duplicates(x):
14
+ H = set()
15
+ for v in x:
16
+ if v in H:
17
+ return True
18
+ H.add(v)
19
+ return False
20
+
21
+
22
+ @default_random_state
23
+ def erx(a, b, random_state=None):
24
+ """
25
+ http://www.rubicite.com/Tutorials/GeneticAlgorithms/CrossoverOperators/EdgeRecombinationCrossoverOperator.aspx
26
+
27
+ Algorithm Pseudo Code:
28
+
29
+ 1. X = the first node from a random parent.
30
+
31
+ 2. While the CHILD chromo isn't full, Loop:
32
+ - Append X to CHILD
33
+ - Remove X from Neighbor Lists
34
+
35
+ if X's neighbor list is empty:
36
+ - Xp = random node not already in CHILD
37
+ else
38
+ - Determine neighbor of X that has fewest neighbors
39
+ - If there is a tie, randomly choose 1
40
+ - Xp = chosen node
41
+ X = Xp
42
+ """
43
+
44
+ assert len(a) == len(b)
45
+
46
+ # calculate the edge matrix considering both permutation
47
+ H = calc_adjency_matrix(a)
48
+ H = calc_adjency_matrix(b, H=H)
49
+
50
+ # randomly select the first node
51
+ _next = random_state.choice(list(H.keys()))
52
+
53
+ y = []
54
+ while True:
55
+
56
+ # append to the child
57
+ y.append(_next)
58
+
59
+ # break if the child was successfully created.
60
+ if len(y) == len(a):
61
+ break
62
+
63
+ # get the neighbors to consider and remove them from the lists
64
+ neighbors = list(H[_next])
65
+ remove_from_adj_list(H, _next)
66
+
67
+ # if the current node does not have any neighbors
68
+ if len(neighbors) == 0:
69
+ _next = random_state.choice(list(H.keys()))
70
+
71
+ # otherwise search in the neighbors for a node with the fewest neighbors
72
+ else:
73
+ # search for the one with minimum neighbors
74
+ n_neighbors = [len(H[e]) for e in neighbors]
75
+ min_n_neighbors = min(n_neighbors)
76
+ _next = [neighbors[k] for k in range(len(neighbors)) if n_neighbors[k] == min_n_neighbors]
77
+
78
+ # break the tie if they might have the same number of neighbors
79
+ _next = random_state.choice(_next)
80
+
81
+ return y
82
+
83
+
84
+ class EdgeRecombinationCrossover(Crossover):
85
+
86
+ def __init__(self, **kwargs):
87
+ super().__init__(2, 1, **kwargs)
88
+
89
+ def _do(self, problem, X, random_state=None, **kwargs):
90
+ _, n_matings, n_var = X.shape
91
+ Y = np.full((self.n_offsprings, n_matings, n_var), -1, dtype=int)
92
+
93
+ for i in range(n_matings):
94
+ a, b = X[:, i, :]
95
+ Y[0, i, :] = erx(a, b, random_state=random_state)
96
+
97
+ return Y
98
+
99
+ class ERX(EdgeRecombinationCrossover):
100
+ pass
101
+
102
+ def number_to_letter(n):
103
+ return chr(ord('@') + n)
104
+
105
+
106
+ def numbers_to_letters(numbers):
107
+ return [number_to_letter(n) for n in numbers]
108
+
109
+
110
+ def letter_to_number(char):
111
+ return ord(char.lower()) - 96
112
+
113
+
114
+ def letters_to_numbers(letters):
115
+ return np.array([letter_to_number(char) for char in letters])
116
+
117
+
118
+ def calc_adjency_matrix(x, H=None):
119
+ H = {} if H is None else H
120
+
121
+ for k in range(len(x)):
122
+ prev = (k - 1) % len(x)
123
+ succ = (k + 1) % len(x)
124
+
125
+ if x[k] not in H:
126
+ H[x[k]] = set()
127
+ H[x[k]].update([x[prev], x[succ]])
128
+
129
+ return H
130
+
131
+
132
+ if __name__ == "__main__":
133
+ a = ['A', 'B', 'F', 'E', 'D', 'G', 'C']
134
+ b = ['G', 'F', 'A', 'B', 'C', 'D', 'E']
135
+
136
+ """
137
+ A: B C F
138
+ B: A F C
139
+ C: A G B D
140
+ D: E G C E
141
+ E: F D G
142
+ F: B E G A
143
+ G: D C E F
144
+ """
145
+
146
+ H = calc_adjency_matrix(a)
147
+ H = calc_adjency_matrix(b, H=H)
148
+
149
+ assert len(H["A"]) == 3
150
+ assert 'B' in H["A"] and 'C' in H["A"] and 'F' in H["A"]
151
+ assert len(H["B"]) == 3
152
+ assert 'A' in H["B"] and 'F' in H["B"] and 'C' in H["B"]
153
+ assert len(H["C"]) == 4
154
+ assert 'A' in H["C"] and 'G' in H["C"] and 'B' in H["C"] and 'D' in H["C"]
155
+ assert len(H["D"]) == 3
156
+ assert 'E' in H["D"] and 'G' in H["D"] and 'C' in H["D"]
157
+ assert len(H["E"]) == 3
158
+ assert 'F' in H["E"] and 'D' in H["E"] and 'G' in H["E"]
159
+ assert len(H["F"]) == 4
160
+ assert 'B' in H["F"] and 'E' in H["F"] and 'G' in H["F"] and 'A' in H["F"]
161
+ assert len(H["G"]) == 4
162
+ assert 'D' in H["G"] and 'E' in H["G"] and 'E' in H["G"] and 'F' in H["G"]
163
+
164
+ c = erx(a, b)
@@ -0,0 +1,53 @@
1
+ import numpy as np
2
+
3
+ from pymoo.core.crossover import Crossover
4
+ from pymoo.core.variable import get, Real
5
+ from pymoo.util import default_random_state
6
+ from pymoo.util.misc import crossover_mask, row_at_least_once_true
7
+
8
+
9
+ @default_random_state
10
+ def mut_exp(n_matings, n_var, prob, at_least_once=True, random_state=None):
11
+ assert len(prob) == n_matings
12
+
13
+ # the mask do to the crossover
14
+ M = np.full((n_matings, n_var), False)
15
+
16
+ # start point of crossover
17
+ s = random_state.integers(0, n_var, size=n_matings)
18
+
19
+ # create for each individual the crossover range
20
+ for i in range(n_matings):
21
+
22
+ # the actual index where we start
23
+ start = s[i]
24
+ for j in range(n_var):
25
+
26
+ # the current position where we are pointing to
27
+ current = (start + j) % n_var
28
+
29
+ # replace only if random value keeps being smaller than CR
30
+ if random_state.random() <= prob[i]:
31
+ M[i, current] = True
32
+ else:
33
+ break
34
+
35
+ if at_least_once:
36
+ M = row_at_least_once_true(M, random_state=random_state)
37
+
38
+ return M
39
+
40
+
41
+ class ExponentialCrossover(Crossover):
42
+
43
+ def __init__(self, prob_exp=0.75, **kwargs):
44
+ super().__init__(2, 2, **kwargs)
45
+ self.prob_exp = Real(prob_exp, bounds=(0.5, 0.9), strict=(0.0, 1.0))
46
+
47
+ def _do(self, _, X, random_state=None, **kwargs):
48
+ _, n_matings, n_var = X.shape
49
+ prob_exp = get(self.prob_exp, size=n_matings)
50
+
51
+ M = mut_exp(n_matings, n_var, prob_exp, at_least_once=True, random_state=random_state)
52
+ _X = crossover_mask(X, M)
53
+ return _X
@@ -0,0 +1,37 @@
1
+ import math
2
+
3
+ import numpy as np
4
+
5
+ from pymoo.core.crossover import Crossover
6
+ from pymoo.util.misc import crossover_mask
7
+
8
+
9
+ class HalfUniformCrossover(Crossover):
10
+
11
+ def __init__(self, prob_hux=0.5, **kwargs):
12
+ super().__init__(2, 2, **kwargs)
13
+ self.prob_hux = prob_hux
14
+
15
+ def _do(self, _, X, random_state=None, **kwargs):
16
+ _, n_matings, n_var = X.shape
17
+
18
+ # the mask do to the crossover
19
+ M = np.full((n_matings, n_var), False)
20
+
21
+ not_equal = X[0] != X[1]
22
+
23
+ # create for each individual the crossover range
24
+ for i in range(n_matings):
25
+ I = np.where(not_equal[i])[0]
26
+
27
+ n = math.ceil(len(I) / 2)
28
+ if n > 0:
29
+ _I = I[random_state.permutation(len(I))[:n]]
30
+ M[i, _I] = True
31
+
32
+ _X = crossover_mask(X, M)
33
+ return _X
34
+
35
+
36
+ class HUX(HalfUniformCrossover):
37
+ pass
@@ -0,0 +1,25 @@
1
+ from pymoo.core.crossover import Crossover
2
+ from pymoo.core.population import Population
3
+
4
+
5
+ class NoCrossover(Crossover):
6
+ def __init__(self, *, n_parents=1, n_offsprings=None, prob=0.0, **kwargs):
7
+ if n_offsprings is None:
8
+ n_offsprings = n_parents
9
+ super().__init__(n_parents, n_offsprings, prob, **kwargs)
10
+
11
+ def do(self, problem, pop, *args, random_state, **kwargs):
12
+ offsprings = []
13
+ for parents in pop:
14
+ if self.n_offsprings < self.n_parents:
15
+ # Select without replacement
16
+ offsprings.extend(random_state.choice(parents, size=self.n_offsprings, replace=False))
17
+ elif self.n_offsprings == self.n_parents:
18
+ # Return all parents as-is
19
+ offsprings.extend(parents)
20
+ else:
21
+ # Keep each parent at least once, then fill randomly
22
+ offsprings.extend(parents)
23
+ extra = self.n_offsprings - self.n_parents
24
+ offsprings.extend(random_state.choice(parents, size=extra, replace=True))
25
+ return Population.create(*offsprings)