Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 从区间列表中高效地查找重叠区间_Algorithm_List_Data Structures_Intervals_Interval Tree - Fatal编程技术网

Algorithm 从区间列表中高效地查找重叠区间

Algorithm 从区间列表中高效地查找重叠区间,algorithm,list,data-structures,intervals,interval-tree,Algorithm,List,Data Structures,Intervals,Interval Tree,这与寻找重叠区间有关。我知道如何在给出间隔列表(间隔树)的情况下执行此操作。我所拥有的是一个时间间隔列表。比如说, 这样做的结果应该是 [2,3],[7,8] 我需要做的是找到所有列表中常见的间隔列表 我认为这个问题类似于合并n列表。问题是我无法应用列表的成对合并。应用此方法可能会导致丢失重叠间隔。所以我需要合并所有列表,一次考虑所有列表(而不是成对) 我可以使用间隔树。将每个列表中的第一个间隔插入间隔树并查找重叠。从树中删除最弱的间隔,并从其中一个列表中插入下一个间隔。我还没有完全弄清楚如何使

这与寻找重叠区间有关。我知道如何在给出间隔列表(间隔树)的情况下执行此操作。我所拥有的是一个时间间隔列表。比如说,

这样做的结果应该是

[2,3],[7,8]

我需要做的是找到所有列表中常见的间隔列表

我认为这个问题类似于合并
n
列表。问题是我无法应用列表的成对合并。应用此方法可能会导致丢失重叠间隔。所以我需要合并所有列表,一次考虑所有列表(而不是成对)

我可以使用间隔树。将每个列表中的第一个间隔插入间隔树并查找重叠。从树中删除最弱的间隔,并从其中一个列表中插入下一个间隔。我还没有完全弄清楚如何使用这种方法,但它似乎会变得太贵

有没有什么有效的算法可以从一系列间隔中找到重叠的间隔

其他信息:
列表中的间隔被排序。它们不会重叠并形成一个序列。

创建一个单独的、有序的转换数组。每个过渡都有一个位置,以及一个基于您加入或离开的间隔数的累积数。在浏览列表时,请记录您所处的间隔时间。当你们处于和系列一样多的时间间隔时,那个就是你们处于一个普通的时间间隔

对于您的示例,转换为:

[2, 1], [6, -1], [7, 1], [11, -1],
[1, 1], [3, -1], [5, 1], [10, -1], [11, 1], [13, -1]
[2, 1], [5, -1], [6, 1], [8, -1]
按位置排序并合并后,折叠为:

[1, 1], [2, 2], [3, -1], [5, 0], [6, 0], [7, 1], [8, -1], [10, -1], [11, 0], [13, -1]
这为您提供了运行以下总数的转换:

[1, 1], [2, 3], [3, 2], [7, 3], [8, 2], [10, 2], [13, 1]
然后我们可以读出3的间隔,一个从
2
开始到
3
,另一个从
7
开始到
8
。这就是答案


创建一个长列表并进行排序的想法无疑是额外的工作。您可以创建这些列表并动态合并它们。节省量是系列数日志的一个因素,而不是事件数日志的一个因素。

我对您要做的理解是在间隔列表上应用交叉操作。你们可以两两做,因为交点是关联的

我会这样做

Let S be the set of sets, R = s1, s1 in S
     for each set s2 in S / {s1}
              for each element e1 in R
                  for each element e2 in s2 s.t. e1.sup < e2.inf
                    e1 <- intersection (e1, e2)

您说过,每个单独的间隔列表都是经过排序的,不重叠的。所以

Keep track of where you are in each list, starting at the beginning of each.
While none of the lists has run out:
    If the current intervals (one from each list) all overlap:
       Output the intersection of the current intervals
    Find which of the current intervals has the earliest end point
    Advance one position within that list.

如果有K个间隔列表和N个间隔,如果以最简单的方式实现,这应该需要O(N K)个时间,但是您应该能够通过跟踪堆或其他优先级队列中当前间隔的信息,将此时间减少到O(N log K)个时间。

很抱歉,我在“这为您提供了运行总计的转换”。请您再详细说明一下。谢谢!第一个条目仍然是位置。第二个条目是到该点的更改的总和。因此,我们开始
[1,1]
,然后
[2,1+2]
,然后
[2,1+2-1]
等等(因为更改遵循
1,2,-1,0,0,1,-1,-1,0,-1
)。0转换并不重要,所以我放弃了它们。我想这是一个蛮力解决方案!如果我能找到一个更有效的解决方案,我期待着找到一个。是的,它是O(n)。如果你的集合是有序的,在一般情况下你可以做得更好(只要你遇到一个元素e2,它的下界高于第二个元素的上界,就退出第二个循环。只需编辑伪代码。
 intersection (e1,e2):
    return new Interval(max(e1.inf, e2.inf), min (e1.sup, e2.sup));
Keep track of where you are in each list, starting at the beginning of each.
While none of the lists has run out:
    If the current intervals (one from each list) all overlap:
       Output the intersection of the current intervals
    Find which of the current intervals has the earliest end point
    Advance one position within that list.