蚁群算法解决TSP问题(c++)

什么是TSP问题?            

        旅行商问题,即TSP问题(Traveling Salesman Problem)又译为旅行推销员问题、货郎担问题,是数学领域中著名问题之一。假设有一个旅行商人要拜访n个城市,他必须选择所要走的路径,路径的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。路径的选择目标是要求得的路径路程为所有路径之中的最小值。

蚁群算法的讲解

       这个博客讲的不错 点击链接

代码实现

       代码参考博客 点击链接

  

#include<iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<cmath>
#include<ctime>
#include<stdlib.h>
using namespace std;
int seed=(int)time(0);//产生随机种子
int CityPos[30][2]= {{87,7},{91,38},{83,46},{71,44},{64,60},{68,58},{83,69},{87,76},{74,78},{71,71},{58,69},{54,62},{51,67},{37,84},{41,94},{2,99},{7,64},{22,60},{25,62},{18,54},{4,50},{13,40},{18,40},{24,42},{25,38},{41,26},{45,21},{44,35},{58,35},{62,32}};
#define CITY_NUM 30//城市数量
#define ANT_NUM 30//蚁群数量
#define TMAC 10000//迭代最大次数
#define ROU 0.5//误差大小
#define ALPHA 1//信息素重要程度的参数
#define BETA 4//启发式因子重要程度的参数
#define Q 100//信息素残留参数
#define maxn 100
#define inf 0x3f3f3f3f
double dis[maxn][maxn];//距离矩阵
double info[maxn][maxn];//信息素矩阵
bool vis[CITY_NUM][CITY_NUM];//标记矩阵

//返回指定范围内的随机整数
int rnd(int low,int upper)
{
    return low+(upper-low)*rand()/(RAND_MAX+1);
}

//返回指定范围内的随机浮点数
double rnd(double low,double upper)
{
    double temp=rand()/((double)RAND_MAX+1.0);
    return low+temp*(upper-low);
}

struct Ant
{
    int path[CITY_NUM];//保存蚂蚁走的路径
    double length;//路径总长度
    bool vis[CITY_NUM];//标记走过的城市
    int cur_cityno;//当前城市
    int moved_cnt;//已走城市数量

    //初始化
    void Init()
    {
        memset(vis,false,sizeof(vis));
        length=0;
        cur_cityno=rnd(0,CITY_NUM);
        path[0]=cur_cityno;
        vis[cur_cityno]=true;
        moved_cnt=1;
    }

    //选择下一个城市
    int Choose()
    {
        int select_city=-1;//所选城市编号
        double sum=0;
        double prob[CITY_NUM];//保存每个城市被选中的概率
        for(int i=0; i<CITY_NUM; i++)
        {
            if(!vis[i])
            {
                prob[i]=pow(info[cur_cityno][i],ALPHA)*pow(1.0/dis[cur_cityno][i], BETA);
                sum=sum+prob[i];
            }
            else
            {
                prob[i]=0;
            }
        }
        //进行轮盘选择
        double temp=0;
        if(sum>0)//总的信息素大于0
        {
            temp=rnd(0.0,sum);
            for(int i=0; i<CITY_NUM; i++)
            {
                if(!vis[i])
                {
                    temp=temp-prob[i];
                    if(temp<0.0)
                    {
                        select_city=i;
                        break;
                    }
                }
            }
        }
        else //信息素太少就随便找个没走过的城市
        {
            for(int i=0; i<CITY_NUM; i++)
            {
                if(!vis[i])
                {
                    select_city=i;
                    break;
                }
            }
        }
        return select_city;
    }

    //蚂蚁的移动
    void Move()
    {
        int nex_cityno=Choose();
        path[moved_cnt]=nex_cityno;
        vis[nex_cityno]=true;
        length=length+dis[cur_cityno][nex_cityno];
        cur_cityno=nex_cityno;
        moved_cnt++;
    }

    //蚂蚁进行一次迭代
    void Search()
    {
        Init();
        while(moved_cnt<CITY_NUM)
        {
            Move();
        }
        //回到原来的城市
        length=length+dis[path[CITY_NUM-1]][path[0]];
    }
};

struct TSP
{
    Ant ants[ANT_NUM];//定义蚁群
    Ant ant_best;//最优路径蚂蚁

    void Init()
    {
        //初始化为最大值
        ant_best.length = inf;
        //计算两两城市间距离
        for (int i = 0; i < CITY_NUM; i++)
        {
            for (int j = 0; j < CITY_NUM; j++)
            {
                info[i][j]=1.0;
                double temp1=CityPos[j][0]-CityPos[i][0];
                double temp2=CityPos[j][1]-CityPos[i][1];
                dis[i][j] = sqrt(temp1*temp1+temp2*temp2);
            }
        }
    }

    //更新信息素
    void UpdateInfo()
    {
        double temp_info[CITY_NUM][CITY_NUM];
        memset(temp_info,0,sizeof(temp_info));
        int u,v;
        for(int i=0; i<ANT_NUM; i++) //遍历每一只蚂蚁
        {
            for(int j=1; j<CITY_NUM; j++)
            {
                u=ants[i].path[j-1];
                v=ants[i].path[j];
                temp_info[u][v]=temp_info[u][v]+Q/ants[i].length;
                temp_info[v][u]=temp_info[u][v];
            }
            //最后城市和开始城市之间的信息素
            u=ants[i].path[0];
            temp_info[u][v]=temp_info[u][v]+Q/ants[i].length;
            temp_info[v][u]=temp_info[u][v];
        }
        for(int i=0; i<CITY_NUM; i++)
        {
            for(int j=0; j<CITY_NUM; j++)
            {
                info[i][j]=info[i][j]*ROU+temp_info[i][j];
            }
        }
    }
    void Search()
    {
        //迭代TMAC次
        for(int i=0; i<TMAC; i++)
        {
            //所有蚂蚁都进行一次遍历
            for(int j=0; j<ANT_NUM; j++)
            {
                ants[j].Search();
            }
            //保存所有蚂蚁遍历的最佳结果
            for(int j=0; j<ANT_NUM; j++)
            {
                if(ant_best.length>ants[j].length)
                {
                    ant_best=ants[j];
                }
            }
            UpdateInfo();
            printf("第%d次迭代最优路径长度是%lf\n", i,ant_best.length);
            printf("\n");
        }
    }
};
int main()
{
    srand(seed);
    TSP tsp;
    tsp.Init();
    tsp.Search();
    printf("最短路径如下\n");
    for(int i=0;i<CITY_NUM;i++)
    {
        printf("%d",tsp.ant_best.path[i]);
        if(i<CITY_NUM-1)
            printf("->");
        else
            printf("\n");
    }
    return 0;
}

 

  • 2
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
蚁群算法是一种模拟蚂蚁觅食行为的启发式算法,可以用于解决旅行商问题(TSP)。下面是一个用C++实现蚁群算法解决旅行商问题的示例代码: ```cpp #include <iostream> #include <vector> #include <cmath> #include <cstdlib> #include <ctime> using namespace std; const int MAX_CITIES = 10; // 城市数量 const int MAX_ANTS = 10; // 蚂蚁数量 const int MAX_ITERATIONS = 100; // 最大迭代次数 const double ALPHA = 1.0; // 信息素重要程度因子 const double BETA = 2.0; // 启发函数重要程度因子 const double RHO = 0.5; // 信息素蒸发系数 const double Q = 100.0; // 信息素增加强度系数 struct City { double x, y; }; double distance(const City& city1, const City& city2) { double dx = city1.x - city2.x; double dy = city1.y - city2.y; return sqrt(dx * dx + dy * dy); } class Ant { public: Ant() { tabu.resize(MAX_CITIES, false); path.resize(MAX_CITIES); } void clear() { for (int i = 0; i < MAX_CITIES; ++i) { tabu[i] = false; path[i] = 0; } } void visitCity(int city) { tabu[city] = true; path[currentCity] = city; currentCity = city; tourLength += distance(cities[path[currentCity]], cities[path[currentCity - 1]]); } int getCurrentCity() const { return currentCity; } double getTourLength() const { return tourLength; } void setCurrentCity(int city) { currentCity = city; } private: vector<bool> tabu; vector<int> path; int currentCity = 0; double tourLength = 0.0; }; class ACO { public: ACO() { cities.resize(MAX_CITIES); ants.resize(MAX_ANTS); pheromone.resize(MAX_CITIES, vector<double>(MAX_CITIES, 1.0)); // 初始化城市坐标 for (int i = 0; i < MAX_CITIES; ++i) { cities[i].x = rand() % 100; cities[i].y = rand() % 100; } // 初始化蚂蚁 for (int i = 0; i < MAX_ANTS; ++i) { ants[i].clear(); ants[i].setCurrentCity(rand() % MAX_CITIES); } } void updatePheromone() { for (int i = 0; i < MAX_CITIES; ++i) { for (int j = 0; j < MAX_CITIES; ++j) { pheromone[i][j] *= (1.0 - RHO); } } for (int i = 0; i < MAX_ANTS; ++i) { for (int j = 0; j < MAX_CITIES; ++j) { int city1 = ants[i].path[j]; int city2 = ants[i].path[(j + 1) % MAX_CITIES]; pheromone[city1][city2] += Q / ants[i].getTourLength(); pheromone[city2][city1] += Q / ants[i].getTourLength(); } } } void antColonyOptimization() { for (int iteration = 0; iteration < MAX_ITERATIONS; ++iteration) { for (int i = 0; i < MAX_ANTS; ++i) { while (ants[i].getCurrentCity() != -1) { int nextCity = selectNextCity(ants[i]); ants[i].visitCity(nextCity); } if (ants[i].getTourLength() < bestTourLength) { bestTourLength = ants[i].getTourLength(); bestTour = ants[i].path; } ants[i].clear(); ants[i].setCurrentCity(rand() % MAX_CITIES); } updatePheromone(); } } int selectNextCity(const Ant& ant) { int currentCity = ant.getCurrentCity(); double sum = 0.0; for (int i = 0; i < MAX_CITIES; ++i) { if (!ant.tabu[i]) { sum += pow(pheromone[currentCity][i], ALPHA) * pow(1.0 / distance(cities[currentCity], cities[i]), BETA); } } double r = (double)rand() / RAND_MAX; double probability = 0.0; for (int i = 0; i < MAX_CITIES; ++i) { if (!ant.tabu[i]) { probability += pow(pheromone[currentCity][i], ALPHA) * pow(1.0 / distance(cities[currentCity], cities[i]), BETA) / sum; if (r <= probability) { return i; } } } return -1; } void printBestTour() { cout << "Best tour: "; for (int i = 0; i < MAX_CITIES; ++i) { cout << bestTour[i] << " "; } cout << endl; cout << "Best tour length: " << bestTourLength << endl; } private: vector<City> cities; vector<Ant> ants; vector<vector<double>> pheromone; vector<int> bestTour; double bestTourLength = numeric_limits<double>::max(); }; int main() { srand(time(nullptr)); ACO aco; aco.antColonyOptimization(); aco.printBestTour(); return 0; } ``` 这段代码实现了蚁群算法解决旅行商问题。它使用了随机生成的城市坐标作为输入,通过迭代更新信息素矩阵和蚂蚁的路径来寻找最优的旅行路径。最终输出最优路径和路径长度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值