Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在字典中存储的图上启动Dijkstra算法_Python_Algorithm_Dictionary_Graph Algorithm_Dijkstra - Fatal编程技术网

Python 如何在字典中存储的图上启动Dijkstra算法

Python 如何在字典中存储的图上启动Dijkstra算法,python,algorithm,dictionary,graph-algorithm,dijkstra,Python,Algorithm,Dictionary,Graph Algorithm,Dijkstra,我想实现Dijkstra的最短路径算法,我正在使用一个多级字典来表示我的图。例如: g = {'A': {'C': 2}, 'B': {'B': 4, 'A': 2}} 我知道如何使用double for循环访问内部字典。但是,如果用户输入一个起点和一个终点,我将面临一个问题,即使用以下for循环在字典中搜索我的起点: 这将改为打印内部的关键点,它将始终从第一个关键点开始并遍历图形。这与算法所说的相反,即将源点与所有其他节点进行比较,然后根据与所有其他节点的权重对后面的点进行比较,依此类推 你

我想实现Dijkstra的最短路径算法,我正在使用一个多级字典来表示我的图。例如:

g = {'A': {'C': 2}, 'B': {'B': 4, 'A': 2}}
我知道如何使用double for循环访问内部字典。但是,如果用户输入一个起点和一个终点,我将面临一个问题,即使用以下for循环在字典中搜索我的起点:

这将改为打印内部的关键点,它将始终从第一个关键点开始并遍历图形。这与算法所说的相反,即将源点与所有其他节点进行比较,然后根据与所有其他节点的权重对后面的点进行比较,依此类推

你能给我一个建议吗?例如,如何从节点B而不是A开始,而不是从第一个键开始


另外,您建议使用此字典方法还是有更好的方法?

起始节点应该是dijkstra函数的一个参数。函数签名应该类似于def dijkstragraph,start:

要在连接的节点上迭代,我将使用:

for node, cost in graph[start].items():
    print node, cost
同样在dijkstra中,您应该有一个数据结构来保存尚未探测的节点,并按成本递减排序。通常使用优先级队列


这里有一个提示:dijkstra函数中的主循环不是for循环,而是while循环检查还有一些节点需要探索。

起始节点应该是dijkstra函数的一个参数。函数签名应该类似于def dijkstragraph,start:

要在连接的节点上迭代,我将使用:

for node, cost in graph[start].items():
    print node, cost
同样在dijkstra中,您应该有一个数据结构来保存尚未探测的节点,并按成本递减排序。通常使用优先级队列

这里有一个提示:dijkstra函数中的主循环不是for循环,而是while循环检查,还有一些节点需要探索。

这段代码:

for start in g:
    print start
让变量开始遍历字典的每个键。如果要打印对应于字典中起点的值/子字典,只需使用

print g[start]
至于算法本身,迭戈·艾伦的建议是正确的。

这段代码:

for start in g:
    print start
让变量开始遍历字典的每个键。如果要打印对应于字典中起点的值/子字典,只需使用

print g[start]

至于算法本身,Diego Allen的建议是正确的。

Dijkstra的算法解决了单源最短路径问题。给定一个图和图中的一个顶点,它会找到到其他每个顶点的最短路径

如果希望实现快速运行,则必须使用。最初可以使用字典表示图形,但您需要提取边并将其插入优先级队列。回想一下,在Dijkstra算法的每一次迭代中,您必须从所有跨越图中未探索部分和已探索部分边界的边中选择最便宜的边。使用最小成本优先级队列,您可以在每次迭代中从队列中弹出最便宜的边缘


优先级队列的一个简单而高效的实现是一个很好的解决方案。我建议您要么使用Python内置的,要么用列表实现自己的最小堆。

Dijkstra的算法解决了单源最短路径问题。给定一个图和图中的一个顶点,它会找到到其他每个顶点的最短路径

如果希望实现快速运行,则必须使用。最初可以使用字典表示图形,但您需要提取边并将其插入优先级队列。回想一下,在Dijkstra算法的每一次迭代中,您必须从所有跨越图中未探索部分和已探索部分边界的边中选择最便宜的边。使用最小成本优先级队列,您可以在每次迭代中从队列中弹出最便宜的边缘


优先级队列的一个简单而高效的实现是一个很好的解决方案。我建议您要么使用Python的内置功能,要么使用列表实现自己的最小堆。

是的,实际上这就是问题所在。但是,如果我想遍历所有节点来搜索连接在一起的节点并最终找到路径,该怎么办?我需要一个循环,对吗?是的,你可能需要一个循环。但是,正如Dallen所建议的,您应该使用类似优先级队列的结构,而不是迭代每个键并在每个步骤中选择成本最低的键。这将在每次迭代中为您节省宝贵的时间。是的,实际上这就是问题所在。但是,如果我想遍历所有节点来搜索连接在一起的节点并最终找到路径,该怎么办?我需要一个循环,对吗?是的,你可能需要一个循环。但不是迭代每个关键点,然后在每个步骤中选择成本最低的关键点,

正如Dallen所建议的,您应该使用类似优先级队列的结构。这将在每次迭代中为您节省宝贵的时间。也许您正在考虑dijksta的不同实现,您能否提供一些您试图构建的伪代码。Dijkstra是一种单源最短路径算法,您将获得从起始节点到图中其他每个节点的距离。如果您想要所有对,您应该使用Floyd Warshall。@AhmedAl haddad我想到的代码是Michael Laszlo在注释中描述的代码。构建一个heap对象,只插入开始节点。使用while循环,条件是堆不是空的,从堆中弹出最便宜的节点,并插入以前未访问过的每个事件节点。循环将在堆为emtpy时结束,因此所有节点都已被访问。您只需存储节点和到目前为止的成本。因此,您的堆可以像这样开始[0,'S'],然后您将从堆中弹出开始节点并推送它的相邻节点,最后得到类似于[1,'V',4,'W']的内容,等等。每次从堆中弹出一个节点时,您都可以从起始节点获得到该节点的最便宜的路由。避免重访已经访问过的节点。可能您正在考虑dijksta的另一个实现,您能否提供一些您试图构建的伪代码。Dijkstra是一种单源最短路径算法,您将获得从起始节点到图中其他每个节点的距离。如果您想要所有对,您应该使用Floyd Warshall。@AhmedAl haddad我想到的代码是Michael Laszlo在注释中描述的代码。构建一个heap对象,只插入开始节点。使用while循环,条件是堆不是空的,从堆中弹出最便宜的节点,并插入以前未访问过的每个事件节点。循环将在堆为emtpy时结束,因此所有节点都已被访问。您只需存储节点和到目前为止的成本。因此,您的堆可以像这样开始[0,'S'],然后您将从堆中弹出开始节点并推送它的相邻节点,最后得到类似于[1,'V',4,'W']的内容,等等。每次从堆中弹出一个节点时,您都可以从起始节点获得到该节点的最便宜的路由。避免重新访问已访问的节点。感谢您的帮助和编辑。你说一开始实现字典是可以的,但是我需要提取边并将它们插入队列,是不是把整个图作为一个堆来写?!有几种方法可以做到这一点。我想说的是,最简单的方法是从一个堆开始,该堆包含起始顶点上的所有边,这是第一个探索的顶点。删除最便宜的边u,v,其中u是已探测的顶点,v是未探测的顶点。将顶点v添加到已探测的顶点,并将从v到未探测顶点的所有边添加到堆中。这是一次迭代。您总共运行了n-1次迭代,其中n是图中的顶点数。我非常感谢您的帮助,先生,但我感到很失落,可能是因为我对python缺乏扎实的知识,但我真的很想学习!你能告诉我我需要知道什么,这样我才能最终弄明白吗?我强烈推荐蒂姆·劳夫加登的。如果你可以观看视频讲座,请转到第5周,观看关于Dijkstra算法的讲座。这将给你提供一个很好的基础来实现它。@ MichaelLaszlo我认为从一个只有开始节点的堆开始比较容易。无需将边缘事件预插入到开始节点。感谢您的帮助和编辑。你说一开始实现字典是可以的,但是我需要提取边并将它们插入队列,是不是把整个图作为一个堆来写?!有几种方法可以做到这一点。我想说的是,最简单的方法是从一个堆开始,该堆包含起始顶点上的所有边,这是第一个探索的顶点。删除最便宜的边u,v,其中u是已探测的顶点,v是未探测的顶点。将顶点v添加到已探测的顶点,并将从v到未探测顶点的所有边添加到堆中。这是一次迭代。您总共运行了n-1次迭代,其中n是图中的顶点数。我非常感谢您的帮助,先生,但我感到很失落,可能是因为我对python缺乏扎实的知识,但我真的很想学习!你能告诉我我需要知道什么,这样我才能最终弄明白吗?我强烈推荐蒂姆·劳夫加登的。如果你可以观看视频讲座,请转到第5周,观看关于Dijkstra算法的讲座。这将给你提供一个很好的基础来实现它。@ MichaelLaszlo我认为从一个只有开始节点的堆开始比较容易。无需预插入与开始节点关联的边。