一个简单的遗传算法应用(java版)

计算智能课的遗传算法上完了,老师布置了一个简单的应用,用java实现了下。

首先是题目要求:

A given function is as follows:

Use genetic algorithm to find a near-maximal value in

f==xsin(10*pi*x)+2

[-1,2]. In addition, the required precision is six places after the decimal point.

代码实现如下:

import java.util.Random;
public class GA {
public static final double A=-1;//下界
public static final double B=2;//
public static final int POP_SIZE=30;//种群数目
public static final int M=22; //编码位数
public static String[]pop=new String[POP_SIZE];//种群编码
public static double[]result=new double[POP_SIZE];//种群代表的结果
public static final int LENGTH=22;//编码长度,因为要精确到小数点后六位,所以编为22位长,有一公式可参考

public static final int MJ2=4194304;//2^22
public static double[]fitness=new double[POP_SIZE];//存放种群适应度
public static final double PC=0.95;//交叉率
public static final double PM=0.05;//变异率
public static double[]p=new double[POP_SIZE];//轮盘赌方法个体适应度概率
public static double[]q=new double[POP_SIZE];//q[i]是前n项p之和
public static Random random=new Random();//用于产生随机数的工具
public static Best best=new Best();//记录最佳答案的对象

/*
* 构造函数,初始化种群
*/
public GA(double d[])
{
   for (int i = 0; i < d.length; i++) {
    result[i]=d[i];
   }
}
/*
* 编码方法,将解值表示为二进制字节码形式
*/
public void encoding()

{
  
   for (int i = 0; i < result.length; i++) {
    double d1=((result[i]-A)/(B-A))*(MJ2-1);
   
    pop[i]=Integer.toBinaryString((int)d1);
   }

   for (int i = 0; i < pop.length; i++) {
    if (pop[i].length()<LENGTH) {
     int k=LENGTH-pop[i].length();
     for (int j = 0; j <k ; j++) {
      pop[i]="0"+pop[i];
     }
    }
   }
   for (int i = 0; i < pop.length; i++) {
    //System.out.println(pop[i]+" "+pop[i].length());
   }
  

}
/*
* 解码方法,讲二进制字节码还原为解
*/
public void decoding()
{
   for (int i = 0; i < pop.length; i++) {
    int k=Integer.parseInt(pop[i], 2);
    result[i]=A+k*(B-A)/(MJ2-1);
   
   }
   for (int i = 0; i < result.length; i++) {
   // System.out.println(result[i]);
   }
}
/*
* 适应度函数
*/
public void fitness()
{
   for (int i = 0; i < result.length; i++) {
    fitness[i]=result[i]*(Math.sin(10*Math.PI*result[i]))+2;
    //System.out.println(fitness[i]);
   }
}
/*
* 交叉操作
*/
public void crossover()
{
  
  
   for (int i = 0; i < POP_SIZE/2; i++) {
    double d=random.nextDouble();
    if(d<PC)
    {
     int k1=random.nextInt(POP_SIZE);
     int k2=random.nextInt(POP_SIZE);
     do {
      k1=(int)random.nextInt(POP_SIZE);
      k2=(int)random.nextInt(POP_SIZE);
     } while (k1==k2);
     int position=random.nextInt(LENGTH);
     //System.out.println("crossover position="+position+" "+k1+ " "+k2);
     String s11=null,s12=null,s21=null,s22=null;
     //System.out.println(pop[k1]+"   "+pop[k1].length());
     s11=pop[k1].substring(0, position);    
     s12=pop[k1].substring(position,LENGTH);
    
     //System.out.println(pop[k2]+"   "+pop[k2].length());
     s21=pop[k2].substring(0, position);
     s22=pop[k2].substring(position,LENGTH);
    
     pop[k1]=s11+s22;
     pop[k2]=s21+s12;
    
    
    }
   
   }
}
/*
* 变异操作
*/
public void mutation()
{
   for (int i = 0; i < pop.length; i++) {
    for (int j = 0; j < LENGTH; j++) {
     double k=random.nextDouble();
     if(PM>k)
     {
      mutation(i,j);
     }
    }
   }
}
public void mutation(int i,int j)
{
   String s=pop[i];
   StringBuffer sb=new StringBuffer(s);
   if(sb.charAt(j)=='0')
    sb.setCharAt(j, '1');
   else
    sb.setCharAt(j, '0');
   pop[i]=sb.toString();
  
}
/*
* 轮盘赌方法
*/
public void roulettewheel()
{
   decoding();
   fitness();
  
   double sum=0;
   for (int i = 0; i <POP_SIZE; i++) {
    sum=fitness[i]+sum;
   }
   for (int i = 0; i < POP_SIZE; i++) {
    p[i]=fitness[i]/sum;
   }
   for (int i = 0; i < POP_SIZE; i++) {
    for (int j = 0; j < i+1; j++) {
     q[i]=p[j];
    }
   }
   double []ran=new double[POP_SIZE];
   String[] tempPop=new String[POP_SIZE];
   for (int i = 0; i < ran.length; i++) {
    ran[i]=random.nextDouble();
   }
   for (int i = 0; i < ran.length; i++) {
    int k = 0;
    for (int j = 0; j < q.length; j++) {
     if(ran[i]<q[j])
     {
      k=j;
      break;
     }
     else continue;
    }
    tempPop[i]=pop[k];
   }
   for (int i = 0; i < tempPop.length; i++) {
    pop[i]=tempPop[i];
   }
}

/*
* 一次进化
*/
public void evolution()
{
   encoding();
   crossover();
   mutation();
   decoding();
   fitness();
   roulettewheel();
   findResult();
  
}
/*
*整个进化过程,n 表示进化多少代
*/
public void dispose(int n)
{
   for (int i = 0; i < n; i++) {
    evolution();
   }
}
/*
* 取得结果
*/
public double findResult()
{
   if(best==null)
    best=new Best();
   double max=best.fitness;
   for (int i = 0; i < fitness.length; i++) {
    if(fitness[i]>max)
    {
     best.fitness=fitness[i];
     best.x=result[i];
     best.str=pop[i];
     //System.out.println(best.fitness);
    }
   }
   return max;
}
/*
* 取得x值
*
*/
public double findx()
{
   fitness();
   double max=0;
   int index=0;
   for (int i = 0; i < fitness.length; i++) {
    System.out.println(result[i]);
    if(fitness[i]>max)
    {
     max=fitness[i];
     index=i;
    }
   }
   return result[index];
}
public static void main(String[] args) {
   //d为初试种群
   double d[]={-0.953181,-0.851234,-0.749723,-0.645386,-0.551234,-0.451644,-0.351534,-0.239566,-0.151234,0.145445,
        0.245445,0.285174,0.345445,0.445445,0.542445,0.645445,0.786445,0.845445,0.923238,1.245445,
        1.383453,1.454245,1.584566,1.644345,1.741545,1.845445,1.981254,-0.012853,0.083413,1.801231};
   //初始化其它参数
   GA ga=new GA(d);
   System.out.println("种群进化中....");
   //进化,这里进化10000次
   ga.dispose(10000);
   System.out.println("+++++++++++++++++++++++++++结果为:");
   System.out.println("x="+best.x);
   System.out.println("f="+best.fitness);
  
}

}
class Best { // 存储最佳的
public int generations;
public String str;
public double fitness;
public double x;
}

原文地址:https://www.cnblogs.com/macula7/p/1960673.html