Yönlendirilmiş bir asiklik grafiğin geçişli kapanışını almak için etkili algoritma


14

Bir grafik problemini çözmeye çalışıyorum (ödev için değil, sadece becerilerimi uygulamak için). Bir DAG verilir, burada , köşe kümesidir ve kenarlardır. Böylece grafik, bir bitişiklik listesi olarak temsil edilir tüm bağlantılarını ihtiva eden bir dizi . Benim görevim v'de her köşe den hangi köşe noktalarına erişilebildiğini bulmak . Kullandığım çözüm , geçişli kapanışla karmaşıklığına sahiptir , ancak bir blogda nasıl olduğunu açıklamamasına rağmen daha hızlı olabileceğini okudum. Birisi bana bir DAG'da geçişli kapatma problemini çözmenin başka bir yolunu (daha iyi karmaşıklıkla) söyleyebilir mi?V E A v v v V O ( V 3 )G(V,E)VEAvvvVO(V3)




Ancak, benim önerim tutmaktır . ancak ortalama olarak karşılaştırma sayısını azaltmaya çalışın. Yani, tahminler yapın ve algoritmanıza basit kurallar ekleyin. Matris çarpımını kullanabilirsiniz - ancak bunu küçük grafikler için kullanıyorsanız - o zaman bu sadece bir karışıklıktır ve aslında pratikte yönteminiz daha iyidir. O(|V|3)
AJ

@AJed Bu özel problemde, zaman sınırını aşacaktır. O(V3)
Rontogiannis Aristofanis

2
@RondogiannisAristophanes Zaman sınırı dediğinizde, bunun topcoder vb. Gibi bazı programlama / algoritma zorluklarında bir sorun olduğu anlamına mı geliyor? Öyleyse ve bir çözümünü doğru bir şekilde uyguladığınızdan eminseniz , soruna tekrar bakmak isteyebilirsiniz. Bazı şeyleri basitleştirebilecek başka gizli özellikler olabilir veya geçişi kapatmaya gerek kalmaması için sorunu ifade etmenin daha iyi bir yolu olabilir. Çünkü geçişli kapanma matris çarpımı kadar zordur. Okuma student.cs.uwaterloo.ca/~cs466/Old_courses/F08/...O(V3)
Paresh

Yanıtlar:


8

Grafiğimizin döngüsel olmaması bu sorunu çok daha basit hale getiriyor.

Topolojik sıralama bize köşe bir düzenlenmesidir verebilir böyle, eğer , o zaman hiçbir kenar yoktur için arka . Köşeleri, listedeki tüm kenarların "ileri" gideceği şekilde listeledik.v1,v2,,vni<jvjvi

(analizi düzeltmek ve biraz daha hızlı algoritma vermek için düzenlenmiştir)

Şimdi son köşesinden başlayarak bu listede geriye doğru . geçişli kapanışı sadece kendisidir. Ayrıca kenarına sahip her köşenin geçişli kapanışına .vnvnvnvn

Birbirinden köşesi, geriye doğru, önce kendi geçişli kapanışına ekleyin , sonra geçişli kapanışındaki her şeyi tüm köşelerin geçişli kapanışına .vivivivi

Çalışma süresi en kötü durumda , köşe noktası sayısı ve kenar sayısıdır. Topolojik sıralama zaman alır . Sonra geriye doğru geçişte başka bir çalışması yaparız: Listede geriye doğru giderken, her kenar için birisinin geçişli kapanışına kadar köşe eklememiz gerekir .n m O ( n 2 ) O ( n + m ) O ( m n ) nO(n+m+nm)=O(n3)nmO(n2)O(n+m)O(mn)n

Bit dizileriyle herkesin geçişli kapanışını temsil ederek güzel bir sabit faktör hızlandırması yapabileceğinizi unutmayın. Diyelim ki sadece ; o zaman bit tek 64 bit int kullanırsınız ise 1'dir yoksa benim Geçişli kapatılması ve 0 içindedir. Sonra 's geçiş kapanış ' s her şeyi eklemek parçası gerçekten hızlı: Biz sadece | = . (İkili VEYA işlem.)i i i j c j c in=64iiijcjci

İçin , Diziden tutmak ve bazı aritmetik yapmak zorunda istiyorum, ama çok daha hızlı bir nesne kümesi daha olurdu.n>64

Ayrıca, en kötü durumda big- hala olduğunu biliyorum , ancak pratikte bunu yenmek için çok daha karmaşık bir şeye sahip olmanız gerekir. Bu algoritma seyrek grafiklerde de çok başarılı.O ( n 3 )OO(n3)


1
Kümeler için büyük olasılıkla bağlantılı bir liste gösterimi kullanabilirsiniz ve bunlar ortak kuyrukları paylaşır.
Kyle Butt
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.