Yol bulmada durumsal farkındalık


11

Örneğin, kilitli kapılar ve anahtarlar gibi belirli öğeler toplandıktan sonra belirli pasajların size açıldığı bir zindandaki en kısa yolu bulmanız gerektiğini varsayın.

"En kısa yol" kelimelerine verilen normal bağırsak reaksiyonu açıkça A * olacaktır. Ancak A * böyle bir ortamda başarısız olur, çünkü güvenilir bir buluşsal yöntem tanımlayan birçok sorun görüyorum ve ayrıca bir düğümün birden çok kez ziyaret edilmesi gerekiyor, bu da geleneksel A * 'da mümkün değil ve aynı zamanda buluşsallaştırmayı zorlaştırır.

Düşündüğüm sadece zindanın başından sonuna kadar bir yol aramak ve engellenmiş kapıları görmezden gelmek. Bu yol bulunduktan sonra, yolumuzu engelleyen her bir kapı için, kapıya ulaşılmadan önce uygun anahtarı ve kapıya geri dönecek ek bir yol aranacak ve geçilecektir. Aynı sistem, bir kapıyı açmak için gereken bir anahtara giden yolun, ilk önce açılması gereken başka bir kapı tarafından tekrar engellendiği bir durumu ele almak için kullanılır.

Çözümümle ilgili gördüğüm büyük bir sorun, madde edinimi için olanlar da dahil olmak üzere tüm yollar bulunduktan sonra, acente tarafından gidilen toplam mesafenin mümkün olan en küçük olmayabilir, çünkü hedeften daha uzak olan başka engellenmiş kapılar olabilir ancak uygun anahtarları çok daha kolay erişilebilir hale getirin. A *, engellenen kapıların göz ardı edildiği ilk geçişte bu kapıları ihmal ederdi.

Eminim bunu çözmeye çalışan ilk kişi ben değilim ve sorunla ilgili bazı girdileri takdir ediyorum.


A * 'nın ne kadar düzenli uygulandığını bilmiyorum, ancak çeşitli yollara sahip bir uygulamanın "ağırlık" ölçeğine sahip olduğunu gördüm, bu da çeşitli yolların ne kadar çekici olduğunu değiştirecektir. Olası tüm yolları hesaplayıp kilitli bir kapıyı pozitif sonsuzluğa geçen yolların "ağırlığını" ayarlayamadınız mı? Bu, o yolun sonsuza kadar uzun görünmesine neden olur ve bu nedenle asla kullanılmaz. Bu, elbette, her bir varlık için her güncelleme için yolları önceden hesaplamak yerine geçerliyse geçerlidir.
William Mariager

Cevabınız için teşekkürler, ancak unutduğunuz şey, bir kapının kilidini açmanın hedef düğüme giden tek yol olabileceğidir, bu durumda bahsettiğiniz algoritma bir yol bulamaz. Veya, engellenen yolun ağırlığı sadece sonsuzsa, engellenen yollardan birini seçer ve orijinal sorunumdan önce kalır.
Marc Müller

Yanıtlar:


8

Basit bir A * kullanarak böyle bir durumu en iyi şekilde ele almanın yolu arama alanını genişletmektir. Yani, karakterinizin taşıyabileceği her bir eşya kombinasyonu için zindanın ayrı bir kopyası olduğunu düşünün.

Zindanın her bir kopyasında, geçilebilen kapılar tam olarak karşılık gelen öğeler kümesi kullanılarak geçirilebilen kapılardır. Bir zindan kopyasından diğerine geçmenin tek yolu bir öğenin bulunduğu yerde durup onu almaktır.

Bu numarayı, kapıları açabilen ve / veya kapatabilen anahtarlar gibi diğer durum değişikliklerini içerecek şekilde genişletebilirsiniz. Oyuncunun eşyaları düşürmesine bile izin verebilirsiniz, ancak durum daha sonra her bırakılan öğenin konumunu içermesi ve potansiyel arama alanını büyük ölçüde artırması nedeniyle karmaşıklaşabilir.

Çok yararlı bir optimizasyon, tüm kapıların kilitli olduğu varsayılarak, her bir kapıdan (aslında her bir kapının her iki yanından) ve diğer erişilebilir kapı / öğelere en kısa yolları önceden hesaplamaktır . Bu yolları bulduktan sonra, bu önemli yerleri birbirine bağlayan bir grafikte her birini ağırlıklı bir kenar olarak ele alabilir ve diğer tüm konumları göz ardı edebilirsiniz.

Örneğin, zindanınızda on kapı ve beş anahtar olduğunu varsayın. Ardından, tam arama alanında toplam 25 * 32 = 800 düğüm için 2 * 10 + 5 = 25 önemli yer ve 2 ^ 5 = 32 olası öğe kombinasyonu olacaktır. Bu, özellikle arama alanının çoğuna ulaşılamayacağı düşünüldüğünde çok mütevazı bir sayıdır.


5

Gerçek dünya açısından: A'dan B'ye doğru yönelmiş ve kilitli bir şekilde D kapısını bulsaydınız, D anahtarını bulmanız gerektiğini fark edersiniz. Yani AI'nız tipik insan kadar bilmiyorsa , bu, kendi içinde küçük bir yol bulma adımları kümesi olan anahtarın keşfini içerecektir. Öte yandan, AI'nızın bir yol denemeden önce, o rotada kilitli bir kapı olduğunu bilmesini isteyebilirsiniz ve bu durumda muhtemelen anahtarı nerede bulacağını da bilir.

Her iki durumda da, sorun iki düzeyde bağlantılardan biridir. "Yerde" seviyesinde, her zaman bir bölünmemiş bölge içinde güvenli bir şekilde hareket edebileceğinizi biliyorsunuz ... kilitli kapılar tarafından bölünmemiş, yani. Bu, mevcut A * yol bulma uygulamanızı özgürce kullanabileceğiniz yerdir. (Basit bir örnekte, bir bölgeyi tek bir oda olarak görebilirsiniz. Kapının kilidini açmadan başka bir odaya gidemezsiniz. Gerçekte, zindanınızın tüm bir bölgesi olabilir.) ama biraz önce göz çevrenizle etrafta dolaşmak yerine etrafınızdaki bölgeyi incelemek yerine etrafta dolaşmak gibi bir şey. Veya bu durumda kilitli bir kapı. Bu nedenle A * cihazınızın üzerinde çalıştığı yer seviyesi haritalarınız, oynatıcıyı yalnızca geçerli bölge içindeki hareketle sınırlamalıdır.

Daha sonra, doğada topografik olandan daha topolojik olan daha yüksek seviye bir harita var. Engellerin yerdeki detaylarını gerçekten önemsemiyor ve bu yüzden sadece bölgeler arasındaki bağlantıyı önemsiyor. Bu topolojik harita, halihazırda aralarında kilitli bir kapıya sahip olan bölgeler arasındaki bağlantılara sahiptir, çünkü zindanınızdaki tüm bölgelerin ideal bağlantısını gösterir. Kenarlarında - her biri bölgeler arasındaki bir kapıyı temsil eder - eğer varsa, o kapıyı açmak için henüz gerekli olan anahtarı depolar, aksi takdirde açık olarak kabul edilir. Bu grafiği en kısa yol için ararken , arama çalışırken kenarlardaki verileri kontrol ederek bulunan yolu yalnızca açık olan yollarla sınırlamalıdır . Buradaki bağlantı açıklık değil, potansiyel açıklık anlamına gelir.

Ayrı bir bölgeye giren bir noktaya gitmek istediğinizde, önce bir yol bulmak için üst düzey haritanızda arama yaparsınız. (A * veya başka bir en kısa yol algoritması bu seviyede kullanılabilir.) Bir yol bulduğunuzda, bu daha yüksek seviyedeki harita, geçerli bölgenizden diğer bölgeye gitmek için hangi kapıyı kullanmanız gerektiği hakkında bilgi sağlamalıdır. Şimdi, yerel bölgede, o kapıya gitmek için yer seviyesinde AI yapabilirsiniz. Kapıya ulaşıldığında, karakteriniz o kapıdan / portaldan geçebilir. Şimdi B bölgesinde. Hedef bölge ise, tuşa gitmek için yer seviyesi navigasyonunu kullanabilir. Değilse, hedef bölgeye ulaşana kadar birinci adımı tekrarlamanız gerekir.

Aranan bir anahtarın kendisinin kilitli bir kapının arkasında olma olasılığı vardır ... ve o kapının anahtarı da benzer şekilde ... ve böylece nauseum'da. Bu aslında bir bağımlılık çözümleme sorunudur ve bununla başa çıkmanın birkaç yolu vardır, bunlardan biri Petri Nets'dir. Bu mükemmel kağıda bakın .

PS. Zindanınızı prosedürel olarak oluşturuyorsanız, o zaman yaptığınız gibi, oyuncunun başlangıç ​​pozisyonunu zaten biliyor olmanız koşuluyla, bağımlılık sıralaması hakkında bilgi depolayabilirsiniz.


2

"En kısa yol" kelimelerine verilen normal bağırsak reaksiyonu açıkça A * olacaktır. Ancak A * böyle bir ortamda başarısız olur, çünkü güvenilir bir buluşsal yöntem tanımlayan birçok sorun görüyorum ve ayrıca bir düğümün birden çok kez ziyaret edilmesi gerekiyor, bu da geleneksel A * 'da mümkün değil ve aynı zamanda buluşsallaştırmayı zorlaştırır.

İlk olarak, kabul edilebilir bir buluşsal yöntem mükemmel olmak zorunda değildir. Sadece hafife almak ve hiçbir şeyden daha iyi olmak zorundadır. Gerçek mesafelerle çalıştığınız düşünüldüğünde, A * en azından biraz yardımcı olacak gibi görünüyor ve sezgisel arama daha fazla geliştirmeseydi bile, muhtemelen standart bir ilk önce yapılan aramadan daha iyi olurdu veya benzeri.

İkincisi, A * bir düğümü istediğiniz kadar ziyaret edebilir. A * 'nın bir yol bulma algoritması değil, bir arama algoritması olduğunu unutmayın. Devletler arasında arama yapar. Oyunlarda genellikle bir durumu bir pozisyonla eşitleriz, çünkü o duruma nasıl ulaştığınızı umursamıyoruz - oraya giden yolun ne kadar kısa olduğu. Ancak böyle bir problemde durum, konumun artı anahtarlar gibi diğer ilgili durumların birleşimidir.

Bununla birlikte, bu komplikasyonların A * 'yı' çok verimli 'alanlarından' başarılı olacağı, ancak muhtemelen istediğim zaman ölçeğinde 'taşımayacağı doğrudur. İstediğiniz zaman ölçeği nedir? Aslında, bunu neden yapmanız gerekiyor - gerçekten en kısa yola mı ihtiyacınız var, yoksa makul bir yol yeterli mi?

Düşündüğüm sadece zindanın başından sonuna kadar bir yol aramak ve engellenmiş kapıları görmezden gelmek. Bu yol bulunduktan sonra, yolumuzu engelleyen her bir kapı için, kapıya ulaşılmadan önce uygun anahtarı ve kapıya geri dönecek ek bir yol aranacak ve geçilecektir.

Böyle bir sistemin yetersiz olacağını kanıtlamak kolaydır. Ek yola nereden başlayacaksınız? Başından beri, o zaman kapının orijinal yolunu çizmek için zamanınızı boşa harcadınız. Sondan başlayarak, bir anahtarın başlangıca yakın yerleştirilmesi, yolun bir zamanlar yeterli olduğunda haritayı iki kez geçtiği anlamına gelir. Kapıya ve orijinal yola giden ve kapıdan çıkan yollar için en uygun birleştirme noktalarını hesaplamaya çalışırsanız, bu en iyi sonucu verir ancak aramayı basitleştirmek için bir sezgisel tarama oluşturma zorluğu ve zorluğu nedeniyle kaynak yoğun olacaktır. Soruna birden fazla anahtar eklerseniz, verimli bir şekilde çözülmesi kolay olmayan Gezgin Satıcı probleminiz var.

'En kısa yol' ölçütünü rahatlatmak mümkün olsaydı, şu şekilde denerdim:

  • Anahtar konumları, kapı konumları, kilitli alanlardaki konumlar gibi yalnızca önemli konumları içeren yüksek düzeyli bir grafik oluşturun ve bunlar arasındaki düz çizgi mesafelerini not edin. Haritanız zaten odalara veya diğer ayrı yerlere ayrılıyorsa, bu harika.
  • Bu grafikte baştan sona kadar bir yol bulmak için A * tuşunu kullanın. Normal Kartezyen mesafe sezgisel yöntemi onu yönetilebilir tutmak için yeterli olmalıdır.
  • Şimdi, bu yol noktaları arasındaki bu basitleştirilmiş yolla, bir yol noktasından diğerine düşük seviyeli bir yol çizmek için A * tuşunu tekrar kullanın.
  • Tüm yolunuzu oluşturmak için bu düşük düzey yollara katılın.

Bir kez çalıştıktan sonra, bazı küçük optimizasyonları düşünürdüm - örneğin. alanların anahtarlarla daha yumuşak bir şekilde ağırlıklandırılması, böylece düşük seviyeli yollamanın anahtarları toplamak için küçük yollar yapması daha olasıdır.


0

verdiğiniz bilgilerle A * 'yı sadece küçük bir değişiklikle kullanabileceğinizi düşünüyorum. normal bir A * algoritmasında, bir daha asla geçmeyeceğinizden emin olmak için her düğümü üzerinden geçerken işaretlersiniz. Bu öğeler ile sorun yapan tam kısmıdır. Önemli değişiklik, daha önce bir düğümden geçtiğinizde öğelerinizin ne olduğunu hatırlamaktır. İşte ne demek istediğimi açıklayan bir sudo kodu:

if (nodestoCheck.notempty())
    newNode = nodeToCheck.first;
    if (notpassed(newNode.pos, newNode.items))
        if (room(newNode).containItem)
            add NewNode + room(NewNode).items 
        else
            do normal A* algorithm for new Node

bu algoritma ile önce tüm düğümleri öğe olmadan kontrol etmeye başlarsınız. ilk arama grubunuzun bazı kapılar tarafından engellenmesi olasılığı yüksektir. ama tüm odaları aramadan önce o kapının anahtarını bulacak. o tuştan o tuşa sahip yeni bir arama başlatırsınız. bu sefer kapıya ulaştığınızda geçebilirsiniz. zindandan çıkış yolunu bulana kadar aynı rutin devam eder. tek sorun, çok sayıda kapı ve anahtar olduğunda bellek tüketimi olabilir. ancak en az 10 veya 15 tuş için sorun olmayacaktır.


0

Neden normal A * ve kilitli kapıları geçilmez bölgeler olarak kullanmıyorsunuz; anahtarı aldığınızda (anahtar karo üzerinde yürümek?), bu kilitli kapıyı geçilebilir bir bölgeye dönüştürür.

Bunun anlamı, yol bulucunuzun en kısa anahtarsız rotaya gideceği ve yol boyunca anahtarlar bulması durumunda, yardımcı olursa bunu yoluna dahil edecektir .

Bu benim için oldukça makul görünüyor. Mükemmel değil, ama soruna basit bir çözüm.

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.