提出问题的最好方法是通过一个明确的例子。考虑2个时间轴(例如,以秒为单位的时间)A和B,其中每个时间轴的间隔为:
intervals_a =
0 1
1 4
4 7
7 9
intervals_b =
0 2
2 3
3 5
5 8
请注意,第一个a-interval与第一个b-interval重叠。第二个a-间隔与第一个,第二个和第三个b-间隔重叠,依此类推。
最终,我需要一个输出,显示a-interval的索引,与b-interval重叠,如下所示:
output =
1 1 \\ 1st a-interval overlaps 1st b-interval
2 1 \\ 2nd a-interval overlaps 1st b-interval
2 2 \\ 2nd a-interval overlaps 2nd b-interval
2 3 \\ 2nd a-interval overlaps 3rd b-interval
3 3 \\ etc...
3 4
4 4
最大的挑战是:解决方案不能包含for / while循环(“为什么”无关紧要)。这可以使用矢量/矩阵/数组/排序或其他工具有效地完成吗? MATLAB实现是完美的,但任何其他语言都可以。提前谢谢!
答案 0 :(得分:1)
要查找重叠间隔,您需要检查一个间隔的开始时间或结束时间是否在另一个间隔的边界内。要一次性执行所有间隔,您可以使用bsxfun
:
ovlp = @(x, y)bsxfun(@ge, x(:, 1), y(:, 1)') & bsxfun(@le, x(:, 1), y(:, 2)');
idx = ovlp(intervals_a, intervals_b) | ovlp(intervals_b, intervals_a)';
[row, col] = ind2sub(size(idx), find(idx));
output = [row, col];
让我们看看它如何适用于您的示例:
intervals_a = [0 1; 1 4; 4 7; 7 9]
intervals_b = [0 2; 2 3; 3 5; 5 8]
匿名函数ovlp
会检查x
中的开始时间(即x(:, 1)
)是否落在y
中给出的时间间隔内。因此,ovlp(intervals_a, intervals_b)
会产生:
ans =
1 0 0 0
1 0 0 0
0 0 1 0
0 0 0 1
'1'表示interval_a的开始时间落在interval_b内。行号是intervals_a
中间隔的索引,列号是intervals_b
中间隔的索引。
我们需要为intervals_b
的开始时间执行相同的过程以找到所有重叠的间隔,并且我们在两个结果之间进行逻辑OR:
idx = ovlp(intervals_a, intervals_b) | ovlp(intervals_b, intervals_a)'
请注意,第二个结果是转置的,以保持与intervals_a
而不是intervals_b
对应的行。生成的矩阵idx
为:
idx =
1 0 0 0
1 1 1 0
0 0 1 1
0 0 0 1
最后一步是将矩阵idx
转换为intervals_a
和intervals_b
中的索引,因此我们获取'1'的行号和列号并将它们连接起来:
[row, col] = ind2sub(size(idx), find(idx));
output = [row, col];
最终结果是:
output =
1 1
2 1
2 2
2 3
3 3
3 4
4 4
答案 1 :(得分:0)
你想要int_A和int_B的索引(ii,jj),使得int_A(ii,1)> int_B(jj,1)和int_A(ii,2)
NA = size(A_int,1);
NB = size(int_B,1);
ABlower= repmat(A_int(:,1),[1,NB]);
ABupper= repmat(A_int(:,2),[1,NB]);
BAlower= repmat(B_int(:,1),[1,NA])';
BAupper= repmat(B_int(:,2),[1,NA])';
inInt = find((ABlower>BAlower & ABlower < BAupper) | (ABupper>BAlower & ABupper<BAupper);
[ii,jj]=ind2sub([NA,NB], inInt);
我现在无法访问Matlab,但我相信这非常接近......