罗马尼亚度假问题 (可自选起始地与终点)c++实现(深度优先搜索,广度优先搜索,A*算法)

 d54ff104ff534324918d2fbbbd70545b.png

数据放在1.h文件,自己估计了一个二维坐标各个城市的坐标值用于启发式函数。

链接: https://pan.baidu.com/s/133PwUZplnTVdmPZBVIo5HQ?pwd=26wt

提取码: 26wt 

M.cpp文件

#include<iostream>
#include<queue>
#include<vector>
#include<stack>
#include<string>
#include<time.h>
#include<cmath>
#include<unordered_map>
#include"1.h"//存放数据

using namespace std;

struct City
{
string nym;               //城市名称
int val=0,gn=0,hn=0;     //val,gn,hn 分别对应A*算法公式  f(n)=g(n)+h(n)
int father=-1;
int x,y;                 //估计的二维坐标中坐标
};

class Graph
{
public:
    Graph();
    int graph[20][20];       //邻接矩阵
    City city[20];

};

Graph::Graph()                   //初始化表和城市节点
{
    for(int i=0;i<20;i++)
    {
        for(int j=0;j<20;j++)
        {
            graph[i][j]=g[i][j];
        }
        city[i].nym=name[i];
        city[i].x=h[i][0];
        city[i].y=h[i][1];
    }
}

-----------------------------深度优先搜索---------------------------------------------

void dfs(int start,int end)
{
    stack<int> openlist;                //open表
    Graph G;              
    long long int time1=clock();        //记录时间
    int x=start;
    bool seek[20]={false};              //记录访问的城市,默认false,访问后true
    openlist.push(x);                   //放入起始地,从起点开始遍历
    stack<string> road;
    while(!openlist.empty())
    {
        x=openlist.top();
        if(x==end)break;                //遍历到终点直接结束
        openlist.pop();
        for(int i=19;i>0;i--)
        {
            if(G.graph[x][i]>1&&G.graph[x][i]<1000&&!seek[i])
            {
                seek[i]=true;
                G.city[i].father=x;     //记录父节点便于后面输出
                openlist.push(i);       //将该城市序号放入open表
            }
        }        
    }
    while(1)                         //用栈整理出路径
    {        
        //cout<<" "<<G.city[x].nym;        //用于调试
        road.push(G.city[x].nym);
        x=G.city[x].father;
        if(x==start)
        {
            road.push(G.city[x].nym);
            break;
        }
    }
    cout<<"dfs搜索出路径为:"<<road.top();
    road.pop();
    while(!road.empty())
    {

        cout<<"->"<<road.top();
        road.pop();
    }
    long long int time2=clock();
    cout<<endl<<"耗时:"<<time2-time1<<"ms"<<endl;
}

------------------------------广度优先搜索-----------------------------------------

//类似于深度优先搜索,不过这里用的是队列,深度优先搜索用的是栈

void bfs(int start,int end)
{
    queue<int> openlist;
    Graph G;
    long long int time1=clock();
    int x=start;
    stack<string> road;
    bool seek[20]={false};        
    openlist.push(x);
    seek[x]=true;

    while(!openlist.empty())
    {
        x=openlist.front();
        if(x==end)break;
        for(int i=0;i<20;i++)
        {
            if(G.graph[x][i]>1&&G.graph[x][i]<1000&&!seek[i])
            {
                seek[i]=true;
                G.city[i].father=x;
                openlist.push(i);
            }
        }        
        openlist.pop();
    }
    while(1)
    {

        road.push(G.city[x].nym);
        x=G.city[x].father;
        if(x=start)
        {
            road.push(G.city[x].nym);
            break;
        }
    }
    cout<<"bfs搜索出路径为:"<<road.top();
    road.pop();
    while(!road.empty())
    {
        cout<<"->"<<road.top();
        road.pop();
    }
    long long int time2=clock();
    cout<<endl<<"耗时:"<<time2-time1<<"ms"<<endl;
}

----------------------------A*算法-------------------------------------------------------

//方便排序用了优先队列

void A_(int start,int end)
{
    Graph G;
    auto cmp=[&G](int a,int b)
    {
        return G.city[a].val<G.city[b].val;
    };
    priority_queue<int,vector<int>,decltype(cmp)> openlist(cmp); 
         //定义一个可以根据序号x的G.city[x].val值进行排序的open表
    long long int time1=clock();
    openlist.push(start);
    int x;
    G.city[start].gn=0;
    bool seek[20]={false};
    stack<string> road;
    while(!openlist.empty())
    {
        x=openlist.top();
        if(x==end)break;
        for(int i=0;i<20;i++)
        {
            if(G.graph[x][i]>0 && G.graph[x][i]<1000 && !seek[i])
            {
                G.city[i].gn=G.graph[x][i]+G.city[x].gn;
                G.city[i].hn=sqrt(pow((G.city[end].x-G.city[i].x),2)+pow((G.city[end].y-G.city[i].y),2));
                G.city[i].val=G.city[i].gn+G.city[i].hn;
                                                       //计算节点的f(n)
                openlist.push(i);
                seek[i]=true;
                G.city[i].father=x;
            }
        }
        openlist.pop();
    }
    while(1)
    {
        road.push(G.city[x].nym);
        x=G.city[x].father;
        if(x==start)
        {
            road.push(G.city[x].nym);
            break;
        }
    }
    cout<<"A*搜索出路径为:"<<road.top();
    road.pop();
    while(!road.empty())
    {
        cout<<"->"<<road.top();
        road.pop();
    }
    long long int time2=clock();
    cout<<endl<<"耗时:"<<time2-time1<<"ms"<<endl;

}

unordered_map<string,int> citylist={{"Arad",0},{"Mehadia",1},{"Bucharest",2},{"Neamt",3},{"Craiova",4},{"Oradea",5},{"Doberta",6},
{"Pitesti",7},{"Eforie",8},{"Rimmicu_Vikea",9},{"Fagaras",10},{"Sibiu",11},{"Giurgiu",12},{"Timisoara",13},
{"Hirsova",14},{"Urziceni",15},{"Iasi",16},{"Vaslui",17},{"Lugoj",18},{"Zerind",19}};
//使用哈希表解决输入城市名字转化为序号的问题

int main()
{
    string start,end;
    int mode;
    cout<<"输入起点城市的名字:"<<endl;
    cin>>start;
    cout<<"输入终点城市的名字:"<<endl;
    cin>>end;
    cout<<"1.深度优先搜索"<<endl<<"2.广度优先搜索"<<endl<<"3.A*算法搜索"<<endl<<"选择算法(序号):";
    cin>>mode;
    switch (mode)
    {
    case 1:    
        dfs(citylist[start],citylist[end]);
        break;
    case 2:
        bfs(citylist[start],citylist[end]);
        break;
    case 3:
        A_(citylist[start],citylist[end]);
        break;
    default:
        break;
    }

}

 

 

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值