Skip to content

Commit

Permalink
Add error tests, separate 2 terminal edge case
Browse files Browse the repository at this point in the history
  • Loading branch information
GroteGnoom committed Jan 14, 2024
1 parent 12cd598 commit c360a87
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 17 deletions.
17 changes: 9 additions & 8 deletions src/paths/steiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,13 @@ igraph_error_t igraph_steiner_dreyfus_wagner(
}
}

if (no_of_nodes == 0 || no_of_terminals == 0 || no_of_terminals == 1) {

igraph_vector_int_clear(res_tree);
*res = 0.0;
return IGRAPH_SUCCESS;
}

/* Check whether all terminals are within the same connected component. */
{
igraph_vector_int_t membership;
Expand All @@ -196,7 +203,6 @@ igraph_error_t igraph_steiner_dreyfus_wagner(
IGRAPH_CHECK(igraph_connected_components(graph, &membership, NULL, &no_comps, IGRAPH_WEAK));

if (no_comps > 1) {
/* The case of zero terminals was already handled above. */
igraph_integer_t component_id = VECTOR(membership)[VECTOR(*terminals)[0]];
for (igraph_integer_t i = 1; i < no_of_terminals; i++) {
if (VECTOR(membership)[VECTOR(*terminals)[i]] != component_id) {
Expand All @@ -211,13 +217,8 @@ igraph_error_t igraph_steiner_dreyfus_wagner(
IGRAPH_FINALLY_CLEAN(1);
}

/* Handle the cases of the null graph and 0,1 or 2 terminals. */
if (no_of_nodes == 0 || no_of_terminals == 0 || no_of_terminals == 1) {

igraph_vector_int_clear(res_tree);
*res = 0.0;
return IGRAPH_SUCCESS;
} else if (no_of_terminals == 2) {
/* Only 2 terminals means we can just take the shortest path. */
if (no_of_terminals == 2) {
IGRAPH_CHECK(igraph_get_shortest_path_dijkstra(
graph, NULL, res_tree, VECTOR(*terminals)[0],
VECTOR(*terminals)[1], weights, IGRAPH_ALL));
Expand Down
38 changes: 29 additions & 9 deletions tests/unit/igraph_steiner_tree_fpt.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,19 @@ void check_graph(const igraph_t *graph, const igraph_vector_int_t *terminals, co
igraph_vector_int_destroy(&tree_edges);
}

void check_error(igraph_t *graph, igraph_vector_int_t *terminals, igraph_vector_t *weights, igraph_error_t error) {
igraph_real_t value;
igraph_vector_int_t tree_edges;
igraph_vector_int_init(&tree_edges, 0);

CHECK_ERROR(igraph_steiner_dreyfus_wagner(graph, terminals, weights, &value, &tree_edges), error);

igraph_vector_int_destroy(&tree_edges);
}

int main(void) {
igraph_t g_null, g_k7, g_k6_k1, g_k7_n, g_k7_n1, g_k7_real, g_k7_non_simple, g_k1, g_k7_self_loop, g_10_9, g_new, g_new_1, g_new_2, g_new_3, g_new_4;
igraph_vector_int_t terminals_null, terminals_k7, terminals_k6_k1, terminals_k7_real, terminals_10_9, terminals_1, terminals_2, terminals_3, terminals_8, terminals_7, terminals_7_special, terminals_square, terminals_square_2, terminals_fpw;
igraph_t g_null, g_k7, g_k6_k1, g_k7_n, g_k7_n1, g_k7_real, g_k7_non_simple, g_k1, g_k7_self_loop, g_10_9, g_new, g_new_1, g_new_2, g_new_3, g_new_4, g_2_unconn;
igraph_vector_int_t terminals_null, terminals_k7, terminals_k6_k1, terminals_k7_real, terminals_10_9, terminals_1, terminals_2, terminals_3, terminals_8, terminals_7, terminals_7_special, terminals_square, terminals_square_2, terminals_fpw, terminals_2_unconn;
igraph_vector_t weights_null, weights_k7, weights_k6_k1, weights_k7_n, weights_k7_n1, weights_k7_real, weights_k7_non_simple, weights_k7_loop, weights_square_2, weights_fp;

/* Null graph */
Expand Down Expand Up @@ -268,6 +278,9 @@ int main(void) {
-1);
igraph_vector_int_init_int(&terminals_fpw, 3, 2, 0, 1);

igraph_small(&g_2_unconn, 2, IGRAPH_UNDIRECTED, -1);
igraph_vector_int_init_int(&terminals_2_unconn, 2, 0, 1);

printf("Null graph:\n");
check_graph(&g_null, &terminals_null, &weights_null);

Expand All @@ -280,13 +293,6 @@ int main(void) {
printf("\nK_7 Non Complete graph-2:\n");
check_graph(&g_k7_n1, &terminals_k7, &weights_k7_n1);

igraph_real_t value;
igraph_vector_int_t tree_edges;
igraph_vector_int_init(&tree_edges, 0);

CHECK_ERROR(igraph_steiner_dreyfus_wagner(&g_k6_k1, &terminals_k6_k1, &weights_k6_k1, &value, &tree_edges), IGRAPH_EINVAL);

igraph_vector_int_destroy(&tree_edges);

igraph_real_t value_unit;
igraph_vector_int_t tree_edges_unit;
Expand Down Expand Up @@ -344,6 +350,18 @@ int main(void) {
printf("\nA different graph than before with floating point weights\n");
check_graph(&g_new_4, &terminals_fpw, &weights_fp);


printf("\nChecking errors:\n");

printf("Graph with 2 unconnected terminals\n");
check_error(&g_2_unconn, &terminals_2_unconn, NULL, IGRAPH_EINVAL);

printf("Unconnected graph with terminals in multiple components\n");
check_error(&g_k6_k1, &terminals_k6_k1, &weights_k6_k1, IGRAPH_EINVAL);

printf("Terminal not in graph\n");
check_error(&g_k7, &terminals_10_9, NULL, IGRAPH_EINVVID);

igraph_destroy(&g_null);
igraph_destroy(&g_k7);
igraph_destroy(&g_k6_k1);
Expand All @@ -359,6 +377,7 @@ int main(void) {
igraph_destroy(&g_new_2);
igraph_destroy(&g_new_3);
igraph_destroy(&g_new_4);
igraph_destroy(&g_2_unconn);

igraph_vector_destroy(&weights_null);
igraph_vector_destroy(&weights_k7);
Expand All @@ -385,6 +404,7 @@ int main(void) {
igraph_vector_int_destroy(&terminals_square);
igraph_vector_int_destroy(&terminals_square_2);
igraph_vector_int_destroy(&terminals_fpw);
igraph_vector_int_destroy(&terminals_2_unconn);


VERIFY_FINALLY_STACK();
Expand Down

0 comments on commit c360a87

Please sign in to comment.