Yönlendirilmiş bir grafikte iki düğüm arasındaki tüm yolları bulmayı gerektiren bir sorun üzerinde çalışıyorum. Grafikte döngü olabilir. Bu özel uygulama yaklaşımının yinelemeli bir DFS olduğuna dikkat edin.Yönlendirilmiş bir grafikte tüm yolları bulma döngüleri
BFS düzgünce düğümler arasındaki pathing ilişkilerin bu tür yönetmek için bir yol var gibi görünmüyor - aşağıdaki gibi ben kabul ettik
Çeşitli yaklaşımlardır.
Sonlandırma düğümü bulunduğunda yolu geçmek için DFS yinelemeli algoritma için kolay bir mekanizma göremiyorum. (Belki bir monad şey türünü uygularsam yeterli olabilirdi).
GRAPH-PARENT rutini oluşturma. Bu, mevcut koda iyi bir miktarlık (& hata) ekler.
Soyut ne olması gereken bir ağaç kökü olarak başlangıç düğümle, oluşturulması gerekiyorsa, ve tüm yapraklar sonlandırma düğümleri vardır. Yapraktan köke giden her yol bir yasal yoldur. Yinelemeli bir DFS'nin izleyeceği şey budur.
Burada yapılabileceğine eminim ama nasıl yapılacağını tam olarak göremiyorum.
Bu algoritma için GRAPH-EQUAL ve GRAPH-NEXT'ın rasgele nesneler için tanımlanabildiği bir protokol tanımladım.
Hata ayıklama düğümü türü SEARCH-NODE'dur ve veri erişim aracı ARAMA-VERİ-VERİ'dir.
(defun all-paths (start end)
(let ((stack (list start))
(mark-list (list start)) ;I've chosen to hold marking information local to all-paths, instead of marking the objects themselves.
(all-path-list '())) ; Not used yet, using debug statements to think about the problem
(do () ;; intializing no variables
;; While Stack still has elements
((not stack))
(let ((item (pop stack)))
;; I'm looking at the item.
(format t "I: ~a~%" (search-node-data item))
(cond ((graph-equal item end)
(format t "*Q: ~a~%" (loop for var in stack collect (search-node-data var)))
;;Unmark the terminal node so we can view it it next time.
(setf mark-list (remove item mark-list))))
(loop for next in (graph-next item)
do
(cond ((not (in next mark-list :test #'graph-equal))
;; mark the node
(push next mark-list)
;;Put it on the stack
(push next stack))))))))
Hm. Bu acımasız bir kağıt. Algoritmanın Lisp'e çıkarılmasının karmaşıklığı ve mevcut kodun temsile karşı arayüz oluşturma gereği nedeniyle kullanmayı denemekten vazgeçtim. –
Kısa versiyon "Floyd'un algoritmasını kullan" dır. Kağıdın jüdü, Floyd'un algoritmasının çok genel bir matematiksel yapı üzerinde - bir * -samanlama - üzerinde çalıştığı ve söz konusu algoritmanın çeşitli * -semirings üzerinde kullanımını gösterdiği yönündedir. –
Kısa sürümü şu şekilde ifade ederdim. Grafiğinizi başlangıç noktanız ile bir DFA olarak düşünün ve son noktanızı sonlandırın ve tüm kenarlarınıza benzersiz etiketler verin ve etiket kümesini alfabeniz olarak kullanın. Bu DFA tarafından kabul edilen dil, başlangıç düğümünden son düğümünüze giden tüm yolların kümesini temsil eder. İsterseniz, McNaughton-Yamada algoritmasını kullanarak bu dil için düzenli bir ifade hesaplayabilirsiniz. –