DFS, ağırlıksız grafiklerde en kısa yolları bulmak için neden kullanılamıyor?


16

DFS'yi "olduğu gibi" kullanmanın, ağırlıksız bir grafikte en kısa yolu bulamayacağını anlıyorum.

Ama neden DFS, ağırlıksız grafiklerde en kısa yolları bulmasına izin vermek için bu kadar umutsuz bir olasılık? Konuyla ilgili tüm metinler bunun yapılamayacağını belirtir. İkna olmadım (kendim denemeden).

DFS'nin ağırlıksız grafiklerde en kısa yolları bulmasına izin verecek herhangi bir değişiklik biliyor musunuz? Değilse, algoritmayı bu kadar zorlaştıran şey nedir?


1
Ağırlıksız grafiklerde en yaygın yol bulma algoritması A * 'dır ve bağların bitişe daha yakın kırıldığı küçük bir değişiklikle. Bu, DFS'ye benzer bir algoritma verecektir, çünkü önce en doğrudan rotayı deneyecek ve sadece gerekiyorsa dışarıya doğru patlayacaktır.
BlueRaja - Dany Pflughoeft

1
Bazı (iyi seçilmiş) grafiklerde DFS kullanmayı deneyin; eğer gerçekten işe yaramazsa sorunlarla karşılaşmalısınız. Btw, sorunuz ağırlıklı grafikler üzerinde çalışıyormuş gibi okuyor.
Raphael

Evet, bunu yapabilirsin. İşte çözüm
Anmol Middha

Yanıtlar:


12

Önce derinlemesine arama yaptığınız tek öğe çocukların araştırılma sırasıdır. Normal versiyon keyfi sırayla, yani çocukların saklandığı sırayla ilerler.

Gelebileceğim tek alternatif (en kısa yollara doğru) açgözlü bir yaklaşım, çocuklara mevcut düğümden (küçükten büyüğe) mesafelerine göre bakıyor. Bu kural için bir karşı örnek oluşturmak kolaydır:

açgözlü kural için karşı örnek
[ kaynak ]

Şimdi, DFS'nin en kısa yolları bulmasını sağlayacak araştırılacak bir sonraki çocuğu seçme stratejisi olmadığının kanıtı yok.

Bununla birlikte, kural ne olursa olsun - açgözlü kural için yaptığım gibi, DFS'nin ilk düğümde uzun bir sapma işlemesi olan grafikler oluşturabilirsiniz. Atama kenarları ve ( s , bir ) kural seçer ziyaret etmek için ağırlıklar örneğin bir birinci ve ata ( a , b )(s,t)(s,bir)bir(bir,b) bir daha büyük bir ağırlık daha büyük . Bu nedenle, DFS'nin asla en kısa yolları bulamaması mantıklıdır (genel grafiklerde).(s,t)

Her (pozitif-tamsayı-) ağırlıklı grafiği ağırlıksız grafik olarak ifade edebildiğiniz için - kenarları maliyet ile c - 1 düğümlü bir zincirle değiştirmeniz yeterlidir - aynı örnekler ağırlıksız grafiklerde DFS ile ilgilidir. Burada durum daha da kasvetli: ağırlıklar olmadan, DFS ziyaret edilecek bir sonraki çocuğu belirlemek için ne kullanabilir?cc-1


  1. Kural belirleyici olduğu sürece. Değilse, her zaman en kısa yolları bulamaz.

Yanılıyorsam beni düzeltin, ancak bu DFS'nin herhangi bir grafikteki en kısa yolu bulabileceği, ancak bunu yaparken üstel zaman alacağı anlamına mı geliyor?
Anmol Singh Jaggi

DFS hiç bir yol bulamıyor.
Raphael

10

Genişlik -ilk arama, ağırlıksız bir grafikte en kısa yolları bulan algoritmadır.

DFS'den ağırlıksız bir grafikte en kısa yolları bulan bir algoritmaya ulaşmak için basit bir değişiklik var. Esasen, DFS tarafından kullanılan yığını bir kuyrukla değiştirirsiniz. Ancak, ortaya çıkan algoritmaya artık DFS adı verilmez. Bunun yerine, genişlik ilk arama uygulayacaksınız.

Yukarıdaki paragraf doğru sezgiyi verir, ancak durumu biraz basitleştirir. Basit takasın genişlik ilk aramanın bir uygulamasını verdiği kodu yazmak kolaydır, ancak ilk başta doğru bir uygulamaya benzeyen ancak aslında olmayan bir kod yazmak da kolaydır. BFS ve DFS hakkında ilgili cs.SE sorusunu burada bulabilirsiniz . Burada bazı güzel sahte kodlar bulabilirsiniz.


3

Yapabilirsin!!!

Derinliğe giderken düğümleri ziyaret edilmiş olarak işaretleyin ve geri döndüğünüzde işaretini kaldırın, aynı şekilde başka bir şube (şube) bulduğunuzda geri dönün.

Hedef düğümü bulduğunuz tüm olası aramalar için maliyeti / yolu kaydedin, tüm bu maliyetleri / yolu karşılaştırın ve en kısa olanı seçin.

Bu yaklaşımla ilgili büyük (ve BÜYÜK demek) sorun, aynı düğümü birden çok kez ziyaret edeceğinizdir, bu da dfs'yi en kısa yol algoritması için bariz bir kötü seçim haline getirir.


1
st

1
@ user2407394 Bu DFS varyasyonunu bir kez uyguladınız ve orta derecede büyük bir grafik için doğru şekilde çalıştırdınız mı? Bu varyasyonu DFS olarak adlandırmaktan çekinirim. Buna derinlik-ilk yol yorucu arama derim.
John L.

Bu tür bir yaklaşım uyguladım, gerçekten yavaş çalışıyor. Performansı artırmak için anımsatıcı eklemeyi düşünüyorum.
Mic

@ user2407394 işe yaradığı anlaşılıyor, ancak hepsinin işaretini kaldırırsanız 'ziyaret edilen' liste olmayacağından ne zaman duracağınızı nasıl kontrol edersiniz?
Joe Black

0

BFS, kökten tüm kenarları kontrol edeceği ve kökten diğer düğümlere olan mesafeyi olabildiğince az tutacağı hoş bir özelliğe sahiptir, ancak dfs sadece ilk bitişik düğüme atlar ve derinlik akıllıca gider. En kısa yolu elde etmek için DFS'yi değiştirebilirsiniz, ancak yalnızca daha yüksek karmaşıklığa sahip bir algoritma elde edersiniz veya BFS'nin yaptığı aynı şeyi yaparsınız.


-3

DFS kullanarak minimum kenar sayısına sahip iki köşe arasındaki yolu bulmak mümkündür. seviye yaklaşımı uygulayabiliriz


2
Lütfen daha fazla ayrıntı verin. Bu tek cümlede hangi algoritmayı tanımlamaya çalıştığınızı söyleyemem.
David Richerby

-3

Yapabilirsin

sadece grafiği dfs biçiminde hareket ettirin ve kontrol edin

if(distance[dest] > distance[source]+cost[source_to_destination]){
    distance[dest] = distance[source] + cost[source_to_destination]);
}

İşte tam çözüm için bağlantı


1
Kabul edilen cevap, bunun mümkün olmadığını iddia ediyor ve bu da talebinizle çelişiyor. Yine de bu yaklaşımın işe yaradığını düşündüğünüzü açıklayabilir misiniz? (veya bu yaklaşımın neden genel olarak işe yaradığını açıklayın)
Ayrık kertenkele

Bu sadece bir açıklama yerine user2407394'ün yanıtı , anlaşılması zor kodla ( bu değişkenlerden herhangi birinin ne anlama geldiğini tanımladınız ve benim için açık değil) yanıtı değil mi?
David Richerby

Evet, user2407394'ün cevabının uygulanmasıdır. Rahatsızlık için üzgünüm. Kodda yorum ekledim. Şimdi kontrol edebilirsiniz.
Anmol Middha
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.