Doğrusal zaman yerinde fırfır karıştırma algoritması


15

Doğrusal bir zaman yerinde tüfek shuffle algoritması var mı? Bu, özellikle titiz ellerin gerçekleştirebileceği algoritmadır: çift boyutlu bir giriş dizisinin eşit olarak bölünmesi ve daha sonra iki yarıya ait elemanların serpiştirilmesi.

MathWorld üzerinde kısa bir sayfası vardır şıraynır shuffle . Özellikle, giriş dizisini 1 2 3 4 5 6'yı 1 4 2 5 3 6'ya dönüştüren karışıklık çeşitliliği ile ilgileniyorum. Tanımlarında giriş uzunluğunun 2n .

İkinci bir boyut n veya daha kullanışlı dizimiz varsa bunu doğrusal zamanda gerçekleştirmek kolaydır . İlk olarak son n öğeyi diziye kopyalayın . Ardından, 0 tabanlı indeksleme varsayalım, ilk n öğeyi indekslerden kopyalayın . . . , N - 1 ][0,1,2,...,n1] için [0,2,4,...,2n2] . Sonra n'yi kopyalayınnendeksleri haritalama giriş dizisine ikinci dizi arka elemanlar, için [ 1 , 3 , 5 , . . . , 2 n - 1 ] . (Bundan biraz daha az iş yapabiliriz, çünkü girişteki ilk ve son elemanlar hareket etmez.)[0,1,2,...,n1][1,3,5,...,2n1]

Bunu yerinde yapmanın bir yolu, permütasyonun ayrık döngülere ayrışmasını ve daha sonra elementlerin her döngüye göre yeniden düzenlenmesini içerir. Yine, 0 tabanlı indeksleme varsayıldığında, 6 element durumunda yer alan permütasyon

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

Beklendiği gibi, ilk ve son elemanlar sabit noktalardır ve ortadaki 4 unsura izin verirsek beklenen sonucu elde ederiz.

Ne yazık ki, permütasyonların matematiğini (ve onların ) çoğunlukla wikipedia'ya dayanır ve bunun doğrusal zamanda yapılabileceğini bilmiyorum. Belki de bu karıştırmaya karışan permütasyonlar çabucak ayrıştırılabilir? Ayrıca, tam bir ayrışmaya bile ihtiyacımız yok. Ayrık döngülerin her birinin tek bir öğesini belirlemek yeterli olacaktır, çünkü döngüyü öğelerinden birinden yeniden yapılandırabiliriz. Belki tamamen farklı bir yaklaşım gerekir.LATEX

İlgili matematikteki iyi kaynaklar bir algoritma kadar değerlidir. Teşekkürler!


Bir zaman çözümü vardır ( O ( 1 ) fazladan boşluk ile). Doğrusal zaman çözümü bilmiyorum. O(nlgn)O(1)
Radu GRIGaha

4
Bu cs.stackexchange için daha uygundur. Düzgün olmayan modelde, süreleri her zaman mümkündür. Bu durumda eşit olarak bile mümkün olmalıdır. O(n)
Yuval Filmus

1
@Radu Bu soruya benzer şekilde , bu sorunun muhtemelen yalnızca fazladan alanı değil, O ( günlük n ) fazladan alanını kullanan bir çözümü yoktur . O(1)O(logn)
Tyson Williams

2
Yorumumu geri alıyorum (ve kapatmak için oy veriyorum)! (Her ne kadar soru literatürde cevaplanmış olsa da.)
Yuval Filmus

1
Bu soruyu geçen hafta bir iş görüşmesinde duyan bir CS öğrencisinden duydum.
Jeffε

Yanıtlar:


12

Sorun şaşırtıcı derecede önemsiz değil. İşte Perfect Shuffle (Bölüm 7) aracılığıyla Ellis ve Markov, In-Situ, Kararlı Birleşme tarafından güzel bir çözüm . Ellis, Krahn ve Fan, Mükemmel Karıştırma Permütasyonundaki Çevrimleri Hesaplamak, daha fazla hafıza pahasına "döngü liderlerini" seçmeyi başarıyor. Ayrıca, oich modeli için genel bir zaman algoritması veren Fich, Munro ve Poblete, Permuting In Place tarafından hazırlanan güzel bir makaleyle de ilgilidir . Sadece permütasyon için bir kehanet mevcutsa, algoritma logaritmik alan gerektirir; tersi için bir kehanetimiz varsa, sabit alan gerektirir.O(nlogn)

Şimdi Ellis ve Markov'un çözümü için. İlk olarak, olduğunu varsayalım . Daha sonra n düzeninin mükemmel karıştırmasını hesaplamak, x ve y siparişlerinin mükemmel karıştırmasını, onlardan önce gelen bir dönüşle hesaplamaya indirgenir . Burada örnek olarak, bir kanıtıdır ( n = 5 , X = 3 , y = 2 ): 012 345 67 89 012 567 34 89 051.627 3849n=x+ynxyn=5x=3y=2

012345678901256734890516273849

Ellis ve Markov , sabit boşluk ve doğrusal zaman kullanarak olduğunda mükemmel karıştırmayı hesaplamanın kolay bir yolunu buldular . Bunu kullanarak, keyfi n için mükemmel shuffle'ı hesaplamak için bir algoritma elde ederiz . İlk olarak, yazma , n = 2 k 0 + + 2 k, w ikili kodlama kullanılarak , n ve izin n i = 2 k i + + 2 k a . Ortadaki n 0 biti döndürün, sağ kolu karıştırın 2 kn=2knn=2k0++2kwnni=2ki++2kwn0 bit. Sağ el2 k 0 bitgöz ardı edilerekortan1bitdöndürülürve sağ el2 k 1 bit karıştırılır. Ve bunun gibi. Döndürmenin kolay olduğuna dikkat edin, çünkü döndürülen ilk birkaç unsur döngü liderleri olarak işlev görür. Toplam dönme karmaşıklığıO(n0++nw)=O(n) 'dir, çünkün t + 1 <nt/2'dir. İç karıştırıcıların toplam karmaşıklığıO(2k02k0n12k1O(n0++nw)=O(n)nt+1<nt/2 .O(2k0++2kw)=O(n)

olduğunda mükemmel shuffle'ın nasıl hesaplanacağını göstermek için kalır . Aslında, kolyeler (Fredricksen ve Maiorana, k renklerindeki boncuk kolyeler ve k- ar de Bruijn dizileri ; Fredricksen ve Kessler, iki renkte boncuk kolyeler üretmek için bir algoritma) , döngü liderlerini tanımlayabileceğiz ).n=2kkk

Bağlantı nedir? Karıştırma permütasyonunun ikili gösterimin sağa kaymasına karşılık geldiğini iddia ediyorum. İşte örnek olarak bir : 000 001 010 011 100 101 110 111 000 100 001 101 010 110 011 111 Bu nedenle, döngü liderlerini bulmak için, uzunluk ikili dizeleri k . Yukarıda belirtilen makaleler, tüm döngü liderlerini oluşturmak için aşağıdaki algoritmayı vermektedir . 0 k ile başlan=8

000001010011100101110111000100001101010110011111
k0k. Her adımda, noktada bir 1a k . Maksimal endeksi bul i sıfır bit bölünüz k tarafından i elde etmek k = d i + r ve aşağıdaki tespittir ( a 1 ... a i - 1 1 ) d a 1 ... a r . Her ne zaman r = 0 , yeni dize bir döngü lideridir.a1akikik=di+r(a1ai11)da1arr=0

n=16

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

Döngü liderleri vurgulanır.


3
2323k30,,3k

Jain'in gazetesinin biraz daha basit olduğunu düşünmeme rağmen, önceki makaleyi ve en çok oy alan önceki yazıyı tercih ediyorum.
Johny

6

Bu cs.stackexchange.com adresindeki bir tohumlama sorusuydu ve bir cevap burada: /cs/332/in-place-algorithm-for-interleaving-an-array/400#400

Bu makalenin bir açıklamasıdır: http://arxiv.org/abs/0805.1598 .

Yukarıdaki algoritma tüm bunlar için genelleme yapar kyönlü karıştırır ( 2- burada karışık) k asalın bazı karelerinin ilkel köküdür (kağıt alır 32 için k=2).

Bu cevabın permütasyonla ilgilendiğini unutmayın j2jmod2n+1, (i.e. Inshuffle) and having that makes it easy to solve this problem (Outshuffle) too.


Ha! I completely forgot about that question, even if I participated in the discussion. This means I didn't really understand how it works that time.
Radu GRIGore

2

What happens if you write down the riffle shuffle as a function? If m is the length of the total array, let n=m2 be the length of the array after removing the first and last element. Then the shuffled index of index i is f(i)=2i if in/2 and f(i)=2(imodn/2)1 if i>n/2. Then you can just "pointer jump" through the array, swapping by re-applying the function.

Assuming random access, this would be linear time while requiring O(1) extra words (for storing the value of the array at any given index), and so O(logn) extra space.


Ah, wait. This assumes that all of the values in the riffle permutation lie on the same cycle. This strategy would have to be modified a bit, depending on how many disjoint cycles there are.
Robert Robere
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.