有效生成Gabriel图?

时间:2018-04-23 11:47:58

标签: python networkx

Gabriel Graph是一组顶点,如果直径(i,j)的圆盘中没有顶点,则链接两个顶点i和j。

我想生成带有很多顶点的Gabriel图。然而,对于1000个顶点,创建这样一个图形所需的时间很长,而且我需要超过1000个顶点。

我的想法就是这个:

def dist(I,J):
    return math.sqrt( (I[0]-J[0])**2 + (I[1]-J[1])**2 )
G=nx.empty_graph(N) #empty graph
I=[(random.random(),random.random()) for i in range(0,N)] #nodes positions
for i in range(0,N-1):
    for j in range(i+1,N):
        xm=0.5*(I[i][0] + I[j][0]) #M is the center of i and j
        ym=0.5*(I[i][1] + I[j][1])
        M=(xm,ym)
        d=min(dist(M,I[i]),dist(M,I[j])) #d is the half-distance between i and j
        possibilites=[k for k in range(0,N) if xm-d<I[k][0]<xm+d and ym-d<I[k][1]<ym+d] #we are only looking around the point M
        inter=[k for k in possibilites if dist(I[k],M)<d]
        if len(inter)==0:
            G.add_edge(i,j)

您是否有更好的想法来生成此图表?

2 个答案:

答案 0 :(得分:5)

这是我的实现(可能效率不高,尚有待改进,但在Macbook上大约需要300秒才能完成,数据集约为300点)。实施效率较低,但您也可以使用它来计算较凉的邻域。我实现了伽马可观察到的邻居图[1],当伽马= 0.5时,您将获得加百利图。希望这是有用的:

import pandas as pd
import numpy as np
import networkx as nx
from scipy.spatial.distance import  pdist, squareform
import bisect

def get_gong(df, y=0.5):
    # df is a pandas dataframe who has x and y as columns
    # y is the gamma parameter 
    graph = nx.DiGraph() 
    graph.add_nodes_from(df.iterrows())
    dists = pdist(df[['x','y']]) 
    dists = squareform(dists)
    y_dists = (1-y)*dists

    for node_a, row_a in df.iterrows():
        node_a_coord = list(row_a[:2]) # O(dn)
        dist_idx = np.argsort(dists[node_a]) # O(nlog n)
        for node_b in dist_idx:
            if node_a == node_b:
                continue

            node_b_coord = list(df.loc[node_b, ['x','y']])

            d_i = y_dists[node_a][node_b]
            first_greater = bisect.bisect_left(dists[node_a][dist_idx], d_i)

            b_is_GONG = True

            for node_j in dist_idx[:first_greater]:
                if node_a == node_j:
                    continue

                d_j = y_dists[node_a][node_j]

                if d_j < d_i:
                    b_is_GONG = False
                    break # node_j could be a GONG

            if b_is_GONG:
                graph.add_edge(node_a, node_b, weight = dists[node_a][node_b])
    return graph

[1]-M. Aupetit,P。Couturier和P. Massotte。 γ可观察到的邻居 用于矢量量化。神经网络,15(8):1017-1027,2002。

答案 1 :(得分:0)

这是一个答案存根,因为我的模拟将在一秒钟内完成,然后我需要重新开始工作。 ; - )

根据引理1 here

  

顶点集V上的Gabriel图是Delaunay的子图   对于V的三角剖分。此外,Delaunay的边缘AB   如果是直线,三角测量是加布里埃尔图的边缘   连接A到B与公共边界线段相交   A和B的Thiessen多边形在除端点之外的点上   边界线段。

可以在O(n log n)时间内计算Delaunay三角剖分。 scipy.spatial中有一个Delaunay三角剖分。然后,您可以使用引用的标准过滤边缘:1)计算Voronoi图(也在scipy.spatial中),以及2)断言边缘端点不在Voronoi点集中。