Basit yolların sayısı bulur algoritması


34

G=(V,E)ststG
tstdolayısıyla, tüm diğer yolun alt yol ise o zaman da DFS biz gelen yollarının sayısını bulmalıyız bitişiklik listesi düşünün örneğin again.For bu alt yolun geçtiği için . Burada DFS, ile başlayacaktır ve sonra ile başlayacağını söyleyecektir, çünkü DFS normal şekilde çalışacaktır. yol çünkü karşılaştığımızda köşelerin rengini değiştirmeyiz, .v p o'in s z o r s v s r r y y v v w zpv
ppzvPsryvvs,r,y,vsov

poszorsvsrryyvvwzwz
ppzvpsryvvs,r,y,vpov rengi yana yolu white.Then hala rengi yana , beyaz ve benzer bir yol içinde bir sayaç .Ayrıca artırılır olsun ki korunur karşılaşılmaktadır.p o'in s r y v s s o r y v vvposryvsporyvv

Algoritmam doğru mu? Aksi takdirde, doğru yapmak için hangi değişikliklerin yapılması gerektiğini, aksi takdirde diğer yaklaşımları takdir edersiniz.

Not : Burada, "Cormen tarafından algoritmalara giriş" başlıklı kitapta verilen DFS algoritmasını , durumlarına göre düğümleri renklendirdiği düşünmüştüm. Yani eğer düğüm görünmezse, keşfedilmemiş ve araştırılmışsa, renk beyaz olacaktır. sırasıyla gri ve siyah. Diğer her şey standart.



4
Yönlendirilmiş bir asiklik grafikteki tüm yolların mutlaka ( asiklik nedeniyle) basit olduğunu unutmayın .
Noldorin

Yanıtlar:


37

Mevcut uygulamanız bir DAG'deki doğru sayıda yolu hesaplayacaktır. Ancak, yolları işaretlemeyerek üssel zaman alacaktır. Örneğin, aşağıdaki çizimde, DAG'nin her aşaması toplam yol sayısını 3 katına çıkarır. Bu üssel büyüme dinamik programlama ile gerçekleştirilebilir.

dag

Bir DAG'deki - yollarının sayısının tekrarı, yineleme tarafından verilir, t Yollar ( u ) = { 1 ise  U = t Σ ( u , v ) e Yollar ( v ) , aksi takdirde.st

Paths(u)={1if u=t(u,v)EPaths(v)otherwise.

DFS'de yapılan basit bir değişiklik bunu aşağıdaki gibi hesaplayacaktır.

def dfs(u, t):
    if u == t:
        return 1
    else:
        if not u.npaths:
            # assume sum returns 0 if u has no children
            u.npaths = sum(dfs(c, t) for c in u.children)
        return u.npaths

Her kenarın sadece bir defa bakıldığını görmek zor değildir, bu nedenle çalışma zamanıdır .O(V+E)


Algoritmanızı anladım ve dinamik programlama kullanarak biraz daha verimli hale getirilebildiğinden, aynı özyinelemeli çağrılar birçok kez çağrılıyor, bu nedenle kaydetmek daha iyi.
Saurabh

1
@ SaurabhHota, dinamik programlama kullanıyor. Tepe ilk karşılaşıldığında, bu yollar sayısını hesaplar bu zorundadır . Bu, USpaths içinde saklanır. Sonraki her çağrısı , yol sayısını yeniden hesaplamaz, ancak u.npath'leri döndürür. t uutu
Nicholas Mancuso

1
Bu tür grafikler için, cevap sadece m ^ n değildir; burada m, bir sütundaki düğüm sayısıdır (burada 3) ve n, s, t (burada 4 hariç) sütun sayısıdır. Örnek grafik için çıktı 3 ^ 4 = 81'dir.
saadtaame

@saadtaame, elbette; Ancak, niyetim sadece bir grafiğin "uzunluğu" büyüdükçe üssel artışı göstermek. Tabii ki yüksek derecede yapılandırılmış bu grafik için kapalı formda sayılabilir, ancak listelenen algoritma tüm grafikler için çalışır.
Nicholas Mancuso

3
çalışma süresi sabit zamanda gerekli ilaveler yapabilir varsayar, ancak sayı olabilir eklenen en kötü durumda bit. Tam yol sayısını istiyorsanız, çalışma süresi (bit işlemlerini sayma) aslında . Θ ( V ) O ( V e )O(V+E)Θ(V)O(VE)
JeffE

15

Yalnızca bir düğümden hedef düğüme giden yol sayısının, çocuklarından hedefe giden yol sayısının toplamı olduğunu fark etmeniz gerekir. Bu algoritmanın her zaman duracağını biliyorsunuz çünkü grafiğinizde herhangi bir döngü yok.

Şimdi, düğümleri ziyaret ederken bir düğümden hedefe giden yol sayısını kaydederseniz, zaman karmaşıklığı tepe sayısında doğrusal olur ve düğüm sayısında doğrusal doğrusal olur.


0

Bir DAG'deki herhangi iki köşe arasındaki yol sayısı, bitişik matris gösterimi kullanılarak bulunabilir.

A'nın G'nin bitişik matrisi olduğunu varsayalım. Buna, kimlik matrisi ekledikten sonra A'nın Kth gücünü alarak, uzunluğu <= K olan yol sayısını verir.

Bir DAG içerisindeki herhangi bir basit yolun maksimum uzunluğu | V | -1 olduğundan, | V | -1. Gücünün hesaplanması tüm köşe çiftleri arasında yol sayısını gösterir.

Her bir TC: | V | ^ 2 log (| V | -1) muliplication yapılarak | V | -1 th gücü hesaplanabilir.


Soru doğrusal bir zaman algoritması için sorar. Algoritmanız bundan daha yavaş.
DW

@Vivek, cevabınızdaki teoremler için bir referanstan bahsedebilir misiniz?
Hamideh
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.