-
Notifications
You must be signed in to change notification settings - Fork 49
Add FixedGraph constexpr fixed-capacity graph container #202
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
qxlsz
commented
Sep 20, 2025
- Allocation-free directed/undirected, weighted/unweighted graph.
- Algorithms: BFS/DFS, shortest paths (BFS/Dijkstra/Bellman-Ford), MST (Kruskal), SCC, topo sort, coloring, bipartite, Eulerian, cycle detection, centrality, density, diameter, clustering, complement/union/intersection.
- Utilities: has_node, find_node_index, remove_edge, edge_count, generators (create_complete_graph, create_cycle_graph), serialization.
- README updated with examples.
90efe4c to
62a9644
Compare
This adds a new template parameter to use a shared edge pool instead of per-node vectors, saving space when node degrees vary.
Bobobalink
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I fear that Alex is going to be very resistant to merging this in, he has really high standards for what makes it into fixed-containers and I'm not sure this really fits the "vibe" of what goes in here...
| bool DIRECTED = true, | ||
| bool USE_MATRIX = false, | ||
| bool USE_POOL = false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you should create separate "graph storage" classes with a minimal interface and then pass one of those as a template parameter into this class instead of mixing three disjoint implementations into one class
| adjacency_storage_.push_back({to, std::forward<Args>(args)...}); | ||
| } | ||
| // Update node's range | ||
| node_ranges_[from].second = insert_pos + 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
won't this cause massive problems if I do, e.g.
add_edge(1, 2);
add_edge(2, 3);
add_edge(1, 4); // oops, now `1` has eaten the ->3 edge| } | ||
|
|
||
| // Shortest path using BFS (for unweighted graphs) | ||
| constexpr FixedVector<NodeIndex, MAX_NODES> shortest_path(NodeIndex start, NodeIndex end) const |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of these graph algorithms that return large structures (e.g. FixedVector, other graphs, etc.) would be significantly more useful if they instead took out<> parameters so the users aren't forced to incur a copy in many use-cases.
|
|
||
| // Serialize graph to binary format | ||
| template <typename OutputIterator> | ||
| constexpr OutputIterator serialize(OutputIterator out) const |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a strong justification for doing this (de)serialization by hand instead of using an existing format like flatbuffers or Avro? What is the use-case here?