就地应用置换的复杂性


27

令我惊讶的是,我找不到关于此的论文-可能是搜索了错误的关键字。

因此,我们得到了一个数组,其中每个函数都有一个索引;f是一个排列。ff

我们如何根据对数组进行重新排序,使其内存和运行时间尽可能接近O 1 O n fO(1)O(n)

当此任务变得更容易时,是否还有其他条件?例如,当我们明确知道一个函数f的逆时?gf

我知道一种算法,该算法遵循循环并为每个索引遍历一个循环以检查它是否在其循环中最小,但是同样,它具有最坏情况下的运行时间,尽管平均而言它似乎表现更好。 ..O(n2)


一个简单的观察:如果不仅项目的数组而且包含函数f的数组都是可写的,那么使用O(1)整数寄存器(每个长度为O( log n)位),并在每个循环之后跟随一个项目的额外空间。但是,如果函数f是在只读存储中给出的(或者f仅是预言的,则这是行不通的),我认为这是该问题的一个假设。
伊藤刚(Tsuyoshi Ito)

23
Fich等。1995年时间,O log n 空间。它还讨论了一些特殊情况。O(nlogn)O(logn)
Jukka Suomela 2011年

是的,我假设我们有f作为一个甲骨文。
jkff 2011年

3
@JukkaSuomela,您应该把它变成一个答案。同样,考虑到是一个任意排列,一个简单的熵参数会产生O n log n )的空间和/或时间,因此如果您在时间空间上比O n log n 更好,我会感到惊讶。fO(nlogn)O(nlogn)
user834 2012年

Answers:


4

选项0:Faith E. Fich,J。Ian Munro,Patricio V. Poblete O n log n 时间O log 2 n 空间的置换(1995)。O(nlogn)O(log2n)

选项1:通过将排列压缩为简洁的数据结构来作弊,请参见Munro http://www.itu.dk/people/ssrao/icalp03-a.pdf

选项2:使用素数周期分解来简洁地存储烫发,并使用多余的空间作弊http://oeis.org/A186202

选项3:跟踪每个循环的最大索引。对于每次迭代,请使用最大的看不见的索引将周期中的所有内容移动一个。如果它达到可见索引,则撤消所有工作,因为该循环已被操纵。时间,O 个周期* log n 空间。O(n2)O(#cycleslogn)

选项4:跟踪所操纵的每个循环的最大索引,但只能以不同的循环长度进行批量处理。对于每次迭代,请使用最大的看不见的索引将周期中的所有内容移动一个。如果达到可见索引,则撤消所有工作,因为该循环已被操纵。时间,Ô 周期_ _ 相同_ 尺寸* 日志Ñ 空间。O(n2distinct_cycle_lengths)O((#cycles_with_same_size)logn)

选项5:Munro与选项0来自同一篇论文,对于如果i是该循环中最大的索引,则n旋转p i )的循环。O n 2时间和O log n 空间。i=1..np(i)iO(n2)O(logn)


nlogn

#5使用的空间比#0小一个对数(n)。
乍得·布鲁贝克2014年

1

如果使用置换的循环表示形式,则需要1个额外的数组元素来存储当前置换的项目,并且可以以更差的O(N)操作来运行循环。


2
jkff已经说过,他知道循环跟踪算法,因此他显然希望将排列本身视为(接近)黑盒。正如他在问题中指出的那样,从(几乎)黑盒转换为周期表示可能需要O(n ^ 2)时间。
约书亚·格罗肖

黑盒p(i)可以。您只是绕着循环走,直到回到i。问题是Kolomogorov的复杂性之一是存储已更新的项目列表,因此您不必多次循环。门罗对此有所了解。itu.dk/people/ssrao/icalp03-a.pdf
乍得·布鲁贝克2014年

-2

可以使用N-1或更少的交换将N个项目的任何排列转换为任何其他排列。此方法最坏的情况可能要求对您的oracle F()进行O(n ^ 2)次调用。从最小的位置开始。令x为我们当前交换的头寸。

如果F(x)> = x,则交换位置x和F(x)。否则,我们必须找到位置F(x)中的项目当前在列表中的位置。我们可以通过以下迭代来做到这一点。令y = F(x)。执行直到y> = x:y = F(y):结束执行。现在交换位置x和y。


3
O(n2)

抱歉。我是这个小组的新手。我喜欢这种方法,因为它很简单。我有时发现简单性要比效率快。我知道另一种方法需要O(n)个步骤,但需要O(nlogn)空间。
罗素

1
罗素,即使分配和归零O(n log n)空间也已经是O(n log n),您的意思是另一个方向吗?
jkff

您实际上没有分配空间和零空间。基本思想是,当F(x)> x时,我们需要记住将物品放置在x位置的位置。对于非常大的n,我将使用数据库并仅记录项x的移动位置。当x到达其最终位置时,可以删除该记录。
罗素(Russell)

1
但是,为什么要说这需要O(n log n)空间呢?
jkff 2011年

-2

此方法使用F的倒数,需要n位存储空间。如果x是项目在原始数组中的位置,则让G(x)是项目在排序数组中的位置。令B为n位数组。将B的所有n位设置为0。

对于x = 1到n-1:如果B(x)== 0然后:y = G(x):直到x == y:交换位置x和y:B(y)= 1:y = G( y):循环:ENDIF:下一个X

此方法会一直将当前在位置x的项目交换为项目的最终位置。当正确的项目交换到位置x时,内部循环结束。由于每次交换都将至少一个项目移动到项目的最终位置,因此内部Do循环在运行期间执行的次数不能超过n-1次。我认为这种方法是O(n)的时间和空间。


2
你看过报纸吗?您在此处列出的两个算法是两个“显而易见的”算法。这篇论文有不那么明显的,具有不同的时空权衡,尤其是空间要少得多。
Yuval Filmus
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.