【c++】使用遗传算法求解旅行商问题(TSP)

数据来源:TSP数据
找到Symmetric traveling salesman problem (TSP),下载相关数据。
本文选取了att48数据集。

遗传算法

遗传算法的基本运算过程如下:

  1. 初始化:设置进化代数计数器t=0、设置最大进化代数T、交叉概率、变异概率、随机生成M个个体作为初始种群P
  2. 个体评价:计算种群P中各个个体的适应度
  3. 选择运算:将选择算子作用于群体。以个体适应度为基础,选择最优个体直接遗传到下一代或通过配对交叉产生新的个体再遗传到下一代
  4. 交叉运算:在交叉概率的控制下,对群体中的个体两两进行交叉
  5. 变异运算:在变异概率的控制下,对群体中的个体两两进行变异,即对某一个体的基因进行随机调整
  6. 经过选择、交叉、变异运算之后得到下一代群体P1。
    重复以上1-6,直到遗传代数为T,以进化过程中所得到的具有最大适应度个体作为最优解输出,终止计算。

选择运算:轮盘赌法

选择算子采用轮盘赌选择,以每个个体的适应度为基础,为每个个体计算累积概率。
在这里插入图片描述
在这里插入图片描述
qa 表示个体a的累积概率,如上图所示个体1、2、3、4的累积概率分别为0.14、0.53、0.69、1。
随机生成一个0到1的浮点数f,若 qa < f <= qb,则个体b被选中。

交叉运算

①部分映射交叉
在这里插入图片描述
②顺序交叉
在这里插入图片描述
③基于位置的交叉
在这里插入图片描述

变异运算

变异算子随机进行多次,每次在个体基因序列中选择两个位置的基因进行交换。

完整代码如下:

#include <iostream>
#include <fstream>
#include <cmath>
#include <string>
#include <stdlib.h>
#include "time.h"     //程序运行时间 
#include <unistd.h>    //哈希函数 
#define CITY_NUM 48   //城市个数
#define POPSIZE 300    //种群个体数 
#define MAXVALUE 0x7ffffffff   //路径最大值上限
#define N 100000       //需要根据实际求得的路径值修正
#define MAX_GEN 50000   //最大进化代数 
#define CROSS 0.5     //交叉算子
#define MUT 0.05      //变异算子
using namespace std;

unsigned seed=(unsigned)time(0);    //每次产生不同的随机序列 
double Hash[CITY_NUM+1];

typedef struct CityPosition{
   
    double x;
    double y;
}CityPosition;                         //城市位置 

CityPosition CityPos[38]={
   };

double CityDistance[CITY_NUM][CITY_NUM];   //城市距离

typedef struct{
   
    int colony[POPSIZE][CITY_NUM+1];   //城市种群,默认出发城市编号为0,则城市编号的最后一个城市还应该为0
    double fitness[POPSIZE];           // 每个个体的适应度,即1/Distance[POPSIZE]
    double Distance[POPSIZE];          //每个个体的总路径
    int BestRooting[CITY_NUM+1];       //最优城市路径序列
    double BestFitness;                //最优路径适应值
    double BestValue;                  //最优路径长度
    int BestNum;                       //最优路径城市数目 
}TSP,*PTSP;

//计算城市距离CityDistance[i][j]
double CalculatDist(CityPosition CityPos[]){
   
    for(int i=0;i<CITY_NUM;i++){
   
        for(int j=0;j<CITY_NUM;j++){
          //最后一个城市还应该返回到出发节点
            if(i!=j) CityDistance[i][j]=sqrt(pow(CityPos[j].x-CityPos[i].x,2)+pow(CityPos[j].y-CityPos[i].y,2));
            else CityDistance[i][i]=0;
        }
    }
}

//数组复制
void copy(int a[],int b[]){
   
    for(int i=0;i<CITY_NUM+1;i++)
    {
   
        a[i]=b[i];
    }
}


//用来检查新生成的节点是否在当前群体中,0号节点是默认出发节点和终止节点
bool check(TSP &city,int pop,int num,int k){
   
    for(int i=0;i<=num;i++){
   
        if(k==city.colony[pop][i])
            return true;    //新生成节点存在于已经生成的路径中
    }
    
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值