2

例如[2 , 5]支配[3 , 8]原因 (2 < 3) 和 (5 < 8)

but[2 , 5]不占主导地位,[3 , 1]因为 (2 < 3) but (5 > 1) 所以这两个向量是非占主导地位的

现在例如假设我有一个这样的矩阵:

a =[ 1 8;
    2 6;
    3 5;
    4 6];

这里前三个是非支配的,但最后一个是由(3,5)支配的,我需要一个可以省略它并给我这个输出的代码:

ans =

    [ 1 8;
    2 6;
    3 5]

请注意,Nx2 矩阵中可能有很多非支配元素

4

2 回答 2

2
  1. 使用bsxfun将一行与其他行进行比较
  2. 使用arrayfun对每一行执行此操作(或者如果您愿意,可以使用循环)并使用 cell2mat 将输出转换回矩阵
  3. 使用anyall检查哪些行占主导地位
  4. 删除这些行

代码:

a=[1 8;2 6;3 5;4 6];
dominated_idxs = any(cell2mat(arrayfun(@(ii) all(bsxfun(@(x,y) x>y,a,a(ii,:)),2),1:size(a,1),'uni',false)),2);

a(dominated_idxs,:) = [];


编辑

如果你想使用>=而不是>比较,每一行都会控制自己并被删除,所以你最终会得到一个空矩阵。通过如下调整代码过滤掉这些误报:

a=[1 8;2 6;3 5;4 6];
N = size(a,1);

compare_matrix = cell2mat(arrayfun(@(ii) all(bsxfun(@(x,y) x>=y,a,a(ii,:)),2),1:N,'uni',false));
compare_matrix(1:N+1:N^2)=false; % set diagonal to false
dominated_idxs = any(compare_matrix,2);

a(dominated_idxs ,:) = [];
于 2012-07-30T09:14:58.453 回答
2

这个问题与识别所谓的帕累托前沿相同。

如果元素N的数量变大和/或您需要经常执行此类操作(我怀疑您这样做),您可能需要考虑为此目的完全优化的 MEX 文件(可在 Mathworks文件交换):

编译这个,把 mex 放在你的 Matlab 路径中,然后使用类似的东西

a = a(paretofront(a));

will accomplish your task much quicker than any combination of Matlab-builtins is able to.

于 2012-07-30T11:12:02.183 回答