遗传算法的C语言实现
- 遗传算法求解TSP问题
- 换位表达、启发式交叉、启发式变异、最优选择策略
前言
本文设计遗传算法对TSP问题进行求解。首先选取100个城市作为旅行过程中要经过的点,城市的坐标已知,求解一个通过每个城市一次且总距离最短的路径。本文采用换位表达对染色体编码,基因的值表示城市的值,基因的顺序表示城市访问的顺序;采用启发式交叉和启发式变异产生新的子代染色体;采用最优选择策略选择下一轮迭代的染色体。本文使用C语言对设计的遗传算法求解,最终求解出问题的近似最优解。
代码
/************************************************************************
* 遗传算法求解TSP问题
* 换位表达、启发式交叉、启发式变异、最优选择策略
* */
//#define GET_ALGORITHM_EXCUTE_TIME //是否获取算法执行时间,不需要获取算法执行时间则每次迭代会打印迭代结果
//头文件
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
//宏定义
#define CITY_COUNTS 100 //基因个数
#define CHORO_COUNTS 50 //种群大小
#define ITERA_COUNTS 20000 //迭代次数
#define CROSS_RATE 1.0 //交叉概率
#define MUTA_RATE 0.05 //变异概率
#define CROSS_NUM (int)(CHORO_COUNTS*CROSS_RATE/2) //交叉种群大小
#define MUTA_NUM (int)(CHORO_COUNTS*MUTA_RATE) //变异种群大小
#define LAMDA (int)(CITY_COUNTS * 0.05) //启发式变异基因个数
#define BETA 100 //启发式变异随机生成BETA条染色体选其中最优解
/**
* @brief: 数组复制
* @param: src 原数组
* @param: dst 目标数组
* @param: n 数组元素个数
* @return: none
* @author:
* @date: 2018-12-10
* */
void ArrayCopy(int *src, int *dst, int n)
{
for(int i = 0; i < n; i++){
dst[i] = src[i];
}
}
/**
* @brief: 生成1到n随机排列的数组,用于生成初始染色体
* @param: arr 随机排列保存到该数组中
* @param: n 1到n的排列组合
* @return: none
* @author:
* @date: 2018-12-10
* */
void RandomArray1ToN(int *arr, int n)
{
//产生1-n的顺序排列的数组
for(int i = 0; i < n; i++)
{
arr[i] = i+1;
}
//随机打乱顺序
for(int i = 0; i < n/2; i++)
{
int p= 0, q = 0;
do{
p = rand()%n;
q = rand()%n;
}while(p == q);
int temp = arr[p];
arr[p] = arr[q];
arr[q] = temp;
}
}
/**
* @brief: 判断数字是否在一个数组之中
* @param: num 要判断的数字
* @param: arr 参与判断的数组
* @param: n 数组大小
* @return: 在数组中返回1,不在数组中返回0
* @author:
* @date: 2018-12-10
* */
int IsNumInArray(int num, const int *arr, int n)
{
for(int i = 0; i < n; i++)
{
if(num == arr[i])
{
return 1;
}
}
return 0;
}
/**
* @brief: 返回数字在数组中的索引
* @param: num 要检索的数字
* @param: arr 参与检索的数组
* @param: n 数组大小
* @return: 在数组中返回索引标号,不在数组中返回-1
* @author:
* @date: 2018-12-10
* */
int PosNumInArray(int num, const int *arr, int n)
{
for(int i = 0; i < n; i++)
{
if(num == arr[i])
{
return i;
}
}
return -1;
}
/**
* @brief: 计算按染色体表达的城市顺序的距离
* @param: c 染色体
* @param: dis 城市间距离矩阵
* @param: n 城市个数
* @return: 返回距离
* @author:
* @da