用python找图_python – 在大图中有效找到最短路径

python-graph

添加:

评论让我很好奇,pypi的表现如何在OP的顺序上出现问题,所以我做了一个玩具程序来找出来.以下是该问题略小版本的输出:

$python2.6 biggraph.py 4 6

biggraph generate 10000 nodes 00:00:00

biggraph generate 1000000 edges 00:00:00

biggraph add edges 00:00:05

biggraph Dijkstra 00:01:32

biggraph shortest_path done 00:04:15

step: 1915 2

step: 0 1

biggraph walk done 00:04:15

path: [9999, 1915, 0]

对于10k个节点和1M个边缘来说,这不是太糟糕.重要的是要注意,Dijkstra通过pygraph计算的方式为每个节点相对于一个目标(这是任意的节点0,并且在图中没有特权位置)产生一个所有生成树的字典.因此,实际计算3.75分钟的解决方案产生了“从所有节点到目标的最短路径是什么”的答案.事实上,一旦最短路径完成,走路的答案只是字典查找,基本上没有时间.还值得注意的是,在约1.5分钟内将预先计算的边添加到图表中是相当昂贵的.这些时间在多个运行中是一致的.

我想说,这个过程很好,但是我仍然在等待五分之一的电脑(Athlon 64,4800 BogoMIPS每个处理器,全部是核心),它已经运行了四分之一个小时.至少内存使用稳定在0.5GB左右.结果是:

biggraph generate 100000 nodes 00:00:00

biggraph generate 1000000 edges 00:00:00

biggraph add edges 00:00:07

biggraph Dijkstra 00:01:27

biggraph shortest_path done 00:23:44

step: 48437 4

step: 66200 3

step: 83824 2

step: 0 1

biggraph walk done 00:23:44

path: [99999, 48437, 66200, 83824, 0]

那是很长的时间,但也是一个沉重的计算(我真的希望我会腌制的结果).这是好奇的代码:

#!/usr/bin/python

import pygraph.classes.graph

import pygraph.algorithms

import pygraph.algorithms.minmax

import time

import random

import sys

if len(sys.argv) != 3:

print ('usage %s: node_exponent edge_exponent' % sys.argv[0])

sys.exit(1)

nnodes = 10**int(sys.argv[1])

nedges = 10**int(sys.argv[2])

start_time = time.clock()

def timestamp(s):

t = time.gmtime(time.clock() - start_time)

print 'biggraph', s.ljust(24), time.strftime('%H:%M:%S', t)

timestamp('generate %d nodes' % nnodes)

bg = pygraph.classes.graph.graph()

bg.add_nodes(xrange(nnodes))

timestamp('generate %d edges' % nedges)

edges = set()

while len(edges) < nedges:

left, right = random.randrange(nnodes), random.randrange(nnodes)

if left == right:

continue

elif left > right:

left, right = right, left

edges.add((left, right))

timestamp('add edges')

for edge in edges:

bg.add_edge(edge)

timestamp("Dijkstra")

target = 0

span, dist = pygraph.algorithms.minmax.shortest_path(bg, target)

timestamp('shortest_path done')

# the paths from any node to target is in dict span, let's

# pick any arbitrary node (the last one) and walk to the

# target from there, the associated distance will decrease

# monotonically

lastnode = nnodes - 1

path = []

while lastnode != target:

nextnode = span[lastnode]

print 'step:', nextnode, dist[lastnode]

assert nextnode in bg.neighbors(lastnode)

path.append(lastnode)

lastnode = nextnode

path.append(target)

timestamp('walk done')

print 'path:', path

列车运行图的最短路径问题可以被视为图论的一个经典问题,通常可以通过图的搜索算法来解决。在Python,我们可以使用Dijkstra算法或者A*算法等来实现寻最短路径的功能。下面我将简要介绍使用Dijkstra算法来寻列车运行图最短路径的实现方式。 Dijkstra算法是一种用于在加权图找到单个源点到其他所有顶点的最短路径的算法。其基本思想是:每次找到距离源点最近的一个顶点,然后对其进行松弛操作。松弛操作指的是更新与该顶点直接相邻的顶点到源点的距离。 以下是使用Python实现列车运行图最短路径的一个简化示例: ```python import heapq def dijkstra(graph, start): # 初始化距离表,所有顶点的距离都设置为无穷大 distances = {vertex: float('infinity') for vertex in graph} # 起点到起点的距离为0 distances[start] = 0 # 用优先队列维护节点的访问顺序 priority_queue = [(0, start)] while priority_queue: # 取出队列距离最小的节点 current_distance, current_vertex = heapq.heappop(priority_queue) # 如果这个节点的距离已经大于当前记录的距离,则跳过 if current_distance > distances[current_vertex]: continue # 遍历当前节点的邻接节点 for neighbor, weight in graph[current_vertex].items(): distance = current_distance + weight # 如果找到更短的路径,则更新最短路径并放入优先队列 if distance < distances[neighbor]: distances[neighbor] = distance heapq.heappush(priority_queue, (distance, neighbor)) return distances # 定义列车运行图的权重(例如:时间或距离) graph = { 'A': {'B': 1, 'C': 4}, 'B': {'A': 1, 'C': 2, 'D': 5}, 'C': {'A': 4, 'B': 2, 'D': 1}, 'D': {'B': 5, 'C': 1} } # 计算从起点A出发到其他节点的最短路径 start_vertex = 'A' shortest_paths = dijkstra(graph, start_vertex) print(f"最短路径表: {shortest_paths}") ``` 在这个例子,我们定义了一个有向图,其包含四个顶点A、B、C和D,以及它们之间的边和相应的权重。然后使用Dijkstra算法计算从顶点A出发到其他所有顶点的最短路径,并打印出来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值