Пример #1
0
    def add_node_to_edge(self, node, edge):
        """
		Adds node to an edge in hypergraph edges

		Parameters
		----------
		node: hashable or Entity 
			If Entity, only uid and properties will be used.
			If uid is already in nodes then the known node will 
			be used

		edge: uid of edge or edge, must belong to self.edges

		Returns
		-------
		hypergraph : Hypergraph

		"""
        if edge in self._edges:
            if not isinstance(edge, Entity):
                edge = self._edges[edge]
            if node in self._nodes:
                if not isinstance(node, Entity):
                    node = self._nodes[node]
                self._edges[edge].add(node)
            else:
                if not isinstance(node, Entity):
                    node = Entity(node)
                else:
                    node = Entity(node.uid, **node.properties)
                self._nodes.add(node)
                self._edges[edge].add(node)
        return self
Пример #2
0
    def restrict_to_nodes(self, nodeset, name=None):
        """
		Constructs a new hypergraph by restricting the edges in the hypergraph to
		the nodes referenced by nodeset.

		Parameters
		----------
		nodeset: iterable of hashables
			References a subset of elements of self.nodes

		name: string, optional, default: None

		Returns
		-------
		new hypergraph : Hypergraph
		"""
        memberships = set()
        for node in nodeset:
            if node in self.nodes:
                memberships.update(set(self.nodes[node].memberships))
        newedgeset = dict()
        for e in memberships:
            if e in self.edges:
                temp = self.edges[e].uidset.intersection(nodeset)
                if temp:
                    newedgeset[e] = Entity(e, temp, **self.edges[e].properties)
        return Hypergraph(newedgeset, name)
Пример #3
0
    def from_bipartite(cls, B, set_names=[0, 1], name=None):
        """
		Static method creates a Hypergraph from a bipartite graph.

		Parameters
		----------

		B: nx.Graph()
			A networkx bipartite graph. Each node in the graph has a property
			'bipartite' taking one of two values

		set_names: iterable
			An ordered list :math:`[x_0, x_1]`, corresponding to the values 
			assigned to the bipartite property in B.

		name: hashable

		Returns
		-------
		new hypergraph : Hypergraph

		Notes
		-----
		A partition for the nodes in a bipartite graph generates a hypergraph as follows.
		For each node n in B with bipartite property equal to set_names[0] there is a 
		node n in the hypergraph.  For each node e in B with bipartite property
		equal to set_names[1], there is an edge in the hypergraph. 
		For each edge (n,e) in B add n to the edge e in the hypergraph.

		"""

        if not bipartite.is_bipartite(B):
            raise HyperNetxError('Error: Method requires a bipartite graph.')
        entities = []
        for n, d in B.nodes(data=True):
            if d['bipartite'] == set_names[1]:
                elements = []
                for nei in B.neighbors(n):
                    elements.append(
                        Entity(nei, [], properties=B.nodes(data=True)[nei]))
                if elements:
                    entities.append(Entity(n, elements, properties=d))
        name = name or '_'
        return Hypergraph(EntitySet(name, entities), name=name)
Пример #4
0
    def _add_nodes_from(self, nodes):
        """
		Private helper method instantiates new nodes when edges added to hypergraph. 

		Parameters
		----------
		nodes : iterable of hashables or Entities

		"""
        for node in nodes:
            if node in self._edges:
                raise HyperNetxError("Node already an edge.")
            elif node in self._nodes and isinstance(node, Entity):
                self._nodes[node].__dict__.update(node.properties)
            elif node not in self._nodes:
                if isinstance(node, Entity):
                    self._nodes.add(Entity(node.uid, **node.properties))
                else:
                    self._nodes.add(Entity(node))
Пример #5
0
    def add_edge(self, edge):
        """
		Adds a single edge to hypergraph.

		Parameters
		----------
		edge : hashable or Entity
			If hashable the edge returned will be empty.

		Returns
		-------
		hypergraph : Hypergraph

		Notes
		-----
		When adding an edge to a hypergraph children must be removed 
		so that nodes do not have elements.
		Each node (element of edge) must be instantiated as a node, 
		making sure its uid isn't already present in the self.
		If an added edge contains nodes that cannot be added to hypergraph
		then an error will be thrown.

		"""
        if edge in self._edges:
            warnings.warn("Cannot add edge. Edge already in hypergraph")
        elif edge in self._nodes:
            warnings.warn("Cannot add edge. Edge is already a Node")
        elif isinstance(edge, Entity):
            if len(edge) > 0:
                self._add_nodes_from(edge.elements.values())
                self._edges.add(
                    Entity(edge.uid,
                           elements=[self._nodes[k] for k in edge],
                           **edge.properties))
                for n in edge.elements:
                    self._nodes[n].memberships[edge.uid] = self._edges[
                        edge.uid]
            else:
                self._edges.add(Entity(edge.uid, **edge.properties))
        else:
            self._edges.add(Entity(edge))  ### this generates an empty edge
        return self
Пример #6
0
    def __init__(self, setsystem=None, name='_'):

        self.name = name

        ##### Check setsystem type and change into an EntitySet before constructing hypergraph:

        if not setsystem:
            setsystem = EntitySet('_', elements=[])

        elif isinstance(setsystem, dict):
            ### Must be a dictionary with values equal to iterables of Entities and hashables.
            ### Keys will be uids for new edges and values of the dictionary will generate the nodes.
            setsystem = EntitySet('_', setsystem)

        ### If no ids are given, return default ids indexed by position in iterator
        ### This should be an iterable of sets
        elif not isinstance(setsystem, EntitySet):
            labels = [self.name + str(x) for x in range(len(setsystem))]
            setsystem = EntitySet('_', dict(zip(labels, setsystem)))

        _reg = setsystem.registry
        _nodes = {k: Entity(k, **_reg[k].properties) for k in _reg}
        _elements = {
            j: {k: _nodes[k]
                for k in setsystem[j]}
            for j in setsystem
        }
        _edges = {
            j: Entity(j,
                      elements=_elements[j].values(),
                      **setsystem[j].properties)
            for j in setsystem
        }

        self._edges = EntitySet(f'{self.name}:Edges',
                                elements=_edges.values(),
                                **setsystem.properties)
        self._nodes = EntitySet(f'{self.name}:Nodes', elements=_nodes.values())