Skip to content

Commit

Permalink
Merge pull request #1158 from PetholzA/feature/20231222_removeEdges_r…
Browse files Browse the repository at this point in the history
…estoreApi

restore_removeEdge_api
  • Loading branch information
fabratu committed Jan 15, 2024
2 parents cc801fd + abcaa9c commit 2ca1c47
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 23 deletions.
44 changes: 35 additions & 9 deletions include/networkit/graph/Graph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,14 @@ class Graph final {
//!< true if edge ids have been assigned
bool edgesIndexed;

//!< true if edge removals should maintain compact edge ids
bool maintainCompactEdges = false;
//!< true if edge removals should maintain sorted edge ids
bool maintainSortedEdges = false;

//!< saves the ID of the most recently removed edge (if exists)
edgeid deletedID;

// per node data
//!< exists[v] is true if node v has not been removed from the graph
std::vector<bool> exists;
Expand Down Expand Up @@ -1981,20 +1989,38 @@ class Graph final {
uint64_t index = 0, bool checkForMultiEdges = false);

/**
* Removes the undirected edge {@a u,@a v}.
* @param u Endpoint of edge.
* @param v Endpoint of edge.
* @param maintainSortedEdges If set to true, the ingoing and outgoing adjacency vectors will
* If set to true, the ingoing and outgoing adjacency vectors will
* automatically be updated to maintain a sorting (if it existed before) by performing up to n-1
* swaps. If the user plans to remove multiple edges, better set it to false and call
* sortEdges() afterwards to avoid redundant swaps. Default = false.
* @param maintainCompactEdgeIDs If set to true, the EdgeIDs will automatically be adjusted,
* sortEdges() afterwards to avoid redundant swaps. Default = true.
*/
void setKeepEdgesSorted(bool sorted = true) { maintainSortedEdges = sorted; }

/**
* If set to true, the EdgeIDs will automatically be adjusted,
* so that no gaps in between IDs exist. If the user plans to remove multiple edges, better set
* it to false and call indexEdges(force=true) afterwards to avoid redundant re-indexing.
* Default = false.
* Default = true.
*/
void setMaintainCompactEdges(bool compact = true) { maintainCompactEdges = compact; }

/**
* Returns true if edges are currently being sorted when removeEdge() is called.
*/
bool getKeepEdgesSorted() const noexcept { return maintainSortedEdges; }

/*
* Returns true if edges are currently being compacted when removeEdge() is called.
*/
bool getMaintainCompactEdges() const noexcept { return maintainCompactEdges; }

/**
*
* Removes the undirected edge {@a u,@a v}.
* @param u Endpoint of edge.
* @param v Endpoint of edge.
*/
void removeEdge(node u, node v, bool maintainSortedEdges = false,
bool maintainCompactEdgeIDs = false);
void removeEdge(node u, node v);

/**
* Removes all the edges in the graph.
Expand Down
18 changes: 8 additions & 10 deletions networkit/cpp/graph/Graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -600,23 +600,21 @@ void erase(node u, index idx, std::vector<std::vector<T>> &vec) {
vec[u].pop_back();
}

void Graph::removeEdge(node u, node v, bool maintainSortedEdges, bool maintainCompactEdgeIDs) {
void Graph::removeEdge(node u, node v) {
assert(u < z);
assert(exists[u]);
assert(v < z);
assert(exists[v]);

if (maintainCompactEdgeIDs && !edgesIndexed) {
throw std::runtime_error(
"Edges have to be indexed if maintainCompactEdgeIDs is set to true");
if (maintainCompactEdges && !edgesIndexed) {
throw std::runtime_error("Edges have to be indexed if maintainCompactEdges is set to true");
}

index vi = indexInOutEdgeArray(u, v);
index ui = indexInInEdgeArray(v, u);

node deletedID;
if (maintainCompactEdgeIDs) {
deletedID = outEdgeIds[u][vi];
if (maintainCompactEdges) {
deletedID = edgeId(u, v);
}

if (vi == none) {
Expand Down Expand Up @@ -680,7 +678,7 @@ void Graph::removeEdge(node u, node v, bool maintainSortedEdges, bool maintainCo
}
}
}
if (maintainCompactEdgeIDs) {
if (maintainCompactEdges) {
// re-index edge IDs from deleted edge upwards
balancedParallelForNodes([&](node u) {
for (index i = 0; i < outEdges[u].size(); ++i) {
Expand Down Expand Up @@ -715,7 +713,7 @@ void Graph::removeEdge(node u, node v, bool maintainSortedEdges, bool maintainCo
}
}

if (maintainCompactEdgeIDs) {
if (maintainCompactEdges) {
// re-index edge ids from target node
balancedParallelForNodes([&](node u) {
for (index i = 0; i < inEdges[u].size(); ++i) {
Expand All @@ -728,7 +726,7 @@ void Graph::removeEdge(node u, node v, bool maintainSortedEdges, bool maintainCo
});
}
}
if (maintainCompactEdgeIDs) {
if (maintainCompactEdges) {
omega--; // decrease upperBound of edges
}
}
Expand Down
10 changes: 6 additions & 4 deletions networkit/cpp/graph/test/GraphGTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2253,8 +2253,9 @@ TEST_P(GraphGTest, testEdgeIdsSortingAfterRemove) {
// remove edges
while (2 * G.numberOfEdges() > original.numberOfEdges()) {
const auto e = GraphTools::randomEdge(G, false);
G.removeEdge(e.first, e.second, true, false); // with sorting after each removal
original.removeEdge(e.first, e.second); // without sorting
G.setKeepEdgesSorted();
G.removeEdge(e.first, e.second); // with sorting after each removal
original.removeEdge(e.first, e.second); // without sorting
}

original.sortEdges(); // calling sort only once
Expand Down Expand Up @@ -2308,10 +2309,11 @@ TEST_P(GraphGTest, testEdgeIdsConsistencyAfterRemove) {
auto original = G;

// remove edges
G.setMaintainCompactEdges();
while (2 * G.numberOfEdges() > original.numberOfEdges()) {
const auto e = GraphTools::randomEdge(G, false);
G.removeEdge(e.first, e.second, false, true); // re-indexing after each removal
original.removeEdge(e.first, e.second); // not re-indexing
G.removeEdge(e.first, e.second); // re-indexing after each removal
original.removeEdge(e.first, e.second); // not re-indexing
}

original.indexEdges(true); // re-indexing only once
Expand Down

0 comments on commit 2ca1c47

Please sign in to comment.