From 508fb8028321814005744b9656e9c9a2972f1716 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Horva=CC=81t?= Date: Sat, 30 Dec 2023 20:49:57 +0000 Subject: [PATCH 1/3] import check_dots_empty() --- NAMESPACE | 1 + R/igraph-package.R | 1 + 2 files changed, 2 insertions(+) diff --git a/NAMESPACE b/NAMESPACE index 3ad0778d3fe..e05ca94aa0f 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -914,6 +914,7 @@ importFrom(pkgconfig,set_config) importFrom(pkgconfig,set_config_in) importFrom(rlang,.data) importFrom(rlang,.env) +importFrom(rlang,check_dots_empty) importFrom(rlang,check_installed) importFrom(rlang,inject) importFrom(rlang,warn) diff --git a/R/igraph-package.R b/R/igraph-package.R index 1413f772a88..fcc2c1e54f7 100644 --- a/R/igraph-package.R +++ b/R/igraph-package.R @@ -5,6 +5,7 @@ #' @importFrom lifecycle deprecated #' @importFrom magrittr %>% #' @importFrom rlang .data .env +#' @importFrom rlang check_dots_empty #' @importFrom rlang check_installed #' @importFrom rlang inject #' @importFrom rlang warn From fc61c8ce8ca44ade62ec0b91fb9c087f41658d80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Horva=CC=81t?= Date: Thu, 28 Dec 2023 22:27:55 +0000 Subject: [PATCH 2/3] feat: k_shortest_paths() --- NAMESPACE | 1 + R/aaa-auto.R | 9 ++-- R/structural.properties.R | 28 ++++++++++- man/bfs.Rd | 1 + man/components.Rd | 1 + man/constraint.Rd | 1 + man/coreness.Rd | 1 + man/degree.Rd | 1 + man/dfs.Rd | 1 + man/distances.Rd | 1 + man/edge_density.Rd | 1 + man/ego.Rd | 1 + man/feedback_arc_set.Rd | 1 + man/girth.Rd | 1 + man/is_acyclic.Rd | 1 + man/is_dag.Rd | 1 + man/k_shortest_paths.Rd | 86 +++++++++++++++++++++++++++++++++ man/knn.Rd | 1 + man/laplacian_matrix.Rd | 1 + man/matching.Rd | 1 + man/reciprocity.Rd | 1 + man/subcomponent.Rd | 1 + man/subgraph.Rd | 1 + man/topo_sort.Rd | 1 + man/transitivity.Rd | 1 + man/unfold_tree.Rd | 1 + man/which_multiple.Rd | 1 + man/which_mutual.Rd | 1 + src/rinterface.c | 4 +- tools/stimulus/functions-R.yaml | 4 ++ 30 files changed, 148 insertions(+), 8 deletions(-) create mode 100644 man/k_shortest_paths.Rd diff --git a/NAMESPACE b/NAMESPACE index e05ca94aa0f..e262d25c6e0 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -564,6 +564,7 @@ export(isomorphisms) export(ivs) export(ivs_size) export(k.regular.game) +export(k_shortest_paths) export(kautz_graph) export(keeping_degseq) export(knn) diff --git a/R/aaa-auto.R b/R/aaa-auto.R index 8fb90e616fd..9b0d2267b8a 100644 --- a/R/aaa-auto.R +++ b/R/aaa-auto.R @@ -796,8 +796,9 @@ voronoi_impl <- function(graph, generators, weights=NULL, mode=c("out", "in", "a res } -get_k_shortest_paths_impl <- function(graph, weights=NULL, k, from, to, mode=c("out", "in", "all", "total")) { +get_k_shortest_paths_impl <- function(graph, from, to, ..., k, weights=NULL, mode=c("out", "in", "all", "total")) { # Argument checks + check_dots_empty() ensure_igraph(graph) if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { weights <- E(graph)$weight @@ -822,10 +823,10 @@ get_k_shortest_paths_impl <- function(graph, weights=NULL, k, from, to, mode=c(" # Function call res <- .Call(R_igraph_get_k_shortest_paths, graph, weights, k, from-1, to-1, mode) if (igraph_opt("return.vs.es")) { - res$vertex.paths <- lapply(res$vertex.paths, unsafe_create_vs, graph = graph, verts = V(graph)) + res$vpaths <- lapply(res$vpaths, unsafe_create_vs, graph = graph, verts = V(graph)) } if (igraph_opt("return.vs.es")) { - res$edge.paths <- lapply(res$edge.paths, unsafe_create_es, graph = graph, es = E(graph)) + res$epaths <- lapply(res$epaths, unsafe_create_es, graph = graph, es = E(graph)) } res } @@ -1196,7 +1197,7 @@ ecc_impl <- function(graph, eids=E(graph), k=3, offset=FALSE, normalize=TRUE) { res } -reciprocity_impl <- function(graph, ignore.loops=TRUE, mode=c('default', 'ratio')) { +reciprocity_impl <- function(graph, ignore.loops=TRUE, mode=c("default", "ratio")) { # Argument checks ensure_igraph(graph) ignore.loops <- as.logical(ignore.loops) diff --git a/R/structural.properties.R b/R/structural.properties.R index b7bc4d3b20f..fdc5d43bb17 100644 --- a/R/structural.properties.R +++ b/R/structural.properties.R @@ -1056,6 +1056,32 @@ all_shortest_paths <- function(graph, from, res } +#' Find the \eqn{k} shortest paths between two vertices +#' +#' Finds the \eqn{k} shortest paths between the given source and target +#' vertex in order of increasing length. Currently this function uses +#' Yen's algorithm. +#' +#' @param graph The input graph. +#' @param from The source vertex of the shortest paths. +#' @param to The target vertex of the shortest paths. +#' @param k The number of paths to find. They will be returned in order of +#' increasing length. +#' @inheritParams shortest_paths +#' @return A named list with two components is returned: +#' \item{vpaths}{The list of \eqn{k} shortest paths in terms of vertices} +#' \item{epaths}{The list of \eqn{k} shortest paths in terms of edges} +#' @references Yen, Jin Y.: +#' An algorithm for finding shortest routes from all source nodes to a given +#' destination in general networks. +#' Quarterly of Applied Mathematics. 27 (4): 526–530. (1970) +#' +#' @export +#' @family structural.properties +#' @seealso [shortest_paths()], [all_shortest_paths()] +#' @keywords graphs +k_shortest_paths <- get_k_shortest_paths_impl + #' In- or out- component of a vertex #' #' Finds all vertices reachable from a given vertex, or the opposite: all @@ -1103,8 +1129,6 @@ subcomponent <- function(graph, v, mode = c("all", "out", "in")) { res } - - #' Subgraph of a graph #' #' `subgraph()` creates a subgraph of a graph, containing only the specified diff --git a/man/bfs.Rd b/man/bfs.Rd index 3d87cba237b..6555e97ab0e 100644 --- a/man/bfs.Rd +++ b/man/bfs.Rd @@ -157,6 +157,7 @@ Other structural.properties: \code{\link{is_acyclic}()}, \code{\link{is_dag}()}, \code{\link{is_matching}()}, +\code{\link{k_shortest_paths}()}, \code{\link{knn}()}, \code{\link{laplacian_matrix}()}, \code{\link{reciprocity}()}, diff --git a/man/components.Rd b/man/components.Rd index 8e691926e4b..9a75d2cc873 100644 --- a/man/components.Rd +++ b/man/components.Rd @@ -105,6 +105,7 @@ Other structural.properties: \code{\link{is_acyclic}()}, \code{\link{is_dag}()}, \code{\link{is_matching}()}, +\code{\link{k_shortest_paths}()}, \code{\link{knn}()}, \code{\link{laplacian_matrix}()}, \code{\link{reciprocity}()}, diff --git a/man/constraint.Rd b/man/constraint.Rd index 5071e4fe04f..3d5075ae542 100644 --- a/man/constraint.Rd +++ b/man/constraint.Rd @@ -66,6 +66,7 @@ Other structural.properties: \code{\link{is_acyclic}()}, \code{\link{is_dag}()}, \code{\link{is_matching}()}, +\code{\link{k_shortest_paths}()}, \code{\link{knn}()}, \code{\link{laplacian_matrix}()}, \code{\link{reciprocity}()}, diff --git a/man/coreness.Rd b/man/coreness.Rd index e8036699c3e..701cfa17c8e 100644 --- a/man/coreness.Rd +++ b/man/coreness.Rd @@ -61,6 +61,7 @@ Other structural.properties: \code{\link{is_acyclic}()}, \code{\link{is_dag}()}, \code{\link{is_matching}()}, +\code{\link{k_shortest_paths}()}, \code{\link{knn}()}, \code{\link{laplacian_matrix}()}, \code{\link{reciprocity}()}, diff --git a/man/degree.Rd b/man/degree.Rd index e7f49c3f960..ae5820b782b 100644 --- a/man/degree.Rd +++ b/man/degree.Rd @@ -71,6 +71,7 @@ Other structural.properties: \code{\link{is_acyclic}()}, \code{\link{is_dag}()}, \code{\link{is_matching}()}, +\code{\link{k_shortest_paths}()}, \code{\link{knn}()}, \code{\link{laplacian_matrix}()}, \code{\link{reciprocity}()}, diff --git a/man/dfs.Rd b/man/dfs.Rd index 91fa4acca7b..678a94412df 100644 --- a/man/dfs.Rd +++ b/man/dfs.Rd @@ -138,6 +138,7 @@ Other structural.properties: \code{\link{is_acyclic}()}, \code{\link{is_dag}()}, \code{\link{is_matching}()}, +\code{\link{k_shortest_paths}()}, \code{\link{knn}()}, \code{\link{laplacian_matrix}()}, \code{\link{reciprocity}()}, diff --git a/man/distances.Rd b/man/distances.Rd index 4b1ee5ef1bf..46c437c4d51 100644 --- a/man/distances.Rd +++ b/man/distances.Rd @@ -268,6 +268,7 @@ Other structural.properties: \code{\link{is_acyclic}()}, \code{\link{is_dag}()}, \code{\link{is_matching}()}, +\code{\link{k_shortest_paths}()}, \code{\link{knn}()}, \code{\link{laplacian_matrix}()}, \code{\link{reciprocity}()}, diff --git a/man/edge_density.Rd b/man/edge_density.Rd index 3c3340b821f..9769851c498 100644 --- a/man/edge_density.Rd +++ b/man/edge_density.Rd @@ -63,6 +63,7 @@ Other structural.properties: \code{\link{is_acyclic}()}, \code{\link{is_dag}()}, \code{\link{is_matching}()}, +\code{\link{k_shortest_paths}()}, \code{\link{knn}()}, \code{\link{laplacian_matrix}()}, \code{\link{reciprocity}()}, diff --git a/man/ego.Rd b/man/ego.Rd index e6d3bc34879..037d1d298a5 100644 --- a/man/ego.Rd +++ b/man/ego.Rd @@ -188,6 +188,7 @@ Other structural.properties: \code{\link{is_acyclic}()}, \code{\link{is_dag}()}, \code{\link{is_matching}()}, +\code{\link{k_shortest_paths}()}, \code{\link{knn}()}, \code{\link{laplacian_matrix}()}, \code{\link{reciprocity}()}, diff --git a/man/feedback_arc_set.Rd b/man/feedback_arc_set.Rd index 7b780162fcc..a39d6b15ece 100644 --- a/man/feedback_arc_set.Rd +++ b/man/feedback_arc_set.Rd @@ -64,6 +64,7 @@ Other structural.properties: \code{\link{is_acyclic}()}, \code{\link{is_dag}()}, \code{\link{is_matching}()}, +\code{\link{k_shortest_paths}()}, \code{\link{knn}()}, \code{\link{laplacian_matrix}()}, \code{\link{reciprocity}()}, diff --git a/man/girth.Rd b/man/girth.Rd index b695e16b73f..1d80a137262 100644 --- a/man/girth.Rd +++ b/man/girth.Rd @@ -65,6 +65,7 @@ Other structural.properties: \code{\link{is_acyclic}()}, \code{\link{is_dag}()}, \code{\link{is_matching}()}, +\code{\link{k_shortest_paths}()}, \code{\link{knn}()}, \code{\link{laplacian_matrix}()}, \code{\link{reciprocity}()}, diff --git a/man/is_acyclic.Rd b/man/is_acyclic.Rd index 80137d0e8b6..d4a2f4e36cc 100644 --- a/man/is_acyclic.Rd +++ b/man/is_acyclic.Rd @@ -49,6 +49,7 @@ Other structural.properties: \code{\link{girth}()}, \code{\link{is_dag}()}, \code{\link{is_matching}()}, +\code{\link{k_shortest_paths}()}, \code{\link{knn}()}, \code{\link{laplacian_matrix}()}, \code{\link{reciprocity}()}, diff --git a/man/is_dag.Rd b/man/is_dag.Rd index 7504e4ae01c..ab9ff545611 100644 --- a/man/is_dag.Rd +++ b/man/is_dag.Rd @@ -49,6 +49,7 @@ Other structural.properties: \code{\link{girth}()}, \code{\link{is_acyclic}()}, \code{\link{is_matching}()}, +\code{\link{k_shortest_paths}()}, \code{\link{knn}()}, \code{\link{laplacian_matrix}()}, \code{\link{reciprocity}()}, diff --git a/man/k_shortest_paths.Rd b/man/k_shortest_paths.Rd new file mode 100644 index 00000000000..15b6b77fbd9 --- /dev/null +++ b/man/k_shortest_paths.Rd @@ -0,0 +1,86 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/structural.properties.R +\name{k_shortest_paths} +\alias{k_shortest_paths} +\title{Find the \eqn{k} shortest paths between two vertices} +\usage{ +k_shortest_paths( + graph, + from, + to, + ..., + k, + weights = NULL, + mode = c("out", "in", "all", "total") +) +} +\arguments{ +\item{graph}{The input graph.} + +\item{from}{The source vertex of the shortest paths.} + +\item{to}{The target vertex of the shortest paths.} + +\item{k}{The number of paths to find. They will be returned in order of +increasing length.} + +\item{weights}{Possibly a numeric vector giving edge weights. If this is +\code{NULL} and the graph has a \code{weight} edge attribute, then the +attribute is used. If this is \code{NA} then no weights are used (even if +the graph has a \code{weight} attribute).} + +\item{mode}{Character constant, gives whether the shortest paths to or from +the given vertices should be calculated for directed graphs. If \code{out} +then the shortest paths \emph{from} the vertex, if \verb{in} then \emph{to} +it will be considered. If \code{all}, the default, then the corresponding +undirected graph will be used, i.e. not directed paths are searched. This +argument is ignored for undirected graphs.} +} +\value{ +A named list with two components is returned: +\item{vpaths}{The list of \eqn{k} shortest paths in terms of vertices} +\item{epaths}{The list of \eqn{k} shortest paths in terms of edges} +} +\description{ +Finds the \eqn{k} shortest paths between the given source and target +vertex in order of increasing length. Currently this function uses +Yen's algorithm. +} +\references{ +Yen, Jin Y.: +An algorithm for finding shortest routes from all source nodes to a given +destination in general networks. +Quarterly of Applied Mathematics. 27 (4): 526–530. (1970) +\url{https://doi.org/10.1090/qam/253822} +} +\seealso{ +\code{\link[=shortest_paths]{shortest_paths()}}, \code{\link[=all_shortest_paths]{all_shortest_paths()}} + +Other structural.properties: +\code{\link{bfs}()}, +\code{\link{component_distribution}()}, +\code{\link{connect}()}, +\code{\link{constraint}()}, +\code{\link{coreness}()}, +\code{\link{degree}()}, +\code{\link{dfs}()}, +\code{\link{distance_table}()}, +\code{\link{edge_density}()}, +\code{\link{feedback_arc_set}()}, +\code{\link{girth}()}, +\code{\link{is_acyclic}()}, +\code{\link{is_dag}()}, +\code{\link{is_matching}()}, +\code{\link{knn}()}, +\code{\link{laplacian_matrix}()}, +\code{\link{reciprocity}()}, +\code{\link{subcomponent}()}, +\code{\link{subgraph}()}, +\code{\link{topo_sort}()}, +\code{\link{transitivity}()}, +\code{\link{unfold_tree}()}, +\code{\link{which_multiple}()}, +\code{\link{which_mutual}()} +} +\concept{structural.properties} +\keyword{graphs} diff --git a/man/knn.Rd b/man/knn.Rd index e3c1d935cba..2c97cadd979 100644 --- a/man/knn.Rd +++ b/man/knn.Rd @@ -104,6 +104,7 @@ Other structural.properties: \code{\link{is_acyclic}()}, \code{\link{is_dag}()}, \code{\link{is_matching}()}, +\code{\link{k_shortest_paths}()}, \code{\link{laplacian_matrix}()}, \code{\link{reciprocity}()}, \code{\link{subcomponent}()}, diff --git a/man/laplacian_matrix.Rd b/man/laplacian_matrix.Rd index 80eb155615d..507e1072b83 100644 --- a/man/laplacian_matrix.Rd +++ b/man/laplacian_matrix.Rd @@ -72,6 +72,7 @@ Other structural.properties: \code{\link{is_acyclic}()}, \code{\link{is_dag}()}, \code{\link{is_matching}()}, +\code{\link{k_shortest_paths}()}, \code{\link{knn}()}, \code{\link{reciprocity}()}, \code{\link{subcomponent}()}, diff --git a/man/matching.Rd b/man/matching.Rd index 4787dd1bf17..60befebec43 100644 --- a/man/matching.Rd +++ b/man/matching.Rd @@ -125,6 +125,7 @@ Other structural.properties: \code{\link{girth}()}, \code{\link{is_acyclic}()}, \code{\link{is_dag}()}, +\code{\link{k_shortest_paths}()}, \code{\link{knn}()}, \code{\link{laplacian_matrix}()}, \code{\link{reciprocity}()}, diff --git a/man/reciprocity.Rd b/man/reciprocity.Rd index 2a7e7a45b78..c7ab70000c8 100644 --- a/man/reciprocity.Rd +++ b/man/reciprocity.Rd @@ -57,6 +57,7 @@ Other structural.properties: \code{\link{is_acyclic}()}, \code{\link{is_dag}()}, \code{\link{is_matching}()}, +\code{\link{k_shortest_paths}()}, \code{\link{knn}()}, \code{\link{laplacian_matrix}()}, \code{\link{subcomponent}()}, diff --git a/man/subcomponent.Rd b/man/subcomponent.Rd index bb483df518a..0b93aaecb2c 100644 --- a/man/subcomponent.Rd +++ b/man/subcomponent.Rd @@ -53,6 +53,7 @@ Other structural.properties: \code{\link{is_acyclic}()}, \code{\link{is_dag}()}, \code{\link{is_matching}()}, +\code{\link{k_shortest_paths}()}, \code{\link{knn}()}, \code{\link{laplacian_matrix}()}, \code{\link{reciprocity}()}, diff --git a/man/subgraph.Rd b/man/subgraph.Rd index 2310c31ba4a..5c1914173f6 100644 --- a/man/subgraph.Rd +++ b/man/subgraph.Rd @@ -80,6 +80,7 @@ Other structural.properties: \code{\link{is_acyclic}()}, \code{\link{is_dag}()}, \code{\link{is_matching}()}, +\code{\link{k_shortest_paths}()}, \code{\link{knn}()}, \code{\link{laplacian_matrix}()}, \code{\link{reciprocity}()}, diff --git a/man/topo_sort.Rd b/man/topo_sort.Rd index db5dcd5cd88..73f3393dc50 100644 --- a/man/topo_sort.Rd +++ b/man/topo_sort.Rd @@ -52,6 +52,7 @@ Other structural.properties: \code{\link{is_acyclic}()}, \code{\link{is_dag}()}, \code{\link{is_matching}()}, +\code{\link{k_shortest_paths}()}, \code{\link{knn}()}, \code{\link{laplacian_matrix}()}, \code{\link{reciprocity}()}, diff --git a/man/transitivity.Rd b/man/transitivity.Rd index 232c1b8fba0..27652f994e1 100644 --- a/man/transitivity.Rd +++ b/man/transitivity.Rd @@ -134,6 +134,7 @@ Other structural.properties: \code{\link{is_acyclic}()}, \code{\link{is_dag}()}, \code{\link{is_matching}()}, +\code{\link{k_shortest_paths}()}, \code{\link{knn}()}, \code{\link{laplacian_matrix}()}, \code{\link{reciprocity}()}, diff --git a/man/unfold_tree.Rd b/man/unfold_tree.Rd index 515b91a95c9..cf9e60d3e98 100644 --- a/man/unfold_tree.Rd +++ b/man/unfold_tree.Rd @@ -59,6 +59,7 @@ Other structural.properties: \code{\link{is_acyclic}()}, \code{\link{is_dag}()}, \code{\link{is_matching}()}, +\code{\link{k_shortest_paths}()}, \code{\link{knn}()}, \code{\link{laplacian_matrix}()}, \code{\link{reciprocity}()}, diff --git a/man/which_multiple.Rd b/man/which_multiple.Rd index 14f9141dada..fe4a7f1c0f9 100644 --- a/man/which_multiple.Rd +++ b/man/which_multiple.Rd @@ -100,6 +100,7 @@ Other structural.properties: \code{\link{is_acyclic}()}, \code{\link{is_dag}()}, \code{\link{is_matching}()}, +\code{\link{k_shortest_paths}()}, \code{\link{knn}()}, \code{\link{laplacian_matrix}()}, \code{\link{reciprocity}()}, diff --git a/man/which_mutual.Rd b/man/which_mutual.Rd index bcaa8c87717..86ce6bf83c1 100644 --- a/man/which_mutual.Rd +++ b/man/which_mutual.Rd @@ -55,6 +55,7 @@ Other structural.properties: \code{\link{is_acyclic}()}, \code{\link{is_dag}()}, \code{\link{is_matching}()}, +\code{\link{k_shortest_paths}()}, \code{\link{knn}()}, \code{\link{laplacian_matrix}()}, \code{\link{reciprocity}()}, diff --git a/src/rinterface.c b/src/rinterface.c index 644039712ff..20cb7a6d472 100644 --- a/src/rinterface.c +++ b/src/rinterface.c @@ -2492,8 +2492,8 @@ SEXP R_igraph_get_k_shortest_paths(SEXP graph, SEXP weights, SEXP k, SEXP from, IGRAPH_FINALLY_CLEAN(1); SET_VECTOR_ELT(r_result, 0, vertex_paths); SET_VECTOR_ELT(r_result, 1, edge_paths); - SET_STRING_ELT(r_names, 0, Rf_mkChar("vertex_paths")); - SET_STRING_ELT(r_names, 1, Rf_mkChar("edge_paths")); + SET_STRING_ELT(r_names, 0, Rf_mkChar("vpaths")); + SET_STRING_ELT(r_names, 1, Rf_mkChar("epaths")); SET_NAMES(r_result, r_names); UNPROTECT(3); diff --git a/tools/stimulus/functions-R.yaml b/tools/stimulus/functions-R.yaml index 0783cfac8f4..5b330476543 100644 --- a/tools/stimulus/functions-R.yaml +++ b/tools/stimulus/functions-R.yaml @@ -374,6 +374,10 @@ igraph_get_all_simple_paths: PP: get.all.simple.paths.pp igraph_get_k_shortest_paths: + PARAM_ORDER: graph, from, to, *, k, ... + PARAM_NAMES: + vertex_paths: vpaths + edge_paths: epaths igraph_get_widest_path: From 58377ebf742d97c3d5fe6c99efceead088eb1d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Horva=CC=81t?= Date: Sat, 30 Dec 2023 20:55:42 +0000 Subject: [PATCH 3/3] tests: k_shortest_paths() --- tests/testthat/test-k_shortest_paths.R | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/testthat/test-k_shortest_paths.R diff --git a/tests/testthat/test-k_shortest_paths.R b/tests/testthat/test-k_shortest_paths.R new file mode 100644 index 00000000000..64c310f33b2 --- /dev/null +++ b/tests/testthat/test-k_shortest_paths.R @@ -0,0 +1,22 @@ +test_that("k_shortest_paths works", { + g <- make_ring(5) + res <- k_shortest_paths(g, 1, 2, k = 3) + expect_length(res$vpaths, 2) + expect_length(res$epaths, 2) + expect_equal(as.numeric(res$vpaths[[1]]), c(1, 2)) + expect_equal(as.numeric(res$epaths[[1]]), c(1)) + expect_equal(as.numeric(res$vpaths[[2]]), c(1, 5, 4, 3, 2)) + expect_equal(as.numeric(res$epaths[[2]]), c(5, 4, 3, 2)) +}) + +test_that("k_shortest_paths works with weights", { + g <- make_graph(c(1,2, 1,3, 3,2)) + E(g)$weight <- c(5, 2, 1) + res <- k_shortest_paths(g, 1, 2, k = 3) + expect_length(res$vpaths, 2) + expect_length(res$epaths, 2) + expect_equal(as.numeric(res$vpaths[[1]]), c(1, 3, 2)) + expect_equal(as.numeric(res$epaths[[1]]), c(2, 3)) + expect_equal(as.numeric(res$vpaths[[2]]), c(1, 2)) + expect_equal(as.numeric(res$epaths[[2]]), c(1)) +})