admin 发表于 2024-7-16 23:18:17

ACO蚁群优化算法求解TSP旅行商问题C++(2020.10.13)



const int CityCount = 29, AntCount = 29;//城市数量和蚂蚁数量
int besttour;//最佳路线
const double α = 1, β = 5,ρ = 0.5, Q = 1;
Graph Map_City;//城市地图,存储城市信息、信息素等
Ant ant//蚁群




const int CityCount = 29, AntCount = 29;//城市数量和蚂蚁数量
int besttour;//最佳路线
const double α = 1, β = 5,ρ = 0.5, Q = 1;
Graph Map_City;//城市地图,存储城市信息、信息素等
Ant ant//蚁群



void Ant::Next_City()
{
        int currentcity = tour;//计算下一步先找到上一步所到的城市
        double temp = 0, sum_probability = 0;
        for (int i = 0; i < CityCount; i++)
        {
                if (can_visit == true)
                        temp += pow((Map_City.τ), α)*pow(1.0 / Map_City.Distance, β);
        }
        for (int i = 0; i < CityCount; i++)
        {
                if (can_visit == false)
                        select_probability = 0;//已经到过的城市选择概率为0
                else
                {
                        select_probability = pow((Map_City.τ), α)*pow(1.0 / Map_City.Distance, β) / temp;//对于未到过的城市,则计算选择概率
                        sum_probability += select_probability;
                }
        }
        double r = random(0, sum_probability);//取概率区间的随机浮点数
        double p = 0;
        int nextcity = -1;
        for (int j = 0; j < CityCount; j++)
        {
                if (can_visit == true) p += select_probability;
                if (p >= r)
                {
                        nextcity = j; break;
                }
        }
        /*if (nextcity == -1)
        {
                temp = -1;
                for (int i = 0; i<CityCount; i++)
                {
                        if (can_visit == true)
                                if (temp<pow((Map_City.τ), α)*pow(1.0 / Map_City.Distance, β))
                                {
                                        temp = pow((Map_City.τ), α)*pow(1.0 / Map_City.Distance, β);
                                        nextcity = i;
                                }
                }
        }*/
        Addcity(nextcity);
}



void UpdatePheromones(Graph Map_City,Ant ant)//更新信息素的函数
{
        for (int i = 0; i<AntCount; i++)
        {
                for (int j = 0; j<CityCount - 1; j++)
                {
                        Map_City.Deltτ.tour].tour] += Q / ant.tour_length;
                        Map_City.Deltτ.tour].tour] += Q / ant.tour_length;
                }
                Map_City.Deltτ.tour].tour] += Q / ant.tour_length;
                Map_City.Deltτ.tour].tour] += Q / ant.tour_length;
        }
        for (int i = 0; i<CityCount; i++)
        {
                for (int j = 0; j<CityCount; j++)
                {
                        Map_City.τ = (1 - ρ)*Map_City.τ + Map_City.Deltτ;
                        Map_City.Deltτ = 0;
                }
        }
}





// main.cpp
#include <iostream>
#include <fstream>
#include <string>
#include <math.h>
#include <ctime>
using namespace std;
const int CityCount = 29, AntCount = 29;//城市数量和蚂蚁数量
int besttour;//最佳路线
const double α = 1, β = 5,ρ = 0.5, Q = 1;
doublerandom(int low, double uper)//生成某个区间内随机数的函数
{
        return (rand() / (double)RAND_MAX)*(uper - low) + low;
};
int random(int uper)//返回一个从0到最大随机数的任意整数
{
        return (rand() % uper);
};
class City
{
public:
        string name;
        double x, y;//城市的x、y坐标
        void shuchu()
        {
                std::cout << name << " " << x << " " << y << endl;
        }
};
class Graph//图信息
{
public:
        City city;
        double Distance;//城市间的距离矩阵
        double τ;//信息素矩阵
        double Deltτ;//信息素变化量矩阵
        void shuchu()
        {
                cout << "城市名称 " << "坐标x" << " " << "坐标y" << endl;
                for (int i = 0; i < CityCount; i++)
                        city.shuchu();
                cout << "距离矩阵: "<< endl;
                for (int i = 0; i < CityCount; i++)
                {
                        for (int j = 0; j < CityCount; j++)
                        {
                                if (j == CityCount - 1)
                                        std::cout << Distance << endl;
                                else
                                        std::cout << Distance << "";
                        }
                }
                cout << "信息素矩阵: " << endl;
                for (int i = 0; i < CityCount; i++)
                {
                        for (int j = 0; j < CityCount; j++)
                        {
                                if (j == CityCount - 1)
                                        std::cout << τ << endl;
                                else
                                        std::cout << τ << "";
                        }
                }
                cout << "信息素增量矩阵: " << endl;
                for (int i = 0; i < CityCount; i++)
                {
                        for (int j = 0; j < CityCount; j++)
                        {
                                if (j == CityCount - 1)
                                        std::cout << Deltτ << endl;
                                else
                                        std::cout << Deltτ << "";
                        }
                }
        }
        void Readcoordinatetxt(string txtfilename);//读取城市坐标文件的函数
};
Graph Map_City;//定义全局对象图
void Graph::Readcoordinatetxt(string txtfilename)
{
        ifstream myfile(txtfilename, ios::in);
        double x = 0, y = 0;
        int z = 0;
        if (!myfile.fail())
        {
                int i = 0;
                while (!myfile.eof() && (myfile >> z >> x >> y))
                {
                        city.name = to_string(long double(z));//城市名称转化为字符串
                        city.x = x; city.y = y;
                        i++;
                }
        }
        else
                cout << "文件不存在";
        myfile.close();//计算城市距离矩阵
        for (int i = 0; i < CityCount; i++)
                for (int j = 0; j < CityCount; j++)
                {
                        Distance = sqrt(pow((city.x - city.x), 2) + pow((city.y - city.y), 2));//计算城市ij之间的距离
                        τ = 1;
                        Deltτ = 0;
                }
}
class Ant
{
public:
        int tour;//蚂蚁所构建路径的CityCount+1元数组
        bool can_visit;//蚂蚁是否能够访问城市的n元布尔数组
        int tour_citycount;//蚂蚁当前走过城市的数量
        double tour_length, tour_length_shortest;//蚂蚁所走的路径长度tour_length
        double select_probability;//蚂蚁对各城市的选择概率数组
        Ant();//蚂蚁的初始化函数
        void Build_Trip();//蚂蚁构造旅行路径的函数
        void Next_City();//蚂蚁选择下一个城市的函数
        void GetFirstCity();//蚂蚁随机到访第一个城市的函数
        void Addcity(int city);//蚂蚁路径上添加城市的函数
        void UpdateTourLength();//更新旅行路径长度的函数
        void Clear();//清空函数
};
Ant ant;//蚁群用m元数组ant来表示
Ant::Ant()//蚂蚁的构造函数
{
        tour_length = tour_length_shortest = 0;
        tour_citycount = 0;//起初所旅行过的城市数量为0
        for (int i = 0; i<CityCount; i++)
        {
                can_visit = true;//每个城市都可以访问
                select_probability = 0;//选择各个城市的概率为0
        }
}
void Ant::Clear()
{
        tour_length = 0;
        for (int i = 0; i<CityCount; i++)
        {
                select_probability = 0;
                can_visit = true;
        }
        tour_citycount = 0;
}
void Ant::Addcity(int city)
{
        //add city to tabu;
        tour = city;
        tour_citycount++;
        can_visit = false;
}
void Ant::GetFirstCity()
{
        srand((unsigned)time(NULL) + rand());
        Addcity(random(CityCount));
}
void Ant::Next_City()
{
        int currentcity = tour;//计算下一步先找到上一步所到的城市
        double temp = 0, sum_probability = 0;
        for (int i = 0; i < CityCount; i++)
        {
                if (can_visit == true)
                        temp += pow((Map_City.τ), α)*pow(1.0 / Map_City.Distance, β);
        }
        for (int i = 0; i < CityCount; i++)
        {
                if (can_visit == false)
                        select_probability = 0;//已经到过的城市选择概率为0
                else
                {
                        select_probability = pow((Map_City.τ), α)*pow(1.0 / Map_City.Distance, β) / temp;//对于未到过的城市,则计算选择概率
                        sum_probability += select_probability;
                }
        }
        double r = random(0, sum_probability);//取概率区间的随机浮点数
        double p = 0;
        int nextcity = -1;
        for (int j = 0; j < CityCount; j++)
        {
                if (can_visit == true) p += select_probability;
                if (p >= r)
                {
                        nextcity = j; break;
                }
        }
        /*if (nextcity == -1)
        {
                temp = -1;
                for (int i = 0; i<CityCount; i++)
                {
                        if (can_visit == true)
                                if (temp<pow((Map_City.τ), α)*pow(1.0 / Map_City.Distance, β))
                                {
                                        temp = pow((Map_City.τ), α)*pow(1.0 / Map_City.Distance, β);
                                        nextcity = i;
                                }
                }
        }*/
        Addcity(nextcity);
}
void Ant::Build_Trip()
{
        for (int i = 0; i < CityCount; i++)
        {
                can_visit = true;
        }
        GetFirstCity();
        while (tour_citycount < CityCount)
        {
                if(tour_citycount <CityCount) Next_City();//轮盘赌法选择下一个城市
                else if (tour_citycount == CityCount - 1)
                {
                        for (int i = 0; i<CityCount; i++)
                                if (can_visit == true)
                                {
                                        Addcity(i);
                                        break;
                                }//如果还剩下一个城市可以访问,那么这个城市就是最后一个城市,添加到蚂蚁旅行的城市上
                }
        }
        tour = tour;//蚂蚁旅行的最后一个城市
}
void Ant::UpdateTourLength()//更新旅行路径长度的函数
{
        for (int i = 0; i<CityCount - 1; i++)
                tour_length += Map_City.Distance]];
        tour_length += Map_City.Distance]];
}
void UpdatePheromones(Graph Map_City,Ant ant)//更新信息素的函数
{
        for (int i = 0; i<AntCount; i++)
        {
                for (int j = 0; j<CityCount - 1; j++)
                {
                        Map_City.Deltτ.tour].tour] += Q / ant.tour_length;
                        Map_City.Deltτ.tour].tour] += Q / ant.tour_length;
                }
                Map_City.Deltτ.tour].tour] += Q / ant.tour_length;
                Map_City.Deltτ.tour].tour] += Q / ant.tour_length;
        }
        for (int i = 0; i<CityCount; i++)
        {
                for (int j = 0; j<CityCount; j++)
                {
                        Map_City.τ = (1 - ρ)*Map_City.τ + Map_City.Deltτ;
                        Map_City.Deltτ = 0;
                }
        }
}
int main()
{
        int MAX_GEN = 1000;
        double global_tourlength = 10e9,Ljia = DBL_MAX;
        int Tjia;//表示蚁群优化算法最终发现的最短路径
        //首先对城市地图进行初始化
        Map_City.Readcoordinatetxt("E:\\下学期课程\\Matlab智能计算\\ACO\\ACO\\bayg29.tsp");
        Map_City.shuchu();
        int temptour;
        for (int iteratorcishu = 0; iteratorcishu < MAX_GEN; iteratorcishu++)
        {
                for (int k = 0; k < AntCount; k++)
                {
                        ant.Build_Trip();
                        ant.UpdateTourLength();//计算蚂蚁k所发现路径Tk的长度Lk
                        if (ant.tour_length < Ljia)
                        {
                                for (int h = 0; h < CityCount; h++)
                                        Tjia = ant.tour;
                                Ljia = ant.tour_length;
                        }
                }
                //找到最短的路径长度,放到temp里
                double temp = ant.tour_length;
                for (int i = 0; i<CityCount; i++) temptour = ant.tour;
                for (int i = 0; i<AntCount; i++)
                {
                        if (temp>ant.tour_length)
                        {
                                temp = ant.tour_length;
                                for (int j = 0; j< CityCount; j++)
                                        temptour = ant.tour;
                        }
                }
                if (temp<global_tourlength)
                {
                        global_tourlength = temp;
                        for (int j = 0; j< CityCount; j++)
                                besttour = temptour;
                }
                std::cout << "第" << iteratorcishu << "次迭代的最短距离:" << global_tourlength << endl;
                UpdatePheromones(Map_City,ant);
                for (int i = 0; i < AntCount; i++) ant.Clear();
        }
        std::cout << "最短路径为:" << endl;
        for (int i = 0; i < CityCount; i++)
        {
                if (i == CityCount - 1)std::cout << Map_City.city].name << endl;
                else std::cout << Map_City.city].name << "->";
        }
        std::cout << "最短路径长度为:" << global_tourlength << endl;
        system("Pause");
        return 0;
}
页: [1]
查看完整版本: ACO蚁群优化算法求解TSP旅行商问题C++(2020.10.13)