package util;
/*
*
* * % 标准合作型协同进化遗传算法(多元函数优化)
%实数编码,求最小值,函数为 bound=[-2.048 2.048];
%f2(x)= ∑i1--(n-1)[100(x(i+1)-xi^2)]^2+(xi-1)^2]
* */
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Vector;
import java.util.Random;
public class GeneticAlgorithm {
static int MAX=100000;
static int GEN=50;
private int generation; //进化代数
private int sizeofpop; //种群个体数量
private int lenofchrom;//染色体长度
private int popnum;//种群数目
private double lower;
private double upper;
private FileWriter writer;
private double crossoverPossibility; //繁殖概率
private double mutationPossibility; //变异概率
//保存每个种群的最优值
//三维数组第一维为页号
private double[][][] best_chrom ; //最优染色体
private double[] best_value;// 最优取值
private double best_so_far_value;
private double best_so_far_chrom[][];
//保存至今为止最优数据记录。
private double[] best_value_per_gen;
// private FunctionFitness calculator = new FunctionFitness(); //适应函数计算
private Vector popvector = new Vector(popnum); //一个list代表一个种群
private static Random random = new Random();
// private Randomizer random1;
// private GenerationDetail detail = new GenerationDetail();
public GeneticAlgorithm( double cp, double mp,double lower,double upper, int sizeofpop,int lenofchrom,int popnum){
this.popnum = popnum;
this.sizeofpop=sizeofpop;
this.lenofchrom=lenofchrom;
this.lower=lower;
this.upper=upper;
this.crossoverPossibility = cp;
this.mutationPossibility = mp;
//random1 = new Randomizer(0,length - 1);
generatePopulation(lower,upper); //用24位表示一组x,y,z的值
}
/** *//**
* 生成初始种群
* @param lower
* @param upper
* @param sizeofpop
* @param lenofchrom
* @param popnum
*/
private void generatePopulation(double lower, double upper){
//随机生成染色体
for(int i = 0; i < popnum; i ++){
popvector.add(new Population(lower,upper,sizeofpop,lenofchrom,1));
}
//计算染色体的适应值
evaluate1();
// this.printPopulation();
}
/** *//**
* 计算群体的适应值,第一次评价,随机取合作者
*/
private void evaluate1(){
this.best_value=new double[popnum];
this.best_chrom=new double[popnum][popnum][lenofchrom];
//第一次评价,将适应值赋一个较大的值
for(int i = 0; i < popnum; i ++){
best_value[i]=MAX;
}
double[] solution=new double[lenofchrom*popnum];
int ran_index=random.nextInt(sizeofpop);
for(int t=0;t<popnum;t++) //从每个种群中随机取个体
{
int begin=t*lenofchrom ;
int end=t*lenofchrom +lenofchrom-1;
for(int s=0;s<lenofchrom;s++)
{
Population poptemp=(Population)popvector.get(t);
solution[begin+s]=poptemp.getPop()[ran_index][s];
//System.out.println(i+","+t+"||");
for(int all=0;all<popnum;all++)
best_chrom[all][t][s]=poptemp.getPop()[ran_index][s];
}
}
for(int i = 0; i < popnum; i ++){//对第i个种群进行评价
int begin=i*lenofchrom;
int end=i*lenofchrom+lenofchrom-1;
Population popnow=new Population();
popnow=(Population)popvector.get(i);
for(int j=0;j<sizeofpop;j++)//对i种群中的第j个体进行评价
{
//用要评价的个体替代之前随机取的个体。
for(int s=0;s<lenofchrom;s++)
{
solution[begin+s]=popnow.getPop()[j][s];
}
double sum=0;
for(int t=0;t<popnum*lenofchrom-1;t++)
{
//System.out.print(t+"::"+Arrays.toString(solution));
sum=sum+100*Math.pow((solution[t+1]-Math.pow(solution[t], 2)),2)+Math.pow(solution[t]-1, 2);
}
// System.out.println(sum);
//记录最优个体
if(sum<best_value[i])
{
best_value[i]=sum;
for(int s=0;s<lenofchrom;s++){
best_chrom[i][i][s] =popnow.getPop()[j][s];
}
}
((Population)popvector.get(i)).setFitness(j, 1.0/sum);
// ((Population)popvector.get(i)).setFitness(j, 10000-sum);
}
}
}
//非第一次评价时使用的函数,取最优合作者
private void evaluate2(){
double[] solution=new double[lenofchrom*popnum];
double[][][] temp_best_chrom=new double[popnum][popnum][lenofchrom];
for(int t=0;t<popnum;t++) //从每个种群中取最优个体
{
int begin=t*lenofchrom ;
int end=t*lenofchrom +lenofchrom-1;
for(int s=0;s<lenofchrom;s++)
{
solution[begin+s]=this.best_chrom[t][t][s];
for(int all=0;all<popnum;all++)
temp_best_chrom[all][t][s]=this.best_chrom[t][t][s];
}
}
for(int i = 0; i < popnum; i ++){//对第i个种群进行评价
//int ran_index=random.nextInt(sizeofpop);
int begin=i*lenofchrom;
int end=i*lenofchrom+lenofchrom-1;
Population popnow=new Population();
popnow=(Population)popvector.get(i);
for(int j=0;j<sizeofpop;j++)//对i种群中的第j个体进行评价
{
//用要评价的个体替代之前取的最优个体。
for(int s=0;s<lenofchrom;s++)
{
solution[begin+s]=popnow.getPop()[j][s];
}
double sum=0;
for(int t=0;t<popnum*lenofchrom-1;t++)
{
sum=sum+100*Math.pow((solution[t+1]-Math.pow(solution[t], 2)),2)+Math.pow(solution[t]-1, 2);
}
//记录最优个体
if(sum<best_value[i])
{
best_value[i]=sum;
for(int s=0;s<lenofchrom;s++){
temp_best_chrom[i][i][s] =popnow.getPop()[j][s];
}
}
((Population)popvector.get(i)).setFitness(j, 1.0/sum);
}
}
this.best_chrom=temp_best_chrom;
}
//每五代毁灭性能低于平均值的个体
private void initialsub(){}
{
for(int i=0;i<popnum;i++)//对第i个种群进行操作
{
double fitness_sum=0;
double fitness_avg=0;
for(int j=0;j<sizeofpop;j++)
{
fitness_sum =fitness_sum+ ((Population)popvector.get(i)).getPop()[j][lenofchrom];
}
fitness_avg=fitness_sum/sizeofpop;
for(int j=0;j<sizeofpop;j++)
{
if(((Population)popvector.get(i)).getPop()[j][lenofchrom]<fitness_avg){
((Population)popvector.get(i)).setIndividual(j);
}
}
}
}
/** *//**
* 在后代中选择新种群
* 生成新种群,提取种群数据数组pop[][],将选中的个体行存入新生成的种群中,更新popvector
*/
private void choose(){
for(int i=0;i<popnum;i++)
{
double best_fitness=1.0/this.best_value[i];
double[][] newpop=new double[sizeofpop][lenofchrom+1];
//非1,new时不生成种群。
double[][] oldPop=((Population)popvector.get(i)).getPop();
int count=0; //用于记录最优个体个数,最优个体不参与交叉(暂时未执行)
for(int tt=0;tt<sizeofpop;tt++)
{
if(oldPop[tt][lenofchrom]==best_fitness){
newpop[count]=oldPop[tt];
count++;
}
}
double totalfit=0;
double[] ratio=new double[sizeofpop];
double[] cumsum=new double[sizeofpop];
for(int tt=0;tt<sizeofpop;tt++)
{
totalfit+=oldPop[tt][lenofchrom];
}
for(int tt=0;tt<sizeofpop;tt++)
{
ratio[tt]=oldPop[tt][lenofchrom]/totalfit;
}
cumsum[0]=ratio[0];
for(int tt=1;tt<sizeofpop;tt++)
{
cumsum[tt]=cumsum[tt-1]+r