遗传算法是计算数学中用于解决最优化的搜索算法,是进化算法的一种。进化算法最初是借鉴了进化生物学中的一些现象而发展起来的,这些现象包括遗传、突变、自然选择以及杂交等。
遗传算法通常实现方式为一种计算机模拟。对于一个最优化问题,一定数量的候选解(称为个体)的抽象表示(称为染色体)的种群向更好的解进化。
对遗传算法,我们不做过多的叙述,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);
}
}