Python - 如果时间间隔列表包含冲突,最有效的测试方法是什么?

时间:2016-06-27 11:17:38

标签: python python-2.7 python-3.x

我有一个时间间隔列表,如下所示:

[ [1,2], [2,3], [4,5], [1,2], [1,1.5], [1.5,2.5] ]

我希望能够测试列表是否包含任何冲突。

就我的目的而言,如果一个事件在与另一个事件开始的同一时间结束时,我不认为它是冲突。在上述情况下,以下条目将被视为冲突:

[1,2] and [1,2]
[1,2] and [1,1.5]
[1,2] and [1.5,2.5]

我实际上并不需要知道列表中的哪些条目发生冲突,只是存在冲突。

我有点不确定在python中做出这个决定的最有效方法是什么。

非常感谢任何帮助。

编辑:在另一种情况下,[1,5]和[2,3]也会被认为是冲突

4 个答案:

答案 0 :(得分:1)

试试这个

def clash(a,b):
    if a == True or b == True:
        return True

    if b[0] >= a[0] and a[-1] >b[0]:
        return True
    return b

def test_clashes(intervals):
    intervals = sorted(intervals)
    if not reduce(clash,intervals) == True:
        return False
    else:
        return True

您宣布您的间隔:

intervals = [ [1,2], [2,3], [4,5], [1,2], [1,1.5], [1.5,2.5] ]

你以这种方式调用函数:

test_clashes(intervals)

如果任何时间范围与另一个时间范围重叠,则输出为真。

工作原理:

sorted在“自然”中指定我们的间隔时间。 python数组的方式:它们按开始时间排序,如果开始时间相同,则按结束时间排序。

我们假设在排序后我们有间隔[a, b, ... , c]

给出a[0] <= b[0] <= ... <= c[0]

我们假设ac发生冲突。

这意味着a[1] > c[0]。但是,这意味着a[1] > c[0] >= b[0],因此如果ca发生冲突,b也会发生冲突。因此,我们只需要检查连续的间隔,而不是每个间隔的每个间隔。

时间复杂度由排序决定,并且是log(n)* n。

答案 1 :(得分:1)

您正在寻找重叠范围,但接受范围的开头可能等于另一个范围的结尾:

def overlap(x, y):
    x_start, x_end = x
    y_start, y_end = y
    # return not (x_end <= y_start or y_end <= x_start)
    return x_end > y_start and y_end > x_start

要强制它,只需检查是否有任何2个组合间隔重叠:

from itertools import combinations

intervals = [[1, 2], [2, 3], [4, 5], [1, 2], [1, 1.5], [1.5, 2.5]]
result = any(overlap(x, y) for x, y in combinations(intervals, 2))

正如所指出的那样,首先对间隔列表进行排序,或者如果将它们排序为开头,则只允许检查连续的间隔:

sorted_intervals = sorted(intervals)
result = any(overlap(x, y) for x, y in zip(sorted_intervals,
                                           sorted_intervals[1:]))

答案 2 :(得分:0)

尝试:

mylist = [ [1,2], [2,3], [4,5], [1,2], [1,1.5], [1.5,2.5] ]
last = 0
for i in mylist:
        if last>i[0]:
            print('Clashed!!',first,last," and ",i[0],i[1])
        first = i[0] 
        last = i[1]

这将检查所有内容并打印两个重叠的地方,希望我帮助,谢谢

答案 3 :(得分:0)

EDIT修改:处理所有可能的组合而不仅仅是相邻的条目。

首先我对列表进行排序。

然后我将第一个元素与列表右侧的所有剩余元素进行比较 然后我将第二个元素与列表右侧的所有剩余元素进行比较 等等。

如果第二个内部列表的第一个值小于第一个内部列表的第二个值,则会发生崩溃。

LL = [[1,2], [2,3], [4,5], [1,2], [1,1.5], [1.5,2.5]]
print 'original',LL
KK = sorted(LL)
print 'sorted  ',KK
for i in range(len(KK)-1):
    for j in range(i+1,len(KK)):
        print i,j,
        if KK[j][0] < KK[i][1]:
            print "crash"
        else:
            print "ok"

输出:

original [[1, 2], [2, 3], [4, 5], [1, 2], [1, 1.5], [1.5, 2.5]]
sorted   [[1, 1.5], [1, 2], [1, 2], [1.5, 2.5], [2, 3], [4, 5]]
0 1 crash
0 2 crash
0 3 ok
0 4 ok
0 5 ok
1 2 crash
1 3 crash
1 4 ok
1 5 ok
2 3 crash
2 4 ok
2 5 ok
3 4 crash
3 5 ok
4 5 ok