Daha set
önce gördüğünüz durumları depolamak için (sözcüğün matematiksel anlamında, yani kopya içeremeyen bir koleksiyonda) kullanabilirsiniz. Bu konuda yapabileceğiniz işlemler şunlardır:
- eleman ekleme
- öğelerin zaten orada olup olmadığını test etmek
Hemen hemen her programlama dili, bu işlemlerin her ikisini de sabit olarak gerçekleştirebilen bir veri yapısı için zaten desteğe sahip olmalıdır (O ( 1 )) zaman. Örneğin:
set
Python'da
HashSet
Java'da
İlk bakışta, gördüğünüz tüm durumları böyle bir sete eklemek, bellek açısından pahalı olacak gibi görünebilir, ancak sınırınız için zaten ihtiyacınız olan belleğe kıyasla çok kötü değil; dallanma faktörünüzb, sınırın büyüyecek b - 1 ziyaret ettiğiniz düğüm başına elemanlar (kaldır 1 sınırdan "ziyaret etmek" için düğüm ekleyin, b yeni halefler / çocuklar), ancak kümeniz yalnızca 1 ziyaret edilen düğüm başına fazladan düğüm.
Sözde kodda, wikipedia'daki sözde kodlaclosed_set
tutarlı olmak için böyle bir küme (diyelim ki) Genişlik-İlk Arama'da aşağıdaki gibi kullanılabilir:
frontier = First-In-First-Out Queue
frontier.add(initial_state)
closed_set = set()
while frontier not empty:
current = frontier.remove_next()
if current == goal_state:
return something
for each child in current.generate_children()
if child not in closed_set: // This operation should be supported in O(1) time regardless of closed_set's current size
frontier.add(child)
closed_set.add(current) // this should also run in O(1) time
(bu sözde kodun bazı varyasyonları da işe yarayabilir ve duruma bağlı olarak daha fazla veya daha az verimli olabilir; örneğin, closed_set
zaten sınıra çocuk eklediğiniz tüm düğümleri içermek için de alabilir ve generate_children()
çağrıdan tamamen kaçınabilirsiniz. current
zaten varsa closed_set
.)
Yukarıda tarif ettiğim, bu sorunu ele almanın standart yolu olacaktır. Sezgisel olarak, farklı bir "çözümün" yeni bir halef devletleri listesinin sırasını, sınıra eklemeden önce her zaman rastgele hale getirmek olabileceğinden şüpheleniyorum. Bu şekilde, önceden sınıra önceden genişlettiğiniz durumları ara sıra ekleme sorununu ortadan kaldırmazsınız, ancak bunun sonsuz döngülere takılma riskini önemli ölçüde azaltması gerektiğini düşünüyorum.
Dikkatli olun : Bu çözümün, sonsuz döngülerden her zaman kaçındığını kanıtlayan herhangi bir resmi analiz bilmiyorum. Bunu kafamdan "çalıştırmaya" çalışırsam, sezgisel olarak, bir tür iş gerektirdiğinden şüphelenirim ve fazladan bellek gerektirmez. Şu anda düşünmediğim uç durumlar olabilir, bu yüzden de işe yaramayabilir, yukarıda açıklanan standart çözüm daha güvenli bir bahis olacaktır (daha fazla bellek pahasına).