Open huaiyan opened 6 years ago
I also noticed this. It looks like his implementation of PSO is wrong
@bonlime @huaiyan have you done this code ?? so can you help me for this code.
@khushbukella I used this repo as a base but added multiprocessing and little fixes to it. Here is my full code of PSO. This repo is actually garbage because some other implementations are also wrong. (For example Cuckoo search is completely wrong).
# -*- coding: UTF-8 -*-
from multiprocessing import Pool
import numpy as np
from tqdm import tqdm
class DummyMapper:
def __init__(self):
pass
def map(self, f, x):
return np.array(list(map(f, x)))
def close(self):
pass
class PSO:
"""
Particle Swarm Optimization
"""
def __init__(self, n, function, param_bounds, iteration, w=0.7, c1=1.5,
c2=1.5, num_workers=None):
"""
Known to give good results:
w value should be about 0.7 to 0.8, and c_1 and c_2 around 1.5 to 1.7.
Args:
n: number of agents
function: test function
param_bounds: list of shape (dimension,2) with lower and upper bound
for each parameter
iteration: the number of iterations
w : balance between the range of research and consideration for
suboptimal decisions found (default value is 0.5):
w>1 the particle velocity increases, they fly apart and inspect
the space more carefully;
w<1 particle velocity decreases, convergence speed depends
on parameters c1 and c2 ;
c1: ratio between "cognitive" and "social" component
c2: ratio between "cognitive" and "social" component
num_workers: number of processes to use. gives 3-4x speed up
"""
self.Positions = []
self.scor_hist = []
dimension = param_bounds.shape[0]
if num_workers == 1:
self.pool = DummyMapper()
else:
self.pool = Pool(num_workers)
# Init
self.__agents = np.array(
[np.random.uniform(param[0], param[1], n) for param in param_bounds]).T
velocity = np.zeros((n, dimension))
self.Positions = []
self.Positions = np.append(self.Positions, self.__agents)
# Pbest - personal best. Gbest - group best
scores = np.asarray(self.pool.map(function, self.__agents))
Pbest_scores = scores
Pbest = self.__agents
Gbest = self.__agents[Pbest_scores.argmin()]
Gbest_score = scores[Pbest_scores.argmin()]
for t in tqdm(range(iteration), desc='Iteration'):
# random step in different directions
# r1 = np.random.random((n, dimension))
# r2 = np.random.random((n, dimension))
# the same step in different directions
r1 = np.random.random()
r2 = np.random.random()
velocity = w * velocity + c1 * r1 * \
(Pbest - self.__agents) + c2 * r2 * (Gbest - self.__agents)
self.__agents += velocity
# check that we are still in param_bounds, clip if not
self.__agents = np.vstack([np.clip(self.__agents[:, idx],
param_bounds[idx][0],
param_bounds[idx][1]) for idx in range(dimension)]).T
# update Pbest & Gbest
scores = np.asarray(self.pool.map(function, self.__agents))
for idx, agent in enumerate(self.__agents):
if scores[idx] <= Pbest_scores[idx]:
Pbest_scores[idx] = scores[idx]
Pbest[idx] = agent
if scores[idx] <= Gbest_score:
Gbest_score = scores[idx]
Gbest = agent
# save history
self.Positions = np.append(self.Positions, self.__agents)
self.scor_hist = np.append(self.scor_hist, Gbest_score)
# print(Gbest_score)
self.Gbest = Gbest
self.Gbest_score = Gbest_score
self.pool.close()
from your code I think in every iteration, to every particle the Pbest are the same which is the previous iteration's best particle, but not every particle's history best position. could you please tell me is that a particular version of PSO or I misunderstand your code?