簡體   English   中英

clojure如何在遞歸循環中停止和輸出

[英]clojure how to stop and output while in a recursive loop

因此,我正在A *搜索一個8難題,它似乎可以工作,但是問題是,一旦找到解決方案,它就會不斷瀏覽優先級圖並輸出所有可能性。 一旦滿足條件,有沒有辦法停止並輸出?

注意 :我感覺像是用一個for循環使dosqqs變得懶惰,並使它們不評估整個過程將是最好的。 有沒有辦法做到這一點?

這是我的代碼:

(defn a-star

   ([board history]

     (if (at-end? board) (print-board board)


           (let [options (filter #(possible-move? % board) *moves*)
                move (into (pm/priority-map) (for [move options] [move (global-man-dis (move-tile board move))]))]


              (doseq [pair move :let [next-move (key pair)]] 


                  (print-board (move-tile board next-move))
                  (println)
                  (a-star (move-tile board next-move) next-move (conj history board))

              )
          )
    ))



  ([board prev-move history]

     (if (or (at-end? board) (history-check history board)) (print-board board)


      (let [options (get-queue board (dont-go-back prev-move))
            move (into (pm/priority-map) (for [move options] [move (global-man-dis (move-tile board move))]))]

        (doseq [pair move :let [next-move (key pair)]] 


             (print-board (move-tile board next-move))
             (println)
             (a-star (move-tile board next-move) next-move (conj history board))

         )
       )
     )))



(defn -main [& args]
  (println "insert a list all numbers no spaces or letters")
  (def board (mapv (fn [^Character c] (Character/digit c 10)) (read-line)))
  ;(def testt [0 8 4 7 2 1 3 5 6])
  ;(def testt [1 2 3 5 4 6 8 0 7])
  (a-star board [])
  )

為了進一步說明我昨天的評論,這里是Clojure中的完整通用A *實現。 由於您沒有包括a-star函數在問題中調用的各種輔助函數,因此我不知道您是如何將8難題完全轉化為圖形搜索問題,但是您應該能夠適應自己編寫代碼。

(ns a-star.core
  (:require [clojure.data.priority-map :refer [priority-map]]))

(defn pred->path
  "Determine the path to GOAL from the map of predecessors PRED."
  [pred goal]
  (loop [node goal, path ()]
    (if (contains? pred node)
      (recur (pred node) (cons node path))
      (cons node path))))

(defn expand
  [node h [open g pred] succ cost]
  (let [g-succ (+ (g node) cost)]
    (if (and (contains? open succ)
             (>= g-succ (g succ)))
      [open g pred]
      [(assoc open succ (+ g-succ (h succ)))
       (assoc g succ g-succ)
       (assoc pred succ node)])))

(defn a*
  "Determine the shortest path from START to GOAL in graph GRAPH
with heuristic cost function H. GRAPH format is {from {to cost}}."
  [start goal graph h]
  (loop [open (priority-map start 0)
         closed ()
         g {start 0}
         pred {}]
    (if (empty? open)
      :no-path-found
      (let [node (key (peek open))]
        (if (= node goal)
          [:path-found (pred->path pred goal) (g goal)]
          (let [successors (apply dissoc (graph node) closed)
                [open* g* pred*] (reduce-kv (partial expand node h)
                                            [(pop open) g pred]
                                            successors)]
            (recur open* (conj closed node) g* pred*)))))))

測試代碼應闡明如何使用a*函數:

(ns a-star.core-test
  (:require [clojure.test :refer :all]
            [a-star.core :refer :all]))

(deftest test-a*
  (is (= (a* :sb :wb
             {:sb {:kl 70, :kr 145}
              :kl {:ff 103, :lh 53}
              :ff {:wb 116}
              :lh {:wb 183}
              :kr {:hb 84}
              :hb {:wb 102}}
             {:sb 222, :kl 158, :ff 96, :wb 0, :lh 108, :kr 140, :hb 87})
         [:path-found '(:sb :kl :ff :wb) 289])
      "Find path in a directed graph.")
  (is (= (a* :sb :wb
             {:sb {:kl 70, :kr 145}
              :kl {:sb 70, :ff 103, :lh 53}
              :ff {:kl 103, :wb 116}
              :lh {:kl 53, :wb 183}
              :kr {:sb 145, :hb 84}
              :hb {:kr 84, :wb 102}
              :wb {:ff 116, :lh 183, :hb 102}}
             {:sb 222, :kl 158, :ff 96, :wb 0, :lh 108, :kr 140, :hb 87})
         [:path-found '(:sb :kl :ff :wb) 289])
      "Find path in an undirected graph.")
  (is (= (a* :sb :wb
             {:kl {:sb 70}
              :ff {:kl 103}
              :lh {:kl 53}
              :kr {:sb 145}
              :hb {:kr 84}
              :wb {:ff 116, :lh 183, :hb 102}}
             {:sb 222, :kl 158, :ff 96, :wb 0, :lh 108, :kr 140, :hb 87})
         :no-path-found)
      "Find no path in reversed directed graph."))

一種常見的方法是在循環調用的末尾放置一個if語句。 就像是:

(if-not (finished? move)
   (a-star ... ))

PS:一個猥瑣點的格式,一些Clojure的程序員發現它更容易閱讀,如果所有的連續收盤)的走在同一條線上,雖然這純粹是個人喜好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM