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

标签 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.
"""
## 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

我之前曾尝试使用一个循环来计算每个点的所有距离,然后接受或拒绝。如果我使用很多点,这种方法会很慢。

最佳答案

这是一个使用 numpy 的可扩展 O(n) 解决方案。它的工作原理是先指定点的等距网格,然后通过一定量扰动点,使点之间的距离最多保持 min_dist

您需要调整点数、框形状和扰动灵敏度以获得您想要的 min_dist

注意:如果您固定框的大小并指定每个点之间的最小距离,那么您可以绘制满足最小距离的点数就会受到限制.

import numpy as np
import matplotlib.pyplot as plt

# specify params
n = 500
shape = np.array([64, 64])
sensitivity = 0.8 # 0 means no movement, 1 means max distance is init_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]))
min_dist = init_dist * (1 - sensitivity)

assert init_dist >= min_dist
print(min_dist)

# 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

# plot
plt.figure(figsize=(10*width_ratio,10))
plt.scatter(coords[:,0], coords[:,1], s=3)
plt.show()

enter image description here

关于python - 如何使用 numpy.random.rand 设置生成点的最小距离约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27499139/

相关文章:

python - 在条件语句中声明变量有问题吗?

python - 用于在 python 中循环数组 - 来自 matlab

python - 在 Python 中以视觉方式绘制波形文件音频

java - Android:当点击按钮时->随机字符串

ruby - 仅从 Ruby 中的数组中选取随机元素

python - Heroku 中的 bson 更新后 Flask 应用程序损坏

Python CRC-32 问题

python - 使用 thread.start_new_thread() 在 Python 2.6 中进行简单线程处理

python - 来自文件的 Numpy 数组 - 预分配?

java - 如何获取集合中的随机范围数