首页 > 其他分享 >12.2迪杰斯特拉方法实现最短路径

12.2迪杰斯特拉方法实现最短路径

时间:2023-12-10 13:55:20浏览次数:32  
标签:int 路径 迪杰 邻接矩阵 12.2 MVNum 斯特拉 顶点

掌握迪杰斯特拉方法

设计文档

 代码

#include<iostream>
using namespace std;
//迪杰特斯拉:邻接矩阵:一维数组+二维数组+点边数
typedef int VexType;
#define MVNum 100
#define MaxInt 32767
int S[MVNum],Path[MVNum],D[MVNum];//迪杰特斯拉的三个数组
typedef struct{
    VexType vexs[MVNum];
    int arcs[MVNum][MVNum];
    int vexnum,arcnum;
}AMGraph;
int LocateVex(AMGraph G,VexType v)
{
    for(int i=0;i<G.vexnum;++i)
        if(G.vexs[i]==v)return i;
    return -1;
}
void CreatAMGraph(AMGraph &G,int &err)
{
    cin>>G.vexnum>>G.arcnum;//输入点数边数
    for(int i=0;i<G.vexnum;++i)cin>>G.vexs[i];
    for(int i=0;i<G.vexnum;++i)
        for(int j=0;j<G.vexnum;++j)
            G.arcs[i][j]=MaxInt;     //初始化二维数组
    for(int k=0;k<G.arcnum;++k)
    {
        VexType v1,v2;
        int w;
        cin>>v1>>v2>>w;
        int i=LocateVex(G,v1),j=LocateVex(G,v2);
        if(i==-1||j==-1)    err=1;
        else    G.arcs[i][j]=w;//有向网,只用一次
    }
}
void ShortestPath_DIJ(AMGraph G,int vo)
{
    for(int v=0;v<G.vexnum;++v)//这里出的问题
    {
        S[v]=0;
        D[v]=G.arcs[vo][v];
        if(D[v]<MaxInt)Path[v]=vo;
        else Path[v]=-1;
    }
    S[vo]=1;D[vo]=0;
//     for(int i=0;i<G.vexnum;++i){
//         if(G.arcs[vo][i]!=MaxInt)//说明i与vo有边的关系
//         {
//             D[i]=G.arcs[vo][i];
//             Path[i]=vo;
//         }
//     }
    for(int k=0;k<G.vexnum-1;++k)//对剩下的n-1个顶点进行计算
    {
        int wmin=MaxInt,vmin;//找权值最小和其下标
        for(int w=0;w<G.vexnum;++w){//找权值最小的,纳入S中
            if(!S[w]&&D[w]<wmin){
                vmin=w;wmin=D[w];
            }
        }
        S[vmin]=1;
        for(int i=0;i<G.vexnum;++i){
            if(!S[i]&&(D[vmin]+G.arcs[vmin][i]<D[i]))
            {
                D[i]=D[vmin]+G.arcs[vmin][i];
                Path[i]=vmin;
            }
        }
    }
}
int main()
{
    AMGraph G;
    int err=0;
    VexType vo,ve;
    CreatAMGraph(G,err);//err的值为1的时候说明在创建邻接矩阵的时候出现了错误
    cin>>vo>>ve;
    int i=LocateVex(G,vo),j=LocateVex(G,ve);
    if(i!=-1&&j!=-1){
        ShortestPath_DIJ(G,i);
        int adj[MVNum],k=1;
        adj[0]=j;
        while(Path[j]!=i)
        {
            adj[k]=Path[j];
            j=Path[j];
            ++k;
        }
        adj[k]=i;
        for(int n=k;n>=0;--n){
            if(n!=0)cout<<G.vexs[adj[n]]<<"-->";
            else cout<<G.vexs[adj[n]];
        }
    }
    return 0;
}

1.实验中遇到的具体问题
1)如何正确地初始化距离和路径信息?

2)如何有效地选取未访问过的顶点中具有最小距离的顶点?

3)如何更新已访问顶点的相邻顶点的距离?

2.问题如何解决的
初始化距离和路径信息:在开始时,将所有顶点的距离设置为无穷大(除了起始顶点,其距离设置为0),并标记所有顶点为未访问。路径信息可以用一个数组来存储,初始时每个顶点的路径设置为空或起始顶点。

选取未访问过的顶点中具有最小距离的顶点:可以使用一个优先队列来实现。优先队列中的元素按照距离进行排序,每次从队列中取出距离最小的顶点进行处理。处理完一个顶点后,更新其相邻顶点的距离,并将更新后的顶点加入优先队列。

更新已访问顶点的相邻顶点的距离:当访问一个顶点时,遍历其所有邻居。如果通过当前顶点到达某个邻居的距离小于该邻居当前的距离,则更新该邻居的距离,并将其路径设置为通过当前顶点到达。

3.实验设计思路

定义了一个结构体 AMGraph 来表示图,其中包含顶点数组 vexs 和邻接矩阵 arcs。邻接矩阵是一个二维数组,其中 arcs[i][j] 表示从顶点 i 到顶点 j 的边的权值。如果 i 和 j 之间没有边,则用 MaxInt 来初始化。

主要函数包括:

LocateVex:这个函数用于在图 G 中查找顶点 v 的索引。如果找到,返回索引;如果没找到,返回 -1。

CreatAMGraph:这个函数用于创建图 G。它首先从输入中读取顶点数和边数,然后读取每个顶点的名字,并将它们存储在 vexs 数组中。然后,它初始化邻接矩阵 arcs 为 MaxInt。最后,它从输入中读取每条边的两个顶点以及它们的权值,并更新邻接矩阵 arcs。如果在读取边的过程中出现错误(例如,某个顶点不在 vexs 数组中),则将 err 设置为 1。

ShortestPath_DIJ:这个函数实现了迪杰斯特拉算法。首先,对于每个顶点 v,设置 S[v] 为 0,D[v] 为从 vo 到 v 的权值(如果存在路径),Path[v] 为 vo(如果存在路径)。然后,对于每个顶点 v,如果它与 vo 之间存在边,则更新 D[v] 和 Path[v]。重复这个过程直到所有的顶点都被处理。

在 main 函数中,首先创建图 G,然后从输入中读取起始点和终点,然后使用迪杰斯特拉算法查找这两个点之间的最短路径。

这个实验的设计思路是使用邻接矩阵来表示图,并实现迪杰斯特拉算法来查找最短路径。这个算法基于贪心策略,每次找到距离起始点最近的顶点,然后更新通过这个顶点的所有边的权值。这个过程重复进行,直到所有的顶点都被处理。

4.实验后的感想
在完成这个实验后,我对图的邻接矩阵表示和迪杰斯特拉算法有了更深入的理解。邻接矩阵是一种常见的图的表示方法,它使用一个二维数组来表示顶点之间的关系。迪杰斯特拉算法是一种用于寻找图中两点间最短路径的算法。

 

 

标签:int,路径,迪杰,邻接矩阵,12.2,MVNum,斯特拉,顶点
From: https://www.cnblogs.com/aixin52129211/p/17892573.html

相关文章

  • 文心一言 VS 讯飞星火 VS chatgpt (152)-- 算法导论12.2 8题
    八、用go语言,证明:在一棵高度为h的二叉搜索树中,不论从哪个结点开始,k次连续的TREE-SUCCESSOR调用所需时间为O(k+h)。文心一言:要证明在一棵高度为h的二叉搜索树中,不论从哪个结点开始,k次连续的TREE-SUCCESSOR调用所需时间为O(k+h),我们可以采用数学归纳法来进行证明。首先,我......
  • 文心一言 VS 讯飞星火 VS chatgpt (150)-- 算法导论12.2 6题
    六、用go语言,考虑一棵二叉搜索树T,其关键字互不相同。证明:如果T中一个结点x的右子树为空,且x有一个后继y,那么y一定是x的最底层祖先,并且其左孩子也是x的祖先。(注意到,每个结点都是它自己的祖先。)文心一言,代码正常运行:灵捷3.5。为了证明上述命题,我们需要定义几个......
  • 文心一言 VS 讯飞星火 VS chatgpt (150)-- 算法导论12.2 6题
    六、用go语言,考虑一棵二叉搜索树T,其关键字互不相同。证明:如果T中一个结点x的右子树为空,且x有一个后继y,那么y一定是x的最底层祖先,并且其左孩子也是x的祖先。(注意到,每个结点都是它自己的祖先。)文心一言,代码正常运行:灵捷3.5。为了证明上述命题,我们需要定义几个辅助......
  • 文心一言 VS 讯飞星火 VS chatgpt (149)-- 算法导论12.2 4题
    五、用go语言,证明:如果一棵二叉搜索树中的一个结点有两个孩子,那么它的后继没有左孩子,它的前驱没有右孩子。灵捷3.5。文心一言:为了证明这个性质,我们首先需要明确二叉搜索树(BST)的定义和特性。一个二叉搜索树是一个有序的树,其中每个节点的左子树上的所有值都小于节点的值,而右子树......
  • 文心一言 VS 讯飞星火 VS chatgpt (148)-- 算法导论12.2 3题
    三、用go语言,写出过程TREE-PREDECESSOR的伪代码。文心一言:以下是使用Go语言编写的TREE-PREDECESSOR函数的伪代码:funcTREE-PREDECESSOR(node){ifnode.parent!=nil{returnnode.parent}//如果节点是根节点,则返回nilifno......
  • 12.2日记
    Scala是一门以Java虚拟机(JVM)为运行环境并将面向对象和函数式编程的最佳特性结合在一起的静态类型编程语言(静态语言需要提前编译的如:Java、C、C++等,动态语言如:JS)。1)Scala是一门多范式的编程语言,Scala支持面向对象和函数式编程。(多范式,就是多种编程方法的意思。有面向过程、面......
  • 求最短路径迪杰斯特拉算法
    代码运行截图:完整代码:#include<stdio.h>#include<stdlib.h>#defineMaxSize20#defineMAX999typedefstructArcNode{//边表intadjvex;//边表中是顶点号!!structArcNode*next;intweight;}ArcNode;typedefstructVN......
  • 2023.12.2——每日总结
    学习所花时间(包括上课):9h代码量(行):0行博客量(篇):1篇今天,上午学习,下午学习;我了解到的知识点:1.jfinal明日计划:学习......
  • 聪明办法学Python_task4_11.28-12.2
    聪明办法学Python_task4_11.28-12.2聪明办法学Python_task4_11.28-12.21.task06循环1.1while循环1.2for循环1.3循环控制语句1.4range()函数2.task07字符串2.1字符串构成2.2字符串操作2.2.1字符串运算2.2.2索引&切片2.2.3相关函数1.task06......
  • 12.2
    实验6熟悉Hive的基本操作 1.实验目的(1)理解Hive作为数据仓库在Hadoop体系结构中的角色。(2)熟练使用常用的HiveQL。2.实验平台操作系统:Ubuntu18.04(或Ubuntu16.04)。Hadoop版本:3.1.3。Hive版本:3.1.2。JDK版本:1.8。3.数据集由《Hive编程指南》(O'Reilly系列,人民邮电出版社)......