【问题标题】:Connecting to random points in a 2d numpy array based on distance根据距离连接到二维 numpy 数组中的随机点
【发布时间】:2022-01-14 19:33:41
【问题描述】:

我有一个 2d numpy 数组并选择一个随机坐标位置(比如 10x10 数组并从位置 2,3 开始)。我想随机连接到 2d 数组中 40% 的其他点,有效地生成元组列表 [(x1, y1), (x2, y2) ...],其中列表是其他坐标的 40%。 然而,另一个约束是目标是降低连接概率,点彼此相距越远(因此点 2,3 连接到 2,2 的可能性远大于 9, 8 但仍然是随机的,所以有连接到 9、8) 的机会虽然很小。

我相信我需要创建某种以 2,3 为中心的高斯函数并使用它来选择点,但我创建的任何高斯函数都会生成非整数值 - 需要额外的逻辑以及需要分别处理 x 和 y 维度。

目前,我正在尝试将 np.meshgrid 与 高斯 = np.exp(-(dst2 / (2.0 * sigma2)))

是否有更简单的方法来执行此操作或有人可能会推荐其他方法?

【问题讨论】:

    标签: python arrays numpy random


    【解决方案1】:

    这个问题非常适合rejection sampling。 基本上,您随机选择一个点,并选择是否应根据定义的概率进行连接。你必须考虑到距离更远的点比 # 更近的距离要多得多(它的数量随半径增长),所以也许你必须在概率函数中引入额外的权重。在这种情况下,我选择使用指数衰减概率。

    此代码在速度方面并不是最佳的,尤其是对于更高的连接百分比,但以这种方式更好地展示了这些想法:请参阅下文以获得更好的选择。

    import numpy as np
    from numpy.random import default_rng
    
    rng = default_rng()
    board = np.zeros((100, 100), dtype=bool)
    percent_connected = 4
    N_points = round((board.size - 1) * percent_connected/100)
    center = np.array((20, 30))
    board[tuple(center)] = True # remove the center point from the pool
    dist_char = 35  # characteristic distance where probability decays to 1/e
    
    endpoints = []
    while N_points:
        point = rng.integers(board.shape)
        if not board[tuple(point)]:
            dist = np.sqrt(np.sum((center-point)**2))
            P = np.exp(-dist / dist_char)
            if rng.random() < P:
                board[tuple(point)] = True
                endpoints.append(point)
                N_points -= 1
    board[tuple(center)] = False # clear the center point
    
    # Graphical test
    import matplotlib.pyplot as plt
    
    plt.figure()
    for ep in endpoints:
        plt.plot(*zip(center, ep), c="blue")
    
    

    在更高的连接性下,稍微快一点的方法要快得多:

    rng = default_rng()
    board = np.zeros((100, 100), dtype=bool)
    percent_connected = 4
    N_points = round((board.size - 1) * percent_connected/100)
    center = np.array((20, 30))
    board[tuple(center)] = True # remove the center point from the pool
    dist_char = 35  # characteristic distance where probability decays to 1/e
    flat_board = board.ravel()
    endpoints = []
    while N_points:
        idx = rng.integers(flat_board.size)
        while flat_board[idx]:
            idx += 1
            if idx >= flat_board.size:
                idx = 0
        if not flat_board[idx]:
            point = np.array((idx // board.shape[0], idx % board.shape[0]))
            dist = np.sqrt(np.sum((center-point)**2))
            P = np.exp(-dist / dist_char)
            if rng.random() < P:
                flat_board[idx] = True
                endpoints.append(point)
                N_points -= 1
    board[tuple(center)] = False # clear the center point
    
    
    plt.figure()
    for ep in endpoints:
        plt.plot(*zip(center, ep), c="blue")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-10
      • 1970-01-01
      • 2020-02-13
      • 1970-01-01
      • 2012-12-25
      • 2014-11-19
      相关资源
      最近更新 更多