线性时间原位浅滩混洗算法


15

是否存在线性时间就地浅滩混洗算法?这是一些特别灵巧的手能够执行的算法:均匀划分偶数大小的输入数组,然后交织两半的元素。

Mathworld上有一个关于浅滩混洗的简短页面。特别是,我对混洗类型感兴趣,该混洗类型将输入数组1 2 3 4 5 6转换为1 4 2 5 3 6。请注意,在其定义中,输入长度为2n

如果我们有第二个大小为n或更大的数组,则可以在线性时间内直接执行此操作。首先将最后n元素复制到数组中。然后,假设为基础的0索引,复制所述第一n元件从索引[0,1,2,...,n1][0,2,4,...,2n2]。然后复制n从第二阵列回输入数组元素,映射索引[0,1,2,...,n1][1,3,5,...,2n1]。(我们可以做的工作比这少一点,因为输入中的第一个和最后一个元素不会移动。)

一种尝试就地执行此操作的方法包括将置换分解为不相交的循环,然后根据每个循环重新排列元素。同样,假设基于0的索引,则6元素情况下涉及的置换为

σ=(012345024135)=(0)(5)(1243).

正如预期的那样,第一个和最后一个元素是固定点,如果我们置换中间的四个元素,我们将获得预期的结果。

不幸的是,我对排列数学的理解(以及它们的)主要基于维基百科,我不知道是否可以在线性时间内完成。也许这种混洗所涉及的排列可以迅速分解?同样,我们甚至不需要完全分解。仅确定每个不相交周期的一个元素就足够了,因为我们可以从其一个元素中重建周期。也许需要一种完全不同的方法。LATEX

相关数学上的大量资源与算法一样有价值。谢谢!


有一个 时间解决方案(具有 O 1 )个额外空间)。我不知道任何线性时间解决方案。O(nlgn)O(1)
Radu GRIGore 2012年

4
这对于cs.stackexchange更合适。在非均匀模型中,次始终是可能的。在这种情况下,应该甚至可以统一。O(n)
Yuval Filmus,2012年

1
@Radu与此问题类似,此问题可能没有仅使用额外空间,而是 O log n 额外空间的解决方案。O(1)O(logn)
泰森·威廉姆斯

2
我接受我的评论(并投票关闭)!(尽管问题在文献中得到了回答。)
Yuval Filmus 2012年

1
上周,我从一名CS学生那里听到了这个问题,他是在一次面试中听到的。
杰夫·ε'12-10-15

Answers:


12

问题出乎意料的是微不足道的。这是Ellis和Markov提出的一个很好的解决方案,它是通过Perfect Shuffle(第7节)进行就地稳定合并。Ellis,Krahn和Fan 在计算“完美随机排列 ”中的循环时,成功选择了“循环领导者”,但以更多的内存为代价。同样相关的是Fich,Munro和Poblete的论文《 Permuting In Place》,它为oracle模型提供了一种通用的时间算法。如果只有排列的预言可用,则该算法需要对数空间;否则,该算法将需要对数空间。如果我们也有一个反演的预言,它需要恒定的空间。O(nlogn)

现在为Ellis和Markov解决问题。首先,假设。然后,计算阶n的完美混叠可简化为计算阶xy的完美混洗,并在它们之前进行旋转。下面是通过示例的证明(Ñ = 5X = 3ÿ = 2): 012 345 67n=x+ynxyn=5x=3y=2

012345678901256734890516273849

Ellis和Markov找到了一种简单的方法,可以在时使用恒定的空间和线性时间来计算完美的混洗。使用此方法,我们获得了一种用于计算任意n的完美混洗的算法。首先,使用n的二进制编码写n = 2 k 0 + + 2 k w,然后让n i = 2 k i + + 2 k w。旋转中间的n 0位,将右侧2 k随机播放n=2knn=2k0++2kwnni=2ki++2kwn0位。忽略右边的2 k 0位,旋转中间的n1 t + 1 <nt/2。内部洗牌的总复杂度为O2k02k0n1位,然后将右侧的位洗牌。等等。请注意,旋转很容易,因为旋转的前几个元素充当循环引导者。旋转的总复杂度为O n 0 + + n w= O n ,因为n 2 k 0 + +2k1O(n0++nw)=O(n)nt+1<nt/2O(2k0++2kw)=O(n)

剩下的内容将展示如何在n = 2时计算完美混洗。事实上,我们将能够识别周期的领导人,下面就项链(弗雷德里克森和Maiorana,经典作品的珠子项链 ķ颜色和 ķ进制德布鲁因序列;弗雷德里克森和凯斯勒,在两种颜色产生的珠子项链算法)。n=2kkk

有什么联系?我声称随机排列对应于二进制表示的右移。这里是一个证明通过例如,对于000 001 010 011 100 101 110 111 000 100 001 101 010 110 011 111 因此,寻找周期领袖,我们需要找到一个代表超出每个等价类的旋转的长度为k的二进制字符串。上面提到的论文给出了以下用于生成所有循环前导的算法。从0 k开始n=8

000001010011100101110111000100001101010110011111
k0k。在每一步中,我们都处于某个位置。发现的最大索引一个零位,除法的ķ通过获得ķ = d + řa1akikik=di+r,让下面的点是。每当r = 0时字符串即为循环前导。(a1ai11)da1arr=0

例如,当这产生序列 000000010010 0011n=16

0000,0001,0010,0011,0101,0110,0111,1111.

周期负责人将突出显示。


3
另请参阅Aryabhata的答案,该答案使用arxiv.org/abs/0805.1598。这纸“一个简单的原地算法在洗牌”,由耆那教,采用了同样的想法,但不是权力,用途的权力3。关键是,由于2是原始根模3 k,因此很容易看出3 0... 3 k是循环前导。比Ellis和Markov还要简单!2323k30,,3k
Yuval Filmus 2012年

尽管我认为Jain的论文更为直接,但我更喜欢早期的论文以及投票最多的早期论文。
约翰尼,2012年

6

这是cs.stackexchange.com上的一个播种问题,答案在这里:https ://cs.stackexchange.com/questions/332/in-place-algorithm-for-interleaving-an-array/400#400

这是对该文件的解释:http : //arxiv.org/abs/0805.1598

k2k32k=2

请注意,该答案涉及排列 j2jmod2n+1,(即Inshuffle)以及具有可以很容易地太解决这个问题(Outshuffle)。


哈!即使我参加了讨论,我也完全忘记了这个问题。这意味着我当时并不十分了解它是如何工作的。
Radu GRIGore 2012年

2

mn=m2if(i)=2iin/2f(i)=2(imodn/2)1i>n/2

Ø1个Ø日志ñ


啊等一下 假定浅滩置换中的所有值都位于同一周期上。取决于有多少个不相交的循环,必须稍微修改此策略。
罗伯特·罗伯
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.