在Matlab中查找距离矩阵中一组点的最近匹配距离

在Matlab中查找距离矩阵中一组点的最近匹配距离,matlab,distance,vectorization,template-matching,Matlab,Distance,Vectorization,Template Matching,我有一个M个平面之间测量角度的矩阵 0 52 77 79 52 0 10 14 77 10 0 3 79 14 3 0 我有一个平面之间已知角度的列表,这是一个N×N矩阵,我将其命名为rho。这是它的一个子集(太大,无法显示): 我的任务是找到M个平面的集合,它们在rho中的角度最接近测量角度。 例如,上述平面的测量角度相对接近平面1、2、4和6之间的已知角度 换句话说,我需要在距离矩阵(使用余弦相关距离)中找

我有一个M个平面之间测量角度的矩阵

 0    52    77    79
52     0    10    14
77    10     0     3
79    14     3     0
我有一个平面之间已知角度的列表,这是一个N×N矩阵,我将其命名为
rho
。这是它的一个子集(太大,无法显示):

我的任务是找到M个平面的集合,它们在
rho
中的角度最接近测量角度。 例如,上述平面的测量角度相对接近平面1、2、4和6之间的已知角度

换句话说,我需要在距离矩阵(使用余弦相关距离)中找到一组点,这些点与我测量的一组距离相匹配。这也可以被认为是将图案与模具相匹配

在我的问题中,我有M=5和N=415

我真的试着去想它,但已经没有时间了。所以目前我使用的是最简单的方法:迭代3个平面的所有可能组合,但速度很慢,目前只针对m=3编写。然后,我返回按匹配分数排序的匹配平面列表:

function [scores] = which_zones(rho, angles)
    N = size(rho,1);
    scores = zeros(N^3, 4);
    index = 1;
    for i=1:N-2
        for j=(i+1):N-1
            for k=(j+1):N
                found_angles = [rho(i,j) rho(i,k) rho(j,k)];
                score = sqrt(sum((found_angles-angles).^2));
                scores(index,:)=[score i j k];
                index = index + 1;
            end
        end;
    end
    scores=scores(1:(index-1),:); % was too lazy to pre-calculate #
    scores=sortrows(scores, 1);
end

我有一种感觉,
pdist2
可能会有所帮助,但不确定如何帮助。如果您能帮我解决这个问题,我将不胜感激。

这里有http://www.mathworks.nl/help/matlab/ref/dsearchn.html 用于最近点搜索,但需要相同的维度。我认为你无论如何都必须找到它,因为这只是一个特殊的问题

这里有一种方法可以对第二个矩阵的所有唯一组合进行bruteforce迭代,并计算
得分
,然后可以找到得分最低的一个

A=[ 0    52    77    79;
   52     0    10    14;
   77    10     0     3;
   79    14     3     0];
B=[ 0    51    68    75    78    81    82;
   51     0    17    24    28    30    32;
   68    17     0     7    11    13    15;
   75    24     7     0     4     6     8;
   78    28    11     4     0     2     4;
   81    30    13     6     2     0     2;
   82    32    15     8     4     2     0];

M = size(A,1);
N = size(B,1);

% find all unique permutations of `1:M`
idx = nchoosek(1:N,M);
K = size(idx,1); % number of combinations = valid candidates for matching A

score = NaN(K,1);
idx_triu = triu(true(M,M),1);
Atriu = A(idx_triu);

for ii=1:K
    partB = B(idx(ii,:),idx(ii,:));
    partB_triu = partB(idx_triu);
    score = norm(Atriu-partB_triu,2);
end

[~, best_match_idx] = min(score);
best_match = idx(best_match_idx,:);
您的示例的解决方案实际上是
[1 2 3 4]
,因此
B的左上部分是
[1 2 4 6]

这在理论上可以解决你的问题,我不知道如何使这个算法更快。但对于大量的人来说,这仍然是缓慢的。例如,对于
M=5
N=415
的情况,存在
100 128 170 583
组合
B
,这是一种可能的解决方案;仅仅生成选择器索引在32位中是不可能的,因为您无法全部寻址它们


我认为这里真正的优化在于在前面的过滤部分中切掉
NxN
矩阵中的一些平面。

谢谢你的回答。然而,由于我特别想要一个非暴力的Frice解决方案,我不能接受它。我不同意你所说的这不是一个普遍的问题。我描述它的方式确实很具体,但我认为它实际上是一个非常普遍的版本。我想你可以把范围缩小到找到几组的交集。我会更加努力,如果我没有找到更好的解决方案(或得到更好的答案),我会接受你的。你不必接受,我只是看到了你的方式,并立即认为这可以加快一点。我真的没有/没有时间/知识想出一个简单的解决方案。
A=[ 0    52    77    79;
   52     0    10    14;
   77    10     0     3;
   79    14     3     0];
B=[ 0    51    68    75    78    81    82;
   51     0    17    24    28    30    32;
   68    17     0     7    11    13    15;
   75    24     7     0     4     6     8;
   78    28    11     4     0     2     4;
   81    30    13     6     2     0     2;
   82    32    15     8     4     2     0];

M = size(A,1);
N = size(B,1);

% find all unique permutations of `1:M`
idx = nchoosek(1:N,M);
K = size(idx,1); % number of combinations = valid candidates for matching A

score = NaN(K,1);
idx_triu = triu(true(M,M),1);
Atriu = A(idx_triu);

for ii=1:K
    partB = B(idx(ii,:),idx(ii,:));
    partB_triu = partB(idx_triu);
    score = norm(Atriu-partB_triu,2);
end

[~, best_match_idx] = min(score);
best_match = idx(best_match_idx,:);