pymoo 0.6.1.5.dev0__cp39-cp39-musllinux_1_2_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 (330) 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-39-x86_64-linux-gnu.so +0 -0
  91. pymoo/cython/calc_perpendicular_distance.pyx +67 -0
  92. pymoo/cython/decomposition.cpython-39-x86_64-linux-gnu.so +0 -0
  93. pymoo/cython/decomposition.pyx +165 -0
  94. pymoo/cython/hv.cpython-39-x86_64-linux-gnu.so +0 -0
  95. pymoo/cython/hv.pyx +18 -0
  96. pymoo/cython/info.cpython-39-x86_64-linux-gnu.so +0 -0
  97. pymoo/cython/info.pyx +5 -0
  98. pymoo/cython/mnn.cpython-39-x86_64-linux-gnu.so +0 -0
  99. pymoo/cython/mnn.pyx +273 -0
  100. pymoo/cython/non_dominated_sorting.cpython-39-x86_64-linux-gnu.so +0 -0
  101. pymoo/cython/non_dominated_sorting.pyx +645 -0
  102. pymoo/cython/pruning_cd.cpython-39-x86_64-linux-gnu.so +0 -0
  103. pymoo/cython/pruning_cd.pyx +197 -0
  104. pymoo/cython/stochastic_ranking.cpython-39-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 +330 -0
  326. pymoo-0.6.1.5.dev0.dist-info/WHEEL +5 -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
  329. pymoo.libs/libgcc_s-2298274a.so.1 +0 -0
  330. pymoo.libs/libstdc++-08d5c7eb.so.6.0.33 +0 -0
@@ -0,0 +1,122 @@
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
+
9
+
10
+ def de_differential(X, F, dither=None, jitter=True, gamma=0.0001, return_differentials=False):
11
+ n_parents, n_matings, n_var = X.shape
12
+ assert n_parents % 2 == 1, "For the differential an odd number of values need to be provided"
13
+
14
+ # make sure F is a one-dimensional vector
15
+ F = np.ones(n_matings) * F
16
+
17
+ # build the pairs for the differentials
18
+ pairs = (np.arange(n_parents - 1) + 1).reshape(-1, 2)
19
+
20
+ # the differentials from each pair subtraction
21
+ diffs = np.zeros((n_matings, n_var))
22
+
23
+ # for each difference
24
+ for i, j in pairs:
25
+
26
+ if dither == "vector":
27
+ F = (F + np.random.random(n_matings) * (1 - F))
28
+ elif dither == "scalar":
29
+ F = F + np.random.random() * (1 - F)
30
+
31
+ # http://www.cs.ndsu.nodak.edu/~siludwig/Publish/papers/SSCI20141.pdf
32
+ if jitter:
33
+ F = (F * (1 + gamma * (np.random.random(n_matings) - 0.5)))
34
+
35
+ # an add the difference to the first vector
36
+ diffs += F[:, None] * (X[i] - X[j])
37
+
38
+ # now add the differentials to the first parent
39
+ Xp = X[0] + diffs
40
+
41
+ if return_differentials:
42
+ return Xp, diffs
43
+ else:
44
+ return Xp
45
+
46
+
47
+ class DEX(Crossover):
48
+
49
+ def __init__(self,
50
+ F=None,
51
+ CR=0.7,
52
+ variant="bin",
53
+ dither=None,
54
+ jitter=False,
55
+ n_diffs=1,
56
+ n_iter=1,
57
+ at_least_once=True,
58
+ **kwargs):
59
+
60
+ super().__init__(1 + 2 * n_diffs, 1, **kwargs)
61
+ self.n_diffs = n_diffs
62
+ self.F = F
63
+ self.CR = CR
64
+ self.variant = variant
65
+ self.at_least_once = at_least_once
66
+ self.dither = dither
67
+ self.jitter = jitter
68
+ self.n_iter = n_iter
69
+
70
+ def do(self, problem, pop, parents=None, **kwargs):
71
+
72
+ # if a parents with array with mating indices is provided -> transform the input first
73
+ if parents is not None:
74
+ pop = [pop[mating] for mating in parents]
75
+
76
+ # get the actual values from each of the parents
77
+ X = np.swapaxes(np.array([[parent.get("X") for parent in mating] for mating in pop]), 0, 1).copy()
78
+
79
+ n_parents, n_matings, n_var = X.shape
80
+
81
+ # a mask over matings that need to be repeated
82
+ m = np.arange(n_matings)
83
+
84
+ # if the user provides directly an F value to use
85
+ F = self.F if self.F is not None else rnd_F(m)
86
+
87
+ # prepare the out to be set
88
+ Xp = de_differential(X[:, m], F)
89
+
90
+ # if the problem has boundaries to be considered
91
+ if problem.has_bounds():
92
+
93
+ for k in range(self.n_iter):
94
+ # find the individuals which are still infeasible
95
+ m = is_out_of_bounds_by_problem(problem, Xp)
96
+
97
+ F = rnd_F(m)
98
+
99
+ # actually execute the differential equation
100
+ Xp[m] = de_differential(X[:, m], F)
101
+
102
+ # if still infeasible do a random initialization
103
+ Xp = repair_random_init(Xp, X[0], *problem.bounds())
104
+
105
+ if self.variant == "bin":
106
+ M = mut_binomial(n_matings, n_var, self.CR, at_least_once=self.at_least_once)
107
+ elif self.variant == "exp":
108
+ M = mut_exp(n_matings, n_var, self.CR, at_least_once=self.at_least_once)
109
+ else:
110
+ raise Exception(f"Unknown variant: {self.variant}")
111
+
112
+ # take the first parents (this is already a copy)
113
+ X = X[0]
114
+
115
+ # set the corresponding values from the donor vector
116
+ X[M] = Xp[M]
117
+
118
+ return Population.new("X", X)
119
+
120
+
121
+ def rnd_F(m):
122
+ return 0.5 * (1 + np.random.uniform(size=len(m)))
@@ -0,0 +1,162 @@
1
+ import numpy as np
2
+
3
+ from pymoo.core.crossover import Crossover
4
+
5
+
6
+ def remove_from_adj_list(H, val):
7
+ for e in list(H[val]):
8
+ H[e].remove(val)
9
+ del H[val]
10
+
11
+
12
+ def has_duplicates(x):
13
+ H = set()
14
+ for v in x:
15
+ if v in H:
16
+ return True
17
+ H.add(v)
18
+ return False
19
+
20
+
21
+ def erx(a, b):
22
+ """
23
+ http://www.rubicite.com/Tutorials/GeneticAlgorithms/CrossoverOperators/EdgeRecombinationCrossoverOperator.aspx
24
+
25
+ Algorithm Pseudo Code:
26
+
27
+ 1. X = the first node from a random parent.
28
+
29
+ 2. While the CHILD chromo isn't full, Loop:
30
+ - Append X to CHILD
31
+ - Remove X from Neighbor Lists
32
+
33
+ if X's neighbor list is empty:
34
+ - Xp = random node not already in CHILD
35
+ else
36
+ - Determine neighbor of X that has fewest neighbors
37
+ - If there is a tie, randomly choose 1
38
+ - Xp = chosen node
39
+ X = Xp
40
+ """
41
+
42
+ assert len(a) == len(b)
43
+
44
+ # calculate the edge matrix considering both permutation
45
+ H = calc_adjency_matrix(a)
46
+ H = calc_adjency_matrix(b, H=H)
47
+
48
+ # randomly select the first node
49
+ _next = np.random.choice(list(H.keys()))
50
+
51
+ y = []
52
+ while True:
53
+
54
+ # append to the child
55
+ y.append(_next)
56
+
57
+ # break if the child was successfully created.
58
+ if len(y) == len(a):
59
+ break
60
+
61
+ # get the neighbors to consider and remove them from the lists
62
+ neighbors = list(H[_next])
63
+ remove_from_adj_list(H, _next)
64
+
65
+ # if the current node does not have any neighbors
66
+ if len(neighbors) == 0:
67
+ _next = np.random.choice(list(H.keys()))
68
+
69
+ # otherwise search in the neighbors for a node with the fewest neighbors
70
+ else:
71
+ # search for the one with minimum neighbors
72
+ n_neighbors = [len(H[e]) for e in neighbors]
73
+ min_n_neighbors = min(n_neighbors)
74
+ _next = [neighbors[k] for k in range(len(neighbors)) if n_neighbors[k] == min_n_neighbors]
75
+
76
+ # break the tie if they might have the same number of neighbors
77
+ _next = np.random.choice(_next)
78
+
79
+ return y
80
+
81
+
82
+ class EdgeRecombinationCrossover(Crossover):
83
+
84
+ def __init__(self, **kwargs):
85
+ super().__init__(2, 1, **kwargs)
86
+
87
+ def _do(self, problem, X, **kwargs):
88
+ _, n_matings, n_var = X.shape
89
+ Y = np.full((self.n_offsprings, n_matings, n_var), -1, dtype=int)
90
+
91
+ for i in range(n_matings):
92
+ a, b = X[:, i, :]
93
+ Y[0, i, :] = erx(a, b)
94
+
95
+ return Y
96
+
97
+ class ERX(EdgeRecombinationCrossover):
98
+ pass
99
+
100
+ def number_to_letter(n):
101
+ return chr(ord('@') + n)
102
+
103
+
104
+ def numbers_to_letters(numbers):
105
+ return [number_to_letter(n) for n in numbers]
106
+
107
+
108
+ def letter_to_number(char):
109
+ return ord(char.lower()) - 96
110
+
111
+
112
+ def letters_to_numbers(letters):
113
+ return np.array([letter_to_number(char) for char in letters])
114
+
115
+
116
+ def calc_adjency_matrix(x, H=None):
117
+ H = {} if H is None else H
118
+
119
+ for k in range(len(x)):
120
+ prev = (k - 1) % len(x)
121
+ succ = (k + 1) % len(x)
122
+
123
+ if x[k] not in H:
124
+ H[x[k]] = set()
125
+ H[x[k]].update([x[prev], x[succ]])
126
+
127
+ return H
128
+
129
+
130
+ if __name__ == "__main__":
131
+ a = ['A', 'B', 'F', 'E', 'D', 'G', 'C']
132
+ b = ['G', 'F', 'A', 'B', 'C', 'D', 'E']
133
+
134
+ """
135
+ A: B C F
136
+ B: A F C
137
+ C: A G B D
138
+ D: E G C E
139
+ E: F D G
140
+ F: B E G A
141
+ G: D C E F
142
+ """
143
+
144
+ H = calc_adjency_matrix(a)
145
+ H = calc_adjency_matrix(b, H=H)
146
+
147
+ assert len(H["A"]) == 3
148
+ assert 'B' in H["A"] and 'C' in H["A"] and 'F' in H["A"]
149
+ assert len(H["B"]) == 3
150
+ assert 'A' in H["B"] and 'F' in H["B"] and 'C' in H["B"]
151
+ assert len(H["C"]) == 4
152
+ assert 'A' in H["C"] and 'G' in H["C"] and 'B' in H["C"] and 'D' in H["C"]
153
+ assert len(H["D"]) == 3
154
+ assert 'E' in H["D"] and 'G' in H["D"] and 'C' in H["D"]
155
+ assert len(H["E"]) == 3
156
+ assert 'F' in H["E"] and 'D' in H["E"] and 'G' in H["E"]
157
+ assert len(H["F"]) == 4
158
+ assert 'B' in H["F"] and 'E' in H["F"] and 'G' in H["F"] and 'A' in H["F"]
159
+ assert len(H["G"]) == 4
160
+ assert 'D' in H["G"] and 'E' in H["G"] and 'E' in H["G"] and 'F' in H["G"]
161
+
162
+ c = erx(a, b)
@@ -0,0 +1,51 @@
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.misc import crossover_mask, row_at_least_once_true
6
+
7
+
8
+ def mut_exp(n_matings, n_var, prob, at_least_once=True):
9
+ assert len(prob) == n_matings
10
+
11
+ # the mask do to the crossover
12
+ M = np.full((n_matings, n_var), False)
13
+
14
+ # start point of crossover
15
+ s = np.random.randint(0, n_var, size=n_matings)
16
+
17
+ # create for each individual the crossover range
18
+ for i in range(n_matings):
19
+
20
+ # the actual index where we start
21
+ start = s[i]
22
+ for j in range(n_var):
23
+
24
+ # the current position where we are pointing to
25
+ current = (start + j) % n_var
26
+
27
+ # replace only if random value keeps being smaller than CR
28
+ if np.random.random() <= prob[i]:
29
+ M[i, current] = True
30
+ else:
31
+ break
32
+
33
+ if at_least_once:
34
+ M = row_at_least_once_true(M)
35
+
36
+ return M
37
+
38
+
39
+ class ExponentialCrossover(Crossover):
40
+
41
+ def __init__(self, prob_exp=0.75, **kwargs):
42
+ super().__init__(2, 2, **kwargs)
43
+ self.prob_exp = Real(prob_exp, bounds=(0.5, 0.9), strict=(0.0, 1.0))
44
+
45
+ def _do(self, _, X, **kwargs):
46
+ _, n_matings, n_var = X.shape
47
+ prob_exp = get(self.prob_exp, size=n_matings)
48
+
49
+ M = mut_exp(n_matings, n_var, prob_exp, at_least_once=True)
50
+ _X = crossover_mask(X, M)
51
+ 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, **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[np.random.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,13 @@
1
+ import numpy as np
2
+
3
+ from pymoo.core.crossover import Crossover
4
+ from pymoo.core.population import Population
5
+
6
+
7
+ class NoCrossover(Crossover):
8
+
9
+ def __init__(self):
10
+ super().__init__(1, 1, 0.0)
11
+
12
+ def do(self, problem, pop, **kwargs):
13
+ return Population.create(*[np.random.choice(parents) for parents in pop])
@@ -0,0 +1,84 @@
1
+ import numpy as np
2
+
3
+ from pymoo.core.crossover import Crossover
4
+
5
+
6
+ def random_sequence(n):
7
+ start, end = np.sort(np.random.choice(n, 2, replace=False))
8
+ return tuple([start, end])
9
+
10
+
11
+ def ox(receiver, donor, seq=None, shift=False):
12
+ """
13
+ The Ordered Crossover (OX) as explained in http://www.dmi.unict.it/mpavone/nc-cs/materiale/moscato89.pdf.
14
+
15
+ Parameters
16
+ ----------
17
+ receiver : numpy.array
18
+ The receiver of the sequence. The array needs to be repaired after the donation took place.
19
+ donor : numpy.array
20
+ The donor of the sequence.
21
+ seq : tuple (optional)
22
+ Tuple with two problems defining the start and the end of the sequence. Please note in our implementation
23
+ the end of the sequence is included. The sequence is randomly chosen if not provided.
24
+
25
+ shift : bool
26
+ Whether during the repair the receiver should be shifted or not. Both version of it can be found in the
27
+ literature.
28
+
29
+ Returns
30
+ -------
31
+
32
+ y : numpy.array
33
+ The offspring which was created by the ordered crossover.
34
+
35
+ """
36
+ assert len(donor) == len(receiver)
37
+
38
+ # the sequence which shall be use for the crossover
39
+ seq = seq if seq is not None else random_sequence(len(receiver))
40
+ start, end = seq
41
+
42
+ # the donation and a set of it to allow a quick lookup
43
+ donation = np.copy(donor[start:end + 1])
44
+ donation_as_set = set(donation)
45
+
46
+ # the final value to be returned
47
+ y = []
48
+
49
+ for k in range(len(receiver)):
50
+
51
+ # do the shift starting from the swapped sequence - as proposed in the paper
52
+ i = k if not shift else (start + k) % len(receiver)
53
+ v = receiver[i]
54
+
55
+ if v not in donation_as_set:
56
+ y.append(v)
57
+
58
+ # now insert the donation at the right place
59
+ y = np.concatenate([y[:start], donation, y[start:]]).astype(copy=False, dtype=int)
60
+
61
+ return y
62
+
63
+
64
+ class OrderCrossover(Crossover):
65
+
66
+ def __init__(self, shift=False, **kwargs):
67
+ super().__init__(2, 2, **kwargs)
68
+ self.shift = shift
69
+
70
+ def _do(self, problem, X, **kwargs):
71
+ _, n_matings, n_var = X.shape
72
+ Y = np.full((self.n_offsprings, n_matings, n_var), -1, dtype=int)
73
+
74
+ for i in range(n_matings):
75
+ a, b = X[:, i, :]
76
+ n = len(a)
77
+
78
+ # define the sequence to be used for crossover
79
+ start, end = random_sequence(n)
80
+
81
+ Y[0, i, :] = ox(a, b, seq=(start, end), shift=self.shift)
82
+ Y[1, i, :] = ox(b, a, seq=(start, end), shift=self.shift)
83
+
84
+ return Y
@@ -0,0 +1,82 @@
1
+ import numpy as np
2
+
3
+ from pymoo.core.crossover import Crossover
4
+ from pymoo.core.variable import Real, get
5
+ from pymoo.operators.repair.bounds_repair import repair_random_init
6
+
7
+
8
+ def pcx(X, eta, zeta, index):
9
+ eps = 1e-32
10
+
11
+ # the number of parents to be considered
12
+ n_parents, n_matings, n_var = X.shape
13
+
14
+ # calculate the differences from all parents to index parent
15
+ diff_to_index = X - X[index]
16
+ dist_to_index = np.linalg.norm(diff_to_index, axis=-1)
17
+ dist_to_index = np.maximum(eps, dist_to_index)
18
+
19
+ # find the centroid of the parents
20
+ centroid = np.mean(X, axis=0)
21
+
22
+ # calculate the difference between the centroid and the k-th parent
23
+ diff_to_centroid = centroid - X[index]
24
+
25
+ dist_to_centroid = np.linalg.norm(diff_to_centroid, axis=-1)
26
+ dist_to_centroid = np.maximum(eps, dist_to_centroid)
27
+
28
+ # orthogonal directions are computed
29
+ orth_dir = np.zeros_like(dist_to_index)
30
+
31
+ for i in range(n_parents):
32
+ if i != index:
33
+ temp1 = (diff_to_index[i] * diff_to_centroid).sum(axis=-1)
34
+ temp2 = temp1 / (dist_to_index[i] * dist_to_centroid)
35
+ temp3 = np.maximum(0.0, 1.0 - temp2 ** 2)
36
+ orth_dir[i] = dist_to_index[i] * (temp3 ** 0.5)
37
+
38
+ # this is the avg of the perpendicular distances from other parents to the parent k
39
+ D_not = orth_dir.sum(axis=0) / (n_parents - 1)
40
+
41
+ # generating zero-mean normally distributed variables
42
+ sigma = D_not[:, None] * eta.repeat(n_var, axis=1)
43
+ rnd = np.random.normal(loc=0.0, scale=sigma)
44
+
45
+ # implemented just like the c code - generate_new.h file
46
+ inner_prod = np.sum(rnd * diff_to_centroid, axis=-1, keepdims=True)
47
+ noise = rnd - (inner_prod * diff_to_centroid) / dist_to_centroid[:, None] ** 2
48
+
49
+ bias_to_centroid = np.random.normal(0.0, zeta) * diff_to_centroid
50
+
51
+ # the array which is finally returned
52
+ Xp = X[index] + noise + bias_to_centroid
53
+
54
+ return Xp
55
+
56
+
57
+ class ParentCentricCrossover(Crossover):
58
+ def __init__(self,
59
+ eta=0.1,
60
+ zeta=0.1,
61
+ **kwargs):
62
+
63
+ super().__init__(n_parents=3, n_offsprings=1, **kwargs)
64
+ self.eta = Real(eta, bounds=(0.01, 0.3))
65
+ self.zeta = Real(zeta, bounds=(0.01, 0.3))
66
+
67
+ def _do(self, problem, X, params=None, **kwargs):
68
+ n_parents, n_matings, n_var = X.shape
69
+ zeta, eta = get(self.zeta, self.eta, size=(n_matings, 1))
70
+
71
+ index = 0
72
+
73
+ Xp = pcx(X, eta, zeta, index=index)
74
+
75
+ if problem.has_bounds():
76
+ Xp = repair_random_init(Xp, X[index], *problem.bounds())
77
+
78
+ return Xp[None, :]
79
+
80
+
81
+ class PCX(ParentCentricCrossover):
82
+ pass
@@ -0,0 +1,49 @@
1
+ import numpy as np
2
+
3
+ from pymoo.core.crossover import Crossover
4
+ from pymoo.util.misc import crossover_mask
5
+
6
+
7
+ class PointCrossover(Crossover):
8
+
9
+ def __init__(self, n_points, **kwargs):
10
+ super().__init__(2, 2, **kwargs)
11
+ self.n_points = n_points
12
+
13
+ def _do(self, _, X, **kwargs):
14
+
15
+ # get the X of parents and count the matings
16
+ _, n_matings, n_var = X.shape
17
+
18
+ # start point of crossover
19
+ r = np.row_stack([np.random.permutation(n_var - 1) + 1 for _ in range(n_matings)])[:, :self.n_points]
20
+ r.sort(axis=1)
21
+ r = np.column_stack([r, np.full(n_matings, n_var)])
22
+
23
+ # the mask do to the crossover
24
+ M = np.full((n_matings, n_var), False)
25
+
26
+ # create for each individual the crossover range
27
+ for i in range(n_matings):
28
+
29
+ j = 0
30
+ while j < r.shape[1] - 1:
31
+ a, b = r[i, j], r[i, j + 1]
32
+ M[i, a:b] = True
33
+ j += 2
34
+
35
+ Xp = crossover_mask(X, M)
36
+
37
+ return Xp
38
+
39
+
40
+ class SinglePointCrossover(PointCrossover):
41
+
42
+ def __init__(self, **kwargs):
43
+ super().__init__(n_points=1, **kwargs)
44
+
45
+
46
+ class TwoPointCrossover(PointCrossover):
47
+
48
+ def __init__(self, **kwargs):
49
+ super().__init__(n_points=2, **kwargs)