The Problem
I want to implement a number of algorithms that work on a graph and return scores for node-pairs indicating whether those nodes are similar. The algorithms should work on a single node-pair and on all possible node-pairs. In the latter case a collection/matrix should be returned.
My Approach
The algorithms derive from
class SimilarityAlgorithm {
public:
Base(const Graph& G);
virtual double run(node u, node v) = 0; // indices for nodes in the graph
virtual ScoreCollection& runAll() = 0;
}
Now the algorithms differ in memory usage. Some algorithms might be symmetric and the scores for (u, v) and (v, u) are identical. This requires different ScoreCollection-types that should be returned. An example would be a sparse-matrix and a triangular matrix that both derive from ScoreCollection
.
This would boil down to covariant return types:
class SpecificAlgorithm : SimilarityAlgorithm {
public:
double run(node u, node v);
// The specific algorithm is symmetric and thus uses a symmetric matrix to save memory
SymmetricScoreCollection& runAll();
}
Question
- Is this design approach a good idea for this problem?
- Should the fact that the collections are all implemented as matrices be exposed?