首先,按開始時間對你的元組進行排序。保存一堆活躍的元組,其中包含最早結束時間最早的元組。
然後,您將遍歷已排序的列表並將元組添加到活動集。這樣做,你也檢查是否需要刪除元組。如果是這樣,你可以報告一個時間間隔。爲了避免重複報告,只有在自上一次報告以來已將新元組添加到活動集中時才報告新的時間間隔。
下面是一些僞代碼,可視化的想法:
sort(tuples)
activeTuples := new Heap
bool newInsertAfterLastReport = false
for each tuple in tuples
while activeTuples is not empty and activeTuples.top.endTime <= tuple.startTime
//the first tuple from the active set has to be removed
if newInsertAfterLastReport
report activeTuples
newInsertAfterLastReport = false
activeTuples.pop()
end while
activeTuples.insert(tuple)
newInsertAfterLastReport = true
next
if activeTuples has more than 1 entry
report activeTuples
與您的示例數據集中您將獲得:
data = [(0, 1, 2), (1, 1.1, 3), (2, 1.5, 2.5), (3, 2.5, 4), (4, 4, 5)]
tuple activeTuples newInsertAfterLastReport
---------------------------------------------------------------------
(0, 1, 2) [] false
[(0, 1, 2)] true
(1, 1.1, 3)
[(0, 1, 2), (1, 1.1, 3)]
(2, 1.5, 2.5)
[(0, 1, 2), (2, 1.5, 2.5), (1, 1.1, 3)]
(3, 2.5, 4) -> report (0, 1, 2)
[(2, 1.5, 2.5), (1, 1.1, 3)] false
[(1, 1.1, 3)]
[(1, 1.1, 3), (3, 2.5, 4)] true
(4, 4, 5) -> report (1, 3) false
[(3, 2.5, 4)]
[]
[(4, 4, 5)]
事實上,我會刪除if activeTuples has more than 1 entry
一部分,總是在報告結束。這將導致額外的報告(4)
,因爲它不包含在任何以前的報告(而(0) ... (3)
是)。
無視我的意見。我以爲你試圖找到所有的對,而不是所有的組合。儘管如此,您仍然可以應用掃描線算法的相同想法:對所有時間進行排序並遍歷它們,同時保留一組當前覆蓋的時間間隔(uid)。每當你達到一個新的點時,你將刪除所有沒有覆蓋的間隔,並建立當前組+當前時間的所有組合。然後將該uid添加到該集合並繼續。 – ale64bit