找到两组矩阵之间最近的点对

Posted

技术标签:

【中文标题】找到两组矩阵之间最近的点对【英文标题】:find the nearest point pairs between two sets of of matrix 【发布时间】:2012-08-18 11:41:30 【问题描述】:

假设我有两组矩阵(AB),每个矩阵内部包含几个点坐标,我想找出B中的点 最接近 A 并输出一个元胞数组 C 相应地列出最近的点对坐标,并且一个元胞数组 D 记录未配对的点,我该怎么做?

更具体地说,这就是我想要的

两组矩阵包含点xy坐标;

A=[ 1 2; 3 4]; B=[1 3; 5 6; 2 1];

想得到C1,1=[1 2; 1 3]; C2,1= [3 4; 5 6]; D1,1=[2 1];

感谢您的帮助。

【问题讨论】:

A 和/或 B 中的元素可以重复使用吗?你想最小化什么样的距离? @aschepler,A 和 B 中的元素不能重复使用。我不太明白你的第二个问题,但我想要的是最小点到点距离。希望这能澄清我的问题。 @aschepler,我想我现在明白你的第二个问题了,我稍微修改一下我的问题,希望这能澄清你提出的第二点。 您是否考虑过使用dsearchn @Ansari,我猜dsearchn在这里可能没用,因为A和B的元素不能被重用。 【参考方案1】:

对于这个问题并没有确切的解决方案,例如(一维,但可扩展为 N-D)的情况:

A= [1; 3];
B= [2];

那么A(1)A(2) 可以是剩余点。你的算法会吐出哪一个,取决于它是如何工作的,即你先从哪个点找到最近的点。

这样的算法由以下组成

    查找A(i)B(j) 的每个组合之间的距离。如果您有统计工具箱,pdist2 会为您执行此操作:

    A=[ 1 2; 3 4];
    B=[1 3; 5 6; 2 1];
    dist = pdist2(A,B);
    

    循环遍历AB 中最小的一个(我会选择A,因为它在您的示例中是最小的)并为A 中的每个点找到B 剩余集合中的最近点:

    N = size(A,1);
    matchAtoB=NaN(N,1);
    for ii=1:N
        dist(:,matchAtoB(1:ii-1))=Inf; % make sure that already picked points of B are not eligible to be new closest point
        [~,matchAtoB(ii)]=min(dist(ii,:));
    end
    matchBtoA = NaN(size(B,1),1);
    matchBtoA(matchAtoB)=1:N;
    remaining_indices = find(isnan(matchBtoA));
    

    将结果组合到您想要的输出矩阵CD

    C=arrayfun(@(ii) [A(ii,:) ; B(matchAtoB(ii),:)],1:N,'uni',false);
    D=mat2cell(B(remaining_indices,:),ones(numel(remaining_indices),1),size(B,2));
    

请注意,此代码也适用于 1D 点或更高 (N-D) 点,pdist2 将所有内容展平为标量距离。

【讨论】:

@Gunther,刚刚发现了一个错误,如果 A=[1 2; 3 4],B=[1 3];当我运行代码时,[1 2] 和 [3 4] 都与 [1 3] 分组,我应该怎么做才能得到 C1,1=[1 2;1 3] 和 C1,2 =[3 4]?谢谢 这不是错误,请阅读我的代码:'2.循环遍历AB'中的最小值;因此,如果B 更小,请切换AB【参考方案2】:

这是我对这个问题的看法:

A=[1 2
   3 4]; 

B=[1 3
   5 6
   2 1];

dists = pdist2(A,B);

[dists, I] = sort(dists,2);

c = NaN(size(A,1),1);
for ii = 1:size(A,1)    
    newC = find(~any(bsxfun(@eq, I(ii,:), c), 1));
    c(ii) = I(ii,newC(1));
end

C = cellfun(@(x)reshape(x,2,2).',...
        mat2cell([A B(c,:)], ones(size(A,1),1), 4), 'uni', false);
D = B(setdiff(1:size(B,1),c), :)

这个解决方案假设

你所有的向量都是二维的 以AB 的行堆叠 并且A 始终是源(即,所有内容都与A 进行比较)

如果这些假设不(总是)成立,您将不得不采取更通用的方法,例如 @GuntherStruyf 建议的方法。

【讨论】:

A=[0 0;1 1]B=[1 1;0 0;2 2] 怎么样?对于这个输入,结果是I= [2 ; 2]!我看不出将dists 的下三角部分设置为NaN 如何解决不多次使用B 的元素的问题。你事先不知道哪些点最接近,除非一切都已经排序,这个问题是无用的...... @GuntherStruyf 是的,我的解决方案是错误的;我被这个特定问题的正确结果蒙蔽了双眼。此编辑应该可以纠正这一点。 @GuntherStruyf 我仍然不喜欢那个 for 循环...我觉得有一个功能,但它没有想到... 必须处理A中的每个坐标,因为它会影响A中其他坐标的解。对于这个问题imo没有直接/无循环/非迭代的解决方案。 @GuntherStruyf 是你的否决票吗?当然,您的解决方案更优雅(更快!),但投反对票...成为一项运动:)

以上是关于找到两组矩阵之间最近的点对的主要内容,如果未能解决你的问题,请参考以下文章

最近的点对算法

平面最近点对

平面最近点对

平面最近点对问题

我可以计算距离严格小于 delta 的最近分割点对吗

Quoit Design (HDU 1007)平面的最近点对