Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
586 views
in Technique[技术] by (71.8m points)

r - How to split an igraph into connected subgraphs?

I have an igraph with several disconnected components. For example:

library(igraph)
g <- simplify(
  graph.compose(
    graph.ring(10), 
    graph.star(5, mode = "undirected")
  )
) + edge("7", "8")

a plot of an igraph with several disconnected components

In this example, node 9 is its own graph, as are nodes 7 and 8, and the rest form a third graph.

I'd like to treat these separately, so I want to convert the single igraph into a list of 3 igraphs (split by connectedness).

I hacked some code to achieve this, but it's inefficient and fairly awful.

split_graph_into_connected_subgraphs <- function(g)
{
  adjacency_list <- get.adjlist(g)

  connected_nodes <- lapply(
    adjacency_list,
    function(adjacent_nodes)
    {
      new_nodes <- out <- adjacent_nodes
      # Keep finding nodes that are adjacent to ones we already know about,
      # until we find no more
      repeat
      {
        doubly_adjacent_nodes <- Reduce(union, adjacency_list[new_nodes])
        new_nodes <- setdiff(doubly_adjacent_nodes, out)
        if(length(new_nodes) == 0)
        {
          break
        }
        out <- union(out, new_nodes)      
      }
      sort(out)
    }
  )

  # Single value nodes should contain themselves, not be empty
  connected_nodes <- ifelse(
    vapply(adjacency_list, length, integer(1)) == 0,
    seq_along(connected_nodes),
    connected_nodes
  )

  # We don't care about repeats, just the unique graphs
  connected_nodes <- unique(connected_nodes)

  # Get the subgraph from each 
  lapply(
    connected_nodes,
    function(nodes) induced.subgraph(g, nodes)
  )
}

list_of_subgraphs <- split_graph_into_connected_subgraphs(g)
lapply(list_of_subgraphs, plot)

Is there a cleaner way of splitting the graph?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You could calculate the connected components of your graph by using:

clusters(g)
# $membership
# [1] 1 1 1 1 1 1 2 2 3 1
# 
# $csize
# [1] 7 2 1
# 
# $no
# [1] 3

Or you could create a separate graph for each component of your graph by using:

dg <- decompose.graph(g) # returns a list of three graphs
plot(dg[[1]]) # plot e.g. the 1st one

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...