java實現差分進化算法


import java.util.*;
/*
* @author Greg
* @date 2018
* @content DE
* @function DE優化最大值
*/

public class DE
{
	private int population_size;	 // population numbers
	private int iter_num;       	// number of iteration
	private int param_num;		 	// variables of problem
	private double param_bottom_bound; 	// lower bound of variables 
	private double param_upper_bound;  	// upper bound of variables
	private double F=0.5;  	//mutation factor
	private double CR=0.5; // cross rate
	// tmp
	private double[][]population;  	     // population's array
	private double[]fitness;			// personal's fitness
	private Random rand;    		   // getting a rand number for using // 申明 rand ,後面new 實例化 ,基礎類型不需要new
	//output
	private double[] final_individual;
	
	
	/*
	* 
	* @param 種羣數量,迭代次數,變量個數,變量的下邊界,變量的上邊界 
	* @return final_individual 
	*/
	
	public DE(int population_size,int iter_num,double MutateFactor,double CrossRate,int param_num,double param_bottom_bound,double param_upper_bound)
	{
		this.population_size=population_size;
		this.iter_num=iter_num;
		this.param_num=param_num;
		this.F=MutateFactor;
		this.CR=CrossRate;
		this.param_bottom_bound=param_bottom_bound;
		this.param_upper_bound=param_upper_bound;
		final_individual=run();
		
	}
	public double[] getTheFinalParams()
	{
		return final_individual;
	}
	/*
	* 
	* @param void 
	* @return final_best_individual 
	*/
	private double[] run()
	{   // step1: 初始化種羣
		this.init();
		// 初始化最終最優值
		double[] final_best_individual=null;
		// step2:開始迭代
		for(int iter=0;iter<iter_num;iter++)
		{   // mutate operation
			double[][] mutated_population=this.mutate();
			// cross operation
			double[][] crossedpopulation=this.cross(mutated_population);
			// select operation
			this.select(crossedpopulation);
			// 找出最值的個體
			int[] index=insertDescendSortIndex(fitness,1);
			
			StringBuffer sb=new StringBuffer();
		sb.append("The "+(iter+1)+"-th iter's score is"+fitness[index[0]]+"(");
		for(int j=0;j<param_num-1;j++)
			sb.append(this.population[index[0]][j]+",");
		sb.append(this.population[index[0]][param_num-1]+")"); 
		System.out.println(sb.toString());
		final_best_individual=this.population[index[0]];
		double final_fitness=scorefunc(final_best_individual);
		System.out.println(final_fitness);
		}			
		return final_best_individual;
		
	}
	
	/*
	* 
	* @param 
	* @return  
	*/
	
	private int[] insertDescendSortIndex(final double[] arr,int sortTopN)
	{
		int[] indexes=new int[arr.length];
		for(int i=0;i<indexes.length;i++)
		{
			indexes[i]=i;
			
		}	
		for(int i=1;i<indexes.length;i++)
		{
			for(int j=0;j<i&&j<sortTopN;j++)
			{
				if(arr[indexes[i]]>arr[indexes[j]])
				{
					int tmp=indexes[i];
					indexes[i]=indexes[j];
					indexes[j]=tmp;
				}
			}
		}
		if(indexes.length>sortTopN)
		{
			int[] ans=new int[sortTopN];
			for(int i=0;i<sortTopN;i++)
			{
				ans[i]=indexes[i];
				
			}
			return ans;
			
		}
		return indexes;
		
	}
	/*
	* 
	* @param void 
	* @return void  
	*/
	private void init()
	{
		rand=new Random(new Date().getTime());  //實例化rand
		population=new double[population_size][param_num];
		fitness=new double[population_size];
		for(int i=0;i<population_size;i++)
		{
			for(int j=0;j<param_num;j++)
			{
				population[i][j]=param_bottom_bound+rand.nextDouble()*(param_upper_bound-param_bottom_bound);
				
			}
			fitness[i]=scorefunc(population[i]);
			
		}
	}
	/*
	* 
	* @param void 
	* @return mutated_population 
	*/
	private double[][] mutate()
	{
		double[][] mutated_population=new double[population_size][param_num]; // 
		for(int i=0;i<population_size;i++)
		{
			int ind1=rand.nextInt(population_size);
			int ind2=rand.nextInt(population_size);
			int ind3=rand.nextInt(population_size);
			while(ind1==i||ind2==i||ind3==i||ind1==ind2||ind1==ind3||ind2==ind3)
			{
				ind1=rand.nextInt(population_size);
				ind2=rand.nextInt(population_size);
				ind3=rand.nextInt(population_size);
				
			}
			for(int j=0;j<param_num;j++)
			{
				mutated_population[i][j]=population[ind1][j]+F*(population[ind2][j]-population[ind3][j]);
			}
				
		}
		return mutated_population;	
	}
	/*
	* 
	* @param mutated_population
	* @return crossedpopulation
	*/
	private double[][] cross(double[][] mutated_population) // 輸入參數是一個二維數組
	{
		double[][] crossedpopulation=new double[population_size][param_num];
		for(int i=0;i<population_size;i++)
		{	
			int Jrand=rand.nextInt(param_num); // 隨機生成一個在param_num間的整數
			for(int j=0;j<param_num;j++)
			{
				if(j==Jrand||rand.nextDouble()<CR)
				{
					crossedpopulation[i][j]=mutated_population[i][j];
					
				}
				else
				{
					crossedpopulation[i][j]=population[i][j];
					
				}
				if(crossedpopulation[i][j]>this.param_upper_bound||crossedpopulation[i][j]<this.param_bottom_bound)
				{
					crossedpopulation[i][j]=param_bottom_bound+rand.nextDouble()*(param_upper_bound-param_bottom_bound);
					
				}
			}
		}
		return crossedpopulation;  // 返回的是一個二維數組
		
	}
	/*
	* 最大值計算
	* @param crossedpopulation
	* @return void 
	*/
	private void select(double[][] crossedpopulation)
	{
		for(int i=0;i<population_size;i++)
		{
			double new_sco=scorefunc(crossedpopulation[i]);
			if(new_sco>fitness[i])
			{
				population[i]=crossedpopulation[i];
				fitness[i]=new_sco;
			}
		}
	}
	/*
	* 
	* 求解問題的適應值函數(度量函數)
	* @param 求解的解
	* @return 適應值
	*/
	
	private double scorefunc(double[] individual)
	{
		double sco=0;
		for(int i=0;i<param_num;i++)
		{
			sco+=individual[i]*individual[i];
			
		}
		return sco;
	}
	/*
	* 主函數開始執行DE算法
	* main function for DE 
	* @param void 
	* @return void
	*/
	
	public static void main(String[] args)
	{
		DE de=new DE(100,500,0.5,0.8,5,0,10);
		double[] params=de.getTheFinalParams();
		System.out.println();
		for(int j=0;j<params.length;j++)
		{
			System.out.printf("%4.6f ,",params[j]);
			
		}
		System.out.println("\nHave a good day!");
	}

}

 

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