python 實現差分進化算法

蟒蛇實現差分進化算法,通過Spere函數測試運行很快速。

差分進化算法總的有四步驟:

(1)種羣初始化

(2)變異操作

(3)交叉操作

(4)貪婪選擇操作

# -*- coding:utf-8 -*-

import numpy as np
import matplotlib.pyplot as plt

class de:
	"""
	pop_pos:
	pop_fit:
	pop_best_pos:
	pop_best_fit:
	CR:
	F:
	max_iter:
	n_var:
	"""
	def __init__(self,max_iter,n_var,CR,F,n_pop,bound,fit_func):
		self.max_iter=max_iter
		self.n_var=n_var
		self.CR=CR
		self.F=F
		self.fit_func=fit_func
		self.n_pop=n_pop	
		self.iter_fit=np.arange(max_iter)
		self.bound=bound
		# 產生種羣
		self.pop_pos=bound[1,:]+np.random.rand(n_pop,n_var)*(bound[0,:]-bound[1,:])
		self.pop_fit=self.fit_func(self.pop_pos)
		
		self.pop_best_fit=np.min(self.pop_fit)
		self.pop_best_pos=self.pop_pos[np.argmin(self.pop_fit),:]
		
		self.pop_cross=self.pop_pos.copy()
		self.pop_cross_fit=self.pop_fit.copy()
		
		self.pop_mutute=self.pop_pos.copy()
		self.pop_mutute_fit=self.pop_fit.copy()
		
	def mutute_pop(self):
		rand1=np.random.choice(self.n_pop)
		rand2=np.random.choice(self.n_pop)
		rand3=np.random.choice(self.n_pop)
		if (rand1==rand2)|(rand2==rand3)|(rand1==rand3):
			rand1=np.random.choice(self.n_pop)
			rand2=np.random.choice(self.n_pop)
			rand3=np.random.choice(self.n_pop)
		for i in range(self.n_pop):
			self.pop_mutute[i,:]=self.pop_pos[rand1,:]+self.F*(self.pop_pos[rand2,:]-self.pop_pos[rand3,:])
			
			index_up=self.pop_mutute[i,:]>self.bound[0,:]
			self.pop_mutute[i,index_up]=self.bound[0,index_up].copy()
			index_down=self.pop_mutute[i,:]<self.bound[1,:]
			self.pop_mutute[i,index_down]=self.bound[1,index_down].copy()
		
	def cross_pop(self):
		for i in range(self.n_pop):
			randc=np.random.choice(self.n_var)
			for j in range(self.n_var):
				randF=np.random.rand()
				if(randc==j|(randF<self.CR)):
					self.pop_cross[i,j]=self.pop_mutute[i,j].copy()
				else:
					self.pop_cross[i,j]=self.pop_pos[i,j].copy()
			
			index_up=self.pop_cross[i,:]>self.bound[0,:]
			self.pop_cross[i,index_up]=self.bound[0,index_up].copy()
			index_down=self.pop_cross[i,:]<self.bound[1,:]
			self.pop_cross[i,index_down]=self.bound[1,index_down].copy()
			
		self.pop_cross_fit=self.fit_func(self.pop_cross)
		
	def greedy_select(self):
		index_x=self.pop_cross_fit<self.pop_fit
		self.pop_pos[index_x,:]=self.pop_cross[index_x,:].copy()
		self.pop_fit[index_x]=self.pop_cross_fit[index_x]
		if np.min(self.pop_fit)<self.pop_best_fit:
			self.pop_best_pos=self.pop_pos[np.argmin(self.pop_fit),:].copy()
			self.pop_best_fit=self.pop_fit[np.argmin(self.pop_fit)].copy()
		
	def show_result(self):
		plt.plot(range(self.max_iter),self.iter_fit,'-b')
		plt.title('converage of process in de')
		plt.xlabel('iter')
		plt.ylabel('fitness')
		plt.show()
	def print_result(self):
		print('the result is showing...')
		print('best_fitness for min problem:',self.pop_best_fit)
		print('best solution for result:',self.pop_best_pos)			
				
	def run(self):
		for it in np.arange(0,self.max_iter):
			self.mutute_pop()
			self.cross_pop()
			self.greedy_select()
			self.iter_fit[it]=self.pop_best_fit.copy()
			print('iter,iter_fit',(it,self.iter_fit[it]))
	
			
def fitness_fun(x):
	result=np.sum(x*x,axis=1)
	return result	
		
		
def main():
	max_iter=1000
	var_num=100
	pop=50
	bound=np.zeros((2,var_num))
	bound[0,:]=np.ones(var_num)*10    #上邊界,每個變量的上邊界可以不同
	bound[1,:]=-np.ones(var_num)*10	  #下邊界,每個變量的下邊界可以不同
	CR=0.2
	F=0.2
	de_new=de(max_iter,var_num,CR,F,pop,bound,fitness_fun)
	de_new.run()
	de_new.show_result()
	de_new.print_result()
	
if __name__=='__main__':
	main()
	
	
		
		
		
		
		

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章