Source code for multilevelgraphs.contraction_schemes.decontraction_edge_based_contraction_scheme

from abc import ABC, abstractmethod
from typing import Callable, Dict, Any, Set, Optional

from multilevelgraphs.dec_graphs import DecGraph, Supernode, Superedge
from multilevelgraphs.contraction_schemes import EdgeBasedContractionScheme, CompTable


[docs]class DecontractionEdgeBasedContractionScheme(EdgeBasedContractionScheme, ABC): """ An abstract class for edge-based contraction schemes which make use of the complete decontraction of its graph in the update algorithms. This abstract class enriches the implementations of two of the update procedures defined in the ContractionScheme class: ``_update_added_node`` and ``_update_removed_node``. The other update procedures, ``_update_added_edge`` and ``_update_removed_edge``, are abstract and should be implemented by the subclasses as they depend on the specific contraction scheme. The ``_add_edge_to_decontraction`` and ``_remove_edge_from_decontraction`` methods of this class can be used to update the complete decontraction of the graph during the update procedures ``_update_added_edge`` and ``_update_removed_edge`` respectively. See also: :class:`EdgeBasedContractionScheme`, :class:`ContractionScheme` """ _decontracted_graph: Optional[DecGraph]
[docs] def __init__(self, supernode_attr_function: Callable[[Supernode], Dict[str, Any]] = None, superedge_attr_function: Callable[[Superedge], Dict[str, Any]] = None, c_set_attr_function: Callable[[Set[Supernode]], Dict[str, Any]] = None): super().__init__(supernode_attr_function, superedge_attr_function, c_set_attr_function) self._decontracted_graph = None # Used to store the current complete decontraction during subsequent updates
[docs] @abstractmethod def contraction_name(self) -> str: pass
[docs] @abstractmethod def clone(self): pass
[docs] @abstractmethod def contraction_function(self, dec_graph: DecGraph) -> CompTable: pass
# The following methods are overridden to update the decontracted graph used during the other update # procedures of the scheme. def _update_added_node(self, node: Supernode): super()._update_added_node(node) if not self._decontracted_graph: self._decontracted_graph = self.dec_graph.complete_decontraction() else: self._decontracted_graph.add_node(node) def _update_removed_node(self, node: Supernode): super()._update_removed_node(node) if not self._decontracted_graph: self._decontracted_graph = self.dec_graph.complete_decontraction() else: self._decontracted_graph.remove_node(node) @abstractmethod def _update_added_edge(self, superedge: Superedge): pass @abstractmethod def _update_removed_edge(self, superedge: Superedge): pass
[docs] def set_decontracted_graph(self): """ Sets the complete decontraction of the graph of this scheme. This method is used to lazily set the decontracted graph during the update procedures. """ if not self._decontracted_graph: self._decontracted_graph = self.dec_graph.complete_decontraction()
def _add_edge_to_decontraction(self, edge: Superedge): """ Adds the superedge to the complete decontraction of the graph of this scheme. This method should be used as the first step of the update procedure ``_update_added_edge``. :param edge: the superedge to add to the complete decontraction """ if not self._decontracted_graph: self._decontracted_graph = self.dec_graph.complete_decontraction() else: self._decontracted_graph.add_edge(Superedge(edge.tail, edge.head)) def _remove_edge_from_decontraction(self, edge: Superedge): """ Removes the superedge from the complete decontraction of the graph of this scheme. This method should be used as the first step of the update procedure ``_update_removed_edge``. :param edge: the superedge to remove from the complete decontraction """ if not self._decontracted_graph: self._decontracted_graph = self.dec_graph.complete_decontraction() else: self._decontracted_graph.remove_edge(Superedge(edge.tail, edge.head))