N 点之间的快速 3d 距离 python 使用 python 中的 networkx 节点
Fast 3d distance between N points python using networkx nodes in python
我整天都在想办法解决这个问题,但我就是做不对。
我目前正在 运行使用站点到站点渗透进行殖民化模拟。我正在尝试将它扩大到大数字 ~10^6 但是传统的计算距离的 numpy 方法我使用二次方缩放所以对于如此大的 运行s 程序 运行s 超过日。我真的希望这更快。我一直在寻找解决方案,但找不到任何可以帮助我解决这个问题的方法,因为我有一个自定义的 class 用于模拟。
所以我想要每个节点到所有其他节点的距离,如果节点在彼此的 D_max 范围内,则绘制一条边,允许两个节点之间的迁移。
`density = 0.14 #Stellar density per cubic parsec
L = 100
Patches = int(0.056*density*L**3+15)
Distance = 5
nearand = np.genfromtxt('/Users/Skippy/nearand.csv', delimiter = ',',usecols=np.arange(0, 3)).astype('float32') # a csv of 3d cartesian co-ordinates
G = nx.Graph()
xcoord = nearand[:,0]
ycoord = nearand[:,1]
zcoord = nearand[:,2]
class patch:
def __init__(self,status=0,pos=(0,0,0)):
self.status = status
self.pos = pos
def __str__(self):
return(str(self.status))
for i in xrange(Patches):
Stat = 1 if np.random.uniform() < P_init else 0 # a parameter used in the algorithm later
Pos = (xcoord[i], ycoord[i], zcoord[i])
G.add_node(patch(Stat,Pos))
for p1 in G.nodes():
for p2 in G.nodes():
Dist = np.sqrt((p1.pos[2] - p2.pos[2])**2 + (p1.pos[1]-p2.pos[1])**2+(p1.pos[0]-p2.pos[0])**2)
if Dist <= Distance:
G.add_edge(p1,p2)`
在此之后,算法是 运行,但较大的 运行 被阻止在距离计算上,因此只有距离需要优化。谁能帮我解决这个问题?它看起来与其他问题类似,但我需要能够按照常规 numpy 计算计算距离的方式绘制这些边。
根据我的理解说几点。
您想要创建一个 "epsilon-neighborhood graph",计算所有节点之间的距离,然后在距离小于阈值 epsilon 时进行过滤。
知道你的图是无向的,你只需要做 (N x (N - 1)) / 2 次计算。它仍然是二次 O(n^2) 但是你创建边的循环应该改变,这样内循环总是从外循环索引 + 1 开始。它将减少一半的计算量。
现在如果你想真正缩放,你应该考虑一下你是否可以使用近似最近邻方法,因为你使用标准的 L2 范数(欧氏距离)。
我建议您查看 NMSLib or Annoy 以执行此操作。它们有 python 绑定,但为了速度在引擎盖下用 C++ 实现。
希望对您有所帮助。
我整天都在想办法解决这个问题,但我就是做不对。
我目前正在 运行使用站点到站点渗透进行殖民化模拟。我正在尝试将它扩大到大数字 ~10^6 但是传统的计算距离的 numpy 方法我使用二次方缩放所以对于如此大的 运行s 程序 运行s 超过日。我真的希望这更快。我一直在寻找解决方案,但找不到任何可以帮助我解决这个问题的方法,因为我有一个自定义的 class 用于模拟。
所以我想要每个节点到所有其他节点的距离,如果节点在彼此的 D_max 范围内,则绘制一条边,允许两个节点之间的迁移。
`density = 0.14 #Stellar density per cubic parsec
L = 100
Patches = int(0.056*density*L**3+15)
Distance = 5
nearand = np.genfromtxt('/Users/Skippy/nearand.csv', delimiter = ',',usecols=np.arange(0, 3)).astype('float32') # a csv of 3d cartesian co-ordinates
G = nx.Graph()
xcoord = nearand[:,0]
ycoord = nearand[:,1]
zcoord = nearand[:,2]
class patch:
def __init__(self,status=0,pos=(0,0,0)):
self.status = status
self.pos = pos
def __str__(self):
return(str(self.status))
for i in xrange(Patches):
Stat = 1 if np.random.uniform() < P_init else 0 # a parameter used in the algorithm later
Pos = (xcoord[i], ycoord[i], zcoord[i])
G.add_node(patch(Stat,Pos))
for p1 in G.nodes():
for p2 in G.nodes():
Dist = np.sqrt((p1.pos[2] - p2.pos[2])**2 + (p1.pos[1]-p2.pos[1])**2+(p1.pos[0]-p2.pos[0])**2)
if Dist <= Distance:
G.add_edge(p1,p2)`
在此之后,算法是 运行,但较大的 运行 被阻止在距离计算上,因此只有距离需要优化。谁能帮我解决这个问题?它看起来与其他问题类似,但我需要能够按照常规 numpy 计算计算距离的方式绘制这些边。
根据我的理解说几点。 您想要创建一个 "epsilon-neighborhood graph",计算所有节点之间的距离,然后在距离小于阈值 epsilon 时进行过滤。
知道你的图是无向的,你只需要做 (N x (N - 1)) / 2 次计算。它仍然是二次 O(n^2) 但是你创建边的循环应该改变,这样内循环总是从外循环索引 + 1 开始。它将减少一半的计算量。
现在如果你想真正缩放,你应该考虑一下你是否可以使用近似最近邻方法,因为你使用标准的 L2 范数(欧氏距离)。
我建议您查看 NMSLib or Annoy 以执行此操作。它们有 python 绑定,但为了速度在引擎盖下用 C++ 实现。
希望对您有所帮助。