我有以下矩阵,它跟踪数据范围的起点和终点(第一列表示"starts",第二列表示"ends"):

myMatrix = [
    162   199; %// this represents the range 162:199
    166   199; %// this represents the range 166:199
    180   187; %// and so on...
    314   326;
    323   326;
    397   399;
    419   420;
    433   436;
    576   757;
    579   630;
    634   757;
    663   757;
    668   757;
    676   714;
    722   757;
    746   757;
    799   806;
    951   953;
    1271  1272
];

我需要消除矩阵中包含的更大范围内的所有范围(即行)例如,范围[166:199][180:187]包含在范围[162:199]内,因此,需要删除行2和3。
我想到的解决方案是在第二列上计算一种“running”max,然后将该列的后续值与之进行比较,以确定是否需要删除它们我使用for循环实现了这一点,如下所示:
currentMax = myMatrix(1,2); %//set first value as the maximum
[sizeOfMatrix,~] = size(myMatrix); %//determine the number of rows
rowsToRemove = false(sizeOfMatrix,1); %//pre-allocate final vector of logicals
for m=2:sizeOfMatrix
    if myMatrix(m,2) > currentMax %//if new max is reached, update currentMax...
        currentMax = myMatrix(m,2);
    else
        rowsToRemove(m) = true; %//... else mark that row for removal
    end
end
myMatrix(rowsToRemove,:) = [];

这将正确删除myMatrix中的“冗余”范围,并生成以下矩阵:
myMatrix =
         162         199
         314         326
         397         399
         419         420
         433         436
         576         757
         799         806
         951         953
        1271        1272

关于这些问题:
1)似乎必须有一种更好的方法来计算“running”max而不是for循环我查看了accumarrayfilter,但无法找到使用这些函数的方法是否有可能跳过for循环(某种效率更高的矢量化代码)?
2)是否有一种完全不同(即更有效)的方法来实现最终目标,即删除myMatrix中包含在较大范围内的所有范围我不知道我是不是想得太多了。。。

最佳答案

方法1
bsxfun基于暴力的方法-

myMatrix(sum(bsxfun(@ge,myMatrix(:,1),myMatrix(:,1)') & ...
    bsxfun(@le,myMatrix(:,2),myMatrix(:,2)'),2)<=1,:)

对拟议解决方案的解释很少:
比较所有的starts指标与其他指标的“包含度”,并对ends指标进行类似的比较注意,“包含性”标准必须适用于以下两种情况之一:
对于starts大于或等于,对于ends小于或等于
对于starts小于或等于,对于ends大于或等于。
我只是碰巧选择了第一个。
查看哪些行满足至少一个“包含性”,并删除这些行以获得所需的结果。
方法2
如果您可以使用根据第一列对行进行排序的输出,并且如果local max's的数目较少,则可以尝试此替代方法-
myMatrix_sorted = sortrows(myMatrix,1);
col2 = myMatrix_sorted(:,2);
max_idx = 1:numel(col2);
while 1
    col2_selected = col2(max_idx);
    N = numel(col2_selected);
    labels = cumsum([true ; diff(col2_selected)>0]);
    idx1 = accumarray(labels, 1:N ,[], @(x) findmax(x,col2_selected));
    if numel(idx1)==N
        break;
    end
    max_idx = max_idx(idx1);
end
out = myMatrix_sorted(max_idx,:); %// desired output

关联功能代码-
function ix = findmax(indx, s)
[~,ix] = max(s(indx));
ix = indx(ix);
return;

09-10 20:06