-
Notifications
You must be signed in to change notification settings - Fork 238
[Do not merge] Proposal for adding node and edgeweight template parameters to Graph #1324
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: master
Are you sure you want to change the base?
Conversation
2f1c9ee to
a5b053d
Compare
e8b10c5 to
6c0d567
Compare
6c0d567 to
5d610bc
Compare
|
We had also offline discussions about this topic. The rationale was basically the same as what is stated here, being more flexible with node ids and edge weights. Also your proposal makes sense. A few (maybe not thorough thoughts):
Likely, other modules/classes like |
|
Not an assigned reviewer, but I wanted to share a quick thought on the topic:
That way:
|
|
Thank you both for your feedback.
That's right. For readability, we could adopt the suggestions from @Schwarf, but we can't avoid other issues like longer compilation time.
I think that an easier solution is to template that code and add default template parameters to minimize changes in non-template algorithms using it. For example, // BucketPQ.hpp
template <class KeyType = int64_t, class ValueType = uint64_t>
class BucketPQ : public PrioQueue<KeyType, ValueType> {
static_assert(std::is_signed<KeyType>() && std::is_integral<KeyType>());
// ...
};
// SomeAlgo.hpp
// Instead of `BucketPQ prioQ;`
BucketPQ<> prioQ;And then we gradually stop using the types declared in Let me know if what you are proposing is simper than this, I might have misinterpreted it.
Yes, we can do something similar as done with template <template <class, class> class GraphType, class NodeType, class EdgeWeightType>
class FloydWarshall : public Algorithm {
public:
// Before:
// FloydWarshall(const GraphType &G);
// Now it becomes:
FloydWarshall(const GraphType<NodeType, EdgeWeightType> &G);
};
// Before:
// template <class GraphType>
// void FloydWarshall<GraphType>::run() {}
// Now it becomes:
template <template <class, class> class GraphType, class NodeType, class EdgeWeightType>
void FloydWarshall<GraphType<NodeType, EdgeWeightType>>::run() {}To me this looks too cluttered. Adding the My question is how do we move from here? If we agree to proceed with this change, I think that we should clarify:
Let me know what you think. |
Problem
The
NetworKit::Graphclass always uses 64-bit integers for node IDs, but NetworKit applications rarely use (if ever) graphs with more than 2^32 nodes. Using smaller node IDs (32-bit or less) significantly reduces the size of the graph and improves scalability.Edge weights have a similar issue:
NetworKit::Graphuses 64-bit floats for edge weights, while applications might only require 32-bit floats or integers.Proposed solution
Adding a
NodeTypeandEdgeWeightTypetemplate parameters to NetworKit's graph class enables users to select the most appropriate type for node IDs and edge weights. I considered two options for implementing this idea:1. [not recommended] Add template parameters to
NetworKit::Graphand to all algorithms usingGraph.With this option, we'll keep the original
NetworKit::Graphclass, but we'll have to add the same template parameters to all NetworKit algorithms using it:Alternatively, we could add a
GraphTypetemplate parameter to all algorithms and access theNodeTypeandEdgeWeightTypeinGraph:I think that none of those solutions are viable because:
Graph(after the change,Graphwill require template parameters).2. [proposal] Rename
GraphtoDynamicGraphand defineGraphas an alias ofDynamicGraph<uint64_t, double>.This is the option implemented in this PR. I also included an example of how we can migrate an existing algorithm (the
NetworKit::FloydWarshall) to the template graph, demonstrating feasibility.If we accept renaming
Graph, this option has two main advantages compared to the previous one:Graphand all algorithms will maintain the same behavior as before, no breakage of external code usingGraph.Graphmaintains the same behavior as before, we can migrate algorithms gradually instead of migrating all of them in one change (see theFloydWarshallexample).Further, the idea of adding a
GraphTypetemplate parameter to algorithms will allow keeping a single implementation and generalize it to different graph types. This should be useful to efforts trying to introduce new graph types like #1231 or #1246.Please let me know if you have any suggestions or if you have other ideas I haven't considered.