Tüm döngüleri bulma


9

Sonlu bir setim var S, bir işlev f:SSve toplam sipariş < üzerinde S. Farklı döngülerin sayısını bulmak istiyorumS.

Belirli bir eleman için sS Floyd'un algoritmasını (veya Brent'in, vb.) f gönderir siçin; biraz daha fazla çaba ile bu döngüyü tanımlayabilirim (örn.<-minimal eleman). Sorunu çözmek için kötü bir yöntem, her bir öğeyi tekrarlamak, yinelenenleri atarak elde edilen minimal öğeleri sıralamak ve sayıyı döndürmek olacaktır. Ancak bu potansiyel olarak aynı elemanlar ve geniş alan gereksinimleri üzerinde birçok geçişi içerir.

Hangi yöntemler daha iyi zaman ve alan performansına sahiptir? Gerekli alanı ölçmenin en iyi yolunun ne olduğundan emin değilim - eğerf kimlik işlevidir, tüm döngüleri depolayan herhangi bir yöntem Ω(n) Uzay.


4
Alanı ölçmenin doğal yollarından biri, S'yi n-bit dizeleri kümesi ve f'yi bir kehanet olarak kabul etmektir. Sonra tarif ettiğiniz naif algoritma üstel alan gerektirir. Sadece polinom alanı kullanan bir algoritma aranabilir, ancak bu benim için mümkün görünmüyor.
Tsuyoshi Ito

"Alanı ölçmek için en iyi yolun ne olduğunu bilmiyorum" derdim. Muhtemelen y'nin çıktı olduğu O (poli (n) + y) 'yi hedeflemeliyim, böylece kullanılan alan y yeterince küçük olduğu sürece polinomdur.
Charles

F işlevinizin kullanılabilir özellikleri var mı? Eğer pratik cevap algoritmanın S'nin kardinalitesine göre hem zaman hem de alan alacağı yönündeyse, algoritmanın giriş boyutunu ifade etmenin tercih ettiğiniz şekilde polinom ya da üstel olup olmadığı biraz tartışmalıdır .
Niel de Beaudrap

@Niel de Beaudrap: Hangi özelliklerin yararlı olacağından emin değilim. Yine de, farklı döngülerin sayısının az olmasını bekliyorum.O(n3); bu yüzden bir işlev önerdimy ve n sadece yerine n. Gerekirse, çıktı bitlerinde boşluk üstel kullanmaya hazırım.
Charles

Yanıtlar:


7

Tüm yapmak istediğiniz döngü sayısını saymak, bunu 2 | S | bit (artı değişim) değer. S veya f özellikle uygun özelliklere sahip olmadıkça çok daha iyisini yapabilmeniz olası görünmemektedir .

Bir dizi A ile başlayarak {0,1,2} tamsayıları - S'nin her elemanı için bir tane - sıfıra başlatılmış; biz bu gösterecektir (unexplored), (partially explored)ve (fully explored). Bir döngü sayacını sıfırlayın. Her bir eleman için, s  ∈  S amacıyla, aşağıdaki işlemi:

  1. A [ s ] = ise  (fully explored), 6. adıma atlayın.
  2. A [ s ] ←  (partially explored)ayarlayın ve bir j yineleyici j  ←  f (s) ayarlayın .
  3. A [ j ] =  iken (unexplored), A [ j ] ← olarak  (partially explored)ayarlayın ve j  ←  f (j) olarak ayarlayın .
  4. A [ j ] = ise  (partially explored), yeni bir döngüyü kapattık; artım c 1. tarafından (bu döngünün bazı temsilcisi kaydını tutmak istiyorsanız, mevcut değeri j keyfi bir seçim olarak yapacak; tabii ki, bu mutlaka tercih altındaki döngüsünde minimal eleman olmayacak sipariş <.) Aksi takdirde, A [ j ] =  değerine sahibiz (fully explored), yani önceden sayılmış bir döngüde sona eren önceden araştırılmış bir yörünge keşfettik; arttırma c .
  5. S ile başlayan yörüngenin artık tamamen araştırıldığını belirtmek için j  ←  s ayarını yapın .
    A [ j ] =  (partially explored), A [ j ] ←  (fully explored)ve j  ←  f (j) olarak ayarlayın .
  6. Sonraki s  ∈  S öğesine ilerleyin .

Böylece, f tarafından indüklenen yörüngeler arasındaki her döngü bir kez sayılacaktır; ve temsilci olarak kaydettiğiniz öğeler farklı döngülerin öğeleri olacaktır. Bellek gereksinimleri 2 | S | dizi sayımı için A, O (log | S |) ve diğer olasılıklar ve sonlar için.

Her bir eleman s  ∈  S , iki kez, en azından ziyaret edilecektir: A değeri [bir kez yazılır s ] değiştirildiğinde (unexplored)için (partially explored)ve değişikliğin bir kez (fully explored). Herhangi bir düğümün, birleştirildikten sonra yeniden ziyaret edilme (fully explored)sayısı, yukarıda başarısız olan yeni döngüleri bulma girişimleriyle sınırlıdır, bu da en fazla | S | - S'nin tüm elemanları boyunca yinelenen ana döngüden kaynaklanır . Bu nedenle, bu sürecin en fazla 3 | S | düğüm geçişleri, düğümlerin ziyaret edildiği veya yeniden ziyaret edildiği her zaman sayılır.

Döngülerin temsili öğelerini takip etmek istiyorsanız ve bunların gerçekten minimal öğeler olmasını istiyorsanız, düğüm ziyaretlerinin sayısını 4 | S |, döngüyü kapattığınızdan daha küçük bir temsilci bulmak için adım 4'te ek bir "döngü etrafında tur" eklerseniz. ( F altındaki yörüngeler sadece döngülerden oluşuyorsa , bu ekstra işten kaçınılabilirdi, ancak bu keyfi f için doğru değil .)


Mükemmel, bu aptalca gelişir O(|S|log|S|)aklımda olan uzay algoritması. Aslında temsilcilere ihtiyacım yok; tanıttım<bazı algoritmalar için yararlı olması durumunda.
Charles

Polinom alanından daha fazla kullanmadan az sayıda toplam döngü olduğu durumda çok daha az alan kullanmanın bir yolu olup olmadığını merak ediyorum. Ah, önemli değil; bu benim ihtiyaçlarım için yapacak.
Charles

1
Bana öyle geliyor ki, bunun #L'de olması gerekir (matris gücünü kullanarak). Bu # L-zor olabilir mi?
Kaveh

@Charles: #cycles ∈ o ( | S | ) olduğunu biliyorsanız, size iyileştirmeler sağlayacak daha yeni cevabımı görün . Polilogdan daha fazlasını kullanır | S | Uzaydan ve zamandan takas yapmaya istekli iseniz, bu sizin için daha iyi olabilir.
Niel de Beaudrap

@Niel de Beaudrap: Teşekkürler! Her ikisi için +1. Bu algoritma, veriler belleğe sığdığı sürece en iyi şekilde görünür; dökülünce diğerini kullanmaya bakacağım. (Önbelleğe her şeyi sığdırabilirsem diğerinin daha iyi olması mümkündür, ancak bu çok fazla güçlük olabilir.)
Charles

5

Çok az sayıda döngünüz varsa, burada daha az yer kaplayan, ancak sonlandırılması oldukça uzun süren bir algoritma.

[Düzenle.] Önceki çalışma zamanı analizim, ziyaret ettiğimiz düğümlerin önceden örneklenmiş olanlar arasında olup olmadığının belirlenmesinin önemli maliyetini kaçırdı; bu cevap bunu düzeltmek için bir şekilde revize edilmiştir.

S'nin tüm unsurlarını tekrarlıyoruz . Biz elemanların yörüngelerini keşfettikçe s  ∈  S , biz onları tekrar rastlamak olmadığını kontrol edebilmek amacıyla, biz ziyaret ettik düğümlerden tadın. Ayrıca, daha önce ziyaret edilmiş olan ortak bir döngüde (ve dolayısıyla döngülere eşit olan) sona eren yörüngeler birlikleri olan 'bileşenlerden' bir örnek listesini tutarız.

Boş bir bileşen listesi başlatın complist,. Her bileşen, o bileşenden bir örnek koleksiyonu ile temsil edilir; samplesbazı bileşenler veya diğerleri için örnek olarak seçilen tüm öğeleri saklayan bir arama ağacı da sağlıyoruz. G'nin n'ye kadar bir tamsayı dizisi olmasına izin verin , bunun için üyelik bazı boole yüklemini hesaplayarak verimli bir şekilde belirlenebilir; örneğin, 2 veya mükemmel yetkileri s inci bir tam sayı için güçler p . Her s  ∈  S için aşağıdakileri yapın:

  1. Eğer ler ise samples, 5. adıma geçin.
  2. Boş bir liste cursample, yineleyici j  ← f ( s ) ve sayaç t  ← 1 başlatın .
  3. İken j değil samples:
    - Eğer t  ∈  G , insert j hem içine cursampleve samples.
    - t değerini artırın ve j  ←  f (j) ayarını yapın .
  4. J'nin olup olmadığını kontrol edin cursample. Değilse, daha önce keşfedilmiş bir bileşenle karşılaştık: j bileşenine ait olup olmadığını kontrol eder ve tüm öğelerini artırmak için ilgili cursampleöğeye complistekleriz. Aksi takdirde, mevcut yörüngedeki bir öğeyle yeniden karşılaştık, yani daha önce keşfedilen döngülerin herhangi bir temsilcisiyle karşılaşmadan en az bir kez bir döngüyü geçtik: cursampleyeni bulunan bir bileşenden örnek koleksiyonu olarak ekliyoruz complist.
  5. Sonraki s  ∈  S öğesine ilerleyin .

For n  = | S |, X (n) beklenen döngü sayısını ( ör.  X (n)n 1/3 ) açıklayan monoton arttırıcı bir fonksiyon olsun ve Y (n) = y (n)  log ( n ) ∈ Ω ( X (n)  log ( n )), bellek kullanımı için bir hedef belirleyen monoton arttırıcı bir fonksiyon olabilir ( örn.  Y (n)n 1/2 ). Y (n)  ∈ Ω ( X (n) ) gereklidir, çünkü her bileşenden bir örnek depolamak en az X (n)  günlük ( n ) alan gerektirir.

  • Bir yörüngenin ne kadar çok örneğini örneklersek, bir yörüngenin sonunda döngüde bir örneği hızlı bir şekilde seçme ve böylece bu döngüyü hızlı bir şekilde algılama olasılığımız o kadar artar. Bakış bir asimptotikler açısından, daha sonra Belleğimiz sınırları izin pek çok numune olarak elde etmek için mantıklı: biz de ayarlayabilir G , beklenen için y (n) ' den az olan öğeleri n .
    - bir yörünge maksimum uzunluğu ise S olması beklenmektedir L biz izin verebilir G tamsayı katları olacak L  /  y (n) .
    - Beklenen uzunluk yoksa, her n  /  y (n)elementler; bu her durumda örnekler arasındaki aralıklarda bir üst sınırdır.

  • Yeni bir bileşen ararken, daha önce ziyaret ettiğimiz S öğelerini ( keşfedilen yeni bir bileşenden veya terminal döngüsü zaten bulunan eski bir bileşenden) geçmeye başlarsak , en fazla n  /  y ( n) önceden örneklenmiş bir elemanla karşılaşma yinelemeleri; bu, o zamana kadar üst sınırdır, her bir yeni bileşen bulma girişimi için artık düğümleri geçiyoruz. Bu tür n denemeler yaptığımızdan, S öğelerini toplamda en fazla n 2  /  y (n) kez ziyaret edeceğiz .

  • Üyeliği test etmek için gereken iş , her ziyarette tekrarladığımız samplesO ( y (n)  log  y (n) ): bu kontrolün kümülatif maliyeti O ( n 2  log  y (n) ). Ayrıca, numuneleri kendi koleksiyonlarına, toplam O ( y (n)  log  y (n) ) olan toplama maliyeti de vardır . Son olarak, daha önce keşfedilen bir bileşenle her karşılaştığımızda, hangi bileşeni yeniden keşfettiğimizi belirlemek için X (n)  log *  y (n) zaman harcamalıyız ; bu n defaya kadar olabileceğinden , ilgili kümülatif çalışma nX (n)  log  y (n) ile sınırlıdır .

Bu nedenle, ziyaret ettiğimiz düğümlerin örnekler arasında olup olmadığını kontrol etmek için yapılan kümülatif çalışma, çalışma süresine hakimdir: bu, O ( n 2  log  y (n) ) maliyetidir . O zaman y (n) 'yi mümkün olduğunca küçük yapmalıyız , yani O ( X (n) ).

Böylece, O ( X (n)  log ( n )) uzayındaki O ( n 2  log  X (n) ) devir sayısı (bu devirlerde biten bileşen sayısıyla aynıdır ) sayılabilir. Bunu yapmak için gereken süre, burada X (n) beklenen döngü sayısıdır.


1

Bir birleşim kümesi veri yapısını kullanarak aynı öğelerin üzerinden birden fazla geçişten kaçınabilirsiniz . Her eleman için bir geçişs içeren seti birleştirme s set içeren f(s). Bu hala çok fazla bellek kullanıyor.

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.