9fdee2ded0d599f739e2f63cadde44f8db7123bf
[imago.git] / pso.py
1 """Particle swarm optimization"""
2
3 import random
4 import multiprocessing
5 from functools import partial
6
7 def particle(dimension, bound, func_d):
8     position = [2 * bound * random.random() - bound for _ in xrange(dimension)]
9     velocity = [2 * bound * random.random() - bound for _ in xrange(dimension)]
10     value = func_d(*position)
11     return value, position, velocity, value, position
12
13 def move(particle, omega, phi_p, phi_g, v_max, global_best, func_d):
14     _, position, velocity, best_value, best_position = particle
15     position = [p + v for (p, v) in zip(position, velocity)]
16     velocity = [omega * v 
17                 + phi_p * random.random() * (b - x)
18                 + phi_g * random.random() * (g - x)
19                 for (v, x, b, g) in zip(velocity, position,
20                                         best_position, global_best)]
21     velocity = [min(max(v, - v_max), v_max) for v in velocity] 
22     value = func_d(*position)
23     if value > best_value:
24         best_value, best_position = value, position
25     return value, position, velocity, best_value, best_position
26
27 def optimize(dimension, boundary, function_d, n_parts, n_turns):
28     pool = multiprocessing.Pool(None)
29     particles = [particle(dimension, boundary, function_d)
30                  for _ in xrange(n_parts)]
31     gl_best = max(particles)
32     for _ in xrange(n_turns):
33         move_p = partial(move, omega=0.9, phi_p=0.9, phi_g=0.2, v_max=20.,
34                          global_best=gl_best[1], func_d=function_d)
35         particles = pool.map(move_p, particles)
36         gl_best = max(max(particles), gl_best)
37     pool.terminate()
38     pool.join()
39     return gl_best[1]