考虑以下元组列表: [(5,4,5),(6,9,6),(3,8,3),(7,9,8)]
我正在尝试设计一个算法来检查列表中是否存在至少一个元组,其中该元组的所有元素都大于或等于给定元组(针)。
例如,对于给定的元组(6,5,7),算法应返回True,因为给定元组中的每个元素都小于列表中的第一个元组,即(5,5,5)。但是,对于给定的元组(9,1,9),算法应该返回False,因为列表中没有元组,其中每个元素都大于给定的元组。特别是,这是由于给定元组的第二个元素1,它小于列表中所有元组的第二个元素。
一个朴素的算法将逐个循环遍历列表中的元组,并循环遍历内循环中元组的元素。假设有n个元组,每个元组都有m个元素,这将给出O(nm)的复杂度。
我在想是否有可能使用算法来生成复杂度较低的任务。允许预处理或任何用于存储数据的奇特数据结构!
我最初的想法是利用二进制搜索的一些变体,但我似乎无法找到一个数据结构,一旦我们根据第一个元素消除了一些元组,我们就不会回到天真的解决方案,这意味着该算法最终也可能是O(nm)。
谢谢!
答案 0 :(得分:1)
请考虑此问题的2元组版本。每个元组(x,y)对应于平面上的轴对齐矩形,其右上角为(x,y),右下角为(-oo,+ oo)。该集合对应于这些矩形的并集。给定一个查询点(针),我们只需确定它是否在联合中。知道边界就足够了。这是一条与轴对齐的折线,相对于x在y中单调不增加:x方向上的“向下楼梯”。使用任何合理的数据结构(例如多段线上的x排序点列表),可以很容易地在O(log n)时间内为n个矩形做出决策。不难看出如何通过一次插入一个矩形来构造O(n log n)时的折线,每个矩形都具有O(log n)的作用。
这里是可视化。这四个点是输入元组。蓝线左下方的区域对应于“ True”返回值:
组合A,B,C影响边界。元组D没有。
所以问题是,该2元组版本是否可以很好地推广到3。将半无限轴对齐的矩形的并集改为矩形棱镜的并集。边界折线变为3d曲面。
存在一些表示此类问题的常用方法。一个是作为八叉树。计算八叉树的并集是一种众所周知的标准算法,效率很高。查询一个成员资格需要O(log k)时间,其中k是其中包含的最大整数坐标范围。这可能是最简单的选择。但是如果整数域很大,八叉树可能会相对较慢并占用大量空间。
另一个没有这些弱点的候选对象是二进制空间分区,它可以处理任意尺寸。 BSP使用维度为n-1的(超)平面来递归拆分n-d空间。一棵树描述了平面的逻辑关系。在此应用程序中,每个元组需要3个平面。由平面引起的“真”半空间的交集将是对应于元组的真半无限棱镜。查询针正在遍历树,以确定您是否在任何棱镜内。 BSP的平均情况行为非常好,但是树的最坏情况大小是可怕的:O(n)在大小为O(2 ^ n)的树上的搜索时间。在实际应用中,从随机插入顺序开始,使用技巧在创建时查找大小适中的BSP。
K-d树是可以适用于此问题的另一种基于树的空间分区方案。但是,这将需要一些工作,因为k-d树的大多数表示方式都与搜索点有关,而不是代表区域。它们具有与BSP相同的最坏情况行为。另一个坏消息是这些算法不适用于大于3的元组。树很快变得太大。搜索高维空间非常困难,并且是积极研究的主题。但是,由于您没有说任何有关元组长度的信息,因此我在这里停止。
答案 1 :(得分:0)
spatial indexing系统解决了这类问题。有许多数据结构可以让您的查询有效执行。
答案 2 :(得分:0)
设S是每个m元组的原始n组的topologically-sorted副本。然后我们可以对S中的任何测试元组使用二进制搜索,每次搜索的代价为O(m ln n)(由于每层最多lg n个搜索层,每层最多m个比较)。
注意,假设在S中存在元组P,Q,使得P≤Q(即,没有Q的元素小于P的对应元素)。然后可以从S中移除元组Q.在实践中,这通常可以将S的大小减小到m的小倍数,这将给出O(m ln m)的性能;但在最坏的情况下,根本不提供任何减少。
答案 3 :(得分:0)
试图回答
all
corresponding
elements greater than or equal to a given tuple (needle)
(将 y 和 z 用于集合/干草堆栈的成员,将 x 用于查询元组/针和 x ll y < / em>当所有ₐ的xₐ≤yₐ时( x占主导地位的 )
一个由每个元素的最小值组成的元组 lower (如果 lower 支配 x 返回True)
和 upper 包含最小值:如果 x 占优 upper