我有一個很難追查我的Clojure的實施Bron-Kerbosch algorithm產生一個計算器錯誤。在Clojure的程序跟蹤下來的StackOverflow,包含SSCCE
下面是我的實現算法本身的,這裏是一個SSCCE概述了問題http://pastebin.com/gtpTT4B4的鏈接。
(defn Bron-Kerbosch [r p x graph cliques]
;(println (str "R:" r " P:" p " X:" x " Clq:" cliques))
(cond (and (empty? p) (empty? x)) (concat cliques r)
:else
(let [neigh (neighV graph (dec (count p)))]
(loop [loop-clq '(cliques)
loop-cnt (dec (count p))
loop-p '(p)
loop-x '(x)]
(cond (= -1 loop-cnt) loop-clq
:else
(recur (concat loop-clq
(Bron-Kerbosch (concat r loop-cnt)
(concat p neigh)
(filter (set x) neigh)
graph cliques))
(dec loop-cnt)
(filter (set p) loop-cnt)
(concat x loop-cnt)))))))
我會認爲這個問題顯然在於我的兩個引導條件(cond (and (empty? p) (empty? x))
一個(cond (= -1 loop-cnt)
因爲函數算法是遞歸的範圍內。
雖然這個假設我正確地建立名單x r p
。根據評論出的印刷語句的輸出結果來判斷(派系總是打印爲EmptyList)我認爲我的列表理解也可能是問題。
沿着同樣的路線,我可以看到的另一個問題是,我實際上並沒有在BK-Call
函數(在SSCCEE)中正確地調用算法。
我的整體問題是,是什麼原因造成的?雖然這太開放了,但可能導致我回答的另一個問題是我如何在第一行中使用print語句。
當打印語句註釋掉它產生的輸出
R:[email protected] P:[email protected] X:[email protected] Clq:[email protected]
我認爲如果我能看到x r p
是在每次調用我也許能看到那裏的算法是怎麼了。
任何人都可以指向正確的方向嗎?
編輯:從SSCCE的neighV
功能
(defn neighV [graph nodenum]
(let [ret-list (for [i (range (count graph)) :when (contains? (graph i) nodenum)] i)]
ret-list))
EDIT2: Noisesmith的回答已經得到我更接近解決方案,對我有意義。我將所有concat
都包裹在doall
中。試圖再次我正在調用該函數後「無法投龍於Seq」的錯誤,我想,這從功能
fptests.core> (BK-Call (sanity1))
IllegalArgumentException Don't know how to create ISeq from: java.lang.Long clojure.lang.RT.seqFrom (RT.java:505)
fptests.core> (concat 1 '(2 3))
IllegalArgumentException Don't know how to create ISeq from: java.lang.Long clojure.lang.RT.seqFrom (RT.java:505)
所以我當時在'()
纏繞。loop-cnt
試圖concat
loop-cnt
到列表朵朵把它變成一個清單之前,它是concat
fptests.core> (concat '(1) '(2 3))
(1 2 3)
其中,我所做的所有這些改變之後,我最終回到我的堆棧溢出。這裏是新的Bron-Kerbosch
功能與所有的修改。我想我現在有和我以前一樣的問題了。
儘管新的是,我是否實施了我應該正確的更改,'()
的用法是否有意義解決之後出現的問題實施noisesmith的變化?
(defn Bron-Kerbosch1 [r p x graph cliques]
(cond (and (empty? p) (empty? x)) (doall (concat cliques r))
:else
(let [neigh (neighV graph (dec (count p)))]
(loop [loop-clq '(cliques)
loop-cnt (dec (count p))
loop-p '(p)
loop-x '(x)]
(cond (= -1 loop-cnt) loop-clq
:else
(recur (doall (concat loop-clq
(Bron-Kerbosch1 (doall (concat r '(loop-cnt)))
(doall (concat p neigh))
(filter (set x) neigh)
graph cliques)))
(dec loop-cnt)
(filter (set p) '(loop-cnt))
(doall (concat x '(loop-cnt)))))))))
EDIT3:後耐心地等待我prn
語句停止(不知道爲什麼,我把他們當我知道這是一個SO)我發現,如果不是所有的語句印刷是沿着線
"R:" (loop-cnt loop-cnt loop-cnt loop-cnt loop-cnt loop-cnt loop-cnt ...)
"P:" (range (count graph) 0 2 3) " X:"() " Clq:"()
在檢查了這個之後,我意識到我沒有正確地遞歸調用函數。我一直在聯合項目P
而不是刪除它們。這導致P
不斷增長。這很可能是我的堆棧溢出的原因。雖然還有一些問題。我仍然在創建一個stackoverflow。
一旦我解決了我的問題繼續工會到P我的問題是,當我concat
loop-cnt
它不是,我想說,評估爲一個值,但它保持作爲變量名loop-cnt
。我懷疑我的堆棧溢出現在處於我的引導條件未滿足的狀態,因爲如果loop-cnt
未計算爲數字,則無法滿足此條件。
所以我認爲我的問題現在與concat
loop-cnt
列表作爲一個數字而不是變量。
發生堆棧溢出時,輸出看起來如何?您可能需要在Clojure中查看更加慣用的BK算法:https://github.com/tgk/bron-kerbosch-in-clojure – mac 2015-04-03 08:35:17
「neighV」函數是什麼樣的? – 2015-04-03 14:13:41
@BobJarvis我在這個問題的編輯中加入了'neighV'。 – KDecker 2015-04-03 14:21:46