前言:
现在看官们对“遗传算法 分类问题”大概比较关切,大家都想要剖析一些“遗传算法 分类问题”的相关资讯。那么小编在网络上汇集了一些对于“遗传算法 分类问题””的相关知识,希望你们能喜欢,朋友们一起来了解一下吧!遗传算法也成进化算法,该算法受到达尔文进化论的启发提出的一种启发式搜索算法。
进化论
种群
生物的进化以群体的形式进行,这样的一个群体称为种群。
个体
组成种群的单个生物。
基因
一个遗传因子。
染色体
包含一组的基因。
生存竞争,适者生存
对环境适应度高的个体参与繁殖的机会比较多,后代就会越来越多。适应度低的个体参与繁殖的机会比较少,后代就会越来越少。
遗传与变异
新个体会遗传父母双方各一部分的基因,同时有一定的概率发生基因变异。
综述
繁殖过程,会发生基因交叉,基因突变 ,适应度低的个体会被逐步淘汰,而适应度高的个体会越来越多。那么经过N代的自然选择后,保存下来的个体都是适应度很高的,其中很可能包含史上产生的适应度最高的那个个体。
遗传算法
遗传算法将要解决的问题模拟成一个生物进化的过程,通过复制、交叉、突变等操作产生下一代的解,并逐步淘汰掉适应度函数值低的解,增加适应度函数值高的解。这样进化N代后就很有可能会进化出适应度函数值很高的个体。下面以0-1背包问题来讲解下遗传算法的步骤
编码
需要将问题的解编码成字符串的形式才能使用遗传算法。最简单的一种编码方式是二进制编码,即将问题的解编码成二进制位数组的形式。例如,问题的解是整数,那么可以将其编码成二进制位数组的形式。将0-1字符串作为0-1背包问题的解就属于二进制编码。
选择
选择一些染色体来产生下一代。一种常用的选择策略是比例选择。也就是轮盘赌算法,如下图所示
群体中每一染色体指定饼图中一个小块。块的大小与染色体的适应性分数成比例,适应性分数愈高,它在饼图中对应的小块所占面积也愈大。为了选取一个染色体,要做的就是旋转这个轮子,直到轮盘停止时,看指针停止在哪一块上,就选中与它对应的那个染色体。
若产生随机数为0.81,则6号个体被选中。
// 轮盘赌代码示意/** 按设定的概率,随机选中一个个体* P[i]表示第i个个体被选中的概率*/int RWS(){ m =0; r =Random(0,1); //r为0至1的随机数 for(i=1;i<=N; i++) { /* 产生的随机数在m~m+P[i]间则认为选中了i * 因此i被选中的概率是P[i] */ m = m + P[i]; if(r<=m) return i; }}交叉
2条染色体交换部分基因,来构造下一代的2条新的染色体。父辈染色体00000|011100000000|1000011100|000001111110|00101随机交叉遗传00000|000001111110|1000011100|011100000000|00101
变异
新产生的染色体中的基因会以一定的概率出错,称为变异。变异前: 000001110000000010000变异后: 000001110000100010000我们认为染色体交叉的概率为Pc,染色体变异的概率为Pm。适应度函数:用于评价某个染色体的适应度,用f(x)表示。有时需要区分染色体的适应度函数与问题的目标函数。例如:0-1背包问题的目标函数是所取得物品价值,但将物品价值作为染色体的适应度函数可能并不一定适合。适应度函数与目标函数是正相关的,可对目标函数作一些变形来得到适应度函数。
遗传算法核心表示
/** * 交叉遗传的概率Pc * 遗传变异的概率Pm * 种群规模M * 终止进化代数G * 当产生出一个个体的适应度超过给定Tf,则终止进化 */ 步骤1 初始化产生 Pc Pm M G Tf参数并随机生成第一代种群population,简称P1 初始化P = P1 do { 计算P中每一个个体的适应度F(i) 初始化空种群newP do { 根据适应度比例选择算法选择出2个个体 if (rnd1 < Pc) { 进行交叉操作 } if (rnd2 < Pm) { 进行变异操作 } 将两个操作后的个体放进newP中,即产生的新个体进入新的种群 } until (M个个体被创建) P = newP } until(任何染色体满足适应度或者繁殖代数>G)
在这里我们看到了,这个随机选择以及产生后代的方式需要斟酌,如果设定的不好,那么很有可能这个种族最后就灭绝了,算个说话也就是我们没有得到我们的解。大自然这里还有一个规律叫做:物竞天择 适者生存在我们这里也需要对算法进行优化:择优 为了防止进化过程中产生的最优解被交叉和变异所破坏,可以将每一代中的最优解原封不动的复制到下一代中。
具体实例
理解实例
求 f(x1, x2) = x1^3 + x2^2 + (x1 * (x1 – x2))的最大值,其中x1属于{-5, -3, 1, 3, 5}, x2属于{0, 2, 4}当然这个题目解法很多,穷举方法也非常的迅速。这个例子为了更加透彻的理解遗传算法。步骤1 编码我们此处定义隐射关系为[[0] = -5,[1] = -3,[2] = 0,[3] = 1,[4] = 2,[5] = 3,[6] = 4,[7] = 5]8可以用4位二进制表示,而x1和x2则用8位二进制即可完成验证比如{0110|0110}则表示[x1 = 3, x2 = 4]步骤2 生成种群,注意生成种群的数量以及作用域关系,写一段js代码来进行测试
生成个体
步骤3 随机选择父代进行通过交叉和变异生成子代(选出适应度较高的进行)
产生多代并得到最后结果
150
代码示意,因为没有变异以及编码是否可以有更好的办法,所以只为显示整体过程
console.log("遗传算法");var everyone = [];var number = 200;function in_array(search, array){ for(var i in array){ if(array[i]==search){ return true; } } return false;}var genChromosome = function(scope) { var timestamp = new Date().getTime(); var index = Math.ceil(Math.random() * timestamp) % scope.length; var chromosome = scope[index].toString(2); while (chromosome.length < 4) { chromosome = "0" + chromosome; } return chromosome;}// 计算每个的适应度var calFitness = function(omo) { var codes = [-5, -3, 0, 1, 2, 3, 4, 5]; var arr1 = [-5, -3, 1, 3, 5]; var arr2 = [0, 2, 4]; var x1 = codes[parseInt(omo.substr(0, 4), 2)]; var x2 = codes[parseInt(omo.substr(4, 4), 2)]; if (x1 != undefined && x2 != undefined && in_array(x1, arr1) && in_array(x2, arr2)) { return x1 * x1 * x1 + x2 * x2 + (x1 * (x1 - x2)); } return -9999;}function sortNumber(a,b) { return a - b } $('#genUnit').click(function() { $('#geti').html(''); var scope1 = [0, 1, 3, 5, 7]; var scope2 = [2, 4, 6]; // 生成50组个体 everyone = []; for (var i = 0; i < number; i++) { var new_omo = genChromosome(scope1) + genChromosome(scope2); everyone.push (new_omo); } for (var i = 0; i < everyone.length; i++) { $('#geti').append(everyone[i] + " "); if ((i + 1) % 10 == 0) { $('#geti').append(""); } }});// 交叉函数var cross = function(omo1, omo2) { // 针对这个,四位是一个染色体特征控制 var ret = ""; var timestamp = new Date().getTime(); var rnd = Math.ceil(Math.random() * timestamp) % 4; if (rnd <= 1) { // 互换前四位 for (var i = 0; i < 4; i++) { var tmp = omo1[i]; omo1[i] = omo2[i]; omo2[i] = tmp; } } else if (rnd <= 3) { // 互换后四位 for (var i = 4; i < 8; i++) { var tmp = omo1[i]; omo1[i] = omo2[i]; omo2[i] = tmp; } } var rnd_next = Math.ceil(Math.random() * timestamp) % 2; if (rnd_next == 0) { ret = omo1; } else { ret = omo2; } return ret;}// 变异函数var variation = function(omo1, omo2) { // 变异某一位,然后做交叉运算 // 这里暂时不需要,所以直接进行选择 var timestamp = new Date().getTime(); var rnd_next = Math.ceil(Math.random() * timestamp) % 2; if (rnd_next == 0) { ret = omo1; } else { ret = omo2; } return ret;}// 判断结束var finish = function() { // 这里直接看第五十代}$('#genNextUnit').click(function() { if (everyone.length == 0) { return } // 至少5代且满足best适应值占75%或最多50代 var g_num = 0; while (g_num < 50) { // 假设淘汰20%,最优的保留,剩下随机 var fitness_score = []; for (var i = 0; i < everyone.length; i++) { fitness_score.push(parseInt(calFitness(everyone[i]))); } fitness_score.sort(sortNumber); var over = Math.ceil(fitness_score.length * 0.2) for (var i = 0; i < over; i++) { fitness_score.shift(); } var best = fitness_score[fitness_score.length - 1]; // 生成子代 var new_generation = []; while (new_generation.length < number) { var curr_unit; // 选择 var timestamp = new Date().getTime(); var choose_fitness1 = everyone[Math.ceil(Math.random() * timestamp) % everyone.length]; var choose_fitness2 = everyone[Math.ceil(Math.random() * timestamp) % everyone.length]; if (calFitness(choose_fitness1) == best && calFitness(choose_fitness2) == best) { // 进行交叉 curr_unit = cross(choose_fitness1, choose_fitness2) if (Math.ceil(Math.random() * timestamp) % 100 < 2) { // 进行变异 curr_unit = variation(choose_fitness1, choose_fitness2) } } else if (Math.ceil(Math.random() * timestamp) % 100 > 50) { // 进行交叉 curr_unit = cross(choose_fitness1, choose_fitness2) // 进行变异 if (Math.ceil(Math.random() * timestamp) % 100 < 2) { // 进行变异 curr_unit = variation(choose_fitness1, choose_fitness2) } } if (curr_unit != undefined) { if (calFitness(curr_unit) > -9999) { new_generation.push(curr_unit); } } } everyone = new_generation; g_num = g_num + 1; } var fitness_score = []; for (var i = 0; i < everyone.length; i++) { fitness_score.push(parseInt(calFitness(everyone[i]))); } console.log(everyone[0]); fitness_score.sort(sortNumber); var best_number = fitness_score[fitness_score.length - 1]; $('#zidai').html(best_number); // 01110010});
标签: #遗传算法 分类问题 #遗传算法函数最优解 #遗传算法论文选题怎么选 #遗传算法的交叉概率取值范围是什么 #遗传算法的研究背景与意义怎么写