Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用numpy.random.rand设置生成点的最小距离约束?_Python_Numpy_Random_Distribution_Correlation - Fatal编程技术网

Python 如何使用numpy.random.rand设置生成点的最小距离约束?

Python 如何使用numpy.random.rand设置生成点的最小距离约束?,python,numpy,random,distribution,correlation,Python,Numpy,Random,Distribution,Correlation,我正在尝试生成一个高效的代码,用于生成大量随机位置向量,然后使用这些向量计算对相关函数。我想知道是否有一种简单的方法来限制放置在我的盒子中的任意两点之间允许的最小距离 我目前的代码如下: def pointRun(number, dr): """ Compute the 3D pair correlation function for a random distribution of 'number' particles placed into a 1.0x1.0x1.0 box. """ ##

我正在尝试生成一个高效的代码,用于生成大量随机位置向量,然后使用这些向量计算对相关函数。我想知道是否有一种简单的方法来限制放置在我的盒子中的任意两点之间允许的最小距离

我目前的代码如下:

def pointRun(number, dr):
"""
Compute the 3D pair correlation function
for a random distribution of 'number' particles
placed into a 1.0x1.0x1.0 box.
"""
## Create array of distances over which to calculate.   
    r = np.arange(0., 1.0+dr, dr)

## Generate list of arrays to define the positions of all points,
##    and calculate number density.
    a = np.random.rand(number, 3)
    numberDensity = len(a)/1.0**3

## Find reference points within desired region to avoid edge effects. 
    b = [s for s in a if all(s > 0.4) and all(s < 0.6) ]

## Compute pairwise correlation for each reference particle
    dist = scipy.spatial.distance.cdist(a, b, 'euclidean')
    allDists = dist[(dist < np.sqrt(3))]

## Create histogram to generate radial distribution function, (RDF) or R(r)
    Rr, bins = np.histogram(allDists, bins=r, density=False)

## Make empty containers to hold radii and pair density values.
    radii = []
    rhor = []

## Normalize RDF values by distance and shell volume to get pair density.
    for i in range(len(Rr)):
        y = (r[i] + r[i+1])/2.
        radii.append(y)
        x = np.average(Rr[i])/(4./3.*np.pi*(r[i+1]**3 - r[i]**3))
        rhor.append(x)

## Generate normalized pair density function, by total number density
    gr = np.divide(rhor, numberDensity)
    return radii, gr
def pointRun(数字,dr):
"""
计算三维对相关函数
对于“数量”粒子的随机分布
放入1.0x1.0x1.0框中。
"""
##创建要计算的距离数组。
r=np.arange(0,1.0+dr,dr)
##生成数组列表以定义所有点的位置,
##并计算数密度。
a=np.random.rand(数字,3)
数字密度=长度(a)/1.0**3
##在所需区域内查找参考点以避免边缘效果。
b=[s表示a中的s,如果全部(s>0.4)和全部(s<0.6)]
##计算每个参考粒子的成对相关性
dist=scipy.space.distance.cdist(a,b,'欧几里德')
allDists=dist[(dist

我以前尝试过使用一个循环,该循环计算每个点的所有距离,然后接受或拒绝。如果我使用了很多点,这种方法的速度会非常慢。

据我所知,您正在寻找一种算法,在一个框中创建许多随机点,这样就不会有两个点的距离超过某个最小距离。如果这是您的问题,那么您可以利用统计物理,并使用分子动力学软件解决它。此外,你确实需要分子动力学或蒙特卡罗来获得这个问题的精确解

将N个原子放置在一个矩形框中,在它们之间创建一个固定半径的排斥相互作用(例如移位的Lennard-Jones相互作用),并运行模拟一段时间(直到您看到点均匀分布在整个框中)。根据统计物理定律,你可以证明点的位置是最大随机的,因为点的距离不能小于某个距离。如果使用迭代算法,例如逐个放置点并在重叠时拒绝这些点,则不会出现这种情况

我估计10000点的运行时间为几秒钟,100k的运行时间为几分钟。我使用OpenMM进行所有moelcular动力学模拟

这是一个使用
numpy
的可伸缩O(n)解决方案。它的工作原理是,首先指定一个等距的点网格,然后对点进行一定程度的扰动,使点之间的距离最大为
min\u dist

您需要调整点数、长方体形状和扰动灵敏度,以获得所需的
minu dist

注意:如果固定长方体的大小并指定每个点之间的最小距离,则有必要限制满足最小距离的点的数量

将numpy导入为np
将matplotlib.pyplot作为plt导入
#指定参数
n=500
shape=np.array([64,64])
灵敏度=0.8#0表示不移动,1表示最大距离为初始距离
#基于点数计算网格形状
宽度比=形状[1]/形状[0]
num_y=np.int32(np.sqrt(n/width_比率))+1
num_x=np.int32(n/num_y)+1
#创建规则间隔的神经元
x=np.linspace(0,shape[1]-1,num_x,dtype=np.float32)
y=np.linspace(0,shape[0]-1,num_y,dtype=np.float32)
坐标=np.stack(np.meshgrid(x,y),-1)。重塑(-1,2)
#计算间距
初始距离=np.min((x[1]-x[0],y[1]-y[0]))
最小距离=初始距离*(1-灵敏度)
断言初始距离>=最小距离
打印(最小距离)
#扰动点
最大移动=(初始距离-最小距离)/2
噪声=np.随机性.均匀性(
低=-最大运动,
高=最大运动,
大小=(长度(坐标),2)
坐标+=噪声
#密谋
plt.图(figsize=(10*宽度与U比率,10))
plt.散射(坐标[:,0],坐标[:,1],s=3)
plt.show()

基于@Samir的答案,并为方便起见将其设置为可调用函数:)

#在4000x4000的正方形中生成50个点的示例,最小距离为400
将numpy作为np导入
作为rnd导入随机数据
n_点=50
x、 y=np.零(n个点),np.零(n个点)
x[0],y[0]=np.圆形(rnd.均匀(04000)),np.圆形(rnd.均匀(04000))
最小距离=[]
i=1
而i400:
最小距离。追加(最小距离)
x[i]=x_温度
y[i]=y_温度
i=i+1
打印(x,y)

您可能可以使用的变体,但需要注意的是,它具有最低分辨率(分辨率越高,成本越高)。
import numpy as np
import matplotlib.pyplot as plt

def generate_points_with_min_distance(n, shape, min_dist):
    # compute grid shape based on number of points
    width_ratio = shape[1] / shape[0]
    num_y = np.int32(np.sqrt(n / width_ratio)) + 1
    num_x = np.int32(n / num_y) + 1

    # create regularly spaced neurons
    x = np.linspace(0., shape[1]-1, num_x, dtype=np.float32)
    y = np.linspace(0., shape[0]-1, num_y, dtype=np.float32)
    coords = np.stack(np.meshgrid(x, y), -1).reshape(-1,2)

    # compute spacing
    init_dist = np.min((x[1]-x[0], y[1]-y[0]))

    # perturb points
    max_movement = (init_dist - min_dist)/2
    noise = np.random.uniform(low=-max_movement,
                                high=max_movement,
                                size=(len(coords), 2))
    coords += noise

    return coords

coords = generate_points_with_min_distance(n=8, shape=(2448,2448), min_dist=256)

# plot
plt.figure(figsize=(10,10))
plt.scatter(coords[:,0], coords[:,1], s=3)
plt.show()
#example of generating 50 points in a square of 4000x4000 and with minimum distance of 400

import numpy as np
import random as rnd

n_points=50
x,y = np.zeros(n_points),np.zeros(n_points)
x[0],y[0]=np.round(rnd.uniform(0,4000)),np.round(rnd.uniform(0,4000))
min_distances=[]
i=1
while i<n_points :
    x_temp,y_temp=np.round(rnd.uniform(0,4000)),np.round(rnd.uniform(0,4000))
    distances = []
    for j in range(0,i):
        distances.append(np.sqrt((x_temp-x[j])**2+(y_temp-y[j])**2))
    min_distance = np.min(distances)
    if min_distance>400 :
        min_distances.append(min_distance)
        x[i]=x_temp
        y[i]=y_temp
        i = i+1

print(x,y)