pymoo 0.6.1.5.dev0__cp311-cp311-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-311-x86_64-linux-musl.so +0 -0
  91. pymoo/cython/calc_perpendicular_distance.pyx +67 -0
  92. pymoo/cython/decomposition.cpython-311-x86_64-linux-musl.so +0 -0
  93. pymoo/cython/decomposition.pyx +165 -0
  94. pymoo/cython/hv.cpython-311-x86_64-linux-musl.so +0 -0
  95. pymoo/cython/hv.pyx +18 -0
  96. pymoo/cython/info.cpython-311-x86_64-linux-musl.so +0 -0
  97. pymoo/cython/info.pyx +5 -0
  98. pymoo/cython/mnn.cpython-311-x86_64-linux-musl.so +0 -0
  99. pymoo/cython/mnn.pyx +273 -0
  100. pymoo/cython/non_dominated_sorting.cpython-311-x86_64-linux-musl.so +0 -0
  101. pymoo/cython/non_dominated_sorting.pyx +645 -0
  102. pymoo/cython/pruning_cd.cpython-311-x86_64-linux-musl.so +0 -0
  103. pymoo/cython/pruning_cd.pyx +197 -0
  104. pymoo/cython/stochastic_ranking.cpython-311-x86_64-linux-musl.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
pymoo/vendor/hv.py ADDED
@@ -0,0 +1,267 @@
1
+ # Copyright (C) 2010 Simon Wessing
2
+ # TU Dortmund University
3
+ # The author (Simon Wessing) has explicitly given the permission for this source code
4
+ # to be included in pymoo. Thank you!
5
+
6
+ __author__ = "Simon Wessing"
7
+
8
+
9
+ class HyperVolume:
10
+ """
11
+ Hypervolume computation based on cross 3 of the algorithm in the paper:
12
+ C. M. Fonseca, L. Paquete, and M. Lopez-Ibanez. An improved dimension-sweep
13
+ algorithm for the hypervolume indicator. In IEEE Congress on Evolutionary
14
+ Computation, pages 1157-1163, Vancouver, Canada, July 2006.
15
+
16
+ Minimization is implicitly assumed here!
17
+
18
+ """
19
+
20
+ def __init__(self, referencePoint):
21
+ """Constructor."""
22
+ self.referencePoint = referencePoint
23
+ self.list = []
24
+
25
+ def compute(self, front):
26
+ """Returns the hypervolume that is dominated by a non-dominated front.
27
+
28
+ Before the HV computation, front and reference point are translated, so
29
+ that the reference point is [0, ..., 0].
30
+
31
+ """
32
+
33
+ def weaklyDominates(point, other):
34
+ for i in range(len(point)):
35
+ if point[i] > other[i]:
36
+ return False
37
+ return True
38
+
39
+ relevantPoints = []
40
+ referencePoint = self.referencePoint
41
+ dimensions = len(referencePoint)
42
+ for point in front:
43
+ # only consider points that dominate the reference point
44
+ if weaklyDominates(point, referencePoint):
45
+ relevantPoints.append(point)
46
+ if any(referencePoint):
47
+ # shift points so that referencePoint == [0, ..., 0]
48
+ # this way the reference point doesn't have to be explicitly used
49
+ # in the HV computation
50
+ for j in range(len(relevantPoints)):
51
+ relevantPoints[j] = [relevantPoints[j][i] - referencePoint[i] for i in range(dimensions)]
52
+ self.preProcess(relevantPoints)
53
+ bounds = [-1.0e308] * dimensions
54
+ hyperVolume = self.hvRecursive(dimensions - 1, len(relevantPoints), bounds)
55
+ return hyperVolume
56
+
57
+ def hvRecursive(self, dimIndex, length, bounds):
58
+ """Recursive call to hypervolume calculation.
59
+
60
+ In contrast to the paper, the code assumes that the reference point
61
+ is [0, ..., 0]. This allows the avoidance of a few operations.
62
+
63
+ """
64
+ hvol = 0.0
65
+ sentinel = self.list.sentinel
66
+ if length == 0:
67
+ return hvol
68
+ elif dimIndex == 0:
69
+ # special case: only one dimension
70
+ # why using hypervolume at all?
71
+ return -sentinel.next[0].cargo[0]
72
+ elif dimIndex == 1:
73
+ # special case: two dimensions, end recursion
74
+ q = sentinel.next[1]
75
+ h = q.cargo[0]
76
+ p = q.next[1]
77
+ while p is not sentinel:
78
+ pCargo = p.cargo
79
+ hvol += h * (q.cargo[1] - pCargo[1])
80
+ if pCargo[0] < h:
81
+ h = pCargo[0]
82
+ q = p
83
+ p = q.next[1]
84
+ hvol += h * q.cargo[1]
85
+ return hvol
86
+ else:
87
+ remove = self.list.remove
88
+ reinsert = self.list.reinsert
89
+ hvRecursive = self.hvRecursive
90
+ p = sentinel
91
+ q = p.prev[dimIndex]
92
+ while q.cargo is not None:
93
+ if q.ignore < dimIndex:
94
+ q.ignore = 0
95
+ q = q.prev[dimIndex]
96
+ q = p.prev[dimIndex]
97
+ while length > 1 and (
98
+ q.cargo[dimIndex] > bounds[dimIndex] or q.prev[dimIndex].cargo[dimIndex] >= bounds[dimIndex]):
99
+ p = q
100
+ remove(p, dimIndex, bounds)
101
+ q = p.prev[dimIndex]
102
+ length -= 1
103
+ qArea = q.area
104
+ qCargo = q.cargo
105
+ qPrevDimIndex = q.prev[dimIndex]
106
+ if length > 1:
107
+ hvol = qPrevDimIndex.volume[dimIndex] + qPrevDimIndex.area[dimIndex] * (
108
+ qCargo[dimIndex] - qPrevDimIndex.cargo[dimIndex])
109
+ else:
110
+ qArea[0] = 1
111
+ qArea[1:dimIndex + 1] = [qArea[i] * -qCargo[i] for i in range(dimIndex)]
112
+ q.volume[dimIndex] = hvol
113
+ if q.ignore >= dimIndex:
114
+ qArea[dimIndex] = qPrevDimIndex.area[dimIndex]
115
+ else:
116
+ qArea[dimIndex] = hvRecursive(dimIndex - 1, length, bounds)
117
+ if qArea[dimIndex] <= qPrevDimIndex.area[dimIndex]:
118
+ q.ignore = dimIndex
119
+ while p is not sentinel:
120
+ pCargoDimIndex = p.cargo[dimIndex]
121
+ hvol += q.area[dimIndex] * (pCargoDimIndex - q.cargo[dimIndex])
122
+ bounds[dimIndex] = pCargoDimIndex
123
+ reinsert(p, dimIndex, bounds)
124
+ length += 1
125
+ q = p
126
+ p = p.next[dimIndex]
127
+ q.volume[dimIndex] = hvol
128
+ if q.ignore >= dimIndex:
129
+ q.area[dimIndex] = q.prev[dimIndex].area[dimIndex]
130
+ else:
131
+ q.area[dimIndex] = hvRecursive(dimIndex - 1, length, bounds)
132
+ if q.area[dimIndex] <= q.prev[dimIndex].area[dimIndex]:
133
+ q.ignore = dimIndex
134
+ hvol -= q.area[dimIndex] * q.cargo[dimIndex]
135
+ return hvol
136
+
137
+ def preProcess(self, front):
138
+ """Sets up the list data structure needed for calculation."""
139
+ dimensions = len(self.referencePoint)
140
+ nodeList = MultiList(dimensions)
141
+ nodes = [MultiList.Node(dimensions, point) for point in front]
142
+ for i in range(dimensions):
143
+ self.sortByDimension(nodes, i)
144
+ nodeList.extend(nodes, i)
145
+ self.list = nodeList
146
+
147
+ def sortByDimension(self, nodes, i):
148
+ """Sorts the list of nodes by the i-th value of the contained points."""
149
+ # build a list of tuples of (point[i], node)
150
+ decorated = [(node.cargo[i], index, node) for index, node in enumerate(nodes)]
151
+ # sort by this value
152
+ decorated.sort()
153
+ # write back to original list
154
+ nodes[:] = [node for (_, _, node) in decorated]
155
+
156
+
157
+ class MultiList:
158
+ """A special data structure needed by FonsecaHyperVolume.
159
+
160
+ It consists of several doubly linked lists that share common nodes. So,
161
+ every node has multiple predecessors and successors, one in every list.
162
+
163
+ """
164
+
165
+ class Node:
166
+
167
+ def __init__(self, numberLists, cargo=None):
168
+ self.cargo = cargo
169
+ self.next = [None] * numberLists
170
+ self.prev = [None] * numberLists
171
+ self.ignore = 0
172
+ self.area = [0.0] * numberLists
173
+ self.volume = [0.0] * numberLists
174
+
175
+ def __str__(self):
176
+ return str(self.cargo)
177
+
178
+ def __init__(self, numberLists):
179
+ """Constructor.
180
+
181
+ Builds 'numberLists' doubly linked lists.
182
+
183
+ """
184
+ self.numberLists = numberLists
185
+ self.sentinel = MultiList.Node(numberLists)
186
+ self.sentinel.next = [self.sentinel] * numberLists
187
+ self.sentinel.prev = [self.sentinel] * numberLists
188
+
189
+ def __str__(self):
190
+ strings = []
191
+ for i in range(self.numberLists):
192
+ currentList = []
193
+ node = self.sentinel.next[i]
194
+ while node != self.sentinel:
195
+ currentList.append(str(node))
196
+ node = node.next[i]
197
+ strings.append(str(currentList))
198
+ stringRepr = ""
199
+ for string in strings:
200
+ stringRepr += string + "\n"
201
+ return stringRepr
202
+
203
+ def __len__(self):
204
+ """Returns the number of lists that are included in this MultiList."""
205
+ return self.numberLists
206
+
207
+ def getLength(self, i):
208
+ """Returns the length of the i-th list."""
209
+ length = 0
210
+ sentinel = self.sentinel
211
+ node = sentinel.next[i]
212
+ while node != sentinel:
213
+ length += 1
214
+ node = node.next[i]
215
+ return length
216
+
217
+ def append(self, node, index):
218
+ """Appends a node to the end of the list at the given index."""
219
+ lastButOne = self.sentinel.prev[index]
220
+ node.next[index] = self.sentinel
221
+ node.prev[index] = lastButOne
222
+ # set the last element as the new one
223
+ self.sentinel.prev[index] = node
224
+ lastButOne.next[index] = node
225
+
226
+ def extend(self, nodes, index):
227
+ """Extends the list at the given index with the nodes."""
228
+ sentinel = self.sentinel
229
+ for node in nodes:
230
+ lastButOne = sentinel.prev[index]
231
+ node.next[index] = sentinel
232
+ node.prev[index] = lastButOne
233
+ # set the last element as the new one
234
+ sentinel.prev[index] = node
235
+ lastButOne.next[index] = node
236
+
237
+ def remove(self, node, index, bounds):
238
+ """Removes and returns 'node' from all lists in [0, 'index'[."""
239
+ for i in range(index):
240
+ predecessor = node.prev[i]
241
+ successor = node.next[i]
242
+ predecessor.next[i] = successor
243
+ successor.prev[i] = predecessor
244
+ if bounds[i] > node.cargo[i]:
245
+ bounds[i] = node.cargo[i]
246
+ return node
247
+
248
+ def reinsert(self, node, index, bounds):
249
+ """
250
+ Inserts 'node' at the position it had in all lists in [0, 'index'[
251
+ before it was removed. This method assumes that the next and previous
252
+ nodes of the node that is reinserted are in the list.
253
+
254
+ """
255
+ for i in range(index):
256
+ node.prev[i].next[i] = node
257
+ node.next[i].prev[i] = node
258
+ if bounds[i] > node.cargo[i]:
259
+ bounds[i] = node.cargo[i]
260
+
261
+
262
+ if __name__ == "__main__":
263
+ # Example:
264
+ referencePoint = [2, 2, 2]
265
+ hv = HyperVolume(referencePoint)
266
+ front = [[1, 0, 1], [0, 1, 0]]
267
+ volume = hv.compute(front)
@@ -0,0 +1,412 @@
1
+ import time
2
+
3
+ import numpy as np
4
+ from cma import CMAOptions
5
+ from cma import optimization_tools as ot
6
+ from cma.evolution_strategy import cma_default_options, CMAEvolutionStrategy
7
+ from cma.utilities import utils
8
+ from cma.utilities.math import Mh
9
+
10
+ all_stoppings = []
11
+
12
+ def void(_):
13
+ pass
14
+
15
+ def my_fmin(x0,
16
+ sigma0,
17
+ objective_function=void,
18
+ options=None,
19
+ args=(),
20
+ gradf=None,
21
+ restarts=0,
22
+ restart_from_best='False',
23
+ incpopsize=2,
24
+ eval_initial_x=False,
25
+ parallel_objective=None,
26
+ noise_handler=None,
27
+ noise_change_sigma_exponent=1,
28
+ noise_kappa_exponent=0, # TODO: add max kappa value as parameter
29
+ bipop=False,
30
+ callback=None):
31
+
32
+ if 1 < 3: # try: # pass on KeyboardInterrupt
33
+ if not objective_function and not parallel_objective: # cma.fmin(0, 0, 0)
34
+ return CMAOptions() # these opts are by definition valid
35
+
36
+ fmin_options = locals().copy() # archive original options
37
+ del fmin_options['objective_function']
38
+ del fmin_options['x0']
39
+ del fmin_options['sigma0']
40
+ del fmin_options['options']
41
+ del fmin_options['args']
42
+
43
+ if options is None:
44
+ options = cma_default_options
45
+ CMAOptions().check_attributes(options) # might modify options
46
+ # checked that no options.ftarget =
47
+ opts = CMAOptions(options.copy()).complement()
48
+
49
+ if callback is None:
50
+ callback = []
51
+ elif callable(callback):
52
+ callback = [callback]
53
+
54
+ # BIPOP-related variables:
55
+ runs_with_small = 0
56
+ small_i = []
57
+ large_i = []
58
+ popsize0 = None # to be evaluated after the first iteration
59
+ maxiter0 = None # to be evaluated after the first iteration
60
+ base_evals = 0
61
+
62
+ irun = 0
63
+ best = ot.BestSolution()
64
+ all_stoppings = []
65
+ while True: # restart loop
66
+ sigma_factor = 1
67
+
68
+ # Adjust the population according to BIPOP after a restart.
69
+ if not bipop:
70
+ # BIPOP not in use, simply double the previous population
71
+ # on restart.
72
+ if irun > 0:
73
+ popsize_multiplier = fmin_options['incpopsize'] ** (irun - runs_with_small)
74
+ opts['popsize'] = popsize0 * popsize_multiplier
75
+
76
+ elif irun == 0:
77
+ # Initial run is with "normal" population size; it is
78
+ # the large population before first doubling, but its
79
+ # budget accounting is the same as in case of small
80
+ # population.
81
+ poptype = 'small'
82
+
83
+ elif sum(small_i) < sum(large_i):
84
+ # An interweaved run with small population size
85
+ poptype = 'small'
86
+ if 11 < 3: # not needed when compared to irun - runs_with_small
87
+ restarts += 1 # A small restart doesn't count in the total
88
+ runs_with_small += 1 # _Before_ it's used in popsize_lastlarge
89
+
90
+ sigma_factor = 0.01 ** np.random.uniform() # Local search
91
+ popsize_multiplier = fmin_options['incpopsize'] ** (irun - runs_with_small)
92
+ opts['popsize'] = np.floor(popsize0 * popsize_multiplier ** (np.random.uniform() ** 2))
93
+ opts['maxiter'] = min(maxiter0, 0.5 * sum(large_i) / opts['popsize'])
94
+ # print('small basemul %s --> %s; maxiter %s' % (popsize_multiplier, opts['popsize'], opts['maxiter']))
95
+
96
+ else:
97
+ # A run with large population size; the population
98
+ # doubling is implicit with incpopsize.
99
+ poptype = 'large'
100
+
101
+ popsize_multiplier = fmin_options['incpopsize'] ** (irun - runs_with_small)
102
+ opts['popsize'] = popsize0 * popsize_multiplier
103
+ opts['maxiter'] = maxiter0
104
+ # print('large basemul %s --> %s; maxiter %s' % (popsize_multiplier, opts['popsize'], opts['maxiter']))
105
+
106
+ if not callable(objective_function) and callable(parallel_objective):
107
+ def objective_function(x, *args):
108
+ """created from `parallel_objective` argument"""
109
+ return parallel_objective([x], *args)[0]
110
+
111
+ # recover from a CMA object
112
+ if irun == 0 and isinstance(x0, MyCMAEvolutionStrategy):
113
+ es = x0
114
+ x0 = es.inputargs['x0'] # for the next restarts
115
+ if np.isscalar(sigma0) and np.isfinite(sigma0) and sigma0 > 0:
116
+ es.sigma = sigma0
117
+ # debatable whether this makes sense:
118
+ sigma0 = es.inputargs['sigma0'] # for the next restarts
119
+ if options is not None:
120
+ es.opts.set(options)
121
+ # ignore further input args and keep original options
122
+ else: # default case
123
+ if irun and eval(str(fmin_options['restart_from_best'])):
124
+ utils.print_warning('CAVE: restart_from_best is often not useful',
125
+ verbose=opts['verbose'])
126
+ es = MyCMAEvolutionStrategy(best.x, sigma_factor * sigma0, opts)
127
+ else:
128
+ es = MyCMAEvolutionStrategy(x0, sigma_factor * sigma0, opts)
129
+ # return opts, es
130
+ if callable(objective_function) and (
131
+ eval_initial_x
132
+ or es.opts['CMA_elitist'] == 'initial'
133
+ or (es.opts['CMA_elitist'] and
134
+ eval_initial_x is None)):
135
+ x = es.gp.pheno(es.mean,
136
+ into_bounds=es.boundary_handler.repair,
137
+ archive=es.sent_solutions)
138
+ es.f0 = yield x
139
+ es.best.update([x], es.sent_solutions,
140
+ [es.f0], 1)
141
+ es.countevals += 1
142
+ es.objective_function = objective_function # only for the record
143
+
144
+ opts = es.opts # processed options, unambiguous
145
+ # a hack:
146
+ fmin_opts = CMAOptions("unchecked", **fmin_options.copy())
147
+ for k in fmin_opts:
148
+ # locals() cannot be modified directly, exec won't work
149
+ # in 3.x, therefore
150
+ fmin_opts.eval(k, loc={'N': es.N,
151
+ 'popsize': opts['popsize']},
152
+ correct_key=False)
153
+
154
+ es.logger.append = opts['verb_append'] or es.countiter > 0 or irun > 0
155
+ # es.logger is "the same" logger, because the "identity"
156
+ # is only determined by the `verb_filenameprefix` option
157
+ logger = es.logger # shortcut
158
+ try:
159
+ logger.persistent_communication_dict.update(
160
+ {'variable_annotations':
161
+ objective_function.variable_annotations})
162
+ except AttributeError:
163
+ pass
164
+
165
+ if 11 < 3:
166
+ if es.countiter == 0 and es.opts['verb_log'] > 0 and \
167
+ not es.opts['verb_append']:
168
+ logger = CMADataLogger(es.opts['verb_filenameprefix']
169
+ ).register(es)
170
+ logger.add()
171
+ es.writeOutput() # initial values for sigma etc
172
+
173
+ if noise_handler:
174
+ if isinstance(noise_handler, type):
175
+ noisehandler = noise_handler(es.N)
176
+ else:
177
+ noisehandler = noise_handler
178
+ noise_handling = True
179
+ if fmin_opts['noise_change_sigma_exponent'] > 0:
180
+ es.opts['tolfacupx'] = inf
181
+ else:
182
+ noisehandler = ot.NoiseHandler(es.N, 0) # switched off
183
+ noise_handling = False
184
+ es.noise_handler = noisehandler
185
+
186
+ # the problem: this assumes that good solutions cannot take longer than bad ones:
187
+ # with EvalInParallel(objective_function, 2, is_feasible=opts['is_feasible']) as eval_in_parallel:
188
+ if 1 < 3:
189
+ while not es.stop(): # iteration loop
190
+ # X, fit = eval_in_parallel(lambda: es.ask(1)[0], es.popsize, args, repetitions=noisehandler.evaluations-1)
191
+ X, fit = yield from es.ask_and_eval(parallel_objective or objective_function,
192
+ args, gradf=gradf,
193
+ evaluations=noisehandler.evaluations,
194
+ aggregation=np.median,
195
+ parallel_mode=parallel_objective) # treats NaN with resampling if not parallel_mode
196
+ # TODO: check args and in case use args=(noisehandler.evaluations, )
197
+
198
+ if 11 < 3 and opts['vv']: # inject a solution
199
+ # use option check_point = [0]
200
+ if 0 * np.random.randn() >= 0:
201
+ X[0] = 0 + opts['vv'] * es.sigma ** 0 * np.random.randn(es.N)
202
+ fit[0] = yield X[0]
203
+ # print fit[0]
204
+ if es.opts['verbose'] > 4: # may be undesirable with dynamic fitness (e.g. Augmented Lagrangian)
205
+ if es.countiter < 2 or min(fit) <= es.best.last.f:
206
+ degrading_iterations_count = 0 # comes first to avoid code check complaint
207
+ else: # min(fit) > es.best.last.f:
208
+ degrading_iterations_count += 1
209
+ if degrading_iterations_count > 4:
210
+ utils.print_message('%d f-degrading iterations (set verbose<=4 to suppress)'
211
+ % degrading_iterations_count,
212
+ iteration=es.countiter)
213
+ es.tell(X, fit) # prepare for next iteration
214
+ if noise_handling: # it would be better to also use these f-evaluations in tell
215
+ es.sigma *= noisehandler(X, fit, objective_function, es.ask,
216
+ args=args) ** fmin_opts['noise_change_sigma_exponent']
217
+
218
+ es.countevals += noisehandler.evaluations_just_done # TODO: this is a hack, not important though
219
+ # es.more_to_write.append(noisehandler.evaluations_just_done)
220
+ if noisehandler.maxevals > noisehandler.minevals:
221
+ es.more_to_write.append(noisehandler.evaluations)
222
+ if 1 < 3:
223
+ # If sigma was above multiplied by the same
224
+ # factor cmean is divided by here, this is
225
+ # like only multiplying kappa instead of
226
+ # changing cmean and sigma.
227
+ es.sp.cmean *= np.exp(-noise_kappa_exponent * np.tanh(noisehandler.noiseS))
228
+ es.sp.cmean[es.sp.cmean > 1] = 1.0 # also works with "scalar arrays" like np.array(1.2)
229
+ for f in callback:
230
+ f is None or f(es)
231
+ es.disp()
232
+ logger.add(
233
+ # more_data=[noisehandler.evaluations, 10**noisehandler.noiseS] if noise_handling else [],
234
+ modulo=1 if es.stop() and logger.modulo else None)
235
+ if (opts['verb_log'] and opts['verb_plot'] and
236
+ (es.countiter % max(opts['verb_plot'], opts['verb_log']) == 0 or es.stop())):
237
+ logger.plot(324)
238
+
239
+ # end while not es.stop
240
+ if opts['eval_final_mean'] and callable(objective_function):
241
+ mean_pheno = es.gp.pheno(es.mean,
242
+ into_bounds=es.boundary_handler.repair,
243
+ archive=es.sent_solutions)
244
+ fmean = yield mean_pheno
245
+ es.countevals += 1
246
+ es.best.update([mean_pheno], es.sent_solutions, [fmean], es.countevals)
247
+
248
+ best.update(es.best, es.sent_solutions) # in restarted case
249
+ # es.best.update(best)
250
+
251
+ this_evals = es.countevals - base_evals
252
+ base_evals = es.countevals
253
+
254
+ # BIPOP stats update
255
+
256
+ if irun == 0:
257
+ popsize0 = opts['popsize']
258
+ maxiter0 = opts['maxiter']
259
+ # XXX: This might be a bug? Reproduced from Matlab
260
+ # small_i.append(this_evals)
261
+
262
+ if bipop:
263
+ if poptype == 'small':
264
+ small_i.append(this_evals)
265
+ else: # poptype == 'large'
266
+ large_i.append(this_evals)
267
+
268
+ # final message
269
+ if opts['verb_disp']:
270
+ es.result_pretty(irun, time.asctime(time.localtime()),
271
+ best.f)
272
+
273
+ irun += 1
274
+ # if irun > fmin_opts['restarts'] or 'ftarget' in es.stop() \
275
+ # if irun > restarts or 'ftarget' in es.stop() \
276
+ all_stoppings.append(dict(es.stop(check=False))) # keeping the order
277
+ if irun - runs_with_small > fmin_opts['restarts'] or 'ftarget' in es.stop() \
278
+ or 'maxfevals' in es.stop(check=False) or 'callback' in es.stop(check=False):
279
+ break
280
+ opts['verb_append'] = es.countevals
281
+ opts['popsize'] = fmin_opts['incpopsize'] * es.sp.popsize # TODO: use rather options?
282
+ try:
283
+ opts['seed'] += 1
284
+ except TypeError:
285
+ pass
286
+
287
+ # while irun
288
+
289
+ # es.out['best'] = best # TODO: this is a rather suboptimal type for inspection in the shell
290
+ if irun:
291
+ es.best.update(best)
292
+ # TODO: there should be a better way to communicate the overall best
293
+ return es.result + (es.stop(), es, logger)
294
+ ### 4560
295
+ # TODO refine output, can #args be flexible?
296
+ # is this well usable as it is now?
297
+ else: # except KeyboardInterrupt: # Exception as e:
298
+ if eval(safe_str(options['verb_disp'])) > 0:
299
+ print(' in/outcomment ``raise`` in last line of cma.fmin to prevent/restore KeyboardInterrupt exception')
300
+ raise KeyboardInterrupt # cave: swallowing this exception can silently mess up experiments, if ctrl-C is hit
301
+
302
+
303
+ class MyCMAEvolutionStrategy(CMAEvolutionStrategy):
304
+
305
+ def ask_and_eval(self, func, args=(), gradf=None, number=None, xmean=None, sigma_fac=1,
306
+ evaluations=1, aggregation=np.median, kappa=1, parallel_mode=False):
307
+
308
+ # initialize
309
+ popsize = self.sp.popsize
310
+ if number is not None:
311
+ popsize = int(number)
312
+
313
+ if self.opts['CMA_mirrormethod'] == 1: # direct selective mirrors
314
+ nmirrors = Mh.sround(self.sp.lam_mirr * popsize / self.sp.popsize)
315
+ self._mirrormethod1_done = self.countiter
316
+ else:
317
+ # method==0 unconditional mirrors are done in ask_geno
318
+ # method==2 delayed selective mirrors are done via injection
319
+ nmirrors = 0
320
+ assert nmirrors <= popsize // 2
321
+ self.mirrors_idx = np.arange(nmirrors) # might never be used
322
+ is_feasible = self.opts['is_feasible']
323
+
324
+ # do the work
325
+ fit = [] # or np.NaN * np.empty(number)
326
+ X_first = self.ask(popsize, xmean=xmean, gradf=gradf, args=args)
327
+ if xmean is None:
328
+ xmean = self.mean # might have changed in self.ask
329
+ X = []
330
+ if parallel_mode:
331
+ if hasattr(func, 'evaluations'):
332
+ evals0 = func.evaluations
333
+ fit_first = yield X_first
334
+ # the rest is only book keeping and warnings spitting
335
+ if hasattr(func, 'evaluations'):
336
+ self.countevals += func.evaluations - evals0 - self.popsize # why not .sp.popsize ?
337
+ if nmirrors and self.opts['CMA_mirrormethod'] > 0 and self.countiter < 2:
338
+ utils.print_warning(
339
+ "selective mirrors will not work in parallel mode",
340
+ "ask_and_eval", "CMAEvolutionStrategy")
341
+ if evaluations > 1 and self.countiter < 2:
342
+ utils.print_warning(
343
+ "aggregating evaluations will not work in parallel mode",
344
+ "ask_and_eval", "CMAEvolutionStrategy")
345
+ else:
346
+ fit_first = len(X_first) * [None]
347
+ for k in range(popsize):
348
+ x, f = X_first.pop(0), fit_first.pop(0)
349
+ rejected = -1
350
+ while f is None or not is_feasible(x, f): # rejection sampling
351
+ if parallel_mode:
352
+ utils.print_warning(
353
+ "rejection sampling will not work in parallel mode"
354
+ " unless the parallel_objective makes a distinction\n"
355
+ "between called with a numpy array vs a list (of"
356
+ " numpy arrays) as first argument.",
357
+ "ask_and_eval", "CMAEvolutionStrategy")
358
+ rejected += 1
359
+ if rejected: # resample
360
+ x = self.ask(1, xmean, sigma_fac)[0]
361
+ elif k >= popsize - nmirrors: # selective mirrors
362
+ if k == popsize - nmirrors:
363
+ self.mirrors_idx = np.argsort(fit)[-1:-1 - nmirrors:-1]
364
+ x = self.get_mirror(X[self.mirrors_idx[popsize - 1 - k]])
365
+
366
+ # constraints handling test hardwired ccccccccccc
367
+
368
+ length_normalizer = 1
369
+ # zzzzzzzzzzzzzzzzzzzzzzzzz
370
+ if 11 < 3:
371
+ # for some unclear reason, this normalization does not work as expected: the step-size
372
+ # becomes sometimes too large and overall the mean might diverge. Is the reason that
373
+ # we observe random fluctuations, because the length is not selection relevant?
374
+ # However sigma-adaptation should mainly work on the correlation, not the length?
375
+ # Or is the reason the deviation of the direction introduced by using the original
376
+ # length, which also can effect the measured correlation?
377
+ # Update: if the length of z in CSA is clipped at chiN+1, it works, but only sometimes?
378
+ length_normalizer = self.N**0.5 / self.mahalanobis_norm(x - xmean) # self.const.chiN < N**0.5, the constant here is irrelevant (absorbed by kappa)
379
+ # print(self.N**0.5 / self.mahalanobis_norm(x - xmean))
380
+ # self.more_to_write += [length_normalizer * 1e-3, length_normalizer * self.mahalanobis_norm(x - xmean) * 1e2]
381
+ if kappa == 1:
382
+ f = yield x
383
+ else:
384
+ f = yield xmean + kappa * length_normalizer * (x - xmean)
385
+
386
+ if is_feasible(x, f) and evaluations > 1:
387
+ if kappa == 1:
388
+ _f = yield x
389
+ f = aggregation([f] + [_f])
390
+ else:
391
+ _f = []
392
+ for _i in range(int(evaluations - 1)):
393
+ v = yield xmean + kappa * length_normalizer * (x - xmean)
394
+ _f.append(v)
395
+ f = aggregation([f] + _f)
396
+
397
+ if (rejected + 1) % 1000 == 0:
398
+ utils.print_warning(' %d solutions rejected (f-value NaN or None) at iteration %d' %
399
+ (rejected, self.countiter))
400
+ fit.append(f)
401
+ X.append(x)
402
+ self.evaluations_per_f_value = int(evaluations)
403
+ if any(f is None or utils.is_nan(f) for f in fit):
404
+ idxs = [i for i in range(len(fit))
405
+ if fit[i] is None or utils.is_nan(fit[i])]
406
+ utils.print_warning("f-values %s contain None or NaN at indices %s"
407
+ % (str(fit[:30]) + ('...' if len(fit) > 30 else ''),
408
+ str(idxs)),
409
+ 'ask_and_tell',
410
+ 'CMAEvolutionStrategy',
411
+ self.countiter)
412
+ return X, fit