SISDevelop / SwarmPackagePy

Library of swarm optimization algorithms.
136 stars 78 forks source link

Confused with pso #4

Open huaiyan opened 6 years ago

huaiyan commented 6 years ago

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?

bonlime commented 6 years ago

I also noticed this. It looks like his implementation of PSO is wrong

khushbukella commented 5 years ago

@bonlime @huaiyan have you done this code ?? so can you help me for this code.

bonlime commented 5 years ago

@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()