在Matlab中查找距离矩阵中一组点的最近匹配距离
我有一个M个平面之间测量角度的矩阵在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之间的已知角度 换句话说,我需要在距离矩阵(使用余弦相关距离)中找
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,:);