📅  最后修改于: 2023-12-03 15:42:28.113000             🧑  作者: Mango
顺风边界半径是指在一个无向图中,以一个点为起点,存在一条最短路径,使得这条路径上所有边的方向均与以该点为起点的有向图中的方向一致,且该路径长度称为该点的顺风边界半径。
在实际应用中,顺风边界半径可以用于网络分析、社区挖掘等领域。
计算顺风边界半径可以使用Dijkstra算法,对于一个有向图G=(V,E),从某一节点u开始,可以得到以u为起点的最短路径树,同时,每个节点v都有两个属性:u到v的距离d[v]和u到v的最后一条边是否满足有向性质,如果是则f[v] = True,反之为False。
在使用Dijkstra算法计算最短路径时,需要记录每个节点v的先前节点p[v],则遍历完整个图后,可以通过回溯p数组计算出每个节点的顺风边界半径。
代码实现:
import queue
def dijkstra(G, u):
d = [float('inf')] * len(G)
f = [False] * len(G)
p = [-1] * len(G)
d[u] = 0
f[u] = True
pq = queue.PriorityQueue()
pq.put((0, u))
while not pq.empty():
p_weight, p_node = pq.get()
if d[p_node] < p_weight:
continue
for to_node, to_weight in G[p_node]:
if f[to_node]:
if d[to_node] > d[p_node] + to_weight:
d[to_node] = d[p_node] + to_weight
p[to_node] = p_node
pq.put((d[to_node], to_node))
else:
if d[to_node] >= d[p_node] + to_weight:
d[to_node] = d[p_node] + to_weight
p[to_node] = p_node
pq.put((d[to_node], to_node))
f[to_node] = True
return d, p
def get_wind_radius(G, u):
d, p = dijkstra(G, u)
wind_radius = [float('inf')] * len(G)
for idx, node in enumerate(G):
if f[idx]:
temp_p = p[idx]
path = [(node, idx)]
while temp_p != u:
path.append((G[temp_p], temp_p))
temp_p = p[temp_p]
path.append((G[temp_p], temp_p))
path.reverse()
for i in range(len(path) - 1):
f_relation = path[i][1] in [to_node for to_node, _ in G[path[i+1][1]]]
if not f_relation:
wind_radius[idx] = float('inf')
break
wind_radius[idx] = min(wind_radius[idx], d[path[i+1][1]])
return wind_radius
[1] 王道义, 于伟, 吕发祥. 图论及其应用[M]. 北京: 高等教育出版社, 2004.
[2] 钟华, 陈熙霖, 高志晖. 大数据分析与挖掘: 开放动手教程[M]. 北京: 电子工业出版社, 2017.