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)
您是否有更好的想法来生成此图表?
答案 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点集中。