我正在尝试使用R中的PairViz包找到一个euler循环(一个访问图中所有边的循环)。我的图的边缘如下:
1 - > 10
2 - > 1,6
3 - > 2
4 - > 2
5 - > 4
6 - > 5,8
7 - > 9
8 - > 7
9 - > 6
10 - > 3个
这里有一个欧拉循环:
6-> 8-&将7-> 9-> 6-将5-将4-> 2→1→10→3→2→ 6
在R中,我首先使用bioconductor的'graph'包创建了一个图g。
g <- new("graphNEL", nodes=as.character(1:10), edgemode="directed")
g <- addEdge(graph=g, from="1", to="10")
g <- addEdge(graph=g, from="2", to="1")
g <- addEdge(graph=g, from="2", to="6")
g <- addEdge(graph=g, from="3", to="2")
g <- addEdge(graph=g, from="4", to="2")
g <- addEdge(graph=g, from="5", to="4")
g <- addEdge(graph=g, from="6", to="5")
g <- addEdge(graph=g, from="6", to="8")
g <- addEdge(graph=g, from="7", to="9")
g <- addEdge(graph=g, from="8", to="7")
g <- addEdge(graph=g, from="9", to="6")
g <- addEdge(graph=g, from="10", to="3")
然后我使用PairViz包中的eulerian()函数。
ecycle <- eulerian(g, weighted=F)
在这里,我得到以下例外:
the graph is undirected and the following edges are not reciprocated:
‘1|2’, ‘6|2’, ‘2|3’, ‘2|4’, ‘4|5’, ‘5|6’, ‘8|6’, ‘9|7’, ‘7|8’, ‘6|9’, ‘3|10’
Error in validObject(.Object) : invalid class “graphNEL” object: FALSE
traceback()显示以下内容:
14: stop(msg, " ", errors, domain = NA)
13: validObject(.Object)
12: .local(.Object, ...)
11: initialize(value, ...)
10: initialize(value, ...)
9: new("graphNEL", nodes = n, edgeL = ed)
8: mk_even_graph(self, weighted = weighted)
7: mk_even_graph(self, weighted = weighted)
6: eulerian(g, weighted = F)
5: eulerian(g, weighted = F) at .active-rstudio-document#14
4: eval(expr, envir, enclos)
3: eval(ei, envir)
2: withVisible(eval(ei, envir))
1: source("~/.active-rstudio-document")
然而,同样的方法适用于从完整的有向图中找到欧拉路径(下面给出的代码)。
g <- new("graphNEL", nodes=c("a","b","c", "d"), edgemode="directed")
g <- addEdge(graph=g, from="a", to="b")
g <- addEdge(graph=g, from="a", to="c")
g <- addEdge(graph=g, from="a", to="d")
g <- addEdge(graph=g, from="b", to="c")
g <- addEdge(graph=g, from="b", to="d")
g <- addEdge(graph=g, from="b", to="a")
g <- addEdge(graph=g, from="c", to="d")
g <- addEdge(graph=g, from="c", to="a")
g <- addEdge(graph=g, from="c", to="b")
g <- addEdge(graph=g, from="d", to="a")
g <- addEdge(graph=g, from="d", to="b")
g <- addEdge(graph=g, from="d", to="c")
eulerian(g, weighted=F)
据我所知,euler路径和euler循环不相同,eulerian()函数返回euler路径。但是,由于我的图表中有一个euler循环,因此必须有一个euler路径(至少),并且应该返回。
如果我犯了任何错误,请帮助我。如果您能为我推荐任何其他套餐或任何其他解决方案,我将不胜感激。
注意:我在Windows 7(64位)中从RStudio(v0.98.501)运行此代码。
提前致谢。
阿希斯。
答案 0 :(得分:3)
我已经实现了算法,以从平衡(对于每个节点,indegree = outdegree)有向图中找到一个euler循环。必须连接所有节点。代码如下:
eulerCycle <- function(g, start=NULL){
eulerCycle <- c()
curNode <- ifelse(is.null(start), nodes(g)[1], start)
while(!is.na(curNode)){
cycle <- curNode
while(!is.na(nextNode <- randomWalkNext(g, curNode))){
g <- removeEdge(graph=g, from=curNode, to=nextNode)
cycle <- append(cycle, nextNode)
curNode <- nextNode
}
if(length(eulerCycle)==0){
eulerCycle <- cycle
}
else{
insertIndex <- which(eulerCycle==cycle[1])[1]
eulerCycle <- append(eulerCycle,after=insertIndex,values=cycle[-1])
}
curNode <- getAnUnexploredNode(g, nodes=eulerCycle)
}
return(eulerCycle)
}
getAnUnexploredNode <- function(g, nodes){
degrees <- degree(g, Nodes=nodes)
nodeIndexes <- which(degrees$outDegree+degrees$inDegree>0)
node <- NA
if(length(nodeIndexes)>0){
node <- nodes[nodeIndexes[1]]
}
return(node)
}
randomWalkNext <- function(g, from){
outEdges <- edges(object=g, which=from)[[1]]
nextNode <- NA
if(length(outEdges)>0){
nextNode <- outEdges[1]
}
return(nextNode)
}
当我使用我感兴趣的图表运行以下代码时,
ec <- eulerCycle(g, start="6")
print(ec)
我得到以下输出。
[1] "6" "5" "4" "2" "1" "10" "3" "2" "6" "8" "7" "9" "6"
希望这会对其他人有所帮助。
答案 1 :(得分:1)
这里的问题是PairViz的eulerian
函数只会作用于偶数图形(即每个节点都是偶数的图形)。有关详细信息,请参阅http://www.inside-r.org/packages/cran/PairViz/docs/eulerian上的文档,并指出mk_euler_graph
(我认为)是mk_even_graph
的拼写错误。
要在R中查看此内容,请在创建图表后尝试此操作:
etour(g)
你会被告知:
Error in etour(g) : Graph must be an even graph.
如果您通过将代码的第一行更改为此来使图表无向:
g <- new("graphNEL", nodes=as.character(1:10), edgemode="undirected")
然后你会产生这个:
> g
A graphNEL graph with undirected edges
Number of Nodes = 10
Number of Edges = 12
> ecycle <- eulerian(g, weighted=F)
> ecycle
[1] "1" "10" "3" "2" "6" "8" "7" "9" "6" "5" "4" "2" "1"
>
这是图的无向版本的Euler循环。
据我所知,没有办法将eulerian
函数应用于这样的有向图。