ruby – 在有向图中给出一个循环的例子
发布时间:2020-12-17 03:28:22 所属栏目:百科 来源:网络整理
导读:我想要一个算法,如果有的话,在有向图中给出一个循环的实例.谁能告诉我一个方向?在伪代码中,或者最好是在 Ruby中? 我之前问过a similar question,并按照那里的建议,我在Ruby中实现了Kahn的算法,它检测图表是否有一个循环,但我不仅要求它是否有一个循环,而且
我想要一个算法,如果有的话,在有向图中给出一个循环的实例.谁能告诉我一个方向?在伪代码中,或者最好是在
Ruby中?
我之前问过a similar question,并按照那里的建议,我在Ruby中实现了Kahn的算法,它检测图表是否有一个循环,但我不仅要求它是否有一个循环,而且还要一个这样的循环的可能实例. example_graph = [[1,2],[2,3],[3,4],5],6],[6,2]] 卡恩的算法 def cyclic? graph ## The set of edges that have not been examined graph = graph.dup n,m = graph.transpose ## The set of nodes that are the supremum in the graph sup = (n - m).uniq while sup_old = sup.pop do sup_old = graph.select{|n,_| n == sup_old} graph -= sup_old sup_old.each {|_,ssup| sup.push(ssup) unless graph.any?{|_,n| n == ssup}} end !graph.empty? end 上面的算法告诉图表是否有一个循环: cyclic?(example_graph) #=> true 但我不仅要这样,而且要像这样的循环示例: #=> [[2,2]] 如果我在检查结束时在上面的代码中输出变量图,它将给出: #=> [[2,2]] 其中包括我想要的循环,但它还包括与循环无关的额外边. 解决方法
我在
the math stackexchange site问了同样的问题,得到了答案.事实证明,Tarjan的算法有助于解决这个问题.我在Ruby中实现它如下:
module DirectedGraph; module_function ## Tarjan's algorithm def strongly_connected_components graph @index,@stack,@indice,@lowlink,@scc = 0,[],{},[] @graph = graph @graph.flatten(1).uniq.each{|v| strong_connect(v) unless @indice[v]} @scc end def strong_connect v @indice[v] = @index @lowlink[v] = @index @index += 1 @stack.push(v) @graph.each do |vv,w| next unless vv == v if !@indice[w] strong_connect(w) @lowlink[v] = [@lowlink[v],@lowlink[w]].min elsif @stack.include?(w) @lowlink[v] = [@lowlink[v],@indice[w]].min end end if @lowlink[v] == @indice[v] i = @stack.index(v) @scc.push(@stack[i..-1]) @stack = @stack[0...i] end end end 因此,如果我将其应用于上面的示例,我会得到图表中强连接组件的列表: example_graph = [[1,2]] DirectedGraph.strongly_connected_components(example_graph) #=> [[4],[5],3,[1]] 通过选择那些长于1的组件,我得到了循环: DirectedGraph.strongly_connected_components(example_graph) .select{|a| a.length > 1} #=> [[2,6]] 而且如果我从图中选择两个顶点都包含在组件中的边,我得到构成循环的关键边: DirectedGraph.strongly_connected_components(example_graph) .select{|a| a.length > 1} .map{|a| example_graph.select{|v,w| a.include?(v) and a.include?(w)}} #=> [[[2,2]]] (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |