问题描述
我在矩形网格中有一个基于加权 8 邻域距离 (Moore) 的加权有向图,我正在寻找具有最大介数中心性的网格单元,用于指定边界点之间的路径。我的图由字典给出,其中包含按方向索引的单细胞步骤的权重。
例如,我可以有一个图,其中这些边的权重为 1,所有未标记的边的权重为 8
(0,0) ⇄ (0,1)
↓ ↖ ↓
(1,0) → (1,1)
用矩阵字典表示
{(0,1): [[1],[1]],(1,1): [[8]],0): [[1,1]],-1): [[8]],(0,-1): [[1],[8]],(-1,-1): [[1]],0): [[8,8]],1): [[8]]}
并且对于 (0,1) 和 (1,0) 之间的所有最短路径,该图中的最大介数节点是 (0,0)。
目前我正在使用来自 networkx
的修改后的 Dijkstra 实现和朴素的路径计数来实现这一点,但是对于 50x50 单元格网格中的 100 个边界节点,此计算需要大约一分钟,这对于生成数千个来说太慢了不同网格上的中心点。
def distances_from_focus(
source: t.Tuple[int,int],destinations: t.Optional[t.Set[t.Tuple[int,int]]],distance_by_direction: t.Dict[t.Tuple[int,numpy.array],pred: t.Optional,) -> numpy.array:
# Dijkstra's algorithm,adapted for our purposes from
# networkx/algorithms/shortest_paths/weighted.html
d = distance_by_direction[0,1]
dist: numpy.array = numpy.full((d.shape[0],d.shape[1] + 1),numpy.nan,dtype=float)
seen: t.Dict[t.Tuple[int,float] = {source: 0.0}
c = count()
# use heapq with (distance,label) tuples
fringe: t.List[t.Tuple[float,int,t.Tuple[int,int]]] = []
push(fringe,next(c),source))
def moore_neighbors(
r0: int,c0: int
) -> t.Iterable[t.Tuple[t.Tuple[int,float]]:
for (r,c),d in distance_by_direction.items():
r1,c1 = r0 + r,c0 + c
r = min(r0,r1)
c = min(c0,c1)
if 0 <= r < d.shape[0] and 0 <= c < d.shape[1]:
yield (r1,c1),d[r,c]
while fringe:
(d,_,spot) = pop(fringe)
if numpy.isfinite(dist[spot]):
continue # already searched this node.
dist[spot] = d
if destinations is not None and spot in destinations:
destinations.remove(spot)
if not destinations:
break
for u,cost in moore_neighbors(*spot):
vu_dist = dist[spot] + cost
if numpy.isfinite(dist[u]):
if vu_dist < dist[u]:
raise ValueError(
"ConTradictory paths found. Do you have negative weights?"
)
elif u not in seen or vu_dist < seen[u]:
seen[u] = vu_dist
push(fringe,(vu_dist,u))
if pred is not None:
pred[u] = spot
return dist
c = t.Counter()
for r0,c0 in border:
pred = {(r0,c0): None}
all_dist = distances_from_focus((r0,c0),set(border),dist,pred=pred)
for b1 in border:
n = b1
while pred[n]:
n = pred[n]
c[n] += 1
(r0,centrality = c.most_common(1)[0]
我知道 Brandes 的介数中心性算法,但在我的案例中,高计算时间似乎来自 Dijkstra,而不是边缘计数,因为我的边界节点在图中非常稀疏。
我可以使用规则的网格形状来实现更快的最短路径算法,或者重复使用部分结果在不同源节点的最短路径之间共享吗?
是否存在介数中心性或其他中心性度量的近似值,在此稀疏网格导出的加权有向图上计算会更有效吗?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)