如何设置最小距离约束以使用numpy.random.rand生成点? [英] How can I set a minimum distance constraint for generating points with numpy.random.rand?

查看:75
本文介绍了如何设置最小距离约束以使用numpy.random.rand生成点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试生成一个有效的代码,以生成许多随机位置矢量,然后将其用于计算对相关函数.我想知道是否有一种简单的方法来对放置在我的盒子中的任何两个点之间的最小距离进行限制.

I am trying to generate an efficient code for generating a number of random position vectors which I then use to calculate a pair correlation function. I am wondering if there is straightforward way to set a constraint on the minimum distance allowed between any two points placed in my 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

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

I have previously tried using a loop that calculated all distances for each point as it was made and then accepted or rejected. This method was very slow if I use a lot of points.

推荐答案

基于@Samir的答案,并使其成为可调用的函数,以方便您使用:)

Based on @Samir 's answer, and make it a callable function for your convenience :)

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()

这篇关于如何设置最小距离约束以使用numpy.random.rand生成点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆