使用Haskell划分和征服已排序的输入

时间:2011-07-27 10:00:37

标签: algorithm haskell

对于分而治之算法的一部分,我有以下问题,其中数据结构没有修复,因此 set 不是字面意思:

给定一个X排序的wrt。元素和子集A和B的一些排序一起由X中的所有元素组成,A和B的排序版本A'和B'可以按时间线性构造在X中的元素数中吗?

目前我正在每个递归步骤进行标准排序,给出递归

T(n) = 2*T(n/2) + O(n*log n)

复杂而不是

T(n) = 2*T(n/2) + O(n)
像在程序版本中一样,可以利用在A和B上具有恒定时间查找的结构在线性时间内形成A'和B'。

添加的log n因素会导致总体复杂性,而O(n* (log n)^2)代替O(n* log n)

编辑: 也许我正在理解术语查找不正确。如果可以在恒定时间内检查A和B的成员资格,则很容易在线性时间内创建A'和B'。

<小时/> 我没有成功通过抽象来使事情更清楚 远离具体细节,所以这是实际问题:

我正在为closest pair problem实施算法。给出一个 有限集合P在平面上找到一对点 在P与最小距离。它大致如下:

如果P 有至少4分,形成Px和 Py,P中的点按x和y坐标排序。通过 分裂Px形式L和R,左和右 一半的分数。递归计算L和中最近的对距离 R,让d为两者中的最小值。现在P的最小距离是 d或从L中的点到R中的点的距离 最小距离是从不同的一半点之间,它会出现 在位于以2 * d为中心的宽度条带中的一对点之间 线x = x0,其中x0是x坐标 L中最右边的点。事实证明,找到一个潜在的最小距离对 条带,它足以计算条带中的每个点 如果条带点在a中,则到达以下七个点的距离 按y坐标排序的集合。

在形成已排序集合的步骤中,将其传递到递归中并按y坐标对带点进行排序,其中我看不到如何进行递归 Haskell利用在递归开始时排序的P。

2 个答案:

答案 0 :(得分:1)

您可能会对以下功能感兴趣:

partition :: (a -> Bool) -> [a] -> ([a], [a])
partition f xs = (filter f xs, filter (not . f) xs)

如果你可以在常量时间内计算集合成员资格,也就是说,有一个类型a -> Bool的谓词在恒定时间内运行,那么分区将在其输入列表的长度上按时间线性运行。此外,partition是稳定的,因此如果对其输入列表进行排序,那么输出列表也是如此。

我还想指出,上面的定义只是为了给出分区的语义; GHC中的实际实现只会对其输入列表进行一次处理,即使整个输出都是强制的。

当然,问题的真正症结在于提供一个恒定时间的谓词。你提出这个问题的方式使得A和B集合非结构化 - 你要求我们可以处理任何特定的分区。在这种情况下,我不知道在任意集中进行常量时间查找的任何特别的Haskell-y方式。但是,这些问题往往更具结构性:通常,您实际上对一些易于计算的属性是否成立感兴趣,而不是设置成员资格。在这种情况下,以上就是医生所要求的。

答案 1 :(得分:0)

我对Haskell知之甚少,但无论如何这里都是一个镜头。

鉴于(A + B)== X可以;你只需迭代X(按排序顺序)并将每个元素添加到A'或B'(如果它存在于A或B中)?在集合A和B中给出元素x的线性时间查找,这将是线性的。