快速检查元素是否排名高于另一个元素的方法

时间:2014-12-14 12:43:57

标签: performance matlab optimization

我在MATLAB中编写了一个程序,用于检查在排名位置是否交换了两个元素AB

示例

假设第一个排名是:

list1 = [1 2 3 4]

而第二个是:

list2 = [1 2 4 3]

我想检查A = 3B = 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文件,但它没有帮助。

2 个答案:

答案 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;