aralığından çizilen kenar ağırlıkları için Dijkstra algoritmasını değiştirme


10

Menzildeyim çekilen kenar ağırlıkları ile bir çizge olduğunu varsayalım [1,,K] burada K sabittir. Dijkstra'nın algoritmasını kullanarak en kısa yolu bulmaya çalışıyorsam , algoritma / veri yapısını nasıl değiştirebilir ve için zaman karmaşıklığını nasıl geliştirebilirim O(|V|+|E|)?


Daha spesifik olmalısınız, Veri yapınız nedir? Ve daha az elde edemezsiniz O(V+E). Dersleri gözden geçirin.
jonaprieto

Belirgin kenar ağırlık olasılıklarının az olması mesafelerin az olduğu anlamına gelmez.
Joe

3
Grafiğinizin ilk renk köşeleri mavi ile, ardından boyutundaki her bir kenarı t kenarlarına tbölün ( t - 1 renksiz köşe ekleyerek ), ardından başlangıç ​​düğümünden mavi düğümlere en kısa yolları bulmak için bu yeni grafikte BFS'yi çalıştırın. O ( | V | + | E | ) Eğer sabit varsa k . tt1O(|V|+|E|)k

@SaeedAmiri bunu neden cevap olarak yazmıyorsunuz?
Joe

@Joe çünkü dijkstra değiştirmiyor (en azından doğrudan dijkstra ile ilgili değil).

Yanıtlar:


16

Kenar ağırlıkları da tamsayı ise , Dijkstra'ları @ rrenaud'un önerisini izleyerek O ( K | V | + | E | ) saatinde çalıştırabilirsiniz. İşte daha açık bir açıklama.{0,1,,K}O(K|V|+|E|)

Herhangi bir zamanda, öncelik kuyruğundaki (sonlu) tuşlar aralığındadır ; burada D , öncelik kuyruğundan kaldırılan son anahtarın değeridir. (Her anahtar en az D'dir , çünkü Dijkstra'nın algoritması tarafından kaldırılan anahtarların sırası azalmaz ve her anahtar en fazla D + K'dir , çünkü her anahtarın d [ u ] + w t ( u , w ) değeri vardır . biraz kenar ( u ,{D,D+1,,D+K}DDD+Kd[u]+wt(u,w) burada d [ u ] kaynaktankaldırılmışolan bir tepe noktasına u mesafedir, bu nedenle d [ u ] D. )(u,w)d[u]ud[u]D

Bu nedenle, öncelik sırasını , her hücre bir kova içerecek şekilde K + 1 boyutunda bir dairesel dizisiyle uygulayabilirsiniz . Her tepe noktasını k tuşu ile A [ h ( k ) ] hücresindeki ; burada . takip edin . İşlemleri aşağıdaki gibi yapın:A[0..K]K+1kA[h(k)]Dh(k)=kmod(K+1)D

  • delete-min : boşken, . Ardından öğesinden bir tepe noktasını silin ve döndürün .D A [ h ( D ) ]A[h(D)]DA[h(D)]

  • tuşu ile yerleştirin : Köşeyi kepçesine ekleyin .A [ h ( k ) ]kA[h(k)]

  • Anahtar azaltmak için :' den tepe taşı üzere .k A [ h ( k ) ] A [ h ( k ) ]kkA[h(k)]A[h(k)]

Ekle ve azaltma tuşu sabit zamanlı işlemlerdir, bu nedenle bu işlemlerde harcanan toplam süre . Delete-min'de harcanan toplam süre artı nin son değeri olacaktır . Nihai değeri (alır silme-min, çünkü herhangi bir tepe kaynaktan maksimum (sonlu) mesafedir artar yineleme ile ). Her yol en fazla kenarına sahip olduğundan , maksimum mesafe en fazla . Böylece, algoritma tarafından harcanan toplam süre .O ( | V | ) D D i D i K ( | V | - 1 ) | V | - 1 O ( K | V | + | E | )O(|V|+|E|)O(|V|)DDiDiK(|V|1)|V|1O(K|V|+|E|)


Dairesel kuyruğu seviyorum, bu temelde herhangi bir zamanda sadece av boyutlu dilim kullanılan bir K * v boyutu dizisine sahip olmak benim fikrimden daha iyi.
rrenaud

Bunu çift bağlantılı bir liste kullanarak uyguladım, bu hala min anahtarını bulmak için O (1) olduğu anlamına mı geliyor?
user1675999

@ user1675999, emin değilim. listeniz anahtarlara göre sıralandıysa, ekleme ve azaltma anahtarını nasıl verimli bir şekilde kullanırsınız? listeniz anahtarla sıralanmamışsa delete-min'i nasıl verimli bir şekilde yapabilirsiniz?
Neal Young

5

Burada bir tam sayı olduğunu ve kenar ağırlıklarının ayrılmaz olduğunu varsayıyorum . Aksi takdirde size gerçekten bir şey satın almaz, her zaman ağırlıkları yeniden ölçeklendirebilirsiniz, böylece min kenarın maliyeti ve maksimumun maliyeti vardır , bu nedenle sorun standart en kısa yol problemiyle aynıdır.1 KK1K

Algoritma / kanıt çizimi: Öncelik kuyruğunu dizisi olarak bu tür çılgın bir şekilde uygulayınmaliyete göre anahtarlanır ve standart Dijkstra algoritmasını kullanır. Öbekteki minimum öğenin maliyetini izleyen bir sayaç tutun. Öğeler doğrusal tarama ile silindikten sonra dequeue çağrısını çözün . Evet, bu tür sesler çılgınca, ama sabit , algoritmik sezginizi lineer taramalara karşı kandırmanıza ve kandırmanıza izin verir. Disjkstra'nın algoritması kuyruk uygulamanız için iyi olduğundan, yalnızca son dakika işaretleyicisinden taramanız gerekir. Bir dequeue istediğinde, kuyruğa eklenen öğeler her zaman bir önceki minimum değere eşit veya daha büyüktür. Mümkün olan en kısa yolun uzunluğuK K × | V | K × | V | = O ( | V | )K×|V|KK×|V|, bu nedenle amortismana tabi tarama maliyetinizK sabit ise .K×|V|=O(|V|)


-2

çözümü bulmak için topolojik sıralama kullanabilir, kaynağın 0 derecesine sahip olmasına izin verin, sonra kaynağın her kenarından gidin, başka bir tepe noktası 0 dereceye sahipse kuyruğa koyun ve bunu yapmaya devam edin. bu durumda (grafik içinde döngü olmadan), her köşe ve kenardan bir ve sadece bir kez geçeceği için V + E'ye ulaşabilir.


Soru ile ilgisi yok mu? Soru, grafiğin döngüsel olmadığını varsayar ve çözümünüz, ağırlıkların sabit bir aralıktan çekildiği gerçeğinden faydalanmaz.
xskxzr
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.