Home > OS >  making sense of bfs and dfs
making sense of bfs and dfs

Time:12-09

I'm trying to make sense of the outputs of bfs and dfs. I have a mst of some 3d point clouds which i am performing registration on, from which I want to derive a sequence of pairwise registrations along the edges. These pairwise registrations rely on previous registrations starting from a seed subsample.

As such I am trying to get an ordered list of edges from a seed edge (or vertex) so that pairwise comparisons can be properly propagated through the tree.

I have been trying to use bfs and dfs but can't make sense of the outputs to construct my ordered edge list.

library(igraph)

edges <- data.frame(
  from = c(2,14,8,17,11,16,14,12,14,13,14,16,13,19,15,23,21,21,22,23,20,22),
  to   = c(1,1,2,2,3,3,4,5,5,6,7,8,9,10,11,13,16,18,18,18,19,20),
 dist  = c(1.7479352,4.1400081,0.9064689,0.5735992,0.7550112,1.3880579,1.6968155,
          1.0064647,2.7119138,2.4033570,3.7260517,1.1921137,2.0857017,0.2903520,
          1.4191598,0.6111305,1.5752026,1.3102844,0.5070067,0.6522495,0.3172266,
          0.6373009
))
g <- graph.data.frame(edges, directed = F)
plot(g)

https://i.stack.imgur.com/I5xd0.png

I then choose the seed as the pair with the largest distance between them and run bfs or dfs

seedPair <- edges[which.max(edges[,3]),1:2]
> seedPair
  row col
2  14   1

For simplicity I just directly input vertex 14 as the root

path <- bfs(g, root = 14, father = T, rank = T)
> path
$root
[1] 14

$mode
[1] "out"

$order
  23/23 vertices, named, from 192f5fa:
 [1] 20 19 22 10 18 23 21 13 16 6  9  8  3  2  11 17 1  15 14 4  5  7  12

$rank
 2 14  8 17 11 16 12 13 19 15 23 21 22 20  1  3  4  5  6  7  9 10 18 
14 19 12 16 15  9 23  8  2 18  6  7  3  1 17 13 20 21 10 22 11  4  5 

$father
  23/23 vertices, named, from 192f5fa:
 [1] 2  14 8  17 11 16 12 13 19 15 23 21 22 20 1  3  4  5  6  7  9  10 18
path <- dfs(g, root = 14, order = T, order.out = T, father = T)
> path
$root
[1] 13

$mode
[1] "out"

$order
  23/23 vertices, named, from 192f5fa:
 [1] 20 19 10 22 18 23 13 6  9  21 16 8  2  17 1  14 4  5  12 7  3  11 15

$order.out
  23/23 vertices, named, from 192f5fa:
 [1] 10 19 6  9  13 23 17 4  12 5  7  14 1  2  8  15 11 3  16 21 18 22 20

$father
  23/23 vertices, named, from 192f5fa:
 [1] 2  14 8  17 11 16 12 13 19 15 23 21 22 20 1  3  4  5  6  7  9  10 18

$dist
NULL

$neimode
[1] "out"

Looking at the mst, neither of these outputs make sense to me if I'm starting at vertex 14. dfs is more intuitive to me and is easier to follow the edge sequence, but I also don't understand why its returning the root as 13, but then actually starting at node 20.

I would very appreciate any help understanding these outputs, or alternative approaches to getting an ordered edge sequence from a seed location. Thanks!

CodePudding user response:

When I run.

edges <- data.frame(
  from = c(2,14,8,17,11,16,14,12,14,13,14,16,13,19,15,23,21,21,22,23,20,22),
  to   = c(1,1,2,2,3,3,4,5,5,6,7,8,9,10,11,13,16,18,18,18,19,20),
 dist  = c(1.7479352,4.1400081,0.9064689,0.5735992,0.7550112,1.3880579,1.6968155,
          1.0064647,2.7119138,2.4033570,3.7260517,1.1921137,2.0857017,0.2903520,
          1.4191598,0.6111305,1.5752026,1.3102844,0.5070067,0.6522495,0.3172266,
          0.6373009
))
g <- graph.data.frame(edges, directed = F)
V(g)$name <- seq(vcount(g))   # ! Reset node n to "n".
>g

The resulting graph is.

IGRAPH 902edcd UN-- 23 22 -- 
  attr: name (v/c), dist (e/n)
  edges from 902edcd (vertex names):
 [1] 1 --15 2 --15 1 --3  1 --4  5 --16 6 --16 2 --17 7 --18 2 --18 8 --19 2 --20 3 --6  8 --21 9 --22 5 --10 8 --11
[17] 6 --12 12--23 13--23 11--23 9 --14 13--14

Running dfs().

path <- dfs(g, root = 14, order = TRUE, order.out = TRUE, father = TRUE)
>path

This gives.

$root
[1] 13

$mode
[1] "out"

$order
  23/23 vertices, named, from e6365e8:
 [1] 14 9  22 13 23 11 8  19 21 12 6  3  1  4  15 2  17 18 7  20 16 5  10

$order.out
  23/23 vertices, named, from e6365e8:
 [1] 22 9  19 21 8  11 4  17 7  18 20 2  15 1  3  10 5  16 6  12 23 13 14

$father
  23/23 vertices, named, from e6365e8:
 [1] 1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20 21 22 23

$dist
NULL

$neimode
[1] "out"

Which is different then the output in the question, The reason being the statement V(g)$name <- seq(vcount(g)). Without this statement V(g)[14] is 20, due to the data frame logic.

The following code implements a simple dfs() search.

visit <- function(g, v){
  if (length(visited)>0L && !visited[v]) {
    cat("order: ", v, '\n')
    visited[v] <<- 1L
    for (w in V(g)[.nei(v)]) visit(g, w)
    cat("order.out: ", v, '\n')
    }
  }
 
# Call dfs()
  visited <- rep(0L, gorder(g))
  visit(g, 14)

According to the docs, $order.out is a numeric vector, the vertex ids, in the order of the completion of their subtree. $order shows the vertex ids at entry.

Try a simple graph, like make_ring(10), to check the logic.

Hope this helps.

  • Related