# !/usr/bin/env python
# Created by "Thieu" at 09:49, 17/03/2020 ----------%
# Email: nguyenthieu2102@gmail.com %
# Github: https://github.com/thieu1995 %
# --------------------------------------------------%
import numpy as np
from copy import deepcopy
from mealpy.optimizer import Optimizer
[docs]class BasePSO(Optimizer):
"""
The original version of: Particle Swarm Optimization (PSO)
Hyper-parameters should fine tuned in approximate range to get faster convergen toward the global optimum:
+ c1 (float): [1, 3], local coefficient, default = 2.05
+ c2 (float): [1, 3], global coefficient, default = 2.05
+ w_min (float): [0.1, 0.5], Weight min of bird, default = 0.4
+ w_max (float): [0.8, 2.0], Weight max of bird, default = 0.9
Examples
~~~~~~~~
>>> import numpy as np
>>> from mealpy.swarm_based.PSO import BasePSO
>>>
>>> def fitness_function(solution):
>>> return np.sum(solution**2)
>>>
>>> problem_dict1 = {
>>> "fit_func": fitness_function,
>>> "lb": [-10, -15, -4, -2, -8],
>>> "ub": [10, 15, 12, 8, 20],
>>> "minmax": "min",
>>> "verbose": True,
>>> }
>>>
>>> epoch = 1000
>>> pop_size = 50
>>> c1 = 2.05
>>> c2 = 2.05
>>> w_min = 0.4
>>> w_max = 0.9
>>> model = BasePSO(problem_dict1, epoch, pop_size, c1, c2, w_min, w_max)
>>> best_position, best_fitness = model.solve()
>>> print(f"Solution: {best_position}, Fitness: {best_fitness}")
References
~~~~~~~~~~
[1] Kennedy, J. and Eberhart, R., 1995, November. Particle swarm optimization. In Proceedings of
ICNN'95-international conference on neural networks (Vol. 4, pp. 1942-1948). IEEE.
"""
ID_VEC = 2 # Velocity
ID_LOP = 3 # Local position
ID_LOF = 4 # Local fitness
def __init__(self, problem, epoch=10000, pop_size=100, c1=2.05, c2=2.05, w_min=0.4, w_max=0.9, **kwargs):
"""
Args:
problem (dict): The problem dictionary
epoch (int): maximum number of iterations, default = 10000
pop_size (int): number of population size, default = 100
c1 (float): [0-2] local coefficient
c2 (float): [0-2] global coefficient
w_min (float): Weight min of bird, default = 0.4
w_max (float): Weight max of bird, default = 0.9
"""
super().__init__(problem, kwargs)
self.nfe_per_epoch = pop_size
self.sort_flag = False
self.epoch = epoch
self.pop_size = pop_size
self.c1 = c1
self.c2 = c2
self.w_min = w_min
self.w_max = w_max
self.v_max = 0.5 * (self.problem.ub - self.problem.lb)
self.v_min = -self.v_max
[docs] def create_solution(self):
"""
To get the position, fitness wrapper, target and obj list
+ A[self.ID_POS] --> Return: position
+ A[self.ID_TAR] --> Return: [target, [obj1, obj2, ...]]
+ A[self.ID_TAR][self.ID_FIT] --> Return: target
+ A[self.ID_TAR][self.ID_OBJ] --> Return: [obj1, obj2, ...]
Returns:
list: wrapper of solution with format [position, [target, [obj1, obj2, ...]], velocity, local_pos, local_fit]
"""
position = np.random.uniform(self.problem.lb, self.problem.ub)
position = self.amend_position(position)
fitness = self.get_fitness_position(position=position)
velocity = np.random.uniform(self.v_min, self.v_max)
local_pos = deepcopy(position)
local_fit = deepcopy(fitness)
return [position, fitness, velocity, local_pos, local_fit]
[docs] def amend_position(self, position=None):
"""
If solution out of bound at dimension x, then it will re-arrange to random location in the range of domain
Args:
position: vector position (location) of the solution.
Returns:
Amended position
"""
return np.where(np.logical_and(self.problem.lb <= position, position <= self.problem.ub),
position, np.random.uniform(self.problem.lb, self.problem.ub))
[docs] def evolve(self, epoch):
"""
The main operations (equations) of algorithm. Inherit from Optimizer class
Args:
epoch (int): The current iteration
"""
# Update weight after each move count (weight down)
w = (self.epoch - epoch) / self.epoch * (self.w_max - self.w_min) + self.w_min
pop_new = []
for idx in range(0, self.pop_size):
agent = deepcopy(self.pop[idx])
v_new = w * self.pop[idx][self.ID_VEC] + self.c1 * np.random.rand() * \
(self.pop[idx][self.ID_LOP] - self.pop[idx][self.ID_POS]) + \
self.c2 * np.random.rand() * (self.g_best[self.ID_POS] - self.pop[idx][self.ID_POS])
# v_new = np.clip(v_new, self.v_min, self.v_max)
x_new = self.pop[idx][self.ID_POS] + v_new # Xi(new) = Xi(old) + Vi(new) * deltaT (deltaT = 1)
pos_new = self.amend_position(x_new)
agent[self.ID_POS] = pos_new
agent[self.ID_VEC] = v_new
pop_new.append(agent)
pop_new = self.update_fitness_population(pop_new)
for idx in range(0, self.pop_size):
if self.compare_agent(pop_new[idx], self.pop[idx]):
self.pop[idx] = deepcopy(pop_new[idx])
if self.compare_agent(pop_new[idx], [None, self.pop[idx][self.ID_LOF]]):
self.pop[idx][self.ID_LOP] = deepcopy(pop_new[idx][self.ID_POS])
self.pop[idx][self.ID_LOF] = deepcopy(pop_new[idx][self.ID_TAR])
[docs]class PPSO(Optimizer):
"""
The original version of: Phasor Particle Swarm Optimization (P-PSO)
Notes
~~~~~
+ This code is converted from matlab code (sent from author: Ebrahim Akbari)
Examples
~~~~~~~~
>>> import numpy as np
>>> from mealpy.swarm_based.PSO import PPSO
>>>
>>> def fitness_function(solution):
>>> return np.sum(solution**2)
>>>
>>> problem_dict1 = {
>>> "fit_func": fitness_function,
>>> "lb": [-10, -15, -4, -2, -8],
>>> "ub": [10, 15, 12, 8, 20],
>>> "minmax": "min",
>>> "verbose": True,
>>> }
>>>
>>> epoch = 1000
>>> pop_size = 50
>>> model = PPSO(problem_dict1, epoch, pop_size)
>>> best_position, best_fitness = model.solve()
>>> print(f"Solution: {best_position}, Fitness: {best_fitness}")
References
~~~~~~~~~~
[1] Ghasemi, M., Akbari, E., Rahimnejad, A., Razavi, S.E., Ghavidel, S. and Li, L., 2019.
Phasor particle swarm optimization: a simple and efficient variant of PSO. Soft Computing, 23(19), pp.9701-9718.
"""
ID_VEC = 2 # Velocity
ID_LOP = 3 # Local position
ID_LOF = 4 # Local fitness
def __init__(self, problem, epoch=10000, pop_size=100, **kwargs):
"""
Args:
problem (dict): The problem dictionary
epoch (int): maximum number of iterations, default = 10000
pop_size (int): number of population size, default = 100
"""
super().__init__(problem, kwargs)
self.nfe_per_epoch = pop_size
self.sort_flag = False
self.epoch = epoch
self.pop_size = pop_size
self.v_max = 0.5 * (self.problem.ub - self.problem.lb)
self.v_min = -self.v_max
# Dynamic variable
self.dyn_delta_list = np.random.uniform(0, 2 * np.pi, self.pop_size)
[docs] def create_solution(self):
"""
To get the position, fitness wrapper, target and obj list
+ A[self.ID_POS] --> Return: position
+ A[self.ID_TAR] --> Return: [target, [obj1, obj2, ...]]
+ A[self.ID_TAR][self.ID_FIT] --> Return: target
+ A[self.ID_TAR][self.ID_OBJ] --> Return: [obj1, obj2, ...]
Returns:
list: wrapper of solution with format [position, [target, [obj1, obj2, ...]], velocity, local_pos, local_fit]
"""
position = np.random.uniform(self.problem.lb, self.problem.ub)
position = self.amend_position(position)
fitness = self.get_fitness_position(position=position)
velocity = np.random.uniform(self.v_min, self.v_max)
local_pos = deepcopy(position)
local_fit = deepcopy(fitness)
return [position, fitness, velocity, local_pos, local_fit]
[docs] def evolve(self, epoch):
"""
The main operations (equations) of algorithm. Inherit from Optimizer class
Args:
epoch (int): The current iteration
"""
pop_new = []
for i in range(0, self.pop_size):
agent = deepcopy(self.pop[i])
aa = 2 * (np.sin(self.dyn_delta_list[i]))
bb = 2 * (np.cos(self.dyn_delta_list[i]))
ee = np.abs(np.cos(self.dyn_delta_list[i])) ** aa
tt = np.abs(np.sin(self.dyn_delta_list[i])) ** bb
v_new = ee * (self.pop[i][self.ID_LOP] - self.pop[i][self.ID_POS]) + tt * (self.g_best[self.ID_POS] - self.pop[i][self.ID_POS])
v_new = np.minimum(np.maximum(v_new, -self.v_max), self.v_max)
agent[self.ID_VEC] = deepcopy(v_new)
pos_new = self.pop[i][self.ID_POS] + v_new
agent[self.ID_POS] = self.amend_position(pos_new)
self.dyn_delta_list[i] += np.abs(aa + bb) * (2 * np.pi)
self.v_max = (np.abs(np.cos(self.dyn_delta_list[i])) ** 2) * (self.problem.ub - self.problem.lb)
pop_new.append(agent)
# Update fitness for all solutions
pop_new = self.update_fitness_population(pop_new)
# Update current position, current velocity and compare with past position, past fitness (local best)
for idx in range(0, self.pop_size):
if self.compare_agent(pop_new[idx], self.pop[idx]):
self.pop[idx] = deepcopy(pop_new[idx])
if self.compare_agent(pop_new[idx], [None, self.pop[idx][self.ID_LOF]]):
self.pop[idx][self.ID_LOP] = deepcopy(pop_new[idx][self.ID_POS])
self.pop[idx][self.ID_LOF] = deepcopy(pop_new[idx][self.ID_TAR])
[docs]class HPSO_TVAC(PPSO):
"""
The original version of: Ant Colony Optimization Continuous (HPSO-TVAC)
Notes
~~~~~
+ This code is converted from matlab code (sent from author: Ebrahim Akbari)
Hyper-parameters should fine tuned in approximate range to get faster convergen toward the global optimum:
+ ci (float): [0.3, 1.0], c initial, default = 0.5
+ cf (float): [0.0, 0.3], c final, default = 0.0
Examples
~~~~~~~~
>>> import numpy as np
>>> from mealpy.swarm_based.PSO import HPSO_TVAC
>>>
>>> def fitness_function(solution):
>>> return np.sum(solution**2)
>>>
>>> problem_dict1 = {
>>> "fit_func": fitness_function,
>>> "lb": [-10, -15, -4, -2, -8],
>>> "ub": [10, 15, 12, 8, 20],
>>> "minmax": "min",
>>> "verbose": True,
>>> }
>>>
>>> epoch = 1000
>>> pop_size = 50
>>> ci = 0.5
>>> cf = 0.0
>>> model = HPSO_TVAC(problem_dict1, epoch, pop_size, ci, cf)
>>> best_position, best_fitness = model.solve()
>>> print(f"Solution: {best_position}, Fitness: {best_fitness}")
References
~~~~~~~~~~
[1] Ghasemi, M., Aghaei, J. and Hadipour, M., 2017. New self-organising hierarchical PSO with
jumping time-varying acceleration coefficients. Electronics Letters, 53(20), pp.1360-1362.
"""
def __init__(self, problem, epoch=10000, pop_size=100, ci=0.5, cf=0.0, **kwargs):
"""
Args:
problem (dict): The problem dictionary
epoch (int): maximum number of iterations, default = 10000
pop_size (int): number of population size, default = 100
ci (float): c initial, default = 0.5
cf (float): c final, default = 0.0
"""
super().__init__(problem, epoch, pop_size, **kwargs)
self.nfe_per_epoch = pop_size
self.sort_flag = False
self.epoch = epoch
self.pop_size = pop_size
self.ci = ci
self.cf = cf
[docs] def evolve(self, epoch):
"""
The main operations (equations) of algorithm. Inherit from Optimizer class
Args:
epoch (int): The current iteration
"""
c_it = ((self.cf - self.ci) * ((epoch + 1) / self.epoch)) + self.ci
pop_new = []
for i in range(0, self.pop_size):
agent = deepcopy(self.pop[i])
idx_k = np.random.randint(0, self.pop_size)
w = np.random.normal()
while np.abs(w - 1.0) < 0.01:
w = np.random.normal()
c1_it = np.abs(w) ** (c_it * w)
c2_it = np.abs(1 - w) ** (c_it / (1 - w))
#################### HPSO
v_new = c1_it * np.random.uniform(0, 1, self.problem.n_dims) * (self.pop[i][self.ID_LOP] - self.pop[i][self.ID_POS]) + \
c2_it * np.random.uniform(0, 1, self.problem.n_dims) * \
(self.g_best[self.ID_POS] + self.pop[idx_k][self.ID_LOP] - 2 * self.pop[i][self.ID_POS])
np.where(v_new == 0, np.sign(0.5 - np.random.uniform()) * np.random.uniform() * self.v_max, v_new)
v_new = np.sign(v_new) * np.minimum(np.abs(v_new), self.v_max)
#########################
v_new = np.minimum(np.maximum(v_new, -self.v_max), self.v_max)
pos_new = self.pop[i][self.ID_POS] + v_new
agent[self.ID_VEC] = v_new
agent[self.ID_POS] = self.amend_position(pos_new)
pop_new.append(agent)
# Update fitness for all solutions
pop_new = self.update_fitness_population(pop_new)
# Update current position, current velocity and compare with past position, past fitness (local best)
for idx in range(0, self.pop_size):
if self.compare_agent(pop_new[idx], self.pop[idx]):
self.pop[idx] = deepcopy(pop_new[idx])
if self.compare_agent(pop_new[idx], [None, self.pop[idx][self.ID_LOF]]):
self.pop[idx][self.ID_LOP] = deepcopy(pop_new[idx][self.ID_POS])
self.pop[idx][self.ID_LOF] = deepcopy(pop_new[idx][self.ID_TAR])
[docs]class C_PSO(BasePSO):
"""
The original version of: Chaos Particle Swarm Optimization (C-PSO)
Hyper-parameters should fine tuned in approximate range to get faster convergen toward the global optimum:
+ c1 (float): [1.0, 3.0] local coefficient, default = 2.05
+ c2 (float): [1.0, 3.0] global coefficient, default = 2.05
+ w_min (float): [0.1, 0.4], Weight min of bird, default = 0.4
+ w_max (float): [0.4, 2.0], Weight max of bird, default = 0.9
Examples
~~~~~~~~
>>> import numpy as np
>>> from mealpy.swarm_based.PSO import C_PSO
>>>
>>> def fitness_function(solution):
>>> return np.sum(solution**2)
>>>
>>> problem_dict1 = {
>>> "fit_func": fitness_function,
>>> "lb": [-10, -15, -4, -2, -8],
>>> "ub": [10, 15, 12, 8, 20],
>>> "minmax": "min",
>>> "verbose": True,
>>> }
>>>
>>> epoch = 1000
>>> pop_size = 50
>>> c1 = 2.05
>>> c2 = 2.05
>>> w_min = 0.4
>>> w_max = 0.9
>>> model = C_PSO(problem_dict1, epoch, pop_size, c1, c2, w_min, w_max)
>>> best_position, best_fitness = model.solve()
>>> print(f"Solution: {best_position}, Fitness: {best_fitness}")
References
~~~~~~~~~~
[1] Liu, B., Wang, L., Jin, Y.H., Tang, F. and Huang, D.X., 2005. Improved particle swarm optimization
combined with chaos. Chaos, Solitons & Fractals, 25(5), pp.1261-1271.
"""
def __init__(self, problem, epoch=10000, pop_size=100, c1=2.05, c2=2.05, w_min=0.4, w_max=0.9, **kwargs):
"""
Args:
problem (dict): The problem dictionary
epoch (int): maximum number of iterations, default = 10000
pop_size (int): number of population size, default = 100
c1 (float): [0-2] local coefficient, default = 2.05
c2 (float): [0-2] global coefficient, default = 2.05
w_min (float): Weight min of bird, default = 0.4
w_max (float): Weight max of bird, default = 0.9
"""
super().__init__(problem, epoch, pop_size, c1, c2, w_min, w_max, **kwargs)
self.nfe_per_epoch = pop_size
self.sort_flag = False
self.epoch = epoch
self.pop_size = pop_size
self.c1 = c1
self.c2 = c2
self.w_min = w_min
self.w_max = w_max
self.v_max = 0.5 * (self.problem.ub - self.problem.lb)
self.v_min = -self.v_max
self.N_CLS = int(self.pop_size / 5) # Number of chaotic local searches
# Dynamic variable
self.dyn_lb = deepcopy(self.problem.lb)
self.dyn_ub = deepcopy(self.problem.ub)
def __get_weights__(self, fit, fit_avg, fit_min):
temp1 = self.w_min + (self.w_max - self.w_min) * (fit - fit_min) / (fit_avg - fit_min)
if self.problem.minmax == "min":
output = temp1 if fit <= fit_avg else self.w_max
else:
output = self.w_max if fit <= fit_avg else temp1
return output
[docs] def evolve(self, epoch):
"""
The main operations (equations) of algorithm. Inherit from Optimizer class
Args:
epoch (int): The current iteration
"""
nfe_epoch = 0
list_fits = [item[self.ID_TAR][self.ID_FIT] for item in self.pop]
fit_avg = np.mean(list_fits)
fit_min = np.min(list_fits)
pop_new = []
for i in range(self.pop_size):
agent = deepcopy(self.pop[i])
w = self.__get_weights__(self.pop[i][self.ID_TAR][self.ID_FIT], fit_avg, fit_min)
v_new = w * self.pop[i][self.ID_VEC] + self.c1 * np.random.rand() * (self.pop[i][self.ID_LOP] - self.pop[i][self.ID_POS]) + \
self.c2 * np.random.rand() * (self.g_best[self.ID_POS] - self.pop[i][self.ID_POS])
v_new = np.clip(v_new, self.v_min, self.v_max)
x_new = self.pop[i][self.ID_POS].astype(float) + v_new
agent[self.ID_VEC] = v_new
agent[self.ID_POS] = self.amend_position(x_new)
pop_new.append(agent)
# Update fitness for all solutions
pop_new = self.update_fitness_population(pop_new)
nfe_epoch += self.pop_size
# Update current position, current velocity and compare with past position, past fitness (local best)
for idx in range(0, self.pop_size):
if self.compare_agent(pop_new[idx], self.pop[idx]):
self.pop[idx] = deepcopy(pop_new[idx])
if self.compare_agent(pop_new[idx], [None, self.pop[idx][self.ID_LOF]]):
self.pop[idx][self.ID_LOP] = deepcopy(pop_new[idx][self.ID_POS])
self.pop[idx][self.ID_LOF] = deepcopy(pop_new[idx][self.ID_TAR])
## Implement chaostic local search for the best solution
g_best = self.g_best
cx_best_0 = (self.g_best[self.ID_POS] - self.problem.lb) / (self.problem.ub - self.problem.lb) # Eq. 7
cx_best_1 = 4 * cx_best_0 * (1 - cx_best_0) # Eq. 6
x_best = self.problem.lb + cx_best_1 * (self.problem.ub - self.problem.lb) # Eq. 8
x_best = self.amend_position(x_best)
fit_best = self.get_fitness_position(x_best)
if self.compare_agent([x_best, fit_best], self.g_best):
g_best = [x_best, fit_best]
r = np.random.rand()
bound_min = np.stack([self.dyn_lb, g_best[self.ID_POS] - r * (self.dyn_ub - self.dyn_lb)])
self.dyn_lb = np.max(bound_min, axis=0)
bound_max = np.stack([self.dyn_ub, g_best[self.ID_POS] + r * (self.dyn_ub - self.dyn_lb)])
self.dyn_ub = np.min(bound_max, axis=0)
pop_new_child = self.create_population(self.pop_size - self.N_CLS)
self.pop = self.get_sorted_strim_population(self.pop + pop_new_child, self.pop_size)
nfe_epoch += 1 + (self.pop_size - self.N_CLS)
self.nfe_per_epoch = nfe_epoch
[docs]class CL_PSO(Optimizer):
"""
The original version of: Comprehensive Learning Particle Swarm Optimization (CL-PSO)
Hyper-parameters should fine tuned in approximate range to get faster convergen toward the global optimum:
+ c_local (float): [1.0, 3.0], local coefficient, default = 1.2
+ w_min (float): [0.1, 0.5], Weight min of bird, default = 0.4
+ w_max (float): [0.7, 2.0], Weight max of bird, default = 0.9
+ max_flag (int): [5, 20], Number of times, default = 7
Examples
~~~~~~~~
>>> import numpy as np
>>> from mealpy.swarm_based.PSO import CL_PSO
>>>
>>> def fitness_function(solution):
>>> return np.sum(solution**2)
>>>
>>> problem_dict1 = {
>>> "fit_func": fitness_function,
>>> "lb": [-10, -15, -4, -2, -8],
>>> "ub": [10, 15, 12, 8, 20],
>>> "minmax": "min",
>>> "verbose": True,
>>> }
>>>
>>> epoch = 1000
>>> pop_size = 50
>>> c_local = 1.2
>>> w_min = 0.4
>>> w_max = 0.9
>>> max_flag = 7
>>> model = CL_PSO(problem_dict1, epoch, pop_size, c_local, w_min, w_max, max_flag)
>>> best_position, best_fitness = model.solve()
>>> print(f"Solution: {best_position}, Fitness: {best_fitness}")
References
~~~~~~~~~~
[1] Liang, J.J., Qin, A.K., Suganthan, P.N. and Baskar, S., 2006. Comprehensive learning particle swarm optimizer
for global optimization of multimodal functions. IEEE transactions on evolutionary computation, 10(3), pp.281-295.
"""
ID_VEC = 2
ID_LOP = 3
ID_LOF = 4
def __init__(self, problem, epoch=10000, pop_size=100, c_local=1.2, w_min=0.4, w_max=0.9, max_flag=7, **kwargs):
"""
Args:
problem (dict): The problem dictionary
epoch (int): maximum number of iterations, default = 10000
pop_size (int): number of population size, default = 100
c_local (float): local coefficient, default = 1.2
w_min (float): Weight min of bird, default = 0.4
w_max (float): Weight max of bird, default = 0.9
max_flag (int): Number of times, default = 7
"""
super().__init__(problem, kwargs)
self.nfe_per_epoch = pop_size
self.sort_flag = False
self.epoch = epoch
self.pop_size = pop_size
self.c_local = c_local # Local coefficient
self.w_min = w_min # [0-1] -> [0.4-0.9] Weight of bird
self.w_max = w_max
self.max_flag = max_flag
self.v_max = 0.5 * (self.problem.ub - self.problem.lb)
self.v_min = -self.v_max
# Dynamic variable
self.flags = np.zeros(self.pop_size)
[docs] def create_solution(self):
"""
To get the position, fitness wrapper, target and obj list
+ A[self.ID_POS] --> Return: position
+ A[self.ID_TAR] --> Return: [target, [obj1, obj2, ...]]
+ A[self.ID_TAR][self.ID_FIT] --> Return: target
+ A[self.ID_TAR][self.ID_OBJ] --> Return: [obj1, obj2, ...]
Returns:
list: wrapper of solution with format [position, [target, [obj1, obj2, ...]], velocity, local_pos, local_fit]
"""
position = np.random.uniform(self.problem.lb, self.problem.ub)
position = self.amend_position(position)
fitness = self.get_fitness_position(position=position)
velocity = np.random.uniform(self.v_min, self.v_max)
local_pos = deepcopy(position)
local_fit = deepcopy(fitness)
return [position, fitness, velocity, local_pos, local_fit]
[docs] def evolve(self, epoch):
"""
The main operations (equations) of algorithm. Inherit from Optimizer class
Args:
epoch (int): The current iteration
"""
wk = self.w_max * (epoch / self.epoch) * (self.w_max - self.w_min)
pop_new = []
for i in range(0, self.pop_size):
agent = deepcopy(self.pop[i])
if self.flags[i] >= self.max_flag:
self.flags[i] = 0
agent = self.create_solution()
pci = 0.05 + 0.45 * (np.exp(10 * (i + 1) / self.pop_size) - 1) / (np.exp(10) - 1)
vec_new = deepcopy(self.pop[i][self.ID_VEC])
for j in range(0, self.problem.n_dims):
if np.random.rand() > pci:
vj = wk * self.pop[i][self.ID_VEC][j] + self.c_local * np.random.rand() * \
(self.pop[i][self.ID_LOP][j] - self.pop[i][self.ID_POS][j])
else:
id1, id2 = np.random.choice(list(set(range(0, self.pop_size)) - {i}), 2, replace=False)
if self.compare_agent(self.pop[id1], self.pop[id2]):
vj = wk * self.pop[i][self.ID_VEC][j] + self.c_local * np.random.rand() * \
(self.pop[id1][self.ID_LOP][j] - self.pop[i][self.ID_POS][j])
else:
vj = wk * self.pop[i][self.ID_VEC][j] + self.c_local * np.random.rand() * \
(self.pop[id2][self.ID_LOP][j] - self.pop[i][self.ID_POS][j])
vec_new[j] = vj
vec_new = np.clip(vec_new, self.v_min, self.v_max)
pos_new = self.pop[i][self.ID_POS] + vec_new
pos_new = self.amend_position(pos_new)
agent[self.ID_VEC] = vec_new
agent[self.ID_POS] = pos_new
pop_new.append(agent)
pop_new = self.update_fitness_population(pop_new)
# Update current position, current velocity and compare with past position, past fitness (local best)
for idx in range(0, self.pop_size):
if self.compare_agent(pop_new[idx], self.pop[idx]):
self.pop[idx] = deepcopy(pop_new[idx])
if self.compare_agent(pop_new[idx], [None, self.pop[idx][self.ID_LOF]]):
self.pop[idx][self.ID_LOP] = deepcopy(pop_new[idx][self.ID_POS])
self.pop[idx][self.ID_LOF] = deepcopy(pop_new[idx][self.ID_TAR])
self.flags[idx] = 0
else:
self.flags[idx] += 1