Skip to content

Commit

Permalink
Implement weak and strong node removal. (#156)
Browse files Browse the repository at this point in the history
* implement weak and strong node removal
  • Loading branch information
leotrs authored Aug 31, 2022
1 parent 14ee956 commit 4fba481
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 6 deletions.
17 changes: 17 additions & 0 deletions tests/classes/test_hypergraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -424,3 +424,20 @@ def test_duplicate_nodes(edgelist1):
if 1 not in members and 2 in members:
H.add_node_to_edge(edgeid, 1)
assert list(H.nodes.duplicates()) == [1, 2]


def test_remove_node_weak(edgelist1):
H = xgi.Hypergraph(edgelist1)
assert 1 in H
H.remove_node(1)
assert 1 not in H
with pytest.raises(IDNotFound):
H.remove_node(10)


def test_remove_node_strong(edgelist1):
H = xgi.Hypergraph(edgelist1)
assert 1 in H
H.remove_node(1, strong=True)
assert 1 not in H
assert 0 not in H.edges
26 changes: 20 additions & 6 deletions xgi/classes/hypergraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,13 +320,21 @@ def add_nodes_from(self, nodes_for_adding, **attr):
self._node_attr[n] = self._node_attr_dict_factory()
self._node_attr[n].update(newdict)

def remove_node(self, n):
"""Remove a single node and all adjacent hyperedges.
def remove_node(self, n, strong=False):
"""Remove a single node.
The removal may be weak (default) or strong. In weak removal, the node is
removed from each of its containing edges. If it is contained in any singleton
edges, then these are also removed. In strong removal, all edges containing the
node are removed, regardless of size.
Parameters
----------
n : node
A node in the hypergraph
A node in the hypergraph
strong : bool (default False)
Whether to execute weak or strong removal.
Raises
------
Expand All @@ -341,11 +349,17 @@ def remove_node(self, n):
edge_neighbors = self._node[n]
del self._node[n]
del self._node_attr[n]
for edge in edge_neighbors:
self._edge[edge].remove(n)
if not self._edge[edge]:

if strong:
for edge in edge_neighbors:
del self._edge[edge]
del self._edge_attr[edge]
else: # weak removal
for edge in edge_neighbors:
self._edge[edge].remove(n)
if not self._edge[edge]:
del self._edge[edge]
del self._edge_attr[edge]

def remove_nodes_from(self, nodes):
"""Remove multiple nodes.
Expand Down

0 comments on commit 4fba481

Please sign in to comment.