阿基米德优化算法
AOA连续
from pylab import *
matplotlib.use('TkAgg')
from pylab import *
mpl.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
class AOA(object):
"""
个体的密度和体积都在向着全局最优个体的密度和体积靠近。
"""
def __init__(self, M, T, lb, ub, l, N):
self.M = M # 种群个数
self.T = T # 迭代次数
self.lb = lb
self.ub = ub
self.L = l
self.N = N
self.u =0.9
self.ul = 0.1
self.c1 = 2
self.c2 = 6
self.c3 = 2
self.c3 = 2
self.c4 = 2
def init_x(self):
x = np.random.uniform(self.lb ,self.ub,(self.M,self.L,self.N))
return x
def init_den(self):
den = np.random.uniform(0,1,(self.M,self.L,self.N))
return den
def init_vol(self):
vol = np.random.uniform(0,1,(self.M,self.L,self.N))
return vol
def init_acc(self):
acc = np.ones((self.M,self.L, self.N)) * self.lb
acc += np.random.uniform(self.lb ,self.ub, (self.M,self.L, self.N))
return acc
def fitness(self,x):
"""
(x1-50)**2+(x2-50)**2
:param x:
:return:
"""
result =(x[0]-90) ** 2 + (x[1]-90) ** 2
return result
def best(self,x):
l = []
for m in range(self.M):
for i in range(self.L):
l.append(self.fitness(x[m,i]))
return l.index(min(l)),l
def up_den(self,den,den_best):
den_new = den+ np.random.uniform(0,1,(self.M,self.L,self.N))*(den_best - den)
return den_new
def up_vol(self,vol,vol_best):
vol_new = vol+ np.random.uniform(0,1,(self.M,self.L,self.N))*(vol_best - vol)
return vol_new
def up_acc_1(self,den,vol,acc):
"""
TF<=0.5
"""
acc1=acc.copy()
for m in range(self.M):
rand = np.random.randint(0, self.M)
dva = den[rand]+vol[rand]*acc1[rand]
acc[m] = (dva)/den[m]*vol[m]
return acc
def up_acc_2(self,den_best,vol_best,acc_best,den,vol):
"""
TF>0.5
"""
acc = (den_best + vol_best*acc_best)/(den*vol)
return acc
def normalize_acc(self,acc):
acc[np.where(acc==np.inf)] = 1.48218442e+308
acc[np.where(acc==-np.inf)] = -1.48218442e+308
if np.max(acc)-np.min(acc) == 0:
acc_nor = 1000000
else:
acc_nor = self.u*((acc - np.min(acc))/(np.max(acc)-np.min(acc))) + self.ul
acc_nor[np.where(acc==np.inf)] = 0
return acc_nor
def up_x_1(self,x,acc_nor,d):
x1 = x.copy()
x2 = x.copy()
for m in range(self.M):
rand = np.random.randint(0, self.M)
x2[m] = x1[rand]
x_new = x1+self.c1*np.random.uniform(0,1,(self.M,self.L,self.N))*acc_nor*d*(x2-x1)
return x_new
def up_x_2(self,x,x_best,acc_nor,d,TF):
p = 2*np.random.rand()-self.c4
if p>=0.5:
F = 1
else:
F = -1
x = x_best+F*self.c2*np.random.uniform(0,1,(self.M,self.L,self.N))*acc_nor*d*(self.c3 * TF * x_best-x)
return x
def main(self):
#第一步初始化
optimum_list = []
x = self.init_x()
den = self.init_den()
vol = self.init_vol()
acc = self.init_acc()
# 求出x,den,vol,acc最优
num ,l= self.best(x)
optimum_list.append(min(l))
x_best = x[num]
den_best = den[num]
vol_best = vol[num]
acc_best = acc[num]
#第二部更新den vol
#第三部分转移运算符和密度因子
for i in range(self.T):
den = self.up_den(den, den_best)
vol = self.up_vol(vol, vol_best)
TF = np.exp((i-self.T)/self.T)
d = np.exp((self.T-i)/self.T)-(i/self.T) #密度递减因子,用于全局搜索
x1 = x.copy()
if TF<=0.5:
acc = self.up_acc_1(den,vol,acc)
acc_nor = self.normalize_acc(acc)
x= self.up_x_1(x,acc_nor,d)
else :
acc = self.up_acc_2(den_best,vol_best,acc_best,den,vol)
acc_nor = self.normalize_acc(acc)
x = self.up_x_2(x,x_best,acc_nor,d,TF)
num,l1= self.best(x)
for i in range(len(l1)):
if l1[i]>l[i]:
x[i]=x1[i]
l1[i] = l[i]
num = l1.index(min(l1))
x_best = x[num]
optimum_list.append(min(l))
den_best = den[num]
vol_best = vol[num]
acc_best = acc[num]
l = l1
print("最优解适应度",optimum_list[-1])
print("最优位置",x_best)
plt.plot(optimum_list, label='AOA')
plt.xlabel('Iterations', size=13)
plt.ylabel('Fitness', size=13)
plt.legend()
plt.show()
if __name__ == '__main__':
#" M, T, lb, ub, l, N"
A1 = AOA( 50, 500, -100, 100, 1, 2)
A1.main()
没有PSO好用
BAOA
from pylab import * from tqdm import tqdm matplotlib.use('TkAgg') from pylab import * mpl.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体 mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题 class BAOA(object): """ 个体的密度和体积都在向着全局最优个体的密度和体积靠近。 """ def __init__(self, M, T, l, N): self.M = M # 种群个数 self.T = T # 迭代次数 self.L = l self.N = N self.u =0.9 self.ul = 0.1 self.c1 = 2 self.c2 = 6 self.c3 = 2 self.c3 = 2 self.c4 = 2 self.Weight = [95, 75, 23, 73, 50, 22, 6, 57, 89, 98] # 物品体积 self.Value = [89, 59, 19, 43, 100, 72, 44, 16, 7, 64] # 物品价值 self.Weight_max = 300 # 背包容量 self.afa = 100# 惩罚系数 def init_x(self): x = np.random.choice([0 ,1],(self.M,self.L,self.N)) return x def init_den(self): den = np.random.uniform(0,1,(self.M,self.L,self.N)) return den def init_vol(self): vol = np.random.uniform(0,1,(self.M,self.L,self.N)) return vol def init_acc(self): acc = np.random.choice([0 ,1], (self.M,self.L, self.N)) return acc def fitness(self,X): fit = sum(X * self.Value) # 物品价值 TotalSize = sum(X* self.Weight) # 物品重量 # xiandinglegeshu if TotalSize <= self.Weight_max: # 如果小于限制重量 fit = fit else: if TotalSize - self.Weight_max > 0: fit = 0 # 对fit进行惩罚 else: fit = 0 # 对fit进行惩罚 return fit # 我们要求result越大 def best(self,x): l = [] for m in range(self.M): for i in range(self.L): l.append(self.fitness(x[m,i])) return l.index(max(l)),l def up_den(self,den,den_best): den_new = den+ np.random.uniform(0,1,(self.M,self.L,self.N))*(den_best - den) return den_new def up_vol(self,vol,vol_best): vol_new = vol+ np.random.uniform(0,1,(self.M,self.L,self.N))*(vol_best - vol) return vol_new def up_acc_1(self,den,vol,acc): """ TF<=0.5 """ acc1=acc.copy() for m in range(self.M): rand = np.random.randint(0, self.M) dva = den[rand]+vol[rand]*acc1[rand] acc[m] = (dva)/den[m]*vol[m] return acc def up_acc_2(self,den_best,vol_best,acc_best,den,vol): """ TF>0.5 """ acc = (den_best + vol_best*acc_best)/(den*vol) return acc def normalize_acc(self,acc): if np.max(acc)-np.min(acc) == 0: acc_nor = self.ul else: acc_nor = self.u*((acc - np.min(acc))/(np.max(acc)-np.min(acc))) + self.ul return acc_nor def up_x_1(self,x,acc_nor,d): x1 = x.copy() x2 = x.copy() for m in range(self.M): rand = np.random.randint(0, self.M) x2[m] = x1[rand] x_new = x1+self.c1*np.random.uniform(0,1,(self.M,self.L,self.N))*acc_nor*d*(x2-x1) return x_new def up_x_2(self,x,x_best,acc_nor,d,TF): p = 2*np.random.rand()-self.c4 if p>=0.5: F = 1 else: F = -1 x = x_best+F*self.c2*np.random.uniform(0,1,(self.M,self.L,self.N))*acc_nor*d*(self.c3 * TF * x_best-x) return x def x_zhuanhuan(self,x): for i in range(self.M): # 遍历每一个粒子 # 修改速度为sigmoid形式 x[i, :] = 1. / (1 + np.exp(-np.array(x[i, :]))) for j in range(self.L): # 遍历粒子中的每一个元素 for n in range(self.N): rand = np.random.random() # 生成 0-1之间的随机数 if x[i, j ,n] > rand: x[i, j ,n] = 1 else: x[i, j ,n] = 0 # 对当前个体进行限制,放在超重 while np.sum(x[i,j] * self.Weight) > self.Weight_max: # 如果当前粒子超重 x[i] = np.random.choice([0, 1], size=(1, self.L,self.N)) return x def main(self): st =time.time() #第一步初始化 optimum_list = [] x = self.init_x() den = self.init_den() vol = self.init_vol() acc = self.init_acc() # 求出x,den,vol,acc最优 num ,l= self.best(x) optimum_list.append(min(l)) x_best = x[num] den_best = den[num] vol_best = vol[num] acc_best = acc[num] #第二部更新den vol #第三部分转移运算符和密度因子 for i in tqdm(range(self.T)): den = self.up_den(den, den_best) vol = self.up_vol(vol, vol_best) TF = np.exp((i-self.T)/self.T) d = np.exp((self.T-i)/self.T)-(i/self.T) #密度递减因子,用于全局搜索 x1 = x.copy() if TF<=0.5: acc = self.up_acc_1(den,vol,acc) acc_nor = self.normalize_acc(acc) x= self.up_x_1(x,acc_nor,d) x = self.x_zhuanhuan(x) else : acc1=acc.copy() acc = self.up_acc_2(den_best,vol_best,acc_best,den,vol) if np.max(acc) == np.inf: break acc_nor = self.normalize_acc(acc) x = self.up_x_2(x,x_best,acc_nor,d,TF) x = self.x_zhuanhuan(x) num,l1= self.best(x) for i in range(len(l1)): if l1[i]<l[i]: x[i]=x1[i] l1[i] = l[i] num = l1.index(max(l1)) x_best = x[num] optimum_list.append(max(l)) den_best = den[num] vol_best = vol[num] acc_best = acc[num] l = l1 print(time.time()*1000-st*1000) print('最优解对应的体积', np.sum(x_best * self.Weight)) print("最优解适应度",optimum_list[-1]) print("最优位置",x_best[0]) plt.plot(optimum_list, label='BAOA') plt.xlabel('Iterations', size=13) plt.ylabel('Fitness', size=13) plt.legend() plt.show() if __name__ == '__main__': #" M, T, lb, ub, l, N" A1 =BAOA( 200, 300, 1, 10) A1.main()