Algorithm D.B.约翰逊是否应该';s";“基本电路”;算法能产生不同的结果吗?
开始描述有向图中不同的基本电路(简单循环): 如果没有顶点,但第一个顶点和最后一个顶点出现两次,则回路是基本回路。如果一个电路不是另一个电路的循环置换,则两个基本电路是不同的。G中有c个不同的基本电路 我试图拼凑出一些模糊地类似于伪代码的东西,有点严重地欺骗了这个。显然,我没有得到清晰的基本电路 这是我的密码。它使用了,但是除了得到强连接的组件之外,实际上没有做太多的事情Algorithm D.B.约翰逊是否应该';s";“基本电路”;算法能产生不同的结果吗?,algorithm,graph,go,graph-theory,graph-algorithm,Algorithm,Graph,Go,Graph Theory,Graph Algorithm,开始描述有向图中不同的基本电路(简单循环): 如果没有顶点,但第一个顶点和最后一个顶点出现两次,则回路是基本回路。如果一个电路不是另一个电路的循环置换,则两个基本电路是不同的。G中有c个不同的基本电路 我试图拼凑出一些模糊地类似于伪代码的东西,有点严重地欺骗了这个。显然,我没有得到清晰的基本电路 这是我的密码。它使用了,但是除了得到强连接的组件之外,实际上没有做太多的事情 package main import ( "fmt" "github.com/gyuho/goraph/
package main
import (
"fmt"
"github.com/gyuho/goraph/algorithm/scc/tarjan"
"github.com/gyuho/goraph/graph/gs"
)
func main() {
gr := gs.NewGraph()
a := gr.CreateAndAddToGraph("A")
b := gr.CreateAndAddToGraph("B")
c := gr.CreateAndAddToGraph("C")
d := gr.CreateAndAddToGraph("D")
e := gr.CreateAndAddToGraph("E")
f := gr.CreateAndAddToGraph("F")
gr.Connect(a, b, 1)
gr.Connect(b, c, 1)
gr.Connect(c, a, 1)
gr.Connect(d, e, 1)
gr.Connect(e, f, 1)
gr.Connect(f, d, 1)
sccs := tarjan.SCC(gr) // returns [][]string
for _, scc := range sccs {
if len(scc) < 3 {
continue
}
for _, v := range scc {
n := node(v)
circuit(n, n, gr)
}
}
fmt.Println(result)
}
type node string
var blocked = make(map[node]bool)
var B = make(map[node][]node)
var path []node
var result [][]node
func circuit(thisNode node, startNode node, g *gs.Graph) bool {
closed := false
path = append(path, thisNode)
blocked[thisNode] = true
adj := g.FindVertexByID(string(thisNode)).GetOutVertices().GetElements()
for _, next := range adj {
nextNode := node(next.(*gs.Vertex).ID)
if nextNode == startNode {
cycle := []node{}
cycle = append(cycle, path...)
cycle = append(cycle, startNode)
result = append(result, cycle)
closed = true
} else if !blocked[nextNode] {
if circuit(nextNode, startNode, g) {
closed = true
}
}
}
if closed {
unblock(thisNode)
} else {
adj = g.FindVertexByID(string(thisNode)).GetOutVertices().GetElements()
for _, next := range adj {
nextNode := node(next.(*gs.Vertex).ID)
inB := false
for _, v := range B[nextNode] {
if v == thisNode {
inB = true
}
}
if !inB {
B[nextNode] = append(B[nextNode], thisNode)
}
}
}
path = path[:len(path)-1]
return closed
}
func unblock(thisNode node) {
stack := []node{thisNode}
for len(stack) > 0 {
n := stack[len(stack)-1]
stack = stack[:len(stack)-1]
if blocked[n] {
blocked[n] = false
stack = append(stack, B[n]...)
B[n] = []node{}
}
}
}
对我来说,图论是一片充满魔力的阴森森林,所以我不确定我错过了什么。我看错报纸了吗?这是否意味着冗余排列应该以其他方式过滤掉?我把代码搞糟了吗?多余的排列被过滤掉,因为每个返回排列的开始节点总是小于所有剩余元素(在某些顺序下) 我怀疑问题在于缺少以下步骤的实施: AK:=具有最小顶点的强分量K的邻接结构 由{s,s+1,n}诱导的G的子图 及 s:=V中的最小顶点
这些步骤应该确保每个置换的开始总是小于置换的其余部分,但我看不到实现这一点的代码,相反,您似乎在强连接组件中的每个节点之间循环。好的,现在更有意义了。这就是我怀疑的地方,但我不知道它应该做什么。这里的“最小顶点”到底是什么意思?在main中去掉嵌套的for循环并用类似于
n:=node(scc[0])的内容替换它是否足够?我不太确定如何订购,但这似乎可以删除重复项。@Greg只要您保持一致,订购顺序并不重要。然而,这并不像选择scc[0]那么简单。您确实需要在scc中的顶点上循环,但是对于每个节点,您需要编辑图形以仅包括顶点的子集(那些>=到s)。因此,s是否将是scc切片/数组中顶点的索引,每次调用circuit()
时递增?很抱歉,我对这件事太过分了。。。
[[C A B C] [B C A B] [A B C A] [F D E F] [E F D E] [D E F D]]