簡體   English   中英

Python:檢查重疊范圍的復雜性

[英]Python: complexity of check for overlapping ranges

我有兩個范圍,想檢查它們是否在Python(v3.5)中重疊。 這些是一些解決方案。

1a :將設置intersection與范圍:

def overlap_intersection_set(range1, range2):
  return bool(set(range1).intersection(range2))

1b :將集合intersection與兩個集合一起使用:

def overlap_intersection_two_sets(range1, range2):
  return bool(set(range1).intersection(set(range2)))

2in以下范圍內使用any和范圍:

def overlap_any(range1, range2):
  return any([i1 in range2 for i1 in range1])

我一直在嘗試計算這些方法的成本,主要是在時間方面,但是空間復雜性也可能相當可觀。

Python Wiki頁面“時間復雜度”列出了設置的相交(平均情況):

交集s&t(平均情況): O(min(len(s), len(t)) (如果t不為set,請將“ min”替換為“ max”)

因此,對於解決方案1b ,我假設O(min(len(range1), len(range2)) ,再加上一個范圍內兩次創建的集合,我認為bool函數非常便宜。

對於解決方案1aO(max(len(range1), len(range2)) ,再加上一次范圍內的集合創建。

對於解決方案2( any ):我還沒有發現有關的復雜多文檔,無論對於any也不對范圍in 對於后者,我假定的范圍內的行為像的列表,這意味着O(n)的每個in呼叫,因此,導致O(n*m)n=len(range1)m=len(range2) 同時,一旦找到匹配項, any都應導致快捷方式,並且可以省去集合的創建。

因此,我的問題涉及算法復雜性及其特定於Python的實現:

  1. 將范圍轉換為集合要多少錢?
  2. bool()函數的實際價格是多少?
  3. in范圍內的行為確實像列表( O(n) )一樣嗎?
  4. 除算法復雜度外,還有哪些其他實現細節相關?
  5. 最終,考慮以下問題:檢查兩個范圍是否重疊的最有效方法是什么?

這很難憑經驗進行評估,因為實際的計算時間在很大程度上取決於范圍的屬性,即,找到重疊元素的時間及其大小。 這就是為什么我要尋找一個更具分析性的解釋。

不要那樣做 代替:

  1. 安排每個范圍從最低到最高排列。
  2. 如果range1.lowest> range2.lowest,則將range1與range2交換
  3. 如果range1.highest> range2.lowest,則范圍相交
  4. 如果range1.highest == range2.lowest,則范圍觸摸
  5. 如果range1.highest <range2.lowest,則范圍是不同的。

上面的算法與范圍的大小無關,並且也可以處理非整數范圍。

就像是:

def is_overlapped(r1, r2):
    if r1.lowest > r2.lowest:
        r1, r2 = r2, r1
    return r1.highest > r2.lowest

更完整的實現:

from collections import namedtuple

class Range(namedtuple('Range', 'lowest, highest')):

    __slots__ = () 

    def __new__(_cls, lowest, highest):
        'Enforces lowest <= highest'
        if lowest > highest:
            lowest, highest = highest, lowest
        return super().__new__(_cls, lowest, highest)

def is_overlapped(r1, r2):
    r1, r2 = sorted([r1, r2])
    return r1.highest > r2.lowest

if __name__ == '__main__':
    range1, range2 = Range(4, -4), Range(7, 3)
    assert is_overlapped(range2, range1) == is_overlapped(range1, range2)
    print(is_overlapped(range2, range1))  # True 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM