遗传算法解决旅行商问题

本文介绍了使用遗传算法(GA)解决旅行商问题的方法。通过随机生成城市距离矩阵,以城市顺序作为基因序列编码,并依据适应度(与总距离成反比)进行种群选择、杂交和变异操作。作者展示了线性函数如何确定杂交可能性,并给出了杂交过程中基因序列的敲除和插入过程的代码实现。经过约一万代,该算法在处理50个城市的例子中得到了较好的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

遗传算法(GA)解决旅行商问题–C

思路

给出常数:城市数量、变异概率、种群数、子群数,父代传递比例
随机生成城市距离矩阵,将经过城市的顺序作为基因序列进行编码,适应度和走过n个城市的总距离成反比。
先随机构建出第一批种群的个体,按照父代传递比例按适应度从高到底选出个体复制进子群(我选的是0.2),之后子群其他个体通过父代种群进行杂交和变异生成,杂交的可能性和适应度呈正比,我使用了一个线性函数计算可能性,函数代码如下

double SelectFunction(Cell c)
{
   
   
    //基因更优秀的更容易被选中
    double longth=c.longth;
    double k=(double)1/(Group[GROUP_NUM-1].longth-Group[0].longth);
    return 1-(k*(longth-Group[0].longth));
}

就是一个x从种群最短路径到最长路径,y从1到0的一次函数
按上面的函数选出父母之后进行杂交,父亲的基因随机插入到母亲的基因序列中,插入的过程分为两个部分,先敲除,再插入。其实就是数组的插入删除数据。代码如下:

int GeneSearch(Cell c,int x)
{
   
   
    if (x<0||x>=CITY_NUM)
    {
   
   
        printf("Error");
        return -1;
    }

    for(int i=0; i<CITY_NUM; i++)
    {
   
   
        if(c.mypath[i]==x)
            return i;
    }
}
void GeneKnockout(Cell &c,int x)
{
   
   
    int loc=GeneSearch(c,x);
    if(loc!=-1)
    {
   
   
        for(int i=loc; i<(c.pathlong-1); i++)
        {
   
   
            c.mypath[i]=c.mypath[i+1];
        }
        c.pathlong--;
    }
}
void GeneInsert(Cell &c,int x,int loc)
{
   
   
    if(x>CITY_NUM||loc>CITY_NUM||x<0||loc<0)
    {
   
   
        printf("Loc or x Error\n");
        return;
    }
    for(int i=c.pathlong-1; i>=loc; i--)
    {
   
   
        c.mypath[i+1]=c.mypath[i];
    }
    c.mypath[loc]=x;
    c.pathlong++;
}

我使用了50个城市的距离矩阵,大概一万代左右就得到比较好的结果了,总代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<algorithm>
using namespace std;

const int CITY_NUM=50;          //城市数
const int GROUP_NUM=100;         //种群数
const int SON_NUM=150;           //子群数
const double P_HYBRID=0.8;      //子群中新生儿比例
const double P_MUTATION=0.07;   //变异概率
const int CYC_NUM=10000;         //循环次数

int CITY_MATRIX[CITY_NUM][CITY_NUM];//城市距离矩阵

typedef struct
{
   
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值