我在MATLAB中编写了一个程序,用于检查在排名位置是否交换了两个元素A
和B
。
示例
假设第一个排名是:
list1 = [1 2 3 4]
而第二个是:
list2 = [1 2 4 3]
我想检查A = 3
和B = 4
是否在排名中交换了相对位置,在这种情况下是正确的,因为在第一个排名3
之前{{1}并且在第二个排名4
之后是3
。
程序
为了做到这一点,我编写了以下MATLAB代码:
4
不幸的是,我需要多次运行此代码,并且positionA1 = find(list1 == A);
positionB1 = find(list1 == B);
positionA2 = find(list2 == A);
positionB2 = find(list2 == B);
if (positionA1 <= positionB1 && positionA2 >= positionB2) || ...
(positionA1 >= positionB1 && positionA2 <= positionB2)
... do something
end
函数非常慢(但需要在列表中获取元素位置)。
我想知道是否有办法加快程序。我还尝试编写一个在C语言中执行查找操作的MEX文件,但它没有帮助。
答案 0 :(得分:1)
如果列表在循环中没有变化,那么您可以提前确定项目的位置。
假设您的项目始终是从1到N的整数:
[~, positions_1] = sort( list1 );
[~, positions_2] = sort( list2 );
这样你就不需要在循环中调用find
,你可以这样做:
positionA1 = positions_1(A);
positionB1 = positions_1(B);
positionA2 = positions_2(A);
positionB2 = positions_2(B);
如果你的循环遍历了A和B的所有可能组合,那么你也可以对其进行矢量化
找到交换相对排名的元素:
rank_diff_1 = bsxfun(@minus, positions_1, positions_1');
rank_diff_2 = bsxfun(@minus, positions_2, positions_2');
rel_rank_changed = sign(rank_diff_1) ~= sign(rank_diff_2);
[A_changed, B_changed] = find(rel_rank_changed);
可选:丢弃一半结果,因为如果(3,4)在列表中,那么(4,3)也将是,并且您可能不希望这样:
mask = (A_changed < B_changed);
A_changed = A_changed(mask);
B_changed = B_changed(mask);
现在只循环那些已交换相对排名的元素
for ii = 1:length(A_changed)
A = A_changed(ii);
B = B_changed(ii);
% Do something...
end
答案 1 :(得分:0)
而不是尝试计算像这样的东西
检查是否有任何交换的值。
if logical(sum(abs(list1-list2)))
do something
end;
对于特定值A和B:
if (list1(logical((list1-list2)-abs((list1-list2))))==A)&&(list1(logical((list1-list2)+abs((list1-list2))))==B)
do something
end;