A * yol bulma çalışmalarının nasıl yürüdüğünü temel düzeyde anlamak istiyorum. Herhangi bir kod veya psuedo kodu uygulamaları ve görselleştirmeler yararlı olacaktır.
A * yol bulma çalışmalarının nasıl yürüdüğünü temel düzeyde anlamak istiyorum. Herhangi bir kod veya psuedo kodu uygulamaları ve görselleştirmeler yararlı olacaktır.
Yanıtlar:
İnternette bulunabilecek A * kod örnekleri ve açıklamaları vardır. Bu soru aynı zamanda birçok faydalı bağlantı içeren birçok harika yanıt aldı. Cevabımda, koddan veya tanımlardan daha kolay anlaşılması için algoritmanın resimli bir örneğini sunmaya çalışacağım.
A'yı anlamak için, öncelikle Dijkstra'nın algoritmasına bir göz atmanızı öneririm . Dijkstra'nın algoritmasının bir arama için gerçekleştireceği adımlar konusunda size rehberlik etmeme izin verin.
Bizim başlangıç düğümümüz, A
en kısa yolu bulmak istiyoruz F
. Grafiğin her kenarı, kendisiyle ilişkili bir hareket maliyetine sahiptir (kenarların yanında siyah rakam olarak belirtilmiştir). Amacımız, hedef düğümümüze ulaşana kadar grafiğin her bir tepe noktası (veya düğümü) için minimum seyahat maliyetini değerlendirmektir.
Bu bizim başlangıç noktamız. İncelenecek bir liste düğümümüz var, bu liste şu anda:
{ A(0) }
A
bir bedeli varsa 0
, diğer tüm düğümler sonsuzluğa ayarlanır (tipik bir uygulamada bu, bunun gibi int.MAX_VALUE
veya benzeri bir şey olur ).
Düğüm listemizden en düşük maliyete sahip düğümü alırız (listemiz yalnızca içerdiğinden A
, bu bizim adayımızdır) ve tüm komşularını ziyaret ederiz. Her komşunun ücretini şu şekilde belirledik :
Cost_of_Edge + Cost_of_previous_Node
ve önceki düğümün kaydını tutun (düğümün altında küçük pembe harf ile gösterilir). A
şimdi çözüldü (kırmızı) olarak işaretlenebilir, böylece onu tekrar ziyaret etmeyiz. Aday listemiz şunun gibi görünüyor:
{ B(2), D(3), C(4) }
Yine listeden ( B
) en düşük maliyetli düğümü alıyoruz ve komşularını değerlendiriyoruz. Bu yol D
şu anki maliyetinden daha pahalıdır D
, bu nedenle bu yol atılabilir. E
şimdi buna benzeyen aday listemize eklenecek:
{ D(3), C(4), E(4) }
İncelenecek bir sonraki düğüm şimdi D
. C
Yol mevcut maliyetten daha kısa olmadığından bağlantı kesilebilir . Yine de daha kısa bir yol bulduk E
, dolayısıyla maliyeti E
ve önceki düğümü güncellenecek. Listemiz şimdi şöyle görünüyor:
{ E(3), C(4) }
Daha önce yaptığımız gibi, şu anda olan listemizdeki en düşük maliyetli düğümü inceliyoruz E
. E
sadece bir tane çözülmemiş komşusu vardır, ki bu aynı zamanda hedef düğümdür. Hedef düğüme ulaşma maliyeti 10
ve önceki düğümü olarak belirlenir E
. Aday listemiz şunun gibi görünüyor:
{ C(4), F(10) }
Daha sonra inceleyeceğiz C
. İçin maliyeti ve önceki düğümü güncelleyebiliriz F
. Listemiz şimdi F
en düşük maliyetli düğüme sahip olduğundan, işimiz bitti. Yolumuz önceki en kısa düğümleri geri alarak oluşturulabilir.
Öyleyse neden A * algoritması yerine Dijkstra'yı size anlattığımı merak ediyor olabilirsiniz ? Eh, tek fark, adaylarınızı nasıl tartıştığınız (veya sıraladığınız). Dijkstra ile bu:
Cost_of_Edge + Cost_of_previous_Node
A * ile:
Cost_of_Edge + Cost_of_previous_Node + Estimated_Cost_to_reach_Target_from(Node)
Nerede Estimated_Cost_to_reach_Target_from
yaygın bir denir Sezgisel fonksiyon. Bu, hedef düğüme ulaşmanın maliyetini tahmin etmeye çalışacak bir fonksiyondur. İyi bir sezgisel işlev, hedefi bulmak için daha az düğümün ziyaret edilmesi gerekecek. Dijkstra'nın algoritması tüm taraflara yayılırken, A * (sezgisel tarama sayesinde) hedef yönünde arama yapar.
Amit'in buluşsal araştırma hakkındaki sayfası , genel buluşsal araştırma üzerine iyi bir genel bakışa sahiptir.
A * yol bulma, ek bir sezgisel tarama kullanan en iyi ilk arama türüdür.
Yapmanız gereken ilk şey, arama alanınızı bölmektir. Bu açıklama için harita kare bir kiremit ızgarasıdır, çünkü çoğu 2B oyun bir kiremit ızgarası kullanır ve çünkü görselleştirilmesi kolaydır. Ancak, arama alanının istediğiniz şekilde ayrılabileceğine dikkat edin: belki bir altıgen ızgara, hatta Risk gibi rasgele şekiller. Çeşitli harita konumlarına "düğümler" denir ve bu algoritma, geçiş yapmak için bir demet düğümünüz olduğunda ve düğümler arasındaki bağlantıları tanımladığınızda çalışacaktır.
Neyse, belirli bir başlangıç döşemesinden başlayarak:
Başlangıç döşemesinin etrafındaki 8 döşeme, a) mevcut döşemeden bir sonraki döşemeye geçme maliyetine (genellikle yatay veya dikey hareketler için 1, çapraz hareket için sqrt (2)) dayalı olarak puanlanır.
Her karoya daha sonra ek bir "sezgisel" puan atanır - her karoya hareket etmenin görece değerinin yaklaşık bir değeri. Farklı buluşsal yöntemler kullanılır, en basit olanı belirtilen karo merkezleriyle son karo merkezleri arasındaki düz çizgi mesafesidir.
Mevcut döşeme daha sonra "kapatılır" ve ajan açık olan komşu karoya hareket eder, en düşük hareket puanı ve en düşük sezgisel puanı vardır.
Bu işlem, hedef düğüme ulaşılana kadar tekrar edilir veya başka açık düğüm yoktur (aracının engellendiği anlamına gelir).
Bu adımları gösteren diyagramlar için bu iyi başlangıç öğreticisine bakın .
Başta buluşsal bulguyu geliştirmede yapılabilecek bazı iyileştirmeler var:
Arazi farklılıkları, pürüzlülük, diklik vb.
Haritanın verimli yollar olmayan alanlarını engellemek için ızgara boyunca bir "tarama" yapmak da bazen yararlı olabilir: örneğin araca bakan bir U şekli. Bir süpürme testi olmadan, ajan önce U'ya girer, arkanı dönüp sonra U'nun kenarına gider ve gider. "Gerçek" bir akıllı ajan, U şeklindeki tuzağı not eder ve basitçe bundan kaçınırdı. Süpürme, bunun benzetimine yardımcı olabilir.
En iyisi olmaktan uzak, ancak bu birkaç yıl önce C ++ ' da A *' da yaptığım bir uygulama .
Algoritmanın tamamını açıklamaya çalışmak yerine, sizi kaynaklara yöneltmem daha iyi olur. Ayrıca, wiki makalesini okurken, demo ile oynayın ve nasıl çalıştığını görselleştirip göremediğinizi görün. Belirli bir sorunuz varsa yorum bırakın.
ActiveTut'un Yol Bulma ile ilgili makalesini yararlı bulabilirsiniz. Hem A * hem de Dijkstra'nın Algoritması ile aralarındaki farkların üzerinden geçer. Flash geliştiricilerine yöneliktir, ancak Flash kullanmasanız bile teori hakkında iyi bir fikir vermelidir.
A * ve Dijkstra'nın Algoritması ile uğraşırken görselleştirmesi gereken önemli bir şey, A * 'nın yönlendirilmesidir; hangi yöne bakılacağını "tahmin ederek" belirli bir noktaya giden en kısa yolu bulmaya çalışır. Dijkstra's Algoritması, her / noktaya en kısa yolu bulur.
Dolayısıyla, ilk ifade olarak, A * kalbinde bir grafik keşif algoritmasıdır. Genellikle oyunlarda, fayans veya diğer dünya geometrisini grafik olarak kullanırız, ancak A * 'ı başka şeyler için kullanabilirsiniz. Grafik geçişi için iki ur algoritması derinlik ilk arama ve genişlik ilk aramadır. DFS'de, geçerli düğümün kardeşlerine bakmadan önce daima geçerli dalınızı tamamen keşfedersiniz ve BFS'de daima önce çocuklara, sonra kardeşlere bakarsınız. A *, istediğiniz hedefe yaklaştığınızda bir daldan aşağıya (DFS gibi daha fazla) keşfettiğinizde, aralarında daha iyi sonuçlar doğuracaksa, bazen bir kardeşi durdurmaya ve denemeye çalışırken aralarında bir orta yol bulmaya çalışır. Gerçek matematik, her birinin bir "iyiliğe" sahip olduğu bir sonraki bölgeyi keşfetmek için olası düğümlerin bir listesini tutmanızdır. puan (ne kadar soyut bir anlamda) hedefe ne kadar yakın olduğunu belirten puan, düşük puanların daha iyi olması (0, hedefi bulduğunuz anlamına gelir). Skorun minimumunu artı kökten uzakta bulunan düğüm sayısını (genellikle mevcut konfigürasyon veya yol bulmadaki mevcut konumdur) bularak hangisinin kullanılacağını seçersiniz. Bir düğümü her keşfettiğinizde, tüm çocuklarını bu listeye ekler ve sonra yenisini seçersiniz.
Soyut bir düzeyde, A * şöyle çalışır: