【问题标题】:find all points within a range to any point of an other set找到一个范围内的所有点到另一个集合的任何点
【发布时间】:2013-08-06 16:54:29
【问题描述】:

我有两组点AB

我想找到 BrA 一定范围内的所有点,其中一个点 ba,则表示 B 中的 /strong> 在 rA 的范围内在 A 中,其到 b 的(欧几里得)距离等于或小于 r。

这两组点中的每一个都是一组连贯的点。它们是从两个非重叠对象的体素位置生成的。

在 1D 中这个问题相当简单:B 的所有点在 [min(A)-r max(A)+r]

但我在 3D 中。

最好的方法是什么?

我目前使用某些 knn 算法(即 matlab 的 rangesearch)重复搜索 A 中所有点在 B 范围内的每个点(即 matlab 的 rangesearch),然后合并所有这些集合。但我觉得应该有更好的方法来做到这一点。我更喜欢 matlab 中的高级/矢量化解决方案,但伪代码也很好:)

我还想过将所有点写入图像并在半径为 r 的对象 A 上使用图像膨胀。但这听起来像是一个相当大的开销。

【问题讨论】:

    标签: algorithm matlab image-processing knn


    【解决方案1】:

    您可以使用k-d tree 来存储A 的所有点。

    迭代 B 的点 b,并且对于 k-d 树中的每个点 - find the nearest point in A(让它成为 a)。当且仅当距离 d(a,b) 小于 r 时,点 b 才应包含在结果中。

    复杂度为O(|B| * log(|A|) + |A|*log(|A|))

    【讨论】:

    • 谢谢。这正是我想要的。它将每个案例的运行时间从 46 秒减少到 10 秒。
    • @YAK 是否可以分享我真正需要的代码?
    • @user1460166 你去吧
    【解决方案2】:

    我通过首先过滤掉 B 中与 A 中的所有点绝对相距太远的点来增强 @amit 的解决方案,从而进一步加快了速度,因为它们太远了即使在一个维度上(有点遵循问题中提到的一维解决方案)。

    这样做会将复杂性限制在O(|B|+min(|B|,(2r/res)^3) * log(|A|) + |A|*log(|A|)),其中res 是两点之间的最小距离,从而将测试用例中的运行时间减少到 5 秒(从 10 秒,在其他情况下甚至更多)。

    matlab中的示例代码:

    r=5;
    A=randn(10,3);
    B=randn(200,3)+5;
    
    roughframe=[min(A,[],1)-r;max(A,[],1)+r];
    
    sortedout=any(bsxfun(@lt,B,roughframe(1,:)),2)|any(bsxfun(@gt,B,roughframe(2,:)),2);
    B=B(~sortedout,:);
    [~,dist]=knnsearch(A,B);
    B=B(dist<=r,:);
    

    【讨论】:

      【解决方案3】:

      bsxfun() 是你的朋友。因此,假设您在集合 A 中有 10 分,在集合 B 中有 3 分。您想让它们排列,以便单例维度位于行/列。我将随机生成它们进行演示

      A = rand(10, 1, 3);                    % 10 points in x, y, z, singleton in rows
      B = rand(1, 3, 3);                     %  3 points in x, y, z, singleton in cols
      

      然后,可以分两步计算所有点之间的距离

      dd = bsxfun(@(x,y) (x - y).^2, A, B);  % differences of x, y, z in squares
      d = sqrt(sum(dd, 3));                  % this completes sqrt(dx^2 + dy^2 + dz^2)
      

      现在,您有了 AB 中点之间的距离数组。因此,例如,A 中的点 3 和 B 中的点 2 之间的距离应该在 d(3, 2) 中。希望这会有所帮助。

      【讨论】:

      • 感谢您的建议!我也想过这个问题,但是它会随着 O(|A| * |B|) 扩展,所以我认为它运行得更慢。但我会测试并报告。
      • 确实如此。 (需要 61 秒)。无论如何,bsxfun 对于 ml 用户来说确实是一个强大的工具,谢谢你提到它。但是 accumarray、sort 和 obv。 knnsearch 可以提供更高的(因为算法)加速。
      • @YAK 我看到上面的 kdtree 答案,它很棒。我今天学了些新东西。谢谢你的好问题!
      猜你喜欢
      • 2022-06-11
      • 2019-08-09
      • 2019-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-13
      相关资源
      最近更新 更多