本文为原创文章,如有任何疑问请留言
遗传算法是一种全局、概率搜索算法,主要用于求解大规模旅行商问题、路径规划问题、任务调度等NP-hard问题。
遗传算法属于进化算法,首先将需要求解的自变量通过编码形成染色体,在遗传过程中通过交叉、变异等操作产生新个体,选择种群中较优的个体遗传到下一代,不断进化,直到达到遗传终止条件为止。
本文以一个小规模的两两组合优化问题为例对遗传算法的流程进行简要介绍。问题:一个仓库有5个包裹需要运输至5个不同的目的地,每辆运输车最多运输两件包裹,求解最佳的组合运输方案。
(1)遗传编码。问题属于路径规划组合优化问题,每个问题当且仅当执行一次,因此,选择任务序号作为基因进行编码产生染色体。
(2)初始解生成。启发式算法初始解的质量直接影响算法收敛速度,因此一般使用一些简单优化方法产生初始解,种群大小一般取经验值20-100。本文使用随机方法产生初始解,种群大小20,例如:个体1:23415,个体2:13245………………个体20:54321.
(3)选择。选择较优个体遗传到下一代,一般使用轮盘赌的方法,多目标时可能选择帕累托法等。选择时需要计算个体的适应值,路径规划问题一般为距离最短或时间最短,使用轮盘赌时需要将最小化问题转换为最大化问题,因此需要引入常数计算适值。
(4)交叉。常用交叉方法有单点交叉、多点交叉和部分映射交叉等。本文使用单点交叉,交叉后可能会产生非法解,需要将个体染色体合法化。
(5)变异。变异一般使用单点变异或交换变异,同样在变异后需要合法化个体染色体。
下面为遗传算法详细C语言代码,编程技术有限,仅供初学者参考,也可在matlab等软件中直接调用算法包实现问题求解。
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#define s 5 /* 随机数个数 */
#define c 10 /* 染色体长度 */
#define add 5 /* 节点数 */
void quchong(); //合法化函数
int maxgen; /* 最大遗传代数 */
int maxruns; /* 最大运行次数 */
float Pc; /* 交叉概率 */
float Pm; /* 变异概率 */
float rf; /* 随机浮点数 */
int ri; /* 随机整数 */
int nc; /* 交叉次数 */
int nm; /* 变异次数 */
int a[add]; /* 初始序列12345 */
int b[s]; /* 随机数数列 */
FILE *fp; //文件指针
int road[6][6]={
{0,738,749,710,520,712}, /* 路径地图 */
{738,0,790,772,870,583},
{749,790,0,885,598,615},
{710,772,885,0,513,607},
{520,870,598,513,0,508},
{712,583,615,607,508,0}};
int ncar=4; /* 车数量 */
struct i