简体   繁体   中英

Traversing a graph in clojure

Hope you are well. I am stuck with a recursive program that is suppose to traverse a graph until it finds a path back to the start node. the code is here,

(def graph {:A {:B 5 :D 5 :E 7}
            :B {:C 4}
            :C {:D 8 :E 2}
            :D {:C 8 :E 6}
            :E {:B 3}
            })

(defn looper [g startnode & args]  
  (let [[inode] (vec args)
        acc []]
    (if (= startnode inode)    
      (conj acc inode)    
      (conj acc inode (map (partial looper g startnode) (vec (keys (get g inode)))))
  )))


(looper graph :C)

there is something wrong with the way I accumulate the result I couldnt find what exactly.

The function should return something like '(CDC CEBC) for the above call.

This did the trick, hope its helpful for someone :)

(defn- dfs
  [graph goal]
  (fn search
    [path visited]
    (let [current (peek path)]
      (if (= goal current)
        [path]
        (->> current graph keys
             (remove visited)
             (mapcat #(search (conj path %) (conj visited %))))))))
(defn findpath
  "Returns a lazy sequence of all directed paths from start to goal
  within graph."
  [graph start goal]
  ((dfs graph goal) [start] #{start}))

(defn circular-path-count [graph node] 
  (flatten (map (fn [s]
       (map count (findpath graph s node))) (vec (keys (get-in graph [node]))) )))



e.g. usage: (circular-path-count paths :B)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM