Skip to content

Commit

Permalink
'add_pso'
Browse files Browse the repository at this point in the history
  • Loading branch information
smasky committed May 6, 2024
1 parent 0d2c058 commit a2e6314
Show file tree
Hide file tree
Showing 9 changed files with 207 additions and 29 deletions.
4 changes: 3 additions & 1 deletion UQPyL/optimization/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from .moea_d import MOEA_D
from .mo_asmo import MOASMO
from ._binary_ga import Binary_GA
from .pso import PSO
__all__=[
'GA',
'Boxmin',
Expand All @@ -16,7 +17,8 @@
'NSGAII',
'MOASMO',
'MOEA_D',
'Binary_GA'
'Binary_GA',
'PSO'
]

MP_List=['Boxmin']
Expand Down
2 changes: 1 addition & 1 deletion UQPyL/optimization/asmo.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
lhs=LHS('classic')
class ASMO():
'''
Adaptive Surrogate Modelling-based Optimization
Adaptive Surrogate Modelling-based Optimization <Single> <Surrogate>
----------------------------------------------
Attributes:
problem: Problem
Expand Down
8 changes: 5 additions & 3 deletions UQPyL/optimization/ga.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import numpy as np
import math
from typing import Callable

from ..problems import Problem
from ..DoE import LHS
class GA():
'''
Genetic Algorithm
Genetic Algorithm <Single>
-------------------------------
Attributes:
problem: Problem
Expand Down Expand Up @@ -95,7 +96,8 @@ def run(self) -> dict:
iter=0
FEs=0

decs=np.random.random((self.n_samples,self.n_input))*(self.ub-self.lb)+self.lb
lhs=LHS('classic')
decs=(lhs(self.n_samples,self.n_input))*(self.ub-self.lb)+self.lb
objs=self.evaluate(decs)
FEs+=objs.shape[0]

Expand Down
2 changes: 1 addition & 1 deletion UQPyL/optimization/mo_asmo.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
lhs=LHS("center")
class MOASMO():
'''
Multi-Objective Adaptive Surrogate Modelling-based Optimization
Multi-Objective Adaptive Surrogate Modelling-based Optimization <Multi-objective> <Surrogate>
-----------------------------------------------------------------
Attributes:
problem: Problem
Expand Down
2 changes: 1 addition & 1 deletion UQPyL/optimization/moea_d.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

class MOEA_D():
'''
Multi_objective Evolutionary Algorithm based on Decomposition
Multi_objective Evolutionary Algorithm based on Decomposition <Multi-objective>
-------------------------------------------
Parameters:
problem: Problem
Expand Down
2 changes: 1 addition & 1 deletion UQPyL/optimization/nsga_ii.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

class NSGAII():
'''
Non-dominated Sorting Genetic Algorithm II
Non-dominated Sorting Genetic Algorithm II <Multi-objective>
------------------------------------------------
Attributes:
problem: Problem
Expand Down
162 changes: 162 additions & 0 deletions UQPyL/optimization/pso.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import numpy as np
import math

from ..problems import Problem
from ..DoE import LHS

class PSO():
'''
Particle Swarm Optimization
-----------------------------
Attributes:
problem: Problem
the problem you want to solve, including the following attributes:
n_input: int
the input number of the problem
ub: 1d-np.ndarray or float
the upper bound of the problem
lb: 1d-np.ndarray or float
the lower bound of the problem
evaluate: Callable
the function to evaluate the input
n_sample: int, default=50
the number of samples as the population
w: float, default=0.1
the inertia weight
c1: float, default=0.5
the cognitive parameter
c2: float, default=0.5
the social parameter
maxIterTimes: int, default=1000
the maximum iteration times
maxFEs: int, default=50000
the maximum function evaluations
maxTolerateTimes: int, default=1000
the maximum tolerate times which the best objective value does not change
tolerate: float, default=1e-6
the tolerate value which the best objective value does not change
Methods:
run: run the Particle Swarm Optimization
References:
[1] J. Kennedy and R. Eberhart, Particle swarm optimization, in Proceedings of ICNN'95 - International Conference on Neural Networks, 1995.
[2] J. Kennedy and R. Eberhart, Swarm Intelligence, Academic Press, 2001.
[3] M. Clerc and J. Kennedy, The particle swarm - explosion, stability, and convergence in a multidimensional complex space, IEEE Transactions on Evolutionary Computation, 2002.
[4] Y. Shi and R. C. Eberhart, A modified particle swarm optimizer, in Proceedings of the IEEE Congress on Evolutionary Computation, 1998.
'''
def __init__(self, problem: Problem, n_sample: int=50,
w: float=0.1, c1: float=0.5, c2: float=0.5,
maxIterTimes: int=1000,
maxFEs: int=50000,
maxTolerateTimes: int=1000,
tolerate=1e-6):
#problem setting
self.evaluate=problem.evaluate
self.n_input=problem.n_input
self.ub=problem.ub.reshape(1,-1);self.lb=problem.lb.reshape(1,-1)

#algorithm setting
self.w=w;self.c1=c1;self.c2=c2
self.n_sample=n_sample

#termination setting
self.maxIterTimes=maxIterTimes
self.maxFEs=maxFEs
self.maxTolerateTimes=maxTolerateTimes
self.tolerate=tolerate

def run(self) -> dict:
'''
Run the Particle Swarm Optimization
-------------------------------
Returns:
Result: dict
the result of the Particle Swarm Optimization, including the following keys:
decs: np.ndarray
the best decision of the Particle Swarm Optimization
objs: np.ndarray
the best objective value of the Particle Swarm Optimization
history_decs: np.ndarray
the history of the decision of the Particle Swarm Optimization
history_objs: np.ndarray
the history of the objective value of the Particle Swarm Optimization
iters: int
the iteration times of the Particle Swarm Optimization
FEs: int
the function evaluations of the Particle Swarm Optimization
'''

time=1
iter=0
FEs=0

lhs=LHS('classic')
decs=(lhs(self.n_sample,self.n_input))*(self.ub-self.lb)+self.lb
objs=self.evaluate(decs)
FEs+=objs.shape[0]

history_decs=[]
history_objs=[]
Result={}

P_best_decs=np.copy(decs)
P_best_objs=np.copy(objs)
ind=np.argmin(P_best_objs)
G_best_dec=np.copy(P_best_decs[ind])
G_best_obj=np.copy(P_best_objs[ind])
vel=np.copy(decs)

while iter<self.maxIterTimes and FEs<self.maxFEs and time<=self.maxTolerateTimes:
decs, vel=self._operationPSO(decs, vel, P_best_decs, G_best_dec, self.w)
decs=self._randomParticle(decs)
objs=self.evaluate(decs)

replace=np.where(objs<P_best_objs)[0]
P_best_decs[replace]=np.copy(decs[replace])
P_best_objs[replace]=np.copy(objs[replace])

ind=np.argmin(P_best_objs)
G_best_dec=np.copy(P_best_decs[ind])
G_best_obj=np.copy(P_best_objs[ind])

history_decs.append(G_best_dec)
history_objs.append(G_best_obj)

iter+=1
FEs+=objs.shape[0]

Result['best_decs']=G_best_dec
Result['best_obj']=G_best_obj[0]
Result['history_best_decs']=np.vstack(history_decs)
Result['history_best_objs']=np.array(history_objs).reshape(-1,1)
Result['iters']=iter
Result['FEs']=FEs

return Result

def _operationPSO(self, decs, vel, P_best_decs, G_best_dec, w):

N, D=decs.shape

PatricleVel=vel

r1=np.random.rand(N,D)
r2=np.random.rand(N,D)

offVel=w*PatricleVel+self.c1*r1*(P_best_decs-decs)+self.c2*r2*(G_best_dec-decs)
offDecs=decs+offVel

offDecs = np.clip(offDecs, self.lb, self.ub)
return offDecs, offVel


def _randomParticle(self, decs):

n_to_reinit = int(0.1 * decs.shape[0])
rows_to_mutate = np.random.choice(decs.shape[0], size=n_to_reinit, replace=False)
cols_to_mutate = np.random.choice(decs.shape[1], size=n_to_reinit, replace=False)

decs[rows_to_mutate, cols_to_mutate] = np.random.uniform(self.lb[0, cols_to_mutate], self.ub[0, cols_to_mutate], size=n_to_reinit)

return decs
2 changes: 1 addition & 1 deletion UQPyL/optimization/sce_ua.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

class SCE_UA():
'''
Shuffled Complex Evolution (SCE-UA) method
Shuffled Complex Evolution (SCE-UA) method <Single>
----------------------------------------------
Attributes:
problem: Problem
Expand Down
52 changes: 32 additions & 20 deletions examples/example_optimization.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,41 @@
import numpy as np

################1. Genetic Algorithm (GA) - Single objective################
# print('################1. Genetic Algorithm (GA) - Single objective################')
# from UQPyL.optimization import GA
# from UQPyL.problems import Sphere
print('################1. Genetic Algorithm (GA) - Single objective################')
from UQPyL.optimization import GA
from UQPyL.problems import Sphere

# problem=Sphere(n_input=30, ub=100, lb=-100)
# ga=GA(problem, n_samples=50)
# res=ga.run()
# print('Best objective:', res['best_obj'])
# print('Best decisions:', res['best_dec'])
# print('FE:', res['FEs'])
problem=Sphere(n_input=30, ub=100, lb=-100)
ga=GA(problem, n_samples=50)
res=ga.run()
print('Best objective:', res['best_obj'])
print('Best decisions:', res['best_dec'])
print('FE:', res['FEs'])

################2. SCE-UA - Single objective################
# print('################2. SCE-UA - Single objective################')
# from UQPyL.optimization import SCE_UA
# problem=Sphere(n_input=30, ub=100, lb=-100)
# sce=SCE_UA(problem)
# res=sce.run()
# print('Best objective:', res['best_obj'])
# print('Best decisions:', res['best_dec'])
# print('FE:', res['FEs'])
print('################2. SCE-UA - Single objective################')
from UQPyL.optimization import SCE_UA
problem=Sphere(n_input=30, ub=100, lb=-100)
sce=SCE_UA(problem)
res=sce.run()
print('Best objective:', res['best_obj'])
print('Best decisions:', res['best_dec'])
print('FE:', res['FEs'])

###############3. PSO - Single objective################
print('###############3. PSO - Single objective################')
from UQPyL.optimization import PSO
from UQPyL.problems import Sphere
problem=Sphere(n_input=30, ub=100, lb=-100)
pso=PSO(problem, n_sample=50, w=0.5, c1=1.5, c2=1.5)
res=pso.run()
print('Best objective:', res['best_obj'])
print('Best decisions:', res['best_decs'])
print('FE:', res['FEs'])



################3. ASMO - Single-objective################
################3. ASMO - Single-objective - Surrogate-assisted################
# print('################3. ASMO - Single-objective################')
# from UQPyL.optimization import ASMO
# from UQPyL.surrogates import RBF
Expand Down Expand Up @@ -72,14 +84,14 @@
from UQPyL.problems import ZDT6
problem=ZDT6(n_input=30)
optimum=problem.get_PF()
moead=MOEA_D(problem, aggregation_type='TCH',maxFEs=50000, maxIters=1000)
moead=MOEA_D(problem, aggregation_type='TCH_M',maxFEs=50000, maxIters=1000)
_, res=moead.run()
import matplotlib.pyplot as plt
plt.scatter(res[:,0], res[:,1])
plt.plot(optimum[:,0], optimum[:,1], 'r')
plt.show()

#############5. MO_ASMO - Multi-objective#################
#############5. MO_ASMO - Multi-objective - Surrogate-assisted#################
from UQPyL.optimization import MOASMO
from UQPyL.problems import ZDT1
from UQPyL.surrogates import RBF, KRG
Expand Down

0 comments on commit a2e6314

Please sign in to comment.