Qt实训:SubwayTransferSystem(三)

内  容

完成“所需时间最少”换乘路线查询

主要知识点

数据结构图的最短路径算法

任务:

1.查询出从起点站到终点站用时最少的乘车路线。

2.提供地铁换乘查询,可通过视图方便的查看乘坐路线和换乘路线

3.提供最小出行时间的换乘策略指南

4.提供最小换乘次数的换乘策略指南


一、路径搜索方式

       根据地铁线路较为稀疏的特性,暂时仅采用了广度优先搜索(bfs)的方式进行寻路。中途不考虑换乘与时间消耗的情况,仅对经过的点进行存储,在打印时再对所选乘线路进行判断。

1.1广度优先算法理论

        广度优先搜索算法(Breadth First Search),又称为"宽度优先搜索"或"横向优先搜索",简称BFS。

       它的思想是:从图中某顶点v出发,在访问了v之后依次访问v的各个未曾访问过的邻接点,然后分别从这些邻接点出发依次访问它们的邻接点,并使得“先被访问的顶点的邻接点先于后被访问的顶点的邻接点被访问,直至图中所有已被访问的顶点的邻接点都被访问到。如果此时图中尚有顶点未被访问,则需要另选一个未曾被访问过的顶点作为新的起始点,重复上述过程,直至图中所有顶点都被访问到为止。

        换句话说,广度优先搜索遍历图的过程是以v为起点,由近至远,依次访问和v有路径相通且路径长度为1,2...的顶点。下面以"无向图"为例,来对广度优先搜索进行演示。还是以上面的图G1为例进行说明。

DFS:使用栈保存未被检测的结点,结点按照深度优先的次序被访问并依次被压入栈中,并以相反的次序出栈进行新的检测。——类似于树的先根遍历

BFS:使用队列保存未被检测的结点。结点按照宽度优先的次序被访问和进出队列。
——类似于树的按层次遍历的过程

BFS用来搜索最短路径的解法是比较合适的。
比如求最少步数的解,最少交换次数的解,最快走出迷宫等等,因为bfs搜索过程中遇到的第一个解一定是离最初位置最近的,所以遇到第一个解,一定就是最优解,此时搜索算法可以终止。
而如果用dfs,会搜一些其他的位置,需要花相对比较多的时间,需要搜很多次,然后如果找到还不一定是最优解,还要记录这次找的位置,与之后找到的答案进行比较,看看谁才是最优解,这样就比较麻烦。

BFS是浪费空间节省时间,DFS是浪费时间节省空间。

二、代码解析

 初始化经过站点队列和站点边队列

stationsList.clear();  
edgesList.clear();

 首先判断起始站点与终点站不是同一站点

if(s1==s2)
    {
        stationsList.push_back(s2);
        stationsList.push_back(s1);
        return true;
    }
stationsList为双向队列

    std::vector<int> path(stations.size(), -1);
    std::vector<double> dist(stations.size(), INF);
    dist[s1]=0;
    std::priority_queue<Node, std::vector<Node>, std::greater<Node>> priQ;
    priQ.push(Node(s1, 0));
    while(!priQ.empty())
    {
        Node top=priQ.top();
        priQ.pop();
        if(top.stationID==s2)
        {
            break ;
        }

        for (int i=0; i<graph[top.stationID].size(); ++i)
        {
            Node &adjNode=graph[top.stationID][i];
            if(top.distance+adjNode.distance<dist[adjNode.stationID])
            {
                path[adjNode.stationID]=top.stationID;
                dist[adjNode.stationID]=top.distance+adjNode.distance;
                priQ.push(Node(adjNode.stationID, dist[adjNode.stationID]));
            }
        }
    }

    if(path[s2]==-1)
    {
        return false;
    }
    int p=s2;
    while(path[p]!=-1)
    {
        stationsList.push_front(p);
        edgesList.push_front(Edge(path[p],p));
        p=path[p];
    }
    stationsList.push_front(s1);

dijkstra算法的核心思想流程

1)dist[]存储第i个节点到家的距离,visited[i]=true 代表第i个点是否已经遍历过。
2)遍历所有visited[i] == false的点,找出dist[i]最小的点 k。
3)遍历与k相连的点j,用 min(dist[j], dist[k] + edge[k][j])来更新 dist[j]。
4)将visited[k] = true;
5)  如果还存在点,返回2)

三、完成调试,在界面中显示“换乘时间最少”路径 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JonathanQian-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值