Skip to content
Merged
112 changes: 79 additions & 33 deletions R/structural.properties.R
Original file line number Diff line number Diff line change
Expand Up @@ -292,12 +292,13 @@ graph.knn <- function(graph, vids = V(graph), mode = c("all", "out", "in", "tota
#'
#' `graph.dfs()` was renamed to `dfs()` to create a more
#' consistent API.
#' @param father Logical scalar, whether to return the father of the vertices.
Comment thread
maelle marked this conversation as resolved.
#' @inheritParams dfs
#' @keywords internal
#' @export
graph.dfs <- function(graph, root, mode = c("out", "in", "all", "total"), unreachable = TRUE, order = TRUE, order.out = FALSE, father = FALSE, dist = FALSE, in.callback = NULL, out.callback = NULL, extra = NULL, rho = parent.frame(), neimode) { # nocov start
lifecycle::deprecate_soft("2.0.0", "graph.dfs()", "dfs()")
dfs(graph = graph, root = root, mode = mode, unreachable = unreachable, order = order, order.out = order.out, father = father, dist = dist, in.callback = in.callback, out.callback = out.callback, extra = extra, rho = rho, neimode = neimode)
dfs(graph = graph, root = root, mode = mode, unreachable = unreachable, order = order, order.out = order.out, parent = father, dist = dist, in.callback = in.callback, out.callback = out.callback, extra = extra, rho = rho, neimode = neimode)
} # nocov end

#' Graph density
Expand Down Expand Up @@ -338,11 +339,12 @@ graph.coreness <- function(graph, mode = c("all", "out", "in")) { # nocov start
#' `graph.bfs()` was renamed to `bfs()` to create a more
#' consistent API.
#' @inheritParams bfs
#' @param father Logical scalar, whether to return the father of the vertices.
#' @keywords internal
#' @export
graph.bfs <- function(graph, root, mode = c("out", "in", "all", "total"), unreachable = TRUE, restricted = NULL, order = TRUE, rank = FALSE, father = FALSE, pred = FALSE, succ = FALSE, dist = FALSE, callback = NULL, extra = NULL, rho = parent.frame(), neimode) { # nocov start
lifecycle::deprecate_soft("2.0.0", "graph.bfs()", "bfs()")
bfs(graph = graph, root = root, mode = mode, unreachable = unreachable, restricted = restricted, order = order, rank = rank, father = father, pred = pred, succ = succ, dist = dist, callback = callback, extra = extra, rho = rho, neimode = neimode)
bfs(graph = graph, root = root, mode = mode, unreachable = unreachable, restricted = restricted, order = order, rank = rank, parent = father, pred = pred, succ = succ, dist = dist, callback = callback, extra = extra, rho = rho, neimode = neimode)
} # nocov end

#' Diameter of a graph
Expand Down Expand Up @@ -2053,7 +2055,8 @@ any_loop <- has_loop_impl
#' given vertices.
#' @param order Logical scalar, whether to return the ordering of the vertices.
#' @param rank Logical scalar, whether to return the rank of the vertices.
#' @param father Logical scalar, whether to return the father of the vertices.
#' @param father `r lifecycle::badge("deprecated")` Use `parent` instead.
#' @param parent Logical scalar, whether to return the parent of the vertices.
#' @param pred Logical scalar, whether to return the predecessors of the
#' vertices.
#' @param succ Logical scalar, whether to return the successors of the
Expand All @@ -2066,6 +2069,7 @@ any_loop <- has_loop_impl
#' @param rho The environment in which the callback function is evaluated.
#' @param neimode `r lifecycle::badge("deprecated")` This argument is deprecated
#' from igraph 1.3.0; use `mode` instead.
#' @inheritParams rlang::args_dots_empty
#' @return A named list with the following entries:
#' \item{root}{Numeric scalar.
#' The root vertex that was used as the starting point of the search.}
Expand All @@ -2075,8 +2079,9 @@ any_loop <- has_loop_impl
#' \item{order}{Numeric vector. The
#' vertex ids, in the order in which they were visited by the search.}
#' \item{rank}{Numeric vector. The rank for each vertex, zero for unreachable vertices.}
#' \item{father}{Numeric
#' vector. The father of each vertex, i.e. the vertex it was discovered from.}
#' \item{parent}{Numeric
#' vector. The parent of each vertex, i.e. the vertex it was discovered from.}
#' \item{father}{Like parent, kept for compatibility for now.}
#' \item{pred}{Numeric vector. The previously visited vertex for each vertex,
#' or 0 if there was no such vertex.}
#' \item{succ}{Numeric vector. The next
Expand All @@ -2086,7 +2091,7 @@ any_loop <- has_loop_impl
#' root of the search tree. Unreachable vertices have a negative distance
#' as of igraph 1.6.0, this used to be `NaN`.}
#'
#' Note that `order`, `rank`, `father`, `pred`, `succ`
#' Note that `order`, `rank`, `parent`, `pred`, `succ`
#' and `dist` might be `NULL` if their corresponding argument is
#' `FALSE`, i.e. if their calculation is not requested.
#' @author Gabor Csardi \email{csardi.gabor@@gmail.com}
Expand All @@ -2099,7 +2104,7 @@ any_loop <- has_loop_impl
#' ## Two rings
#' bfs(make_ring(10) %du% make_ring(10),
#' root = 1, "out",
#' order = TRUE, rank = TRUE, father = TRUE, pred = TRUE,
#' order = TRUE, rank = TRUE, parent = TRUE, pred = TRUE,
#' succ = TRUE, dist = TRUE
#' )
#'
Expand All @@ -2124,28 +2129,40 @@ bfs <- function(
graph,
root,
mode = c("out", "in", "all", "total"),
...,
unreachable = TRUE,
restricted = NULL,
order = TRUE,
rank = FALSE,
father = FALSE,
parent = FALSE,
pred = FALSE,
succ = FALSE,
dist = FALSE,
callback = NULL,
extra = NULL,
rho = parent.frame(),
neimode = deprecated()) {
neimode = deprecated(),
father = deprecated()) {

rlang::check_dots_empty()

ensure_igraph(graph)

if (lifecycle::is_present(neimode)) {
lifecycle::deprecate_stop(
"1.3.0",
"bfs(neimode)",
"bfs(mode)"
"bfs(neimode = )",
"bfs(mode = )"
)
}

if (lifecycle::is_present(father)) {
lifecycle::deprecate_warn("2.2.0", "bfs(father = )", "bfs(parent = )")
if (missing(parent)) {
parent <- father
}
}

if (length(root) == 1) {
root <- as_igraph_vs(graph, root) - 1
roots <- NULL
Expand All @@ -2171,7 +2188,7 @@ bfs <- function(
res <- .Call(
R_igraph_bfs, graph, root, roots, mode, unreachable,
restricted,
as.logical(order), as.logical(rank), as.logical(father),
as.logical(order), as.logical(rank), as.logical(parent),
as.logical(pred), as.logical(succ), as.logical(dist),
callback, extra, rho
)
Expand All @@ -2181,13 +2198,13 @@ bfs <- function(

if (order) res$order <- res$order + 1
if (rank) res$rank <- res$rank + 1
if (father) res$father <- res$father + 1
if (parent) res$parent <- res$parent + 1
if (pred) res$pred <- res$pred + 1
if (succ) res$succ <- res$succ + 1

if (igraph_opt("return.vs.es")) {
if (order) res$order <- V(graph)[.env$res$order, na_ok = TRUE]
if (father) res$father <- create_vs(graph, res$father, na_ok = TRUE)
if (parent) res$parent <- create_vs(graph, res$parent, na_ok = TRUE)
if (pred) res$pred <- create_vs(graph, res$pred, na_ok = TRUE)
if (succ) res$succ <- create_vs(graph, res$succ, na_ok = TRUE)
} else {
Expand All @@ -2196,7 +2213,7 @@ bfs <- function(

if (igraph_opt("add.vertex.names") && is_named(graph)) {
if (rank) names(res$rank) <- V(graph)$name
if (father) names(res$father) <- V(graph)$name
if (parent) names(res$parent) <- V(graph)$name
if (pred) names(res$pred) <- V(graph)$name
if (succ) names(res$succ) <- V(graph)$name
if (dist) names(res$dist) <- V(graph)$name
Expand All @@ -2210,6 +2227,9 @@ bfs <- function(
res$dist[is.nan(res$dist)] <- -3
}

# Remove this later? https://github.com/igraph/rigraph/issues/1576
res$father <- res$parent

res
}

Expand Down Expand Up @@ -2242,7 +2262,8 @@ bfs <- function(
#' vertices.
#' @param order.out Logical scalar, whether to return the ordering based on
#' leaving the subtree of the vertex.
#' @param father Logical scalar, whether to return the father of the vertices.
#' @param father `r lifecycle::badge("deprecated")`, use `parent` instead.
#' @param parent Logical scalar, whether to return the parent of the vertices.
#' @param dist Logical scalar, whether to return the distance from the root of
#' the search tree.
#' @param in.callback If not `NULL`, then it must be callback function.
Expand All @@ -2254,18 +2275,21 @@ bfs <- function(
#' @param rho The environment in which the callback function is evaluated.
#' @param neimode `r lifecycle::badge("deprecated")` This argument is deprecated from igraph 1.3.0; use
#' `mode` instead.
#' @inheritParams rlang::args_dots_empty
#' @return A named list with the following entries: \item{root}{Numeric scalar.
#' The root vertex that was used as the starting point of the search.}
#' \item{neimode}{Character scalar. The `mode` argument of the function
#' call. Note that for undirected graphs this is always \sQuote{all},
#' irrespectively of the supplied value.} \item{order}{Numeric vector. The
#' vertex ids, in the order in which they were visited by the search.}
#' \item{order.out}{Numeric vector, the vertex ids, in the order of the
#' completion of their subtree.} \item{father}{Numeric vector. The father of
#' each vertex, i.e. the vertex it was discovered from.} \item{dist}{Numeric
#' completion of their subtree.} \item{parent}{Numeric vector. The parent of
#' each vertex, i.e. the vertex it was discovered from.}
#' \item{father}{Like parent, kept for compatibility for now.}
#' \item{dist}{Numeric
#' vector, for each vertex its distance from the root of the search tree.}
#'
#' Note that `order`, `order.out`, `father`, and `dist`
#' Note that `order`, `order.out`, `parent`, and `dist`
#' might be `NULL` if their corresponding argument is `FALSE`, i.e.
#' if their calculation is not requested.
#' @author Gabor Csardi \email{csardi.gabor@@gmail.com}
Expand All @@ -2276,9 +2300,13 @@ bfs <- function(
#' @examples
#'
#' ## A graph with two separate trees
#' dfs(make_tree(10) %du% make_tree(10),
#' root = 1, "out",
#' TRUE, TRUE, TRUE, TRUE
#' dfs(
#' graph = make_tree(10) %du% make_tree(10),
#' root = 1, mode = "out",
#' unreachable = TRUE,
#' order = TRUE,
#' order.out = TRUE,
#' parent = TRUE
#' )
#'
#' ## How to use a callback
Expand All @@ -2290,34 +2318,49 @@ bfs <- function(
#' cat("out:", paste(collapse = ", ", data), "\n")
#' FALSE
#' }
#' tmp <- dfs(make_tree(10),
#' root = 1, "out",
#' tmp <- dfs(
#' graph = make_tree(10),
#' root = 1, mode = "out",
#' in.callback = f.in, out.callback = f.out
#' )
#'
#' ## Terminate after the first component, using a callback
#' f.out <- function(graph, data, extra) {
#' data["vid"] == 1
#' }
#' tmp <- dfs(make_tree(10) %du% make_tree(10),
#' tmp <- dfs(
#' graph = make_tree(10) %du% make_tree(10),
#' root = 1,
#' out.callback = f.out
#' )
#'
dfs <- function(graph, root, mode = c("out", "in", "all", "total"),
Comment thread
maelle marked this conversation as resolved.
...,
unreachable = TRUE,
order = TRUE, order.out = FALSE, father = FALSE, dist = FALSE,
order = TRUE, order.out = FALSE,
parent = FALSE, dist = FALSE,
in.callback = NULL, out.callback = NULL, extra = NULL,
rho = parent.frame(), neimode = deprecated()) {
rho = parent.frame(), neimode = deprecated(),
father = deprecated()) {

rlang::check_dots_empty()

ensure_igraph(graph)
if (lifecycle::is_present(neimode)) {
lifecycle::deprecate_stop(
"1.3.0",
"dfs(neimode)",
"dfs(mode)"
"dfs(neimode = )",
"dfs(mode = )"
)
}

if (lifecycle::is_present(father)) {
lifecycle::deprecate_warn("2.2.0", "dfs(father = )", "dfs(parent = )")
if (missing(parent)) {
parent <- father
}
}

root <- as_igraph_vs(graph, root) - 1
mode <- switch(igraph.match.arg(mode),
"out" = 1,
Expand All @@ -2336,7 +2379,7 @@ dfs <- function(graph, root, mode = c("out", "in", "all", "total"),
on.exit(.Call(R_igraph_finalizer))
res <- .Call(
R_igraph_dfs, graph, root, mode, unreachable,
as.logical(order), as.logical(order.out), as.logical(father),
as.logical(order), as.logical(order.out), as.logical(parent),
as.logical(dist), in.callback, out.callback, extra, rho
)

Expand All @@ -2345,22 +2388,25 @@ dfs <- function(graph, root, mode = c("out", "in", "all", "total"),

if (order) res$order <- res$order + 1
if (order.out) res$order.out <- res$order.out + 1
if (father) res$father <- res$father + 1
if (parent) res$parent <- res$parent + 1

if (igraph_opt("return.vs.es")) {
if (order) res$order <- V(graph)[.env$res$order, na_ok = TRUE]
if (order.out) res$order.out <- V(graph)[.env$res$order.out, na_ok = TRUE]
if (father) res$father <- create_vs(graph, res$father, na_ok = TRUE)
if (parent) res$parent <- create_vs(graph, res$parent, na_ok = TRUE)
} else {
if (order) res$order <- res$order[res$order != 0]
if (order.out) res$order.out <- res$order.out[res$order.out != 0]
}

if (igraph_opt("add.vertex.names") && is_named(graph)) {
if (father) names(res$father) <- V(graph)$name
if (parent) names(res$parent) <- V(graph)$name
if (dist) names(res$dist) <- V(graph)$name
}

# Remove this later? https://github.com/igraph/rigraph/issues/1576
res$father <- res$parent

res
}

Expand Down
21 changes: 14 additions & 7 deletions man/bfs.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading