我在跟踪Bron-Kerbosch non-pivoting and pivoting算法的Clojure实现中的问题时遇到了问题。
这是没有旋转的Bron-Kerbosch(BK)
这是带旋转的BK(BKP)
我在SO的帮助下管理了BK而没有转向工作。我通过相当多的健全性测试/图表验证了它找到了正确的最大集团集。
我的问题在于使用旋转算法的BK。我不太确定如何确定问题所在,我不得不认为这是我实现它的一个问题。
以下是具有必要功能http://pastebin.com/wm7dxvc8的问题的SSCCE。以下是我对BK和BKP算法的实现。
; Bron-Kerbosch with no pivot
(defn BK [r p x graph]
(if (and (empty? p) (empty? x))
[(set r)]
(loop [p p, x x, cliques []]
(if (empty? p)
cliques
(let [v (first p)
nv (graph v)
cliques (into cliques
(BK (into r (list v))
(filter nv p)
(filter nv x)
graph))
p (rest p)
x (into x (list v))]
(recur p x cliques))))))
; Bron-Kerbosch with pivoting
(defn BKP [r p x graph]
(if (and (empty? p) (empty? x))
[(set r)]
(let [u (first (into p x))
nu (graph u)
pnu (remove #(some (partial = %) nu) p)]
(loop [p p, pnu pnu, x x, cliques []]
(if (empty? pnu)
cliques
(let [v (first pnu)
nv (graph v)
cliques (into cliques
(BKP (into r (list v))
(filter nv p)
(filter nv x)
graph))
p (rest p)
x (into x (list v))]
(recur p (rest pnu) x cliques)))))))
大多数情况下,使用小的简单随机图这两种算法都可以找到正确的最大集合。
fptests.core> (testallbk (random-graph 5 6))
Starting test...
Timing evaluation of graph with BK :"Elapsed time: 0.098467 msecs"
Timing evaluation of graph with BKP:"Elapsed time: 0.144646 msecs"
BK cliques count: 3 Largest: 3
Cliques: [#{0 4} #{1 4} #{1 3 2}]
BKP cliques count: 3 Largest: 3
Cliques: [#{0 4} #{1 4} #{1 3 2}]
虽然有时候,大约10%,BKP算法设法找到比BK算法更多的派系。几乎所有BKP都有错误的时候它会报告两个相同的集团
fptests.core> (testallbk (random-graph 5 6))
Starting test...
Timing evaluation of graph with BK :"Elapsed time: 0.102083 msecs"
Timing evaluation of graph with BKP:"Elapsed time: 0.097479 msecs"
BK cliques count: 2 Largest: 3
Cliques: [#{0 1 4} #{0 3 2}]
BKP cliques count: 3 Largest: 3
Cliques: [#{0 1 4} #{0 3 2} #{0 3 2}]
但也有一些情况,它只报告一个正确的派系,似乎"切割"关闭其中一个
fptests.core> (testallbk (random-graph 5 6))
Starting test...
Timing evaluation of graph with BK :"Elapsed time: 0.076546 msecs"
Timing evaluation of graph with BKP:"Elapsed time: 0.079762 msecs"
BK cliques count: 4 Largest: 2
Cliques: [#{0 1} #{0 3} #{1 2} #{4 3}]
BKP cliques count: 4 Largest: 2
Cliques: [#{0 1} #{0 3} #{4 3} #{2}]
当使用更大的随机图时,BKP算法有时会找到比BK更少或更多的派系
fptests.core> (testallbk (random-graph 500 600))
Starting test...
Timing evaluation of graph with BK :"Elapsed time: 113.128014 msecs"
Timing evaluation of graph with BKP:"Elapsed time: 166.300653 msecs"
BK cliques count: 631 Largest: 3
BKP cliques count: 629 Largest: 3
fptests.core> (testallbk (random-graph 500 600))
Starting test...
Timing evaluation of graph with BK :"Elapsed time: 109.454454 msecs"
Timing evaluation of graph with BKP:"Elapsed time: 166.39116 msecs"
BK cliques count: 641 Largest: 3
BKP cliques count: 642 Largest: 3
看到派系的数量永远不会相互远离,我会假设在BKP算法的某个时刻,我的集合联合,差异和从集合中删除值的实现有一些不考虑的边缘情况。
尽管如此,我迄今为止对Clojure的有限了解使我无法进一步分析问题所在。看到BK算法适用于任何大小的图形,并且BK和BKP算法中的loop
语句都是相同的。我认为问题在于选择枢轴以及u
,nu
和pnu
的计算。但是,据我所知,这对我来说似乎都是正确的。
任何更有知识的人都可以追踪我的问题或指出我正确的方向吗?