Skip to content

Conversation

@qxlsz
Copy link

@qxlsz 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.

@qxlsz qxlsz force-pushed the user/rjosyula/fixed-graph-impl branch from 90efe4c to 62a9644 Compare September 20, 2025 18:40
This adds a new template parameter to use a shared edge pool instead
 of per-node vectors, saving space when node degrees vary.
Copy link
Contributor

@Bobobalink Bobobalink left a 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...

Comment on lines 33 to 35
bool DIRECTED = true,
bool USE_MATRIX = false,
bool USE_POOL = false,
Copy link
Contributor

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;
Copy link
Contributor

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
Copy link
Contributor

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
Copy link
Contributor

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants