【问题标题】:Generating N random unit vectors with their sum equal to 0 (Python)生成 N 个随机单位向量,它们的和等于 0 (Python)
【发布时间】:2021-04-13 00:48:33
【问题描述】:

我想在单位球面上(均匀地)生成 N 个随机 3 维向量,但条件是它们的总和等于 0。我的尝试是生成 N/2 个随机单位向量,而另一个只是带有减号的相同向量。问题是,当我试图实现尽可能少的相关性时,我的想法显然并不理想,因为我的一半向量与其对应的对完全反相关。

【问题讨论】:

  • 您提出的问题永远不会导致没有相关性的解决方案。如果向量可以相互抵消,这是您想要的,那么它们是相关的,因为它们只是彼此的变换。所以,你的问题没有答案。
  • 如果和为0,那不是限制一个向量吗?你能生成n-1个随机数,那么最后一个就是取消其他的精确向量吗?
  • 这是真的,但是我想知道有没有更好的方法来解决这个问题。正如我所说,我只是想尽量减少相关性。为了正确看待事情,我试图生成一个初始状态,然后使用 Metropolis 算法并检查向量的自相关函数,但它们的总和等于 0 的条件在整个过程中得到尊重算法。我的方法效果不佳,我想知道是否有任何方法可以改进它们。
  • @K.Cl 他们必须都放在单位球面上。

标签: python vector random


【解决方案1】:

您的问题并没有真正的解决方案,但是您可以生成一组向量,这些向量的相关性将比您最初的否定它们的解决方案稍微少一些。准确地说,如果你生成N / 2向量并将它们取反,然后将取反的向量围绕它们的总和旋转任意角度,你可以保证总和为零,并且相关性将是比负单位矩阵更复杂的旋转.

import numpy as np
from scipy.spatial.transform import Rotation

N = 10

v1 = np.random.normal(size=(N / 2, 3))
v1 /= np.linalg.norm(v1, axis=1, keepdims=True)

axis = v1.sum(0)
rot = Rotation.from_rotvec(np.random.uniform(2.0 * np.pi) * axis / np.linalg.norm(axis))

v2 = rot.apply(-v1)

result = np.concatenate((v1, v2), axis=0)

这假定N 在所有情况下都是偶数。正态分布是在球面上均匀生成点的一种相当标准的方法:https://mathworld.wolfram.com/SpherePointPicking.html

如果总和正好为零,您可以对齐两组随机的N / 2 向量,使它们的总和彼此相对。

【讨论】:

    【解决方案2】:

    在这段代码中,我尝试通过将theta, phi 转换为x, y, z 来生成从球体中选择的向量。

    import numpy as np
    
    def vectorize(theta, phi):
        x = np.cos(phi) * np.cos(theta)
        y = np.cos(phi) * np.sin(theta)
        z = np.sin(phi)
        return np.array([x, y, z])
    
    theta_range = np.arange(0, 2 * np.pi, 0.01)
    phi_range = np.arange(-np.pi / 2, np.pi / 2, 0.01)
    TH, PI = np.meshgrid(theta_range, phi_range)
    whole_map = np.vstack((TH.flatten(), PI.flatten())).T
    
    # Number of vectors: 
    N = 100
    
    # Selecting N/2 Vectors first at random
    v_selected = np.random.choice(range(whole_map.shape[0]), N // 2)
    
    vectors = np.array([vectorize(whole_map[ind][0], whole_map[ind][1]) for ind in v_selected])
    
    # Doubling up the number of vectors by adding the negate of each vector to the vector set
    vectors = np.vstack((vectors, -vectors))
    
    
    print(vectors.sum(axis=0))
    # array([1.94289029e-16, 1.17961196e-16, 1.11022302e-16])
    # Almost 0, but isn't zero because of floating number precision when converted to binary
    

    这是在球体上使用radius=1 生成的点的散点图:

    【讨论】:

    • 感谢您的努力,但问题是最后一个向量 sum_v 不是单位向量。我的条件是所有向量必须位于单位球面上。
    • @mb28025 好的,我找到了方法。首先我们选择n/2 向量,然后,对于每个向量,我们将其相反相加,总共有n 向量,所有这些都是单位向量。
    • 另外,您的分布严重偏向两极
    • @aminrd。 OP 已经声明这不是一个有效的选项
    猜你喜欢
    • 2016-11-15
    • 1970-01-01
    • 1970-01-01
    • 2011-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多