Skip to content

Methods inOut* broken for directed graphs #406

Open
@bbannier

Description

@bbannier

It looks to me that most of the methods inOutEdges or inOutNeighbors are implemented incorrectly for directed graphs. All these methods use the adjacency matrix to access edges, e.g.,

Graph<T>::inOutEdges(shared<const Node<T>> node) const {
if (cachedAdjMatrix->find(node) == cachedAdjMatrix->end()) {
return std::unordered_set<shared<const Edge<T>>, edgeHash<T>>();
}
auto nodeEdgePairs = cachedAdjMatrix->at(node);
std::unordered_set<shared<const Edge<T>>, edgeHash<T>> outEdges;
for (auto pair : nodeEdgePairs) {
outEdges.insert(pair.second);
}

This works well-enough for undirected graphs where the adjacency matrix is kept symmetric,

} else {
if (edge->isWeighted().has_value() && edge->isWeighted().value()) {
auto edge_shared = make_shared<UndirectedWeightedEdge<T>>(
*dynamic_cast<const UndirectedWeightedEdge<T> *>(edge));
this->edgeSet.insert(edge_shared);
std::pair<shared<const Node<T>>, shared<const Edge<T>>> elem = {
edge_shared->getNodePair().second, edge_shared};
(*cachedAdjMatrix)[edge_shared->getNodePair().first].push_back(
std::move(elem));
std::pair<shared<const Node<T>>, shared<const Edge<T>>> elem1 = {
edge_shared->getNodePair().first, edge_shared};
(*cachedAdjMatrix)[edge_shared->getNodePair().second].push_back(
std::move(elem1));
} else {
auto edge_shared = make_shared<UndirectedEdge<T>>(*edge);
this->edgeSet.insert(edge_shared);
std::pair<shared<const Node<T>>, shared<const Edge<T>>> elem = {
edge_shared->getNodePair().second, edge_shared};
(*cachedAdjMatrix)[edge_shared->getNodePair().first].push_back(
std::move(elem));
std::pair<shared<const Node<T>>, shared<const Edge<T>>> elem1 = {
edge_shared->getNodePair().first, edge_shared};
(*cachedAdjMatrix)[edge_shared->getNodePair().second].push_back(
std::move(elem1));
}
}

For directed graphs the adjacency matrix is not symmetric which means that it cannot be used as-is to obtain incoming edges for a node,

if (edge->isWeighted().has_value() && edge->isWeighted().value()) {
auto edge_shared = make_shared<DirectedWeightedEdge<T>>(
*dynamic_cast<const DirectedWeightedEdge<T> *>(edge));
this->edgeSet.insert(edge_shared);
std::pair<shared<const Node<T>>, shared<const Edge<T>>> elem = {
edge_shared->getNodePair().second, edge_shared};
(*cachedAdjMatrix)[edge_shared->getNodePair().first].push_back(
std::move(elem));
} else {
auto edge_shared = make_shared<DirectedEdge<T>>(*edge);
this->edgeSet.insert(edge_shared);
std::pair<shared<const Node<T>>, shared<const Edge<T>>> elem = {
edge_shared->getNodePair().second, edge_shared};
(*cachedAdjMatrix)[edge_shared->getNodePair().first].push_back(
std::move(elem));
}

Originally posted by @bbannier in #405 (comment)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Priority:HighPriority Label for high priority issuebugSomething isn't workingcoresomething about corehacktoberfesthacktoberfest issue

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions