struct traversal1_graph t1g;
struct shortcut1_graph s1g;
struct shortcut2_graph s2g;
+ struct negacycle_graph ng;
- plan_tests(2 + 7 + 35 + 30 + 30 + 42 + 9 + 30 + 9 + 9);
+ plan_tests(2 + 7 + 35 + 30 + 30 + 42 + 9 + 30 + 9 + 9 + 9);
trivial_graph_init(&tg);
test_adjacency("trivial", &tg.sg, trivial_adjacency);
shortcut2_graph_init(&s2g);
test_adjacency("shortcut2 graph", &s2g.sg, shortcut2_adjacency);
+ negacycle_graph_init(&ng);
+ test_adjacency("negacycle graph", &ng.sg, negacycle_adjacency);
+
return exit_status();
}
aga_finish(&s2g.sg.g);
}
+static void test_negacycle(void)
+{
+ struct negacycle_graph ng;
+
+ negacycle_graph_init(&ng);
+
+ ok1(aga_bellman_ford_start(&ng.sg.g, &ng.sg.nodes[1]) == 0);
+ aga_bellman_ford_complete(&ng.sg.g);
+ ok1(aga_error(&ng.sg.g) == AGA_ERR_NEGATIVE_COST);
+ aga_finish(&ng.sg.g);
+}
+
int main(void)
{
plan_tests(5 + 15
+ FULL_LEN * (1 + FULL_LEN * 4)
+ CHAIN_LEN * (1 + CHAIN_LEN * 2)
- + 10 + 32 + 7 + 7);
+ + 10 + 32 + 7 + 7 + 2);
test_trivial();
test_parallel();
test_traversal1();
test_shortcut1();
test_shortcut2();
+ test_negacycle();
return exit_status();
}
struct grid_graph gg1, gg2;
struct error_graph eg;
struct traversal1_graph t1g;
+ struct negacycle_graph ng;
struct aga_node *node;
- plan_tests(2 * 13 + 10 + 10);
+ plan_tests(2 * 13 + 10 + 10 + 6);
trivial_graph_init(&tg);
test_bfs(&tg.sg, 1, 1);
test_bfs_partial(&t1g.sg, 1, 1, 2, 3);
aga_finish(&t1g.sg.g);
+ negacycle_graph_init(&ng);
+ test_bfs(&ng.sg, 1, 1, 2, 3);
+ test_bfs(&ng.sg, 2, 2, 3, 1);
+ test_bfs(&ng.sg, 3, 3, 1, 2);
+
return exit_status();
}
struct grid_graph gg1, gg2;
struct error_graph eg;
struct traversal1_graph t1g;
+ struct negacycle_graph ng;
struct aga_node *node;
- plan_tests(2 * 13 + 10 + 10);
+ plan_tests(2 * 13 + 10 + 10 + 6);
trivial_graph_init(&tg);
test_dfs(&tg.sg, 1, 1);
test_dfs_partial(&t1g.sg, 1, 1, 2, 3);
aga_finish(&t1g.sg.g);
+ negacycle_graph_init(&ng);
+ test_dfs(&ng.sg, 1, 1, 2, 3);
+ test_dfs(&ng.sg, 2, 2, 3, 1);
+ test_dfs(&ng.sg, 3, 3, 1, 2);
+
return exit_status();
}
aga_finish(&s2g.sg.g);
}
+static void test_negacycle(void)
+{
+ struct negacycle_graph ng;
+
+ negacycle_graph_init(&ng);
+
+ ok1(aga_dijkstra_start(&ng.sg.g, &ng.sg.nodes[1]) == 0);
+ aga_dijkstra_complete(&ng.sg.g);
+ ok1(aga_error(&ng.sg.g) == AGA_ERR_NEGATIVE_COST);
+ aga_finish(&ng.sg.g);
+}
+
int main(void)
{
plan_tests(7 + 20
+ FULL_LEN * (1 + FULL_LEN*4)
+ CHAIN_LEN * (1 + CHAIN_LEN*2)
- + 12 + 32 + 7 + 2);
+ + 12 + 32 + 7 + 2 + 2);
test_trivial();
test_parallel();
test_traversal1();
test_shortcut1();
test_shortcut2();
+ test_negacycle();
return exit_status();
}
--- /dev/null
+#include "config.h"
+
+#include <assert.h>
+
+#include <ccan/container_of/container_of.h>
+#include <ccan/ptrint/ptrint.h>
+
+#include <ccan/aga/aga.h>
+
+#include "simple-graph.h"
+
+static ptrint_t *negacycle_first_edge(const struct aga_graph *g,
+ const struct aga_node *n)
+{
+ return int2ptr(1);
+}
+
+static ptrint_t *negacycle_next_edge(const struct aga_graph *g,
+ const struct aga_node *n,
+ ptrint_t *e)
+{
+ assert(ptr2int(e) == 1);
+ return NULL;
+}
+
+static int negacycle_edge_info(const struct aga_graph *g,
+ const struct aga_node *n,
+ ptrint_t *e, struct aga_edge_info *ei)
+{
+ struct negacycle_graph *ng = container_of(g, struct negacycle_graph,
+ sg.g);
+ int ni = n - ng->sg.nodes;
+
+ assert(ptr2int(e) == 1);
+ ei->to = &ng->sg.nodes[(ni % 3) + 1];
+ if (ni == 3)
+ ei->icost = -3;
+ return 0;
+}
+
+void negacycle_graph_init(struct negacycle_graph *ng)
+{
+ simple_graph_init(&ng->sg, negacycle_first_edge,
+ negacycle_next_edge,
+ negacycle_edge_info);
+}
{},
};
+/* Negacycle graph
+ *
+ * A <---- (-3) ----- C
+ * \ ^
+ * (1)-> B -- (1)-/
+ *
+ * Graph with a negative length cycle, and so lacking well-defined shortest paths.
+ */
+struct negacycle_graph {
+ struct simple_graph sg;
+};
+void negacycle_graph_init(struct negacycle_graph *ng);
+static const struct adjacency_list negacycle_adjacency[] = {
+ {1, {2}},
+ {2, {3}},
+ {3, {1}},
+ {},
+};
+
#endif /* _TEST_GRAPHS_H */
tal_free(sr);
}
+static void test_negacycle(void)
+{
+ struct agar_state *sr;
+
+ ok1(sr = agar_bellman_ford_new(NULL, &negacycle_graphr.gr, int2ptr(1)));
+ agar_bellman_ford_complete(sr);
+ ok1(agar_error(sr) == AGA_ERR_NEGATIVE_COST);
+ tal_free(sr);
+}
+
int main(void)
{
plan_tests(3 + 15
+ FULL_LEN * (FULL_LEN*4 - 1)
+ CHAIN_LEN * (1 + CHAIN_LEN*2)
- + 10 + 32 + 7 + 7);
+ + 10 + 32 + 7 + 7 + 2);
test_trivial();
test_parallel();
test_traversal1();
test_shortcut1();
test_shortcut2();
+ test_negacycle();
return exit_status();
}
struct agar_state *sr;
const void *nr;
- plan_tests(2 * 13 + 12 + 10);
+ plan_tests(2 * 13 + 12 + 10 + 6);
test_bfs(&trivial_graphr.gr, 1, 1);
test_bfs_partial(sr, 1, 1, 2, 3);
tal_free(sr);
+ test_bfs(&negacycle_graphr.gr, 1, 1, 2, 3);
+ test_bfs(&negacycle_graphr.gr, 2, 2, 3, 1);
+ test_bfs(&negacycle_graphr.gr, 3, 3, 1, 2);
+
return exit_status();
}
struct agar_state *sr;
const void *nr;
- plan_tests(2 * 13 + 12 + 10);
+ plan_tests(2 * 13 + 12 + 10 + 6);
test_dfs(&trivial_graphr.gr, 1, 1);
test_dfs_partial(sr, 1, 1, 2, 3);
tal_free(sr);
+ test_dfs(&negacycle_graphr.gr, 1, 1, 2, 3);
+ test_dfs(&negacycle_graphr.gr, 2, 2, 3, 1);
+ test_dfs(&negacycle_graphr.gr, 3, 3, 1, 2);
+
return exit_status();
}
tal_free(sr);
}
+static void test_negacycle(void)
+{
+ struct agar_state *sr;
+
+ ok1(sr = agar_dijkstra_new(NULL, &negacycle_graphr.gr, int2ptr(1)));
+ agar_dijkstra_complete(sr);
+ ok1(agar_error(sr) == AGA_ERR_NEGATIVE_COST);
+ tal_free(sr);
+}
+
int main(void)
{
plan_tests(6 + 23
+ FULL_LEN * (FULL_LEN*4 - 1)
+ CHAIN_LEN * (1 + CHAIN_LEN*2)
- + 12 + 32 + 7 + 2);
+ + 12 + 32 + 7 + 2 + 2);
test_trivial();
test_parallel();
test_traversal1();
test_shortcut1();
test_shortcut2();
+ test_negacycle();
return exit_status();
}
--- /dev/null
+#include "config.h"
+
+#include <assert.h>
+
+#include <ccan/container_of/container_of.h>
+#include <ccan/ptrint/ptrint.h>
+
+#include <ccan/agar/agar.h>
+
+#include "simple-graphr.h"
+
+static const void *negacycle_first_edge_r(const struct agar_graph *gr,
+ const void *nr)
+{
+ return int2ptr(1);
+}
+
+static const void *negacycle_next_edge_r(const struct agar_graph *gr,
+ const void *nr, const void *e)
+{
+ assert(ptr2int(e) == 1);
+ return NULL;
+}
+
+static int negacycle_edge_info_r(const struct agar_graph *gr,
+ const void *nr, const void *e,
+ struct agar_edge_info *eir)
+{
+ int ni = ptr2int(nr);
+
+ assert(ptr2int(e) == 1);
+ eir->to = int2ptr((ni % 3) + 1);
+ if (ni == 3)
+ eir->icost = -3;
+ return 0;
+}
+
+struct negacycle_graphr negacycle_graphr = {
+ AGAR_INIT_GRAPH(negacycle_first_edge_r,
+ negacycle_next_edge_r,
+ negacycle_edge_info_r),
+};
{},
};
+/* Negacycle graph
+ *
+ * A <---- (-3) ----- C
+ * \ ^
+ * (1)-> B -- (1)-/
+ *
+ * Graph with a negative length cycle, and so lacking well-defined shortest paths.
+ */
+struct negacycle_graphr {
+ struct agar_graph gr;
+};
+extern struct negacycle_graphr negacycle_graphr;
+static const struct adjacency_listr negacycle_adjacencyr[] = {
+ {1, {2}},
+ {2, {3}},
+ {3, {1}},
+ {},
+};
+
#endif /* _SIMPLE_GRAPHR_H */