使用R(v 3.0.2)中的PairViz包查找euler循环

时间:2014-02-13 07:24:06

标签: r igraph

我正在尝试使用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)运行此代码。

提前致谢。

阿希斯。

2 个答案:

答案 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函数应用于这样的有向图。