在计算机上选择n维球面上的随机点

5

我需要随机选择一个长度为1的n维向量。我的最佳想法是在球体中选择一个随机点并对其进行归一化:

import random

def point(n):
    sq = 0
    v = []
    while len(v) < n:
        x = 1 - 2*random.random()
        v.append(x)
        sq = sq + x*x
        if sq > 1:
            sq = 0
            v = []
    l = sq**(0.5)
    return [x / l for x in v]

唯一的问题在于,随着维度的增加,n-球的体积会变得越来越小,因此即使是对于像17这样的小n,使用random.random中的均匀分布也需要很长时间。是否有更好(更快)的方法来获得n-球面上的随机点?

你可以在这里找到该算法。 - Leandro Caniglia
1
http://mathworld.wolfram.com/HyperspherePointPicking.html - le_m
@Bakuriu 这在数学上是正确的,因为我使用 if 语句将一个均匀的立方体切割成一个均匀的球形。然后我将其投射到表面上。但是它并不正确,因为即使对于小值,它也无法停止。 - yberman
YBerman,抱歉,我误解了你的问题。 - Leandro Caniglia
please add the language tag - phuclv
显示剩余3条评论
1个回答

5
根据Muller, M. E. "A Note on a Method for Generating Points Uniformly on N-Dimensional Spheres",您需要创建一个n高斯随机变量的向量,并除以其长度。
import random
import math

def randnsphere(n):
  v = [random.gauss(0, 1) for i in range(0, n)]
  inv_len = 1.0 / math.sqrt(sum(coord * coord for coord in v))
  return [coord * inv_len for coord in v]

正如评论中@Bakuriu所述,使用numpy.random在处理较大向量时可以提供更好的性能优势。


尊重在除法使用中的优化。 - yberman
@YBerman 我刚刚在删除它以期望的早期优化后将其编辑回来了 ;) - le_m
3
你可以考虑使用 numpy.random 来处理这些向量,这可能更有效率。 - Bakuriu
你仍然需要拒绝在N维球外的点。技术上说,你冒着除以零的风险。 - Jyaif

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接