clojure中的统一成本搜索
这个程序似乎有一个bug,如果有人能帮忙,我将不胜感激clojure中的统一成本搜索,clojure,Clojure,这个程序似乎有一个bug,如果有人能帮忙,我将不胜感激 (defn findmincostindex [frontier] (loop [i 0 n 0] (if (< i (count frontier)) (if (< (:cost (get frontier i)) (:cost (get frontier n))) (recur (inc i) i) (recur (inc i) n)) n))) (de
(defn findmincostindex [frontier]
(loop [i 0 n 0]
(if (< i (count frontier))
(if (< (:cost (get frontier i)) (:cost (get frontier n)))
(recur (inc i) i)
(recur (inc i) n))
n)))
(defn uniformcostsearch [graph start end]
((fn [frontier explored]
(if (empty? frontier)
"Failure"
(let [pathwithmincost (findmincostindex (into [] frontier))
;(let [pathwithmincost (findmincostindex frontier)
path (:path (get frontier pathwithmincost))
cost (:cost (get frontier pathwithmincost))
node (peek path)
childs (keys (graph node))]
(if (= node end)
path
(recur
(concat (subvec frontier 0 pathwithmincost) (subvec frontier (inc pathwithmincost))
(map (fn [c] {:path (conj path c) :cost (+ cost ((graph node) c))})
(filter #(not (contains? explored %)) childs)))
(conj explored node))))))
[{:path [start] :cost 0}] #{}))
(def graph {
"Oradea" {
"Zerind" 71,
"Sibiu" 151
},
"Zerind" {
"Oradea" 71,
"Arad" 75
},
"Arad" {
"Zerind" 75,
"Sibiu" 140,
"Timisoara" 118
},
"Sibiu" {
"Oradea" 151,
"Arad" 140,
"Fagaras" 99,
"Rimnicu Vilcea" 80
},
"Fagaras" {
"Sibiu" 99,
"Bucharest" 211
},
"Rimnicu Vilcea" {
"Sibiu" 80,
"Pitesti" 97,
"Craiova" 146
},
"Timisoara" {
"Arad" 118,
"Lugoj" 111
},
"Lugoj" {
"Timisoara" 111,
"Mehadia" 70
},
"Pitesti" {
"Rimnicu Vilcea" 97,
"Craiova" 138,
"Bucharest" 101
},
"Mehadia" {
"Lugoj" 70,
"Drobeta" 75
},
"Drobeta" {
"Mehadia" 75,
"Craiova" 120
},
"Craiova" {
"Drobeta" 120,
"Rimnicu Vilcea" 146,
"Pitesti" 138
},
"Bucharest" {
"Pitesti" 101,
"Fagaras" 211,
"Giurgiu" 90,
"Urziceni" 85
},
"Giurgiu" {
"Bucharest" 90
},
"Urziceni" {
"Bucharest" 85,
"Vaslui" 142,
"Hirsova" 98
},
"Hirsova" {
"Urziceni" 98,
"Eforie" 86
},
"Eforie" {
"Hirsova" 86
},
"Vaslui" {
"Iasi" 92,
"Urziceni" 142
},
"Iasi" {
"Neamt" 87,
"Vaslui" 92
},
"Neamt" {
"Iasi" 87
}})
(println (uniformcostsearch graph "Neamt" "Iasi"))
(println (uniformcostsearch graph "Neamt" "Vaslui"))
(println (uniformcostsearch graph "Bucharest" "Arad"))
但它说:
clojure.lang.LazySeq不能强制转换为
clojure.lang.ipersis
当我使用
(into [] frontier)
如果我单独使用frontier,它会说
java.lang.NullPointerException
异常发生在您的
recur
中的第一个子向量中。您使用的是concat
的结果,这是一个惰性序列,您不能获取惰性序列的子向量。快速修复方法是将其包装在vec
:
(vec (concat (subvec frontier 0 pathwithmincost) (subvec frontier (inc pathwithmincost))
(map (fn [c] {:path (conj path c) :cost (+ cost ((graph node) c))})
(remove explored childs))))
其他一些提示:
findmincostindex
本质上是它的一个重新实现,它的通用性较低,您可以通过使用它使它更干净
集合也是函数,如果它是集合的成员,则返回参数(truthy值)。您可以使用此选项对(筛选(不包含已探索的%)childs))
-例如(删除已探索的childs)
您的let
可以通过使用李>
以下是我的尝试:
(let [[idx {:keys [path cost]}] (apply min-key (comp :cost second) (map-indexed vector frontier))
node (peek path)
childs (keys (graph node))]
这里的过程是
(映射索引向量边界)
将边界
分成索引和节点对
min key
查找(:cost(second pair))
的最小值对李>
let
将名称idx
绑定到该对的索引,将path
和cost
绑定到节点的:path
和:cost
键李>
(let [[idx {:keys [path cost]}] (apply min-key (comp :cost second) (map-indexed vector frontier))
node (peek path)
childs (keys (graph node))]