From 31bfea47a934afb8005b7c5a10fce107ed513390 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Horva=CC=81t?= Date: Thu, 1 Feb 2024 21:47:12 +0000 Subject: [PATCH] feat: distances() now supports the Floyd-Warshall algorithm --- R/structural.properties.R | 11 +++++++---- man/distances.Rd | 9 ++++++--- src/rinterface_extra.c | 3 +++ 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/R/structural.properties.R b/R/structural.properties.R index 0838746588..f86f93b529 100644 --- a/R/structural.properties.R +++ b/R/structural.properties.R @@ -677,8 +677,10 @@ degree_distribution <- function(graph, cumulative = FALSE, ...) { #' are breadth-first search (\sQuote{`unweighted`}), this only works for #' unweighted graphs; the Dijkstra algorithm (\sQuote{`dijkstra`}), this #' works for graphs with non-negative edge weights; the Bellman-Ford algorithm -#' (\sQuote{`bellman-ford`}), and Johnson's algorithm -#' (\sQuote{`johnson`}). The latter two algorithms work with arbitrary +#' (\sQuote{`bellman-ford`}); Johnson's algorithm +#' (\sQuote{`johnson`}); and a faster version of the Floyd-Warshall algorithm +#' with expected quadratic running time (\sQuote{`floyd-warshall`}). The latter +#' three algorithms work with arbitrary #' edge weights, but (naturally) only for graphs that don't have a negative #' cycle. Note that a negative-weight edge in an undirected graph implies #' such a cycle. Johnson's algorithm performs better than the Bellman-Ford @@ -833,7 +835,7 @@ distances <- function(graph, v = V(graph), to = V(graph), weights = NULL, algorithm = c( "automatic", "unweighted", "dijkstra", - "bellman-ford", "johnson" + "bellman-ford", "johnson", "floyd-warshall" )) { ensure_igraph(graph) @@ -858,7 +860,8 @@ distances <- function(graph, v = V(graph), to = V(graph), "unweighted" = 1, "dijkstra" = 2, "bellman-ford" = 3, - "johnson" = 4 + "johnson" = 4, + "floyd-warshall" = 5 ) if (is.null(weights)) { diff --git a/man/distances.Rd b/man/distances.Rd index 46c437c4d5..6e48a7114a 100644 --- a/man/distances.Rd +++ b/man/distances.Rd @@ -24,7 +24,8 @@ distances( to = V(graph), mode = c("all", "out", "in"), weights = NULL, - algorithm = c("automatic", "unweighted", "dijkstra", "bellman-ford", "johnson") + algorithm = c("automatic", "unweighted", "dijkstra", "bellman-ford", "johnson", + "floyd-warshall") ) shortest_paths( @@ -176,8 +177,10 @@ the \code{weight} edge attribute of the graph. The implemented algorithms are breadth-first search (\sQuote{\code{unweighted}}), this only works for unweighted graphs; the Dijkstra algorithm (\sQuote{\code{dijkstra}}), this works for graphs with non-negative edge weights; the Bellman-Ford algorithm -(\sQuote{\code{bellman-ford}}), and Johnson's algorithm -(\sQuote{\code{johnson}}). The latter two algorithms work with arbitrary +(\sQuote{\code{bellman-ford}}); Johnson's algorithm +(\sQuote{\code{johnson}}); and a faster version of the Floyd-Warshall algorithm +with expected quadratic running time (\sQuote{\code{floyd-warshall}}). The latter +three algorithms work with arbitrary edge weights, but (naturally) only for graphs that don't have a negative cycle. Note that a negative-weight edge in an undirected graph implies such a cycle. Johnson's algorithm performs better than the Bellman-Ford diff --git a/src/rinterface_extra.c b/src/rinterface_extra.c index d17db2561b..ea5036647e 100644 --- a/src/rinterface_extra.c +++ b/src/rinterface_extra.c @@ -4264,6 +4264,9 @@ SEXP R_igraph_shortest_paths(SEXP graph, SEXP pvids, SEXP pto, case 4: /* johnson */ IGRAPH_R_CHECK(distances_johnson(&g, &res, vs, to, pw, mode, negw)); break; + case 5: /* floyd-warshall */ + IGRAPH_R_CHECK(igraph_distances_floyd_warshall(&g, &res, vs, to, pw, mode, IGRAPH_FLOYD_WARSHALL_AUTOMATIC)); + break; } PROTECT(result=R_igraph_matrix_to_SEXP(&res)); igraph_matrix_destroy(&res);