【问题标题】:Python: Dynamic interval data structure [closed]Python:动态区间数据结构
【发布时间】:2010-10-25 11:51:06
【问题描述】:

我正在寻找一些 python 代码来有效地计算间隔重叠。 我以前使用过 bx-python 包的区间树,但现在需要从树中删除区间(或者更好的是,修改它们)。 看来 bx-python 树不支持这个。

任何指针?

【问题讨论】:

  • 我最近需要这样做,并决定在由start 索引的(红/黑)btree 中使用一组(start, length) 对(用C 编写,带有Python 绑定)。然后我意识到,在我的情况下,位图将足够有效,当然位图实现相对微不足道。这对你有用吗?
  • 感谢您的回复!就我而言,事情有点复杂,因为我需要将数据附加到每个间隔,并且随着间隔发生更改或合并,我也需要更改/合并相应的数据。不确定保持从位数组区域到数据的映射是否容易/有效。在树中,我只需将数据存储在节点中。

标签: python overlap intervals


【解决方案1】:

banyan 支持从树中删除间隔。例如,要从区间列表中删除最少数量的区间,以使剩余的区间在O(n log n)banyan.SortedSet(增强红黑树)中不重叠:

from banyan import SortedSet, OverlappingIntervalsUpdator # pip install banyan

def maximize_nonoverlapping_count(intervals):
    # build "interval" tree sorted by the end-point O(n log n)
    tree = SortedSet(intervals, key=lambda (start, end): (end, (end - start)),
                     updator=OverlappingIntervalsUpdator)
    result = []
    while tree: # until there are intervals left to consider
        # pop the interval with the smallest end-point, keep it in the result
        result.append(tree.pop()) # O(log n)

        # remove intervals that overlap with the popped interval
        overlapping_intervals = tree.overlap(result[-1]) # O(m log n)
        tree -= overlapping_intervals # O(m log n)
    return result

例子:

print maximize_nonoverlapping_count([[3, 4], [5, 8], [0, 6], [1, 2]])
# -> [[1, 2], [3, 4], [5, 8]]

Python - Removing overlapping lists

【讨论】:

    【解决方案2】:

    也许存储所有相交区间会有所帮助。

    你需要:

    • 所有区间的联合边界,
    • 对于每个交叉点的左边界和产生交叉点的区间列表。

    相交区间可以存储在树中,因为它们仅用左边界表示。方法插入和删除间隔看起来像(简化):

    插入:找到新区间左右边界的交叉区间,将这些交叉区间分成2或3个新的交叉区间。为每个相交区间添加指向新区间的指针。

    删除:找到左右边界的交叉区间,合并到之前的交叉区间。对于删除指针到删除间隔之间的每个交集间隔。

    【讨论】:

      【解决方案3】:

      如果您正在寻找处理区间算术的 Python 库,请考虑 python-interval。免责声明:我是该库的维护者。

      这个库支持检查重叠,并自动合并间隔。例如:

      >>> import intervals as I
      >>> I.closed(1,2) | I.closed(2,3)
      [1,3]
      >>> I.closed(1,2).overlaps(I.closed(3,4))
      False
      

      如果你想专门计算重叠:

      >>> I.closed(1,3) & I.closed(2, 4)
      [2,3]
      

      它支持开/闭区间,有限或无限。要删除给定间隔的间隔,只需使用差异运算符:

      >>> I.closed(1, 4) - I.closed(2, 3)
      [1,2) | (3,4]
      

      如果您可以更具体一点,我可以为您提供帮助。

      【讨论】:

      • 我看到您的库仅限于整数、浮点数和其他默认变量类型。但我看到了这个库在版本控制方面的惊人用途。例如。 I.openclosed(1.2.1,1.3.2) 将是 (1.2.1,1.3.2] 并且将包含从 1.2.1.x,>1.2.2 到 1.3.2 的所有内容
      • 它不限于整数或浮点数,但允许将任何可比较的值存储为边界。你建议使用版本作为边界很有趣,因为这正是我最初创建这个库的原因;-) 我需要一种统一的方法来编码不同包装生态系统中使用的依赖约束,最简单的方法是转换所有这些对间隔的限制(当时我没有找到处理这种间隔的库)。
      • 太棒了。我想知道您是否有该版本控制库的开源版本。我试着用我自己的和你的。我得到 AttributeError 的 AttributeError: '_PInf' object has no attribute 'vlist' vlist 这是我的版本控制类中的一个对象,它是从版本字符串派生的。
      猜你喜欢
      • 2014-06-11
      • 2015-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-07
      • 1970-01-01
      相关资源
      最近更新 更多