高中学习生物时就想利用类似自然选择的原理来编写一个只用描述选择过程的程序,后来了解到遗传算法正是以此为原理的算法。近学习《人工智能》,教材提供了遗传算法的伪代码和以N皇后为例的分析,故尝试利用C语言来实现。(用遗传算法解决N皇后并不合适,文章中会说明)
本文将简单记录遗传算法的思想,并利用C语言来实现遗传算法。
=====================================================================
遗传算法概述
遗传算法简而言之就是模拟自然界中自然选择而构造的一种算法。
下面借助《人工智能 一种现代的方法》中的伪代码进行详细分析。function Genetic_Algorithm(population,Fitness_FN) returns an individual //输入为包含了一定数量个体的种群对象,以及针对个体评估其适应程度的方法 repeat new_population <- empty set //初始化下一代种群,该种群的大小与原来的种群大小保持一致(这个可以根据算力修改) //下面的循环开始生成新种群中的个体 for i = 1 to sizeof(population) do father <- Random_Selection(population,Fitness_FN) mother <- Random_Selection(population,Fitness_FN) //下一代的个体的父母通过评估函数计算其生存概率从种群中选择 child <- Reproduce(father , mother) //下一代个体通过将其父母的基因根据随机分段位置分别取出拼凑而成 if(small random probability) child <- Mutate(child) //下一代个体将有一定概率发生基因突变 add child to new_population //将新的个体加入到新的种群中 population <- new_population //结束本代种群组建,准备开始下一代种群的组建 until some individual is fit enough or enough time has clasped //当种群中有些个体已经足够符合,或者计算时间达到限制,结束循环 return the best individual in population according to Fitness_FN //返回本种群中最佳个体
根据以上伪代码已可大致理解遗传算法的思路。将每一代的种群中基因优良的个体杂交,期望获取更优个体,而基因突变则为种群带来新的变化,或许会引导种群向更好的方向发展。
由此也可以大体推出遗传算法适合的问题模型,这种问题的最优解是处于一个连续的区间,也就是与次优解的差距不大。N皇后实则不太符合这个规律,其轻微移动一步会造成极大的改动,切与另一个得分高棋局相结合并不会获取一个更小冲突的棋局,反而有时会适得其反。N皇后采用遗传算法只能靠其筛选来保持总体发展,遗传对其引导性不足。
由于课本是以N皇后来举例的,这里实现也就先以其为案例。C语言实现
很久没有写c语言了,代码有些乱,存在可以优化的地方,见谅。结果分析
由于计算机性能有限,这里采用的参数是:变异几率1% 种族大小为30 变异代数上限为500000
多次运行尝试后可以进化出正确的后代。
在尝试结果的过程中,发现了一些有趣的现象:
当变异率极低时,个体数为10 经过14代进化后 其种族基因只剩下一种。
通过增大种群中个体数,或者增大变异概率,改变产生后代的方法可以避免出现这种极端情况。