遗传算法的C语言设计

本文使用遗传算法求解100个城市点的旅行商问题,采用换位表达编码、启发式交叉和变异策略,以及最优选择策略。通过C语言实现,展示了遗传算法在解决NP难题上的应用,并探讨了编码方式、交叉变异算子选择、资源消耗及参数选择的重要性。
摘要由CSDN通过智能技术生成

遗传算法的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
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值