遗传算法简单入门

久远的记忆,发上来和有缘人分享一下,格式有些乱掉了。。。

 

 

内部交流系列二

遗传算法简单入门

 

    对遗传算法感兴趣,一方面源自中学生物,另一方面,进化计算,个人认为也是一种趋势,多少需要了解一点。

神经网络让人流连忘返,乐此不疲的构造各种训练样本,然后看看网络的反应是如何的;如果说用神经网络可以构建一个脑,那么遗传算法帮助下,我们则可以创建一个全新的世界。

 

1、算法步骤

初始化第一代

适合度分等

选择(赌轮选择法)

交叉变异(杂交,杂交变异率)

随机突变(突变率)

不断演化

 

2、算法步骤简单说明

    说的很玄乎,实际上这个算法的思路很好理解:

    (注:如果有疑问,多看看括号里面的话,对比思考一下,如果还有疑问,说明解释的不够清晰,自己再查查资料啦^_^)

1、针对问题,构造问题的解为二进制数据串,算法中看做一个染色体串

    (人的基因序列)

2、初始化第一代的个体染色体群

    (new 100个亚当、100个夏娃,上帝只造了一对,很冒险的说,还是仿造咱们老古人,一百对童男童女渡船到某个岛上。。。 。。。扯远了,come back)

3、不断循环演化出新一代染色体群,直到找出一个解(最重要的部分,一个时代epoch)

(怎么说的来着,子子孙孙无穷溃也,可能直到地球毁灭吧)

(注:也有可能算法不收敛,即找不到解,要设定一个最大演化次数)

(1)检查每一个个体,看看解决问题的能力怎么样,对其打分,即适应度分等

(对于控制人类演化的大神来说,要清楚每个亚当和夏娃的综合能力怎么样,以便使下一代得到好的遗传基因的概率最大化)

(2)从当前个体中选出若干个体,作为下一代的母染色体

这里常用的选择方式是“赌轮选择法 roulette wheel selection”,也就是说,适应度越高,被选中的概率越大,注意不是适应度最高的一定被选中,而是说概率最大。

(夏娃竞争超女,同时亚当进行高考相亲,实力最强的晋级几率最大,也难保有运气好的黑马让它阴沟里翻船)

(3)按照预定的杂交率(crossover rate),从每个选中染色体的一个随机确定的点上进行杂交。

(计算机世界貌似不太好处理这一步,实际上,就是生个娃下个崽的事情)

(衍生一下,其实用代码处理这个事情相当容易且强大,如果思维够开阔的话,就会慢慢发现这个算法的魅力:下一代不一定只能由一个母体一个父体杂交创建,综合多个母体父体的优秀基因也许会更好;染色体不一定要对位交换基因序列,某一小段优秀基因,在其它位置也许也是表现很优秀的;变异率不一定是比较低才好,整代表现差的时候,变异率设为很高也许能让这一代人脱胎换骨)

(4)随机突变按照预定的变异率(mutation rate),把个体染色体相应的位进行翻转(flip)

    (比较好理解,就不类比了)

(5)重复步骤(2)、(3)、(4),直到新一代的数量达到上一代的数量

(下一代的数量不能太少,算法中保持相同比较好处理,也不知道要演化多少代)

3、算法源代码

模拟一个花朵的演化过程:

1、这个世界的环境参数:

private int flowerNumber;   // 种群数量(一代中的花朵数量)

private Random r;       // 决定种群初始状态,随机突变等随机过程以及随机结果

private int[] temperature; // 每朵花的最佳生长温度

private int[] water;        // 最佳水分

private int[] sunlight;    // 最佳光照

private int[] nutrient;    // 最佳养分

private int[] beneficialInsect;  // 对它有益的虫子(编号?数量?)

private int[] harmfulInsect;     // 对它有害的虫子(编号?数量?),注意作者这里是举例多个参数,明白意思即可,别抠字眼哦

// 当前的环境条件

private int currentTemperature;

private int currentWater;

private int currentSunlight;

private int currentNutrient;

private int currentBeneficialInsect;

private int currentHarmfulInsect;

2、第一代花朵的当前生存环境采用随机值:(多数情况下,根据实际问题设定一个初始值)

// [0,75)之间

   currentTemperature = r.nextInt(75);

   currentWater = r.nextInt(75);

   currentSunlight = r.nextInt(75);

   currentNutrient = r.nextInt(75);

   currentBeneficialInsect = r.nextInt(75);

   currentHarmfulInsect = r.nextInt(75);

3、第一代花朵中,每朵花的最佳环境参数,也采用随机值:(多数情况下,根据实际问题设定一组经验值)

for(int i = 0; i < flowerNumber; i++){

       temperature[i] = r.nextInt(75);

       water[i] = r.nextInt(75);

       sunlight[i] = r.nextInt(75);

       nutrient[i] = r.nextInt(75);

       beneficialInsect[i] = r.nextInt(75);

       harmfulInsect[i] = r.nextInt(75);

}

4、找出最适应当前环境的花朵:(具体问题不同,这里的策略可能不同,每个条件的权重也可能不一样等等)

// 花朵适应度函数,找出长的最高的

public int fitness(int flower){

int theFitness = 0;    

   theFitness = Math.abs(temperature[flower] - currentTemperature);

   theFitness += Math.abs(water[flower] - currentWater);

   theFitness += Math.abs(sunlight[flower] - currentSunlight);

   theFitness += Math.abs(nutrient[flower] - currentNutrient);

theFitness += Math.abs(beneficialInsect[flower] - currentBeneficialInsect);

theFitness += Math.abs(harmfulInsect[flower] - currentHarmfulInsect);    

   return theFitness;

}

5、最重要的时代函数:

// 花朵演化函数(  没有贴源代码,这里主要是几个步骤比较重要,实现起来不尽相同  )

public int evolve(){

   // 首先找出适合度最小的成员,即误差最大的

// 把适合度最小的成员的特征,重新赋值,即丢弃最不合适的基因

   

// 交叉变异,随机混合花群特征

// 以百分之一的概率随机突变,这个突变概率太大,主要是演示思想

 

// 返回新一代中,适应度最高的花朵

 

// 每一代都会淘汰部分适应度最低的花朵,以使得总体基因的水平逐步提高

}

6、演示Main()方法

while(i < 100000){ // 设定最多演化的次数,超过这么多代还不满足适应度需求,视为不收敛,说明第一代的基因和环境条件差距过大

    Thread.sleep(1000);

   System.out.print("\n第 " + i++ + "代花朵\t");

   best = flowerWorld.evolve();   // 演化一代,得到最适应环境的花朵

if(flowerWorld.fitness(best) < 50) // 如果已经满足适应度需求

           break;

}

 

附注:

这是一个思想简单功效强大的算法,简洁而博大,极好的探索素材^_^

 

4、Java类库:

JGAP,sourceforge上面开源项目,已经发展了比较久

5、推荐书籍

<游戏开发中的人工智能><AI for Game Developers>(David M. Borug & Glenn Seemann)

<游戏编程中的人工智能技术><AI Techniques for Game Programming>(Mat Buckland)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值