我的编程空间,编程开发者的网络收藏夹
学习永远不晚

python3实现无权最短路径的方法

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

python3实现无权最短路径的方法

问题描述

现有一个有向无权图。如下图所示:

这里写图片描述 

问题:使用某个顶点s作为输入参数,找出从s到所有其他顶点的最短路径。
说明:因为是无权图,因此我们可以为每台边赋值为1。这里选择v3为s作为起点。

问题分析

此时立刻可以说,从s到v3的最短路径是长为0的路径,标记此信息,得到下图。

这里写图片描述 

现在开始寻找从s出发距离为1的顶点。这些顶点肯定是与s邻接的顶点,很明显,v1,v6从s出发只需要一条边就到了。所以,从s出发距离为1的顶点,为v1,v6。

这里写图片描述 

现在开始寻找从s出发距离为2的顶点。这些顶点肯定是与v1,v6(距离为1的顶点)邻接的顶点。发现与v1邻接的顶点为v2,v4,与v6邻接的顶点没有(不能往回走,没有出边)。所以,从s出发距离为2的顶点,为v2,v4。

这里写图片描述 

最后,考察与v2,v4邻接的顶点,即v5,v7。所以,从s出发距离为3的顶点,为v5,v7。

这里写图片描述 

这种搜索图的方法称为广度优先搜索(breadth-first search)。按层处理顶点,距离起点近的顶点先处理,距离起点远的后处理。

伪代码(处理节点)


void unweighted(Vertex s){
    Queue<Vertex> q = new Queue<Vertex>();
    //把每个顶点的距离设为无穷大
    for each Vertex v
        v.dist = INFINITY
    //将起点的距离设为0
    s.dist = 0;
    //起点入队,作为算法的开始
    q.enqueue(s);
    //只要队列不为空,便继续循环
    while( !q.isEmpty() ){
        //获得出队顶点
        Vertex v = q.dequeue();
        //对与v邻接的每个顶点进行处理
        for each Vertex w adjacent to v
            if(w.dist == INFINITY){
                w.dist = v.dist + 1;
                w.path = v;//代表w的上一个经过的顶点为v
                //完成操作后,便入队,以用来接着分析与w邻接的顶点们
                q.enqueue( w );
            }
    }
}

实现过程

这里写图片描述 

这里写图片描述 

从s开始到顶点的距离放到dv列里,pv列用来代表,当前行代表的顶点的上一个经过的顶点。known列代表此顶点已经被处理过了。

初始化时,将起点的距离设置为0,且所有的顶点都不是know的。

这里写图片描述 

结合伪代码进行分析:
【1】当第一次循环中,出队的是v3(每次循环只出队一个顶点)
【2】而第一次循环结束时,就是上表中“v3出队后”的数据情况,如下
【3】此时,对v3的邻接的顶点们都作了处理,所以v3就从F变成了T(即已知)
【4】与v3邻接的顶点v1,v6都作了处理,dv都变成了1,pv都为v3
【5】而因为与v1,v6的邻接顶点都还没有开始处理呢,所以v1,v6的F还不能变成T

得到无权最短路径

通过观察图,可以发现有两条路径长为3的最短路径。
【1】v3 => v1 => v2 => v5
【2】v3 => v1 => v4 => v7
我们可以通过数据变化表的最终情况来找到这两条路径。

这里写图片描述 

注意,第一行代表v1,以此类推。
以找到v3 => v1 => v2 => v5路径为例,过程如下:
【1】找到距离为0的顶点,0在且只在第三行,所以第一个顶点为v3
【2】找到距离为1且pv为v3的顶点,有第一行和第六行,这里必须选一个,这里选第一行,所以第二个顶点为v1
【3】找到距离为2且pv为v1的顶点,有第二行和第四行,这里选第二行,所以第三个顶点为v2
【4】找到距离为3且pv为v2的顶点,只有第五行,所以第四个顶点为v5
【5】找到距离为4且pv为v5的顶点,没有,结束。
其实,以上步骤,是给出了,在对顶点进行数据处理后,找出无权最短路径的算法的思想。
其实可以,维护一些顶点间指针,用来指向下一个顶点,这样就可以用递归的思路来做,从起点开始,每递归到下一层距离dv便加1,用一个中间变量存储经过的顶点,每调用一次递归,便打印这个中间变量,这样,便能得到所有的无权最短路径。
这里得到无权最短路径的伪代码也不给出了,以上分析供大家理解参考。

代码实现

纸上得来终觉浅,绝知此事要躬行!还是觉得用代码实现一遍比较好。


from queue import Queue
class Vertex:
    #顶点类
    def __init__(self,vid,outList):
        self.vid = vid#出边
        self.outList = outList#出边指向的顶点id的列表,也可以理解为邻接表
        self.know = False#默认为假
        self.dist = float('inf')#s到该点的距离,默认为无穷大
        self.prev = 0#上一个顶点的id,默认为0

#创建顶点对象
v1=Vertex(1,[2,4])
v2=Vertex(2,[4,5])
v3=Vertex(3,[1,6])
v4=Vertex(4,[3,5,6,7])
v5=Vertex(5,[7])
v6=Vertex(6,[])
v7=Vertex(7,[6])
#创建一个长度为8的数组,来存储顶点,0索引元素不存
vlist = [False,v1,v2,v3,v4,v5,v6,v7]
def unweighted():
    #起点为v3
    vlist[3].dist = 0
    q = Queue()
    q.put(vlist[3])
    while(not q.empty()):
        v = q.get()#返回并删除队列头部元素
        for w in v.outList:
            if(vlist[w].dist == float('inf')):
                vlist[w].dist = v.dist + 1
                vlist[w].prev = v.vid
                q.put(vlist[w])

unweighted()
print('v1.prev:',v1.prev,'v1.dist',v1.dist)
print('v2.prev:',v2.prev,'v2.dist',v2.dist)
print('v3.prev:',v3.prev,'v3.dist',v3.dist)
print('v4.prev:',v4.prev,'v4.dist',v4.dist)
print('v5.prev:',v5.prev,'v5.dist',v5.dist)
print('v6.prev:',v6.prev,'v6.dist',v6.dist)
print('v7.prev:',v7.prev,'v7.dist',v7.dist)

运行结果:

这里写图片描述 

与数据变化表的最终情况一致。
这里你可能会问,Vertex类的init函数中,明明有know成员,为什么在程序没有使用know成员(在处理节点后,就把该节点的know置为Ture),因为if(vlist[w].dist == float('inf'))的判断就相当于判断节点的know是否为Ture,因为一个已知的节点,它的距离就肯定不是无穷大了。
然后再使用递归,打印出所有可能的最短路径,把以下代码和以上代码合在一起就可以了。


traj_list = [3]#v3是起点直接加上

def print_traj(dist):
    last = traj_list[-1]
    print(traj_list,'该路径的长度为:',vlist[last].dist)
    temp_list = []#存储下一步的选项
    for i in range(1,len(vlist)):
        v = vlist[i]
        if((v.dist==dist) and (v.prev==last)):
            temp_list.append(i)
    if(len(temp_list)==0):
        return#终点
    #递归每个选项
    for i in temp_list:#i为顶点的索引
        traj_list.append(i)
        print_traj(dist+1)
        traj_list.pop()


print_traj(1)

这里写图片描述

到此这篇关于python3实现无权最短路径的方法的文章就介绍到这了,更多相关python3 无权最短路径内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

python3实现无权最短路径的方法

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Java实现Floyd算法求最短路径

本文实例为大家分享了Java实现Floyd算法求最短路径的具体代码,供大家参考,具体内容如下import java.io.FileInputStream; import java.io.FileNotFoundException; impo
2023-05-30

C++最短路径Dijkstra算法如何实现

这篇文章主要介绍“C++最短路径Dijkstra算法如何实现”,在日常操作中,相信很多人在C++最短路径Dijkstra算法如何实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++最短路径Dijkstra
2023-07-05

Java实现Dijkstra输出最短路径的实例

Java实现Dijkstra输出指定起点到终点的最短路径前言:最近在公司参加了一个比赛,其中涉及的一个问题,可以简化成如是描述:一个二维矩阵,每个点都有权重,需要找出从指定起点到终点的最短路径。马上就想到了Dijkstra算法,所以又重新温
2023-05-31

java实现最短路径算法之Dijkstra算法的示例

这篇文章主要介绍了java实现最短路径算法之Dijkstra算法的示例,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、知识准备:1、表示图的数据结构用于存储图的数据结构有多
2023-05-31

C#图表算法之最短路径怎么实现

本篇内容主要讲解“C#图表算法之最短路径怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C#图表算法之最短路径怎么实现”吧!从一个顶点到达另一个顶点的成本最小的路径。我们采用一个一般性的模
2023-06-30

C++最短路径Dijkstra算法的分析与具体实现详解

经典的求解最短路径算法有这么几种:广度优先算法、Dijkstra算法、Floyd算法。本文是对 Dijkstra算法的总结,该算法适用于带权有向图,可求出起始顶点到其他任意顶点的最小代价以及对应路径,希望对大家有所帮助
2023-03-10

Python和Matlab怎么实现蚂蚁群算法求解最短路径

这篇文章主要介绍“Python和Matlab怎么实现蚂蚁群算法求解最短路径”,在日常操作中,相信很多人在Python和Matlab怎么实现蚂蚁群算法求解最短路径问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”P
2023-06-29

php隐藏路径下载的实现方法

小编给大家分享一下php隐藏路径下载的实现方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!php隐藏路径下载的实现方法:1、通过“download_docume
2023-06-14

Vite配置路径别名的简单实现方法

Vite项目中我们可以手动将src路径设置**@**路径别名,可以省下很多引入路径的冗余路径,下面这篇文章主要给大家介绍了关于Vite配置路径别名的简单实现方法,需要的朋友可以参考下
2023-05-14

android用java和c实现查找sd卡挂载路径(sd卡路径)的方法

方法一: 分析 mount 命令的返回信息,例如: 代码如下:$ mountrootfs / rootfs ro,relatime 0 0tmpfs /dev tmpfs rw,nosuid,relatime,mode=755 0 0dev
2022-06-06

QT实现多文件拖拽获取路径的方法

这篇文章主要为大家详细介绍了QT实现多文件拖拽获取路径的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
2022-11-13

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录