Skip to content

Commit

Permalink
feat: simple_cycles()
Browse files Browse the repository at this point in the history
  • Loading branch information
szhorvat committed Nov 12, 2024
1 parent 3b7839f commit e63943b
Show file tree
Hide file tree
Showing 11 changed files with 130 additions and 25 deletions.
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,7 @@ export(similarity)
export(similarity.dice)
export(similarity.invlogweighted)
export(similarity.jaccard)
export(simple_cycles)
export(simplified)
export(simplify)
export(simplify_and_colorize)
Expand Down
19 changes: 0 additions & 19 deletions R/aaa-auto.R
Original file line number Diff line number Diff line change
Expand Up @@ -3580,25 +3580,6 @@ find_cycle_impl <- function(graph, mode=c("out", "in", "all", "total")) {
res
}

simple_cycles_impl <- function(graph, mode=c("out", "in", "all", "total"), min.cycle.length=-1, max.cycle.length=-1) {
# Argument checks
ensure_igraph(graph)
mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L)
min.cycle.length <- as.numeric(min.cycle.length)
max.cycle.length <- as.numeric(max.cycle.length)

on.exit( .Call(R_igraph_finalizer) )
# Function call
res <- .Call(R_igraph_simple_cycles, graph, mode, min.cycle.length, max.cycle.length)
if (igraph_opt("return.vs.es")) {
res$vertices <- lapply(res$vertices, unsafe_create_vs, graph = graph, verts = V(graph))
}
if (igraph_opt("return.vs.es")) {
res$edges <- lapply(res$edges, unsafe_create_es, graph = graph, es = E(graph))
}
res
}

is_eulerian_impl <- function(graph) {
# Argument checks
ensure_igraph(graph)
Expand Down
56 changes: 56 additions & 0 deletions R/cycles.R
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,59 @@
#' @export

find_cycle <- find_cycle_impl


#' Finds all simple cycles in a graph.
#'
#' @description
#' `r lifecycle::badge("experimental")`
#'
#' This function lists all simple cycles in a graph within a range of cycle
#' lengths. A cycle is called simple if it has no repeated vertices.
#'
#' Multi-edges and self-loops are taken into account. Note that graph can have
#' exponentially many cycles and the presence of multi-edges exacerbates this
#' combinatorial explosion.
#'
#' @inheritParams find_cycle
#' @param min Lower limit on cycle lengths to consider. `NULL` means no limit.
#' @param max Upper limit on cycle lengths to consider. `NULL` means no limit.
#' @return A named list, with two entries:
#' \item{vertices}{The list of cycles in terms of their vertices.}
#' \item{edges}{The list of cycles in terms of their edges.}
#' @keywords graphs
#' @examples
#'
#' g <- graph_from_literal(A-+B-+C-+A-+D-+E+-F-+A, E-+E, A-+F, simplify=F)
#' simple_cycles(g)
#' simple_cycles(g, mode = "all") # ignore edge directions
#' simple_cycles(g, mode = "all", min = 2, max = 3) # limit cycle lengths
#'
#' @family cycles
#' @cdocs igraph_simple_cycles
#' @export

simple_cycles <- function(graph, mode=c("out", "in", "all", "total"), min=NULL, max=NULL) {
# Argument checks
ensure_igraph(graph)
mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L)

if (is.null(min)) {
min <- -1
}

if (is.null(max)) {
max <- -1
}

on.exit( .Call(R_igraph_finalizer) )
# Function call
res <- .Call(R_igraph_simple_cycles, graph, mode, as.numeric(min), as.numeric(max))
if (igraph_opt("return.vs.es")) {
res$vertices <- lapply(res$vertices, unsafe_create_vs, graph = graph, verts = V(graph))
}
if (igraph_opt("return.vs.es")) {
res$edges <- lapply(res$edges, unsafe_create_es, graph = graph, es = E(graph))
}
res
}
3 changes: 2 additions & 1 deletion man/feedback_arc_set.Rd

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

3 changes: 2 additions & 1 deletion man/find_cycle.Rd

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

3 changes: 2 additions & 1 deletion man/girth.Rd

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

3 changes: 2 additions & 1 deletion man/has_eulerian_path.Rd

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

3 changes: 2 additions & 1 deletion man/is_acyclic.Rd

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

3 changes: 2 additions & 1 deletion man/is_dag.Rd

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

60 changes: 60 additions & 0 deletions man/simple_cycles.Rd

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

1 change: 1 addition & 0 deletions tools/stimulus/functions-R.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1464,6 +1464,7 @@ igraph_solve_lsap:
igraph_find_cycle:

igraph_simple_cycles:
IGNORE: RR

igraph_simple_cycles_callback:
IGNORE: RR, RC
Expand Down

0 comments on commit e63943b

Please sign in to comment.