【编程书籍】《The Nature of Code》笔记 -《代码本色》9.代码的进化

9.1 遗传算法:启发自真实现象

1.传统遗传算法:
随着猜测答案的迭代次数增加,答案可以发生进化(如二分法猜数)
2.交互式选择
用户点击过A后,程序根据A自动产生(进化出)与A相似的搜索结果
3.生态系统模拟

9.2 为什么使用遗传算法

尽管计算机对进化过程的模拟可以追溯到20世纪50年代,但大部分人认为当今的遗传算法(Genetic Algorithm,GA)是由密歇根大学的约翰·霍兰德教授率先提出的。

求解答案已知的问题有助于我们验证算法的正确性。一旦遗传算法成功地解决了这个问题,它的有效性就能得到证明。我 们就能以更自信的心态用它求解答案未知的问题。所以,第一个示例的目的仅仅在于 演示遗传算法的工作原理。如果GA算出的结果和已知结果相同,就代表它已被正确地实现。

9.4 遗传算法,第一部分:创建种群

遗传领域有两个重要概念:基因型和表现型,两者之间有重要区别。基因型 (genotype)就是遗传密码,也就是本例的字符串,它会从父代传给子代;表现型 (phenotype)就是基因型的表达。
在这里插入图片描述

9.5 遗传算法,第二部分:选择

1.评估适应度
为了让遗传算法有效,我们需要设计一个适应度函数。这个函数会产生一个描述个体 适应度的分值。
再一次简化这个问题,假设我们只想进化出单词“cat”,“car”有两个正确字符,它的适应度最高。“hut”只有一个正 确字符,“box”没有正确字符。
因此,适应度函数如下: 适应度 = 正确字符的数量
在这里插入图片描述

2.创建交配池
概率方法,我们称为“命运之轮”
假设种群中有5个个体,它们都有自己的适应度分值。

在这里插入图片描述
在这里插入图片描述

9.5 遗传算法,第三部分:繁殖

1.交叉
在这里插入图片描述

2.突变
突变的作用就是在进化过程中不断引入多样性。
一个遗传算法可能有5%、1%或0.1%的突变率。假设交叉完成后,某子代个体是“FORY”,如果突变率为1%,这意味着每个字符有1%的突变概 率。而字符怎么发生突变呢?

在本例中,我们把突变定义为用一个随机的字符替换原字符。
在这里插入图片描述

在获得新种群之前,我们会不断地进行选择(选择两个父本)和繁殖(交叉和突变) 操作。一旦子代种群代替了当前种群,我们还会回到之前的步骤:再次评估适应度, 再次进行选择和繁殖操作。

9.6 遗传算法步骤

SETUP
第1步:初始化 创建由N个个体组成的种群,随机确定个体的DNA。

LOOP
第2步:选择 评估个体的适应度,创建交配池。
第3步:繁殖 重复N次。
a) 根据相对适应度,概率性地选择两个父本。
b) 杂交——结合父本的DNA,创建出一个“子代个体”。
c) 突变——以一定的概率使子代的DNA发生突变。
d) 将这个子代加入新种群。 第4步:用新种群替换旧种群,再回到第2步。

class DNA 
{
   
	char[] genes = new char[18];
	DNA() 
	{
   
		for (int i = 0; i < genes.lenght; i++) 
		{
   
			genes[i] = (char) random(32,128); //从编号为32~128的ASCII字符中随机选择一系列字
		}
	}
}
String target = "to be or not to be";
class DNA 
{
   
	float fitness; //在DNA类中加入一个适应度变量
	void fitness () //该函数的作用是计算适应度
	{
    
		int score = 0;
		for (int i = 0; i < genes.length; i++) 
		{
   
			if (genes[i] == target.charAt(i)) //字符是否正确
			{
    
				score++; //如果正确,增加分值
			}
		}
		fitness = float(score)/target.length(); //适应度就是正确字符的百分比
	}
}
void mutate() 
{
   
	for (int i = 0; i < genes.length; i++) //遍历数组中的每个基因
	{
    
		if(random(1) < mutationRate) 
		{
   
			genes[i] = (char) random(32,128); //突变,产生随机字符
		}
	}
}

9.8 遗传算法:整合代码

遗传算法:进化出莎士比亚名言

float mutationRate; //突变率
int totalPopulation = 150; //个体总数
DNA[] population; //个体数组
ArrayList<DNA> matingPool; //交配池数组
String target; //目标答案
void setup() {
   
	size(200, 200);
	target = "to be or not to be"; //初始化目标答案和突变率
	mutationRate = 0.01;
	population = new DNA[totalPopulation]; //步骤1:初始化种群
	for (int i = 0; i < population.length; i++) {
    //步骤2a:计算适应度
		population[i] = new DNA();
	}
}
void draw() {
   
	for (int i = 0; i < population.length; i++) {
   
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值