simple-graph.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. #ifndef _TEST_GRAPHS_H
  2. #define _TEST_GRAPHS_H
  3. #include <stdbool.h>
  4. #define MAX_NODES 16
  5. #define MAX_EDGES 16 /* Max edges per node */
  6. struct simple_graph {
  7. struct aga_graph g;
  8. /* We don't use nodes[0] just to avoid awkward -1 and +1 in
  9. * the code */
  10. struct aga_node nodes[MAX_NODES + 1];
  11. };
  12. void simple_graph_init_(struct simple_graph *sg);
  13. #define simple_graph_init(sg_, fefn_, nefn_, eifn_) \
  14. do { \
  15. simple_graph_init_((sg_)); \
  16. aga_init_graph(&(sg_)->g, (fefn_), (nefn_), (eifn_)); \
  17. } while (0)
  18. struct adjacency_list {
  19. int from;
  20. int to[MAX_EDGES];
  21. };
  22. /* Trivial graph
  23. *
  24. * (A)
  25. *
  26. * The simplest possible graph: one node, no edges
  27. */
  28. struct trivial_graph {
  29. struct simple_graph sg;
  30. };
  31. void trivial_graph_init(struct trivial_graph *tg);
  32. static const struct adjacency_list trivial_adjacency[] = {
  33. {1, {}},
  34. {},
  35. };
  36. /* Parallel graph
  37. *
  38. * --
  39. * / \
  40. * (A) => (B)
  41. * \ /
  42. * --
  43. *
  44. * Two nodes (A & B), with PARALLEL_NLINKS edges all from A->B.
  45. */
  46. struct parallel_graph {
  47. int nlinks;
  48. struct simple_graph sg;
  49. };
  50. void parallel_graph_init(struct parallel_graph *pg, int nlinks);
  51. static const struct adjacency_list parallel_adjacency_nlinks3[] = {
  52. {1, {2, 2, 2}},
  53. {2, {}},
  54. {},
  55. };
  56. /* Full graph
  57. *
  58. * n nodes with an edge from every node to every other node (including
  59. * itself)
  60. */
  61. struct full_graph {
  62. int nnodes;
  63. struct simple_graph sg;
  64. };
  65. void full_graph_init(struct full_graph *fg, int nnodes);
  66. static const struct adjacency_list full_adjacency_5[] = {
  67. {1, {1, 2, 3, 4, 5}},
  68. {2, {1, 2, 3, 4, 5}},
  69. {3, {1, 2, 3, 4, 5}},
  70. {4, {1, 2, 3, 4, 5}},
  71. {5, {1, 2, 3, 4, 5}},
  72. {},
  73. };
  74. struct aga_node *full_first_edge(const struct aga_graph *g,
  75. const struct aga_node *node);
  76. struct aga_node *full_next_edge(const struct aga_graph *g,
  77. const struct aga_node *node,
  78. struct aga_node *edge);
  79. /* Chain graph
  80. *
  81. * --> --> -->
  82. * A B C D
  83. * <-- <-- <--
  84. *
  85. * nnodes nodes arranged in a linear sequence, edges from each node to
  86. * the previous and next
  87. */
  88. struct chain_graph {
  89. struct full_graph fg;
  90. };
  91. void chain_graph_init(struct chain_graph *cg, int nnodes);
  92. static const struct adjacency_list chain_adjacency_8[] = {
  93. {1, {2}},
  94. {2, {1, 3}},
  95. {3, {2, 4}},
  96. {4, {3, 5}},
  97. {5, {4, 6}},
  98. {6, {5, 7}},
  99. {7, {6, 8}},
  100. {8, {7}},
  101. {},
  102. };
  103. /* Grid graph(s)
  104. *
  105. * A -> B -> C
  106. * | | |
  107. * v v v
  108. * D -> E -> F
  109. * | | |
  110. * v v v
  111. * G -> H -> I
  112. *
  113. * nx * ny nodes arranged in an nx * ny grid. Depending on
  114. * parameters, edges to the node to the right / down / left / up of
  115. * each node
  116. */
  117. struct grid_graph {
  118. int nx, ny;
  119. bool right, down, left, up;
  120. struct simple_graph sg;
  121. };
  122. void grid_graph_init(struct grid_graph *gg, int nx, int ny,
  123. bool right, bool down, bool left, bool up);
  124. static const struct adjacency_list grid_adjacency_3x3_rightdown[] = {
  125. {1, {2, 4}},
  126. {2, {3, 5}},
  127. {3, {6}},
  128. {4, {5, 7}},
  129. {5, {6, 8}},
  130. {6, {9}},
  131. {7, {8}},
  132. {8, {9}},
  133. {9, {}},
  134. {},
  135. };
  136. static const struct adjacency_list grid_adjacency_3x3_all[] = {
  137. {1, {2, 4}},
  138. {2, {3, 5, 1}},
  139. {3, {6, 2}},
  140. {4, {5, 7, 1}},
  141. {5, {6, 8, 4, 2}},
  142. {6, {9, 5, 3}},
  143. {7, {8, 4}},
  144. {8, {9, 7, 5}},
  145. {9, {8, 6}},
  146. {},
  147. };
  148. /* Error graph
  149. *
  150. * A -> B
  151. *
  152. * C -> D -> ???
  153. *
  154. * This is for testing reporting of errors by the edge_info function.
  155. * 5 nodes are arranged as above, with the link from D always
  156. * returning an error.
  157. */
  158. struct error_graph {
  159. struct simple_graph sg;
  160. };
  161. void error_graph_init(struct error_graph *eg);
  162. static const struct adjacency_list error_adjacency[] = {
  163. {1, {2}},
  164. {2, {}},
  165. {3, {4}},
  166. {4, {-1}},
  167. {},
  168. };
  169. /* Traversal-1 graph
  170. *
  171. * -> D <-
  172. * / \
  173. * -> B G <-
  174. * / \ / \
  175. * A => E <= I
  176. * \ / \ /
  177. * -> C H <-
  178. * \ /
  179. * -> F <-
  180. *
  181. * This provides an example of a graph which can't be traversed (with
  182. * DFS or BFS) from a single starting node. It can be traversed with
  183. * two starting points, but several nodes can be reached from either,
  184. * complicating the logic to avoid double-traversal.
  185. */
  186. struct traversal1_graph {
  187. struct simple_graph sg;
  188. };
  189. void traversal1_graph_init(struct traversal1_graph *t1g);
  190. static const struct adjacency_list traversal1_adjacency[] = {
  191. {1, {2, 3}},
  192. {2, {4, 5}},
  193. {3, {5, 6}},
  194. {4, {}},
  195. {5, {}},
  196. {6, {}},
  197. {7, {5, 4}},
  198. {8, {6, 5}},
  199. {9, {8, 7}},
  200. {},
  201. };
  202. #endif /* _TEST_GRAPHS_H */