Eşit sayıda 0 ve 1 ile tüm ikili dizileri nasıl verimli bir şekilde üretir?


10

Bir ikili dizi uzunluğu , sadece sıralı bir dizi olup böylece her birinin ya olup ya da . Tüm bu ikili dizileri oluşturmak için, bariz ikili ağaç yapısını şu şekilde kullanabilirsiniz: kök "boş" dur, ancak her sol çocuk , mevcut dizeye ve her bir sağ alt öğeyi ekler. . Şimdi, her ikili dizi, kökten başlayıp bir yaprakta sonlanan uzunluğundaki bir yoldur .x 1 , , x n x j 0 1 0 1 n + 1nx1,,xnxj0101n+1

İşte sorum:

Eğer tam olarak sıfır ve olan uzunluğundaki tüm ikili dizgileri üretmek istiyorsak daha iyisini yapabilir miyiz ?n n2nnn

"Daha iyisini yapabilir miyiz" derken, önce yukarıdaki tüm ağacı oluşturan ve daha sonra eşit sayıda "sol" ve "sağ" kenarlara sahip bu yolları bulmaya çalışan aptal algoritmadan daha az karmaşıklığa sahip olmalıyız.


1'den kadar tüm kesin olarak artan sayı dizilerini verimli bir şekilde üretmenin bir yolunu bulabilir misiniz ? 2 nn2n
Cornelius Markası

Karmaşıklık hakkında yorum yapamam, ama saf algoritmam bir kare ızgara kenarları boyunca bir köşeden diyagonal bir köşeye doğru yürüyüşler üretiyordu. Bu, 01 ve 10'un aynı konumda (ağacınızın aksine) bittiği anlamına gelir, ancak backtrack ile bu geçmişi biliyoruz.
Hendrik Ocak

Muhtemelen farklı bir notta, burada bir select -iterator Java uygulaması vardır . (nk)
Pål GD

Yanıtlar:


6

Açıkçası uzunluğunda ikili dizeler vardır . İkili dosyadan geçmek için bir algoritmanın her düğümü bir kez ziyaret etmesi gerekir, yani adımlar.4n2n

i=02n2i=22n+11=O(4n)

Açıkladığınız ağacı geçen, ancak yolda olanları ve sıfırları sayan, yani sadece ağacın iyi kısmını geçecek özyinelemeli bir algoritmayı düşünelim.
Ama 0 ve 1 ile kaç tane ikili dizge var? uzunluktaki dizelerimiz için 1'i seçiyoruz ve 2. adımda Stirling'in formülünü kullanıyoruz: nnn2n

(2nn)=(2n)!(n!)2=4nπn(1+O(1/n))

DÜZENLEME
Peter Shor'un yorumları sayesinde, 1 ve 0'ları sayan ikinci algoritmanın ihtiyaç duyduğu adım sayısını da analiz edebiliriz. Yorumunu aşağıdan atıyorum:

Tam olarak 0 ve 1 içeren tüm ikili dizileri bulmak istiyoruz . Her düğümün en fazla 0 ve 1'lik bir dizi olduğu ikili ağacı hareket . 0'dan fazla veya 1'den fazla olan herhangi bir düğümü ziyaret etmemiz gerekmez . kaç tane düğüme gitmemiz gerekiyor? Orada dizelerle 0 yılların ve 1'ler. Tüm bu Özetle verir . Şimdi, bu düğümlerin her birini sabit bir ortalama düğüm başına maliyetle ziyaret etmemiz gerekiyor. İlk önce her sol çocuğu ve ikinci sağ çocuğu ziyaret ederek bunu yapabiliriz.nn2nnn(i+ji)iji,jni=0nj=0n(i+ji)=(2n+2n+1)1

Stirling'in formülünü kullanarak tekrar yeni algoritmanın çalışma süresi olarak.

(2n+2n+1)1=4n+11n+1(1+O(1/n))1=O(4nn)

Biraz daha dikkatli olmalısın. Her dizeyi oluşturduktan sonra zamanında . Bu nedenle, sadece dengeli dizelerin işlenmesi zaman alır . Optimize edilmiş "saçma" nesil algoritması gerçekten , hatalara yönelik fırsatlar dışında daha akıllı bir algoritmaya geçerek kazanılacak çok şey yoktur. Ω(n)Ω(4nn)O(4n)
Yuval Filmus

@Yuval Filmus: "Tel işleme" tam olarak ne demek istiyorsun? Çıktı için harcanan zamanı kastediyorsanız, bu kesinlikle , o zaman bu faktörü "aptal" algoritmanın çalışma zamanında da dikkate almalısınız, o zaman . Θ(n)O(4nn)
tranisstor

2
Demek istediğim, ve arasındaki farkla ilgileniyorsanız, en azından doğru çalışma sürelerini belirtmeniz gerektiğiydi; iki algoritma arasındaki potansiyel farkı ortaya çıkarmak için yeterli değildir. Buna ek olarak, bu "ihmal edilebilir" küçük faktörlerin onu önemsiz algoritmadan daha yavaş yapmadığını görmek için, önerilen yeni algoritmanızı analiz ederken dikkatli olmalısınız. 4n4n/nO~(4n)
Yuval Filmus

2
Ağacın "iyi kısmını" sadece "kötü kısımları" da eklemek zorunda kalmadan nasıl kurarsınız? Sen daha yok ağacın bütün düğümlerin eklemeniz gerekir sol çocuk veya kendilerine kökünden yolda sağ çocuklar. Bu işe yarıyor, ancak işe yaradığını göstermek için ek bir argümana ihtiyacınız var. Özellikle, formülünü kullanmanız gerekir . nni=0nj=0n(i+ji)=(2n+2n+1)1
Peter Shor

2
Tam olarak 0 ve 1 içeren tüm ikili dizileri bulmak istiyoruz . Her düğümün en fazla 0 ve 1'lik bir dizi olduğu ikili ağacı hareket . 0'dan fazla veya 1'den fazla olan herhangi bir düğümü ziyaret etmemiz gerekmez . kaç tane düğüme gitmemiz gerekiyor? Orada ile asar 0 yılların ve 1'ler. Tüm bu Özetle verir . Şimdi, bu düğümlerin her birini sabit bir ortalama düğüm başına maliyetle ziyaret etmemiz gerekiyor. İlk önce her sol çocuğu ve ikinci sağ çocuğu ziyaret ederek bunu yapabiliriz.nn2nnn(i+ji)iji,jni=0nj=0n(i+ji)=(2n+2n+1)1
Peter Shor

2

Belki de kalın oluyorum, ancak orijinal soru 2n uzunluğundaki tüm ikili dizilerin bir ağacından geçmekten ve sadece dengelenmiş olanların çıktısından daha verimli olan 2n uzunluğundaki tüm "dengeli" ikili dizileri üretmenin bir yolunu istedi . Öyleyse neden bir ağaç kullanıyorsunuz?

İşte bu tür tüm sekansları üreten bir özyinelemeli algoritma için sözde kod ("verim" anahtar kelimesi çıktıya bir sekans gönderir):

function all-balanced(n) {
  all-specified( "", n, n );
};

function all-specified( currentString, zeroes, ones ) {

  if (zeroes == 0) {
    for i = 0 to ones {
      currentString += "1";
    };
    yield currentString;
    return;
  };

  if (ones == 0) {
    for i = 0 to zeroes {
      currentString += "0";
    };
    yield currentString;
    return;
  };

  all-specified( currentString+"0", zeroes-1, ones );
  all-specified( currentString+"1", zeroes, ones-1 );
  return;
};

Eğer bir şeyi yanlış anlıyorsam, lütfen söyle bana, ama bana öyle geliyor ki, bu aslında ortaya çıkan problemin en etkili yanıtıdır, ki bu hiçbir zaman ağaç kullanımını belirtmez.

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.