遗传算法实现表达式在一定[x,y]求最大值

4 篇文章 0 订阅

 

遗传算法是计算数学中用于解决最优化的搜索算法,是进化算法的一种。进化算法最初是借鉴了进化生物学中的一些现象而发展起来的,这些现象包括遗传、突变、自然选择以及杂交等。

 

遗传算法通常实现方式为一种计算机模拟。对于一个最优化问题,一定数量的候选解(称为个体)的抽象表示(称为染色体)的种群向更好的解进化。

 

对遗传算法,我们不做过多的叙述,google一下,有大量的相关文章,我在这里用Java 实现求解 x^2在[x, y]上的最大值的过程,大家不要喷,我主要的目的是熟悉和理解遗传算法的过程。主要参考了http://blog.csdn.net/v_JULY_v/article/details/6132775

 

直接贴代码:

遗传算法接口类:

package Arithmetic.sga;

import java.util.List;

/**
 * 遗传算法接口
 *
 *@ClassName: ISimpleGA
 *@author riverpp    
 *@since V1.0.0
 */
public interface ISimpleGA
{
 /**
  * 遗传算法的工作流程
  * @return
  */
 Object sgaWorkflow();

  /**
   * 初始化种族
   * @param ppl
   */
 void initializePopulation(List ppl);
 
 /**
  * 选择强壮优秀的基因遗传下去
  * @param ppl
  * @return
  */
 List selectStrong(List ppl);
 
 /**
  * 选择两个基因交配
  * @param ppl
  * @param posM
  * @param posF
  */
 void geneCross(List ppl, int posM, int posF);
 
 /**
  * 交配生成的新生代基因发生变异
  * @param ppl
  * @param posSon1
  * @param posSon2
  */
 void geneMutate(List ppl, int posSon1, int posSon2);
 
 /**
  * 选择过程,选择出新的种群
  * @param ppl
  */
 void selecting(List ppl);
 
 /**
  * 判断遗传算法是否结束,结束条件:1)已经求得最优解(对于复杂的任务, 最优解很难求得);2)遗传代数达到最大
  * @param ppl
  * @return
  */
 boolean isOver(List ppl);
 
 /**
  * 适应函数 
  * @param ele
  * @return
  */
 Object fitnessFuncion(Object ele);
 
 /**
  * 获取最后的结果
  * @param ppl
  * @return
  */
 Object lastResult(List ppl);
}

 

表达式x^2在闭区间最大值求解实现:

package Arithmetic.sga;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;

/**
 * 求解x^2在某个范围上的最大值遗传算法实现
 *
 *@ClassName: SGAFormula
 *@author riverpp    
 *@since V1.0.0
 */
public class SGAFormula implements ISimpleGA
{
 /*
  * 遗传的算法遗传的代数
  */
 private int pgap;
 
 /*
  * 遗传算法初始化种群个数
  */
 private int initPPLNums;
 
 /*
  * 遗传算法最大执行代数
  */
 private int maxPgap;
 
 /*
  *求解的最小值
  */
 private int minValue;
 
 /*
  * 求解的最大值
  */
 private int maxValue;
 
 /*
  * 交配的概率
  */
 private double perCross;
 
 /*
  * 变异的概率
  */
 private double perMut;

 /*
  * 种群
  */
 private List<Integer> pplList;

 /**
  * 遗传算法求(x^2)在某个范围上的求解的最大值的构造函数
 *     
 *     
 * @param initPPLNums 初始种群种的个数
 * @param maxPgap  遗传算法执行的最大代数
 * @param min   求解的最小值
 * @param max   求解的最大值
 * @param perCross  交配的概率
 * @param perMut   变异的概率
  */
 SGAFormula(int initPPLNums, int maxPgap, int min, int max, double perCross,
   double perMut)
 {
  this.pgap = 0;
  this.initPPLNums = initPPLNums;
  this.maxPgap = maxPgap;
  this.minValue = min;
  this.maxValue = max;
  this.perCross = perCross;
  this.perMut = perMut;
  pplList = new ArrayList<Integer>(initPPLNums);
 }

 @Override
 public Object sgaWorkflow()
 {
  Random rand = new Random();
  int posX = 0;
  int posY = 0;
  List<Integer> top = null;
  Set<Integer> iSet = new TreeSet<Integer>();
  initializePopulation(pplList);
  printPPL(pplList);

  //遗传算法结束条件:1)求得最优解(对于x^2,最优解就是最大值),2)遗传算法到最大代数
  while (!isOver(pplList))
  {
   //选取优良基因, 在本轮遗传中不交配和变异
   top = selectStrong(pplList);
   iSet.clear();
   iSet.addAll(top);

   //选取种群中两个基因进行交配和变异
   for (int i = 0; i < initPPLNums; i++)
   {
    
    do
    {
     posX = rand.nextInt(initPPLNums);
     posY = rand.nextInt(initPPLNums);
    }//选取的基因不是优良基因,
    while (iSet.contains(posX) || iSet.contains(posY)
      || (posX == posY));

    //基因交配
    geneCross(pplList, posX, posY);
    printPPL(pplList);

    //基因变异
    geneMutate(pplList, posX, posY);
    printPPL(pplList);
   }

   //基因选择, 采用轮盘赌选择法
   selecting(pplList);
   printPPL(pplList);
  }

  //获取最后的结果
  return lastResult(pplList);
 }

 @Override
 public void initializePopulation(List ppl)
 {
  int ele = 0;
  Random rand = new Random();
  for (int i = 0; i < initPPLNums; i++)
  {
   do
   {
    //随机生成 在[minValue, maxValue]内地整数作为初始化种群的种子基因
    ele = rand.nextInt(maxValue);
   }
   while (ele <= maxValue && ele >= minValue);

   ppl.add(ele);
  }
 }

 @Override
 public List selectStrong(List ppl)
 {
  int fit = 0;
  int max = 0;
  int idxMax = 0;
  
  //选择最大值最为最优基因
  for (int i = 0; i < ppl.size(); i++)
  {
   fit = (Integer) fitnessFuncion(ppl.get(i));
   if (fit > max)
   {
    max = fit;
    idxMax = i;
   }
  }

  List<Integer> result = new ArrayList<Integer>();
  result.add(idxMax);
  return result;
 }

 @Override
 public void geneCross(List ppl, int posM, int posF)
 {
  //随机生成一个小数
  double pc = Math.random();

  //判断是否可以进行交配
  if (pc <= perCross)
  {
   Random rand = new Random();
   int m = (Integer) ppl.get(posM);
   int f = (Integer) ppl.get(posF);

   int rd = rand.nextInt(maxValue - minValue);
   //基因可以向好的变化
   if (m + rd <= maxValue)
   {
    m += rd;
    ppl.remove(posM);
    ppl.add(posM, m);
   }

   //基因可以向坏的变化
   if (f - rd >= minValue)
   {
    f -= rd;
    ppl.remove(posF);
    ppl.add(posF, f);
   }
  }
 }

 @Override
 public void geneMutate(List ppl, int posSon1, int posSon2)
 {
  double pm = Math.random();

  //判断是否可以变异
  if (pm <= perMut)
  {
   Random rand = new Random();
   int son1 = (Integer) ppl.get(posSon1);
   int son2 = (Integer) ppl.get(posSon2);

   int rd = rand.nextInt(maxValue - minValue);
   //基因变异
   if (son1 + rd <= maxValue)
   {
    son1 += rd;
    ppl.remove(posSon1);
    ppl.add(posSon1, son1);
   }

   rd = rand.nextInt(maxValue - minValue);
   //基因变异
   if (son2 - rd >= minValue)
   {
    son2 -= rd;
    ppl.remove(posSon2);
    ppl.add(posSon2, son2);
   }
  }
 }

 @Override
 public void selecting(List ppl)
 {
  int fitSum = 0;
  int fit = 0;
  double per = 0.0D;
  double pFit[] = new double[ppl.size()];
  double pRand[] = new double[ppl.size()];
  
  //随机生成N个[0, 1)
  for (int i = 0; i < pRand.length; i++)
  {
   pRand[i] = Math.random();
  }
  
  //求所有所有元素的适度函数值之和
  for (int i = 0; i < ppl.size(); i++)
  {
   fit = (Integer)fitnessFuncion(ppl.get(i));
   fitSum += fit;
  }
  
  //求每个元素的累积概率
  for (int i = 0; i < ppl.size(); i++)
  {
   fit = (Integer)fitnessFuncion(ppl.get(i));
   per += 1.0D * fit / fitSum;;
   pFit[i] =  per;
  }
  
  int strand[] = new int[ppl.size()];
  for (int i = 0; i < ppl.size(); i++)
  {
   for (int j = 0; j < ppl.size(); j++)
   {
    //计算随机数在[pFit[j - 1], pFit[j]]之间的个数, 个数最多的作为优秀基因, 替换最少的
    if (pRand[i] < pFit[j])
    {
     strand[j]++;
    }
   }
  }
  
  int max = 0;
  int idx = 0;
  for (int i = 0; i < strand.length; i++)
  {
   if (strand[i] > max)
   {
    max = strand[i];
    idx = i;
   }
  }
  
  for (int i = 0; i < strand.length; i++)
  {
   if (0 == strand[i])
   {
    ppl.remove(i);
    ppl.add(i, max);
   }
  }
  
  ++pgap;
 }

 @Override
 public boolean isOver(List ppl)
 {
  //遗传代数达到最大
  if (pgap > maxPgap)
  {
   return true;
  }

  //选择最强的种子,
  List<Integer> top = selectStrong(ppl);
  if (null == top)
  {
   return true;
  }

  //如果最强的种子已经是最优解,则结束
  int rlt = (Integer) top.get(0);
  if (rlt == maxValue)
  {
   return true;
  }

  return false;
 }

 @Override
 public Object fitnessFuncion(Object ele)
 {
  int x = (Integer) ele;

  return Integer.valueOf(x * x);
 }

 @Override
 public Object lastResult(List ppl)
 { 
  return ppl.get((Integer)selectStrong(ppl).get(0));
 }
 
 void printPPL(List ppl)
 {
  System.out.print("PPL=");
  for (int i = 0; i < ppl.size(); i++)
  {
   System.out.print((Integer)ppl.get(i) + ", ");
  }
  System.out.println();
 }
 public static void main(String[] argv)
 {
  SGAFormula sgaf = new SGAFormula(5, 10, 2, 20, 0.87, 0.03);
  
  int result = (Integer)sgaf.sgaWorkflow();
  
  System.out.println("Result = " + result);
 }
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值