import numpy as np
import numpy.random as rand
T=1000 ###迭代次数
c1=0.5
c2=0.05
c3 = 2
q=0.5
e = 0.0001
lb = [1000,2000,3000] ###下限
ub=[0,0,0] ###上限
size=15 ###雄蛇或雌蛇数量
dim=3 ###维度
def fitness(a):
###这里自己写适应度函数
for i in range(len(a)):
result[i] = np.sum(a[i,0]*a[i,1]) - np.exp(a[i,1]) - a[i,0]**2 + a[i,2]**2 - a[i,2]**3 + a[i,0]*a[i,2]
return result
def conversion(k,man,woman,Q,temp):
man_=man.copy()
woman_=woman.copy()
man_best_index = man_[:,-1].argmin()
woman_best_index = woman_[:,-1].argmin()
dim_index = [i for i in range(dim)]
if k==0: #寻找食物的变化
ran_man_index = rand.randint(0, len(man), size=(len(man), dim))
man_3y = man_[:, -1].reshape(-1, 1) * np.ones_like(ran_man_index)
ran_woman_index = rand.randint(0, len(man), size=(len(woman), dim))
woman_3y = woman_[:, -1].reshape(-1, 1) * np.ones_like(ran_woman_index)
mask_man = rand.uniform(0,1,size=(len(man),3))
mask_woman = rand.uniform(0,1,size=(len(woman),3))
mask_man = np.where(mask_man>0.5,1,-1)
mask_woman = np.where(mask_woman>0.5,1,-1)
dim_y = -np.ones(dim,dtype=int)
kid1 = man_[ran_man_index,dim_index] + mask_man * c2 * np.exp(-man_3y[ran_man_index,dim_y] /np.where(man_[:, -1]>0,man_[:,-1]+e,man_[:,-1]-e).reshape(-1,1)) * rand.uniform(lb, ub, (len(man), dim))
kid2 = woman_[ran_woman_index,dim_index] + mask_woman* c2 * np.exp(-woman_3y[ran_woman_index,dim_y]/(np.where(woman_[:, -1]>0,woman_[:,-1]+e,woman_[:,-1]-e)).reshape(-1,1) ) * rand.uniform(lb, ub, (len(woman), dim))
if k==1:
if man_[man_best_index,-1] > woman_[woman_best_index,-1]:
snake_best_postion = woman_[woman_best_index]
else:
snake_best_postion = man_[man_best_index]
mask_man = rand.uniform(0, 1, size=(len(man), dim))
mask_woman = rand.uniform(0, 1, size=(len(woman), dim))
mask_man = np.where(mask_man > 0.5, 1, -1)
mask_woman = np.where(mask_woman > 0.5, 1, -1)
kid1 = snake_best_postion[:-1] + mask_man*c3*temp*rand.uniform(0,1)*(snake_best_postion[:-1]-man_[:,:-1])
kid2 = snake_best_postion[:-1] + mask_woman*c3*temp*rand.uniform(0,1)*(snake_best_postion[:-1]-woman_[:,:-1])
if k==2: #战斗的变化
kid11 = man_[:,:-1]+c3*np.exp(-woman_[woman_best_index,-1]/(np.where(man_[:, -1]>0,man_[:,-1]+e,man_[:,-1]-e))).reshape(-1,1)*rand.uniform(0,1,(len(man),dim))*(Q*woman_[woman_best_index,:-1]-man_[:,:-1])
kid12 = woman_[:,:-1]+c3*np.exp(-man_[man_best_index,-1]/(np.where(woman_[:,-1]>0,woman_[:,-1]+e,woman_[:,-1]-e))).reshape(-1,1)*rand.uniform(0,1,(len(woman),dim))*(Q*man_[man_best_index,:-1]-woman_[:,:-1])
#交配的变化
kid21 = man_[:,:-1]+c3*np.exp(-woman_[:,-1]/(np.where(man_[:, -1]>0,man_[:,-1]+e,man_[:,-1]-e))).reshape(-1,1) * rand.uniform(0,1,(len(man),dim))*(Q*woman_[:,:-1]-man_[:,:-1])
kid22 = woman_[:,:-1]+c3*np.exp(-man_[:,-1]/(np.where(woman_[:,-1]>0,woman_[:,-1]+e,woman_[:,-1]-e))).reshape(-1,1) * rand.uniform(0,1,(len(man),dim))*(Q*man_[:,:-1]-woman_[:,:-1])
mask_man = rand.random(size=(len(man),dim))
mask_woman = rand.random(size=(len(man),dim))
kid1 = np.where(mask_man>0.6,kid21,kid11)
kid2 = np.where(mask_woman>0.6,kid22,kid12)
kid1=np.clip(kid1,lb,ub,out=None)
kid2=np.clip(kid2,lb,ub,out=None)
kid1_y=fitness(kid1)
kid2_y=fitness(kid2)
worst_man_index = kid1_y.argmax()
worst_woman_index = kid2_y.argmax()
best_kid1_index = kid1_y.argmin()
best_kid2_index = kid2_y.argmin()
if kid1_y[best_kid1_index] >= man_[man_best_index, -1]:
kid1_y[best_kid1_index] = man_[man_best_index, -1]
kid1[best_kid1_index] = man[man_best_index, :-1]
if kid2_y[best_kid2_index] >= woman_[woman_best_index, -1]:
kid2_y[best_kid2_index] = woman_[woman_best_index, -1]
kid2[best_kid2_index] = woman_[woman_best_index, :-1]
man_[:,:-1] = kid1.copy()
woman_[:,:-1] = kid2.copy()
man_[:,-1] = kid1_y.copy()
woman_[:,-1] = kid2_y.copy()
man_[worst_man_index,:-1] = rand.uniform(low=lb,high=ub,size=(1,dim))
woman_[worst_woman_index,:-1] = rand.uniform(low=lb,high=lb,size=(1,dim))
return man_,woman_
def run():
man = rand.uniform(lb,ub,size=(size,dim))
woman = rand.uniform(lb,ub,size=(size,dim))
man = np.concatenate([man,fitness(man).reshape(-1,1)],axis=1)
woman = np.concatenate([woman,fitness(woman).reshape(-1,1)],axis=1)
best_result = []
best_X = []
for t in range(T):
temp = np.exp(-t / T)
Q = c1 * np.exp((t - T) / T)
if Q<0.25:
man,woman = conversion(k=0,man=man,woman=woman,Q=Q,temp=temp)
if Q>=0.25:
if temp>0.6:
man,woman = conversion(k=1,man=man,woman=woman,Q=Q,temp=temp)
if temp<=0.6:
man,woman = conversion(2,man=man,woman=woman,Q=Q,temp=temp)
if man[:,-1].min() > woman[:,-1].min():
best_woman_index = woman[:,-1].argmin().copy()
best_x =woman[best_woman_index,:-1].copy()
best_y = woman[best_woman_index,-1].copy()
best_result.append(best_y)
best_X.append(best_x)
if man[:,-1].min()<= woman[:,-1].min():
best_man_index = man[:, -1].argmin().copy()
best_x = man[best_man_index, :-1].copy()
best_y = man[best_man_index, -1].copy()
best_result.append(best_y)
best_X.append(best_x)
best_result = np.array(best_result)
return best_X,best_result
论文里好像没有提及子代和父代怎么保存,这里采用的是每次保留种群最优解。交配和战斗的概率采用的是每次交配或战斗时,每个个体都有60%的概率选择战斗