在加权摩尔邻域图上有效计算介数中心性

问题描述

我在矩形网格中有一个基于加权 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 (将#修改为@)