+"""Particle swarm optimization"""
+
+import random
+import multiprocessing
+from functools import partial
+
+def particle(dimension, bound, func_d):
+ position = [2 * bound * random.random() - bound for _ in xrange(dimension)]
+ velocity = [2 * bound * random.random() - bound for _ in xrange(dimension)]
+ value = func_d(*position)
+ return value, position, velocity, value, position
+
+def move(particle, omega, phi_p, phi_g, v_max, global_best, func_d):
+ _, position, velocity, best_value, best_position = particle
+ position = [p + v for (p, v) in zip(position, velocity)]
+ velocity = [omega * v
+ + phi_p * random.random() * (b - x)
+ + phi_g * random.random() * (g - x)
+ for (v, x, b, g) in zip(velocity, position,
+ best_position, global_best)]
+ velocity = [min(max(v, - v_max), v_max) for v in velocity]
+ value = func_d(*position)
+ if value > best_value:
+ best_value, best_position = value, position
+ return value, position, velocity, best_value, best_position
+
+def optimize(dimension, boundary, function_d, n_parts, n_turns):
+ pool = multiprocessing.Pool(None)
+ particles = [particle(dimension, boundary, function_d)
+ for _ in xrange(n_parts)]
+ gl_best = max(particles)
+ for _ in xrange(n_turns):
+ move_p = partial(move, omega=0.9, phi_p=0.9, phi_g=0.2, v_max=20.,
+ global_best=gl_best[1], func_d=function_d)
+ particles = pool.map(move_p, particles)
+ gl_best = max(max(particles), gl_best)
+ pool.terminate()
+ pool.join()
+ return gl_best[1]