]> git.ozlabs.org Git - ccan/blobdiff - ccan/agar/agar.c
Makefile: fix fastcheck.
[ccan] / ccan / agar / agar.c
index b2809abd3bb91fc0a206ed698b3f0fef564dc7e7..aa4628404864affe29578122fb69f729f1a059c8 100644 (file)
@@ -79,6 +79,7 @@ static int convert_edge_info(const struct aga_graph *g,
        int rc;
 
        eir.to = NULL;
+       eir.icost = ei->icost; /* Inherit the default from aga */
 
        rc = sr->gr->edge_info(sr->gr, nr, e, &eir);
 
@@ -87,6 +88,8 @@ static int convert_edge_info(const struct aga_graph *g,
        else
                ei->to = NULL;
 
+       ei->icost = eir.icost;
+
        return rc;
 }
 
@@ -164,6 +167,7 @@ int agar_edge_info(const struct agar_graph *gr, const void *nr, const void *e,
        int rc;
 
        eir->to = NULL;
+       eir->icost = 1;
        rc = gr->edge_info(gr, nr, e, eir);
        assert(rc <= 0);
        return rc;
@@ -230,3 +234,105 @@ bool agar_bfs_explore(struct agar_state *sr, const void *nr,
        *nextr = n_to_nr(sr, next);
        return true;
 }
+
+/*
+ * Dijkstra's algorithm
+ */
+
+struct agar_state *agar_dijkstra_new(void *ctx, struct agar_graph *gr,
+                                    const void *nr)
+{
+       struct agar_state *sr = agar_new(ctx, gr);
+
+       if (aga_dijkstra_start(&sr->g, nr_to_n(sr, nr)) < 0) {
+               tal_free(sr);
+               return NULL;
+       }
+
+       return sr;
+}
+
+bool agar_dijkstra_step(struct agar_state *sr, const void **nextr)
+{
+       struct aga_node *next = aga_dijkstra_step(&sr->g);
+
+       if (!next)
+               return false;
+
+       *nextr = n_to_nr(sr, next);
+       return true;
+}
+
+bool agar_dijkstra_path(struct agar_state *sr, const void *destr,
+                       aga_icost_t *total_cost,
+                       const void **prevr, const void **prevedge)
+{
+       struct aga_node *dest = nr_to_n(sr, destr);
+       struct aga_node *prev;
+
+       if (!aga_dijkstra_path(&sr->g, dest, total_cost, &prev, prevedge))
+               return false;
+
+       /*
+        * When destr is the same as the source node, there obviously
+        * isn't a previous node or edge.  In that case aga, sets them
+        * to NULL.  But for agar, NULL could be a valid node
+        * references (particularly if using ptrint).  So we don't
+        * have much choice here but to leave *prevr as undefined when
+        * destr is the source node. */
+       if (prevr && prev)
+               *prevr = n_to_nr(sr, prev);
+
+       return true;
+}
+
+void agar_dijkstra_complete(struct agar_state *sr)
+{
+       aga_dijkstra_complete(&sr->g);
+}
+
+
+/*
+ * Bellman-Ford algorithm
+ */
+
+struct agar_state *agar_bellman_ford_new(void *ctx, struct agar_graph *gr,
+                                        const void *nr)
+{
+       struct agar_state *sr = agar_new(ctx, gr);
+
+       if (aga_bellman_ford_start(&sr->g, nr_to_n(sr, nr)) < 0) {
+               tal_free(sr);
+               return NULL;
+       }
+
+       return sr;
+}
+
+bool agar_bellman_ford_path(struct agar_state *sr, const void *destr,
+                           aga_icost_t *total_cost,
+                           const void **prevr, const void **prevedge)
+{
+       struct aga_node *dest = nr_to_n(sr, destr);
+       struct aga_node *prev;
+
+       if (!aga_bellman_ford_path(&sr->g, dest, total_cost, &prev, prevedge))
+               return false;
+
+       /*
+        * When destr is the same as the source node, there obviously
+        * isn't a previous node or edge.  In that case aga sets them
+        * to NULL.  But for agar, NULL could be a valid node
+        * references (particularly if using ptrint).  So we don't
+        * have much choice here but to leave *prevr as undefined when
+        * destr is the source node. */
+       if (prevr && prev)
+               *prevr = n_to_nr(sr, prev);
+
+       return true;
+}
+
+void agar_bellman_ford_complete(struct agar_state *sr)
+{
+       aga_bellman_ford_complete(&sr->g);
+}