예제 #1
0
 def __init__(self, degree, idgenerator="set"):
     """
     constructor of an empty mesh
     """
     self._degree = degree
     self._borders = [None] + [
         IdDict(idgenerator=idgenerator) for i in xrange(degree)
     ]
     self._regions = [IdDict(idgenerator=idgenerator)
                      ] + [{} for i in xrange(degree - 1)]
예제 #2
0
    def __init__(self, graph=None, idgenerator="set"):
        """constructor

        if graph is not none make a copy of the topological structure of graph
        (i.e. don't use the same id)

        :param graph: the graph to copy, default=None
        :type graph: Graph
        """
        self._vertices = IdDict(idgenerator=idgenerator)
        self._edges = IdDict(idgenerator=idgenerator)
        if graph is not None:
            dummy = self.extend(graph)
예제 #3
0
    def __init__(self, graph=None, idgenerator = "set"):
        """constructor

        if graph is not none make a copy of the topological structure of graph
        (i.e. don't use the same id)

        :param graph: the graph to copy, default=None
        :type graph: Graph
        """
        self._vertices=IdDict(idgenerator = idgenerator)
        self._edges=IdDict(idgenerator = idgenerator)
        if graph is not None :
            dummy=self.extend(graph)
예제 #4
0
 def __init__ (self, idgenerator = "set") :
     """
     constructor of an empty relation
     """
     self._left_links=IdDict(idgenerator = idgenerator)
     self._right_links=IdDict(idgenerator = idgenerator)
     self._link_extremities=IdDict(idgenerator = idgenerator)
예제 #5
0
class Relation (IRelation,ILeftListRelation,IRightListRelation,ILinkRelation,IMutableRelation) :
    """
    implementation of a relation
    """
    def __init__ (self, idgenerator = "set") :
        """
        constructor of an empty relation
        """
        self._left_links=IdDict(idgenerator = idgenerator)
        self._right_links=IdDict(idgenerator = idgenerator)
        self._link_extremities=IdDict(idgenerator = idgenerator)

    ########################################################################
    #
    #               Relation concept
    #
    ########################################################################
    def is_valid (self) :
        return True
    is_valid.__doc__=IRelation.is_valid.__doc__

    def has_left (self, elmid) :
        return elmid in self._left_links
    has_left.__doc__=IRelation.has_left.__doc__

    def has_right (self, elmid) :
        return elmid in self._right_links
    has_right.__doc__=IRelation.has_right.__doc__

    def has_link (self, lid) :
        return lid in self._link_extremities
    has_link.__doc__=IRelation.has_link.__doc__
    ########################################################################
    #
    #               Left list concept
    #
    ########################################################################
    def left_elements (self) :
        return self._left_links.iterkeys()
    left_elements.__doc__=ILeftListRelation.left_elements.__doc__

    def nb_left_elements (self) :
        return len(self._left_links)
    nb_left_elements.__doc__=ILeftListRelation.nb_left_elements.__doc__
    ########################################################################
    #
    #               Right list concept
    #
    ########################################################################
    def right_elements (self) :
        return self._right_links.iterkeys()
    right_elements.__doc__=IRightListRelation.right_elements.__doc__

    def nb_right_elements (self) :
        return len(self._right_links)
    nb_right_elements.__doc__=IRightListRelation.nb_right_elements.__doc__
    ########################################################################
    #
    #               Link Relation concept
    #
    ########################################################################
    def links (self) :
        return self._link_extremities.iterkeys()
    links.__doc__=ILinkRelation.links.__doc__

    def from_left (self, elmid) :
        try :
            return iter(self._left_links[elmid])
        except KeyError :
            raise StrInvalidLeft(elmid)
    from_left.__doc__=ILinkRelation.from_left.__doc__

    def nb_links_from_left (self, elmid) :
        try :
            return len(self._left_links[elmid])
        except KeyError :
            raise StrInvalidLeft(elmid)
    nb_links_from_left.__doc__=ILinkRelation.nb_links_from_left.__doc__

    def from_right (self, elmid) :
        try :
            return iter(self._right_links[elmid])
        except KeyError :
            raise StrInvalidRight(elmid)
    from_right.__doc__=ILinkRelation.from_right.__doc__

    def nb_links_from_right (self, elmid) :
        try :
            return len(self._right_links[elmid])
        except KeyError :
            raise StrInvalidRight(elmid)
    nb_links_from_right.__doc__=ILinkRelation.nb_links_from_right.__doc__

    def left (self, lid) :
        try :
            return self._link_extremities[lid][0]
        except KeyError :
            raise StrInvalidLink(lid)
    left.__doc__=ILinkRelation.left.__doc__

    def right (self, lid) :
        try :
            return self._link_extremities[lid][1]
        except KeyError :
            raise StrInvalidLink(lid)
    right.__doc__=ILinkRelation.right.__doc__
    ########################################################################
    #
    #               Mutable relation concept
    #
    ########################################################################
    def add_left_element (self, elmid=None) :
        return self._left_links.add(set(),elmid)
    add_left_element.__doc__=IMutableRelation.add_left_element.__doc__

    def remove_left_element (self, elmid) :
        for lid in list(self.from_left(elmid)) :
            self.remove_link(lid)
        del self._left_links[elmid]
    remove_left_element.__doc__=IMutableRelation.remove_left_element.__doc__

    def add_right_element (self, elmid=None) :
        return self._right_links.add(set(),elmid)
    add_right_element.__doc__=IMutableRelation.add_right_element.__doc__

    def remove_right_element (self, elmid) :
        for lid in list(self.from_right(elmid)) :
            self.remove_link(lid)
        del self._right_links[elmid]
    remove_right_element.__doc__=IMutableRelation.remove_right_element.__doc__

    def add_link (self, left_elmid, right_elmid, lid=None) :
        if not self.has_left(left_elmid) :
            raise StrInvalidLeft(left_elmid)
        if not self.has_right(right_elmid) :
            raise StrInvalidRight(right_elmid)
        lid=self._link_extremities.add( (left_elmid,right_elmid),lid )
        self._left_links[left_elmid].add(lid)
        self._right_links[right_elmid].add(lid)
        return lid
    add_link.__doc__=IMutableRelation.add_link.__doc__

    def remove_link (self, lid) :
        self._left_links[self.left(lid)].remove(lid)
        self._right_links[self.right(lid)].remove(lid)
        del self._link_extremities[lid]
    remove_link.__doc__=IMutableRelation.remove_link.__doc__
예제 #6
0
class Graph(IGraph, IVertexListGraph, IEdgeListGraph, IMutableVertexGraph, IMutableEdgeGraph, IExtendGraph):
    """
    directed graph with multiple links
    in this implementation :

        - vertices are tuple of edge_in,edge_out
        - edges are tuple of source,target
    """

    def __init__(self, graph=None, idgenerator="set"):
        """constructor

        if graph is not none make a copy of the topological structure of graph
        (i.e. don't use the same id)

        :param graph: the graph to copy, default=None
        :type graph: Graph
        """
        self._vertices = IdDict(idgenerator=idgenerator)
        self._edges = IdDict(idgenerator=idgenerator)
        if graph is not None:
            dummy = self.extend(graph)

    # ##########################################################
    #
    # Graph concept
    #
    # ##########################################################
    def source(self, eid):
        try:
            return self._edges[eid][0]
        except KeyError:
            raise InvalidEdge(eid)

    source.__doc__ = IGraph.source.__doc__

    def target(self, eid):
        try:
            return self._edges[eid][1]
        except KeyError:
            raise InvalidEdge(eid)

    target.__doc__ = IGraph.target.__doc__

    def edge_vertices(self, eid):
        try:
            return self._edges[eid]
        except KeyError:
            raise InvalidEdge(eid)

    edge_vertices.__doc__ = IGraph.edge_vertices.__doc__

    def edge(self, source, target):
        link_in, link_out = self._vertices[source]
        for eid in link_in:
            if self._edges[eid][0] == target:
                return eid
        for eid in link_out:
            if self._edges[eid][1] == target:
                return eid
        return None

    edge.__doc__ = IGraph.edge.__doc__

    def __contains__(self, vid):
        return self.has_vertex(vid)

    __contains__.__doc__ = IGraph.__contains__.__doc__

    def has_vertex(self, vid):
        return self._vertices.has_key(vid)

    has_vertex.__doc__ = IGraph.has_vertex.__doc__

    def has_edge(self, eid):
        return self._edges.has_key(eid)

    has_edge.__doc__ = IGraph.has_edge.__doc__

    def is_valid(self):
        return True

    is_valid.__doc__ = IGraph.is_valid.__doc__

    # ##########################################################
    #
    # Vertex List Graph Concept
    #
    # ##########################################################
    def vertices(self):
        return iter(self._vertices)

    vertices.__doc__ = IVertexListGraph.vertices.__doc__

    def __iter__(self):
        return iter(self._vertices)

    __iter__.__doc__ = IVertexListGraph.__iter__.__doc__

    def nb_vertices(self):
        return len(self._vertices)

    nb_vertices.__doc__ = IVertexListGraph.nb_vertices.__doc__

    def __len__(self):
        return self.nb_vertices()

    __len__.__doc__ = IVertexListGraph.__len__.__doc__

    def in_neighbors(self, vid):
        if vid not in self:
            raise InvalidVertex(vid)
        neighbors_list = [self.source(eid) for eid in self._vertices[vid][0]]
        return iter(set(neighbors_list))

    in_neighbors.__doc__ = IVertexListGraph.in_neighbors.__doc__

    def out_neighbors(self, vid):
        if vid not in self:
            raise InvalidVertex(vid)
        neighbors_list = [self.target(eid) for eid in self._vertices[vid][1]]
        return iter(set(neighbors_list))

    out_neighbors.__doc__ = IVertexListGraph.out_neighbors.__doc__

    def neighbors(self, vid):
        neighbors_list = list(self.in_neighbors(vid))
        neighbors_list.extend(self.out_neighbors(vid))
        return iter(set(neighbors_list))

    neighbors.__doc__ = IVertexListGraph.neighbors.__doc__

    def nb_in_neighbors(self, vid):
        neighbors_set = list(self.in_neighbors(vid))
        return len(neighbors_set)

    nb_in_neighbors.__doc__ = IVertexListGraph.nb_in_neighbors.__doc__

    def nb_out_neighbors(self, vid):
        neighbors_set = list(self.out_neighbors(vid))
        return len(neighbors_set)

    nb_out_neighbors.__doc__ = IVertexListGraph.nb_out_neighbors.__doc__

    def nb_neighbors(self, vid):
        neighbors_set = list(self.neighbors(vid))
        return len(neighbors_set)

    nb_neighbors.__doc__ = IVertexListGraph.nb_neighbors.__doc__

    # ##########################################################
    #
    # Edge List Graph Concept
    #
    # ##########################################################
    def _iter_edges(self, vid):
        """
        internal function that perform 'edges' with vid not None
        """
        link_in, link_out = self._vertices[vid]
        for eid in link_in:
            yield eid
        for eid in link_out:
            yield eid

    def edges(self, vid=None):
        if vid is None:
            return iter(self._edges)
        if vid not in self:
            raise InvalidVertex(vid)
        return self._iter_edges(vid)

    edges.__doc__ = IEdgeListGraph.edges.__doc__

    def nb_edges(self, vid=None):
        if vid is None:
            return len(self._edges)
        if vid not in self:
            raise InvalidVertex(vid)
        return len(self._vertices[vid][0]) + len(self._vertices[vid][1])

    nb_edges.__doc__ = IEdgeListGraph.nb_edges.__doc__

    def in_edges(self, vid):
        if vid not in self:
            raise InvalidVertex(vid)
        for eid in self._vertices[vid][0]:
            yield eid

    in_edges.__doc__ = IEdgeListGraph.in_edges.__doc__

    def out_edges(self, vid):
        if vid not in self:
            raise InvalidVertex(vid)
        for eid in self._vertices[vid][1]:
            yield eid

    out_edges.__doc__ = IEdgeListGraph.out_edges.__doc__

    def nb_in_edges(self, vid):
        if vid not in self:
            raise InvalidVertex(vid)
        return len(self._vertices[vid][0])

    nb_in_edges.__doc__ = IEdgeListGraph.nb_in_edges.__doc__

    def nb_out_edges(self, vid):
        if vid not in self:
            raise InvalidVertex(vid)
        return len(self._vertices[vid][1])

    nb_out_edges.__doc__ = IEdgeListGraph.nb_out_edges.__doc__

    # ##########################################################
    #
    # Mutable Vertex Graph concept
    #
    # ##########################################################
    def add_vertex(self, vid=None):
        return self._vertices.add((set(), set()), vid)

    add_vertex.__doc__ = IMutableVertexGraph.add_vertex.__doc__

    def remove_vertex(self, vid):
        if vid not in self:
            raise InvalidVertex(vid)
        link_in, link_out = self._vertices[vid]
        for edge in list(link_in):
            self.remove_edge(edge)
        for edge in list(link_out):
            self.remove_edge(edge)
        del self._vertices[vid]

    remove_vertex.__doc__ = IMutableVertexGraph.remove_vertex.__doc__

    def clear(self):
        self._edges.clear()
        self._vertices.clear()

    clear.__doc__ = IMutableVertexGraph.clear.__doc__

    # ##########################################################
    #
    # Mutable Edge Graph concept
    #
    # ##########################################################
    def add_edge(self, sid, tid, eid=None):
        if sid not in self:
            raise InvalidVertex(sid)
        if tid not in self:
            raise InvalidVertex(tid)
        eid = self._edges.add((sid, tid), eid)
        self._vertices[sid][1].add(eid)
        self._vertices[tid][0].add(eid)
        return eid

    add_edge.__doc__ = IMutableEdgeGraph.add_edge.__doc__

    def remove_edge(self, eid):
        if not self.has_edge(eid):
            raise InvalidEdge(eid)
        sid, tid = self._edges[eid]
        self._vertices[sid][1].remove(eid)
        self._vertices[tid][0].remove(eid)
        del self._edges[eid]

    remove_edge.__doc__ = IMutableEdgeGraph.remove_edge.__doc__

    def clear_edges(self):
        self._edges.clear()
        for vid, (in_edges, out_edges) in self._vertices.iteritems():
            in_edges.clear()
            out_edges.clear()

    clear_edges.__doc__ = IMutableEdgeGraph.clear_edges.__doc__

    # ##########################################################
    #
    # Extend Graph concept
    #
    # ##########################################################
    def extend(self, graph):
        # vertex adding
        trans_vid = {}
        for vid in list(graph.vertices()):
            trans_vid[vid] = self.add_vertex()

        # edge adding
        trans_eid = {}
        for eid in list(graph.edges()):
            sid = trans_vid[graph.source(eid)]
            tid = trans_vid[graph.target(eid)]
            trans_eid[eid] = self.add_edge(sid, tid)

        return trans_vid, trans_eid

    extend.__doc__ = IExtendGraph.extend.__doc__

    def sub_graph(self, vids):
        """
        """
        from copy import deepcopy

        vids = set(vids)

        result = deepcopy(self)
        result._vertices.clear()
        result._edges.clear()

        for key, edges in self._vertices.items():
            if key in vids:
                inedges, outedges = edges
                sortedinedges = set([eid for eid in inedges if self.source(eid) in vids])
                sortedoutedges = set([eid for eid in outedges if self.target(eid) in vids])
                result._vertices.add((sortedinedges, sortedoutedges), key)
                for eid in sortedoutedges:
                    result._edges.add(self._edges[eid], eid)

        return result
예제 #7
0
class Graph (IGraph,\
                        IVertexListGraph,IEdgeListGraph,\
                        IMutableVertexGraph,IMutableEdgeGraph,\
                        IExtendGraph):
    """
    directed graph with multiple links
    in this implementation :

        - vertices are tuple of edge_in,edge_out
        - edges are tuple of source,target
    """
    def __init__(self, graph=None, idgenerator = "set"):
        """constructor

        if graph is not none make a copy of the topological structure of graph
        (i.e. don't use the same id)

        :param graph: the graph to copy, default=None
        :type graph: Graph
        """
        self._vertices=IdDict(idgenerator = idgenerator)
        self._edges=IdDict(idgenerator = idgenerator)
        if graph is not None :
            dummy=self.extend(graph)

    # ##########################################################
    #
    # Graph concept
    #
    # ##########################################################
    def source(self, eid):
        try :
            return self._edges[eid][0]
        except KeyError :
            raise InvalidEdge(eid)
    source.__doc__=IGraph.source.__doc__

    def target(self, eid):
        try :
            return self._edges[eid][1]
        except KeyError :
            raise InvalidEdge(eid)
    target.__doc__=IGraph.target.__doc__

    def edge_vertices(self, eid):
        try :
            return self._edges[eid]
        except KeyError :
            raise InvalidEdge(eid)
    edge_vertices.__doc__=IGraph.edge_vertices.__doc__
    
    def edge(self, source, target) :
        link_in,link_out=self._vertices[source]
        for eid in link_in : 
            if self._edges[eid][0] == target: 
                return eid
        for eid in link_out :
            if self._edges[eid][1] == target: 
                return eid        
        return None
        
    edge.__doc__=IGraph.edge.__doc__

    def __contains__(self, vid):
        return self.has_vertex(vid)
    __contains__.__doc__=IGraph.__contains__.__doc__

    def has_vertex(self,vid):
        return self._vertices.has_key(vid)
    has_vertex.__doc__=IGraph.has_vertex.__doc__

    def has_edge(self,eid):
        return self._edges.has_key(eid)
    has_edge.__doc__=IGraph.has_edge.__doc__

    def is_valid(self):
        return True
    is_valid.__doc__=IGraph.is_valid.__doc__

    # ##########################################################
    #
    # Vertex List Graph Concept
    #
    # ##########################################################
    def vertices(self):
        return iter(self._vertices)
    vertices.__doc__=IVertexListGraph.vertices.__doc__

    def __iter__ (self) :
        return iter(self._vertices)
    __iter__.__doc__=IVertexListGraph.__iter__.__doc__

    def nb_vertices(self):
        return len(self._vertices)
    nb_vertices.__doc__=IVertexListGraph.nb_vertices.__doc__

    def __len__(self):
        return self.nb_vertices()
    __len__.__doc__=IVertexListGraph.__len__.__doc__

    def in_neighbors(self, vid):
        if vid not in self :
            raise InvalidVertex(vid)
        neighbors_list=[self.source(eid) for eid in self._vertices[vid][0] ]
        return iter(set(neighbors_list))
    in_neighbors.__doc__=IVertexListGraph.in_neighbors.__doc__

    def out_neighbors(self, vid):
        if vid not in self :
            raise InvalidVertex(vid)
        neighbors_list=[self.target(eid) for eid in self._vertices[vid][1] ]
        return iter(set(neighbors_list))
    out_neighbors.__doc__=IVertexListGraph.out_neighbors.__doc__

    def neighbors(self, vid):
        neighbors_list=list(self.in_neighbors(vid))
        neighbors_list.extend(self.out_neighbors(vid))
        return iter(set(neighbors_list))
    neighbors.__doc__=IVertexListGraph.neighbors.__doc__

    def nb_in_neighbors(self, vid):
        neighbors_set=list(self.in_neighbors(vid))
        return len(neighbors_set)
    nb_in_neighbors.__doc__=IVertexListGraph.nb_in_neighbors.__doc__

    def nb_out_neighbors(self, vid):
        neighbors_set=list(self.out_neighbors(vid))
        return len(neighbors_set)
    nb_out_neighbors.__doc__=IVertexListGraph.nb_out_neighbors.__doc__

    def nb_neighbors(self, vid):
        neighbors_set=list(self.neighbors(vid))
        return len(neighbors_set)
    nb_neighbors.__doc__=IVertexListGraph.nb_neighbors.__doc__

    # ##########################################################
    #
    # Edge List Graph Concept
    #
    # ##########################################################
    def _iter_edges (self, vid) :
        """
        internal function that perform 'edges' with vid not None
        """
        link_in,link_out=self._vertices[vid]
        for eid in link_in : yield eid
        for eid in link_out : yield eid

    def edges(self, vid=None):
        if vid is None :
            return iter(self._edges)
        if vid not in self :
            raise InvalidVertex(vid)
        return self._iter_edges(vid)
    edges.__doc__=IEdgeListGraph.edges.__doc__

    def nb_edges(self, vid=None):
        if vid is None :
            return len(self._edges)
        if vid not in self :
            raise InvalidVertex(vid)
        return len(self._vertices[vid][0])+len(self._vertices[vid][1])
    nb_edges.__doc__=IEdgeListGraph.nb_edges.__doc__

    def in_edges(self, vid):
        if vid not in self :
            raise InvalidVertex(vid)
        for eid in self._vertices[vid][0] : yield eid
    in_edges.__doc__=IEdgeListGraph.in_edges.__doc__

    def out_edges(self, vid):
        if vid not in self :
            raise InvalidVertex(vid)
        for eid in self._vertices[vid][1] : yield eid
    out_edges.__doc__=IEdgeListGraph.out_edges.__doc__

    def nb_in_edges(self, vid):
        if vid not in self :
            raise InvalidVertex(vid)
        return len(self._vertices[vid][0])
    nb_in_edges.__doc__=IEdgeListGraph.nb_in_edges.__doc__

    def nb_out_edges(self, vid):
        if vid not in self :
            raise InvalidVertex(vid)
        return len(self._vertices[vid][1])
    nb_out_edges.__doc__=IEdgeListGraph.nb_out_edges.__doc__

    # ##########################################################
    #
    # Mutable Vertex Graph concept
    #
    # ##########################################################
    def add_vertex(self, vid=None):
        return self._vertices.add((set(),set()),vid )
    add_vertex.__doc__=IMutableVertexGraph.add_vertex.__doc__

    def remove_vertex(self, vid):
        if vid not in self :
            raise InvalidVertex(vid)
        link_in,link_out=self._vertices[vid]
        for edge in list(link_in) : self.remove_edge(edge)
        for edge in list(link_out) : self.remove_edge(edge)
        del self._vertices[vid]
    remove_vertex.__doc__=IMutableVertexGraph.remove_vertex.__doc__

    def clear(self):
        self._edges.clear()
        self._vertices.clear()
    clear.__doc__=IMutableVertexGraph.clear.__doc__

    # ##########################################################
    #
    # Mutable Edge Graph concept
    #
    # ##########################################################
    def add_edge(self, sid, tid, eid=None):
        if sid not in self :
            raise InvalidVertex(sid)
        if tid not in self :
            raise InvalidVertex(tid)
        eid=self._edges.add((sid,tid),eid)
        self._vertices[sid][1].add(eid)
        self._vertices[tid][0].add(eid)
        return eid
    add_edge.__doc__=IMutableEdgeGraph.add_edge.__doc__

    def remove_edge(self,eid):
        if not self.has_edge(eid) :
            raise InvalidEdge(eid)
        sid,tid=self._edges[eid]
        self._vertices[sid][1].remove(eid)
        self._vertices[tid][0].remove(eid)
        del self._edges[eid]
    remove_edge.__doc__=IMutableEdgeGraph.remove_edge.__doc__

    def clear_edges(self):
        self._edges.clear()
        for vid,(in_edges,out_edges) in self._vertices.iteritems() :
            in_edges.clear()
            out_edges.clear()
    clear_edges.__doc__=IMutableEdgeGraph.clear_edges.__doc__
    
    # ##########################################################
    #
    # Extend Graph concept
    #
    # ##########################################################
    def extend(self, graph):
        #vertex adding
        trans_vid={}
        for vid in list(graph.vertices()) :
            trans_vid[vid]=self.add_vertex()

        #edge adding
        trans_eid={}
        for eid in list(graph.edges()) :
            sid=trans_vid[graph.source(eid)]
            tid=trans_vid[graph.target(eid)]
            trans_eid[eid]=self.add_edge(sid,tid)

        return trans_vid,trans_eid
    extend.__doc__=IExtendGraph.extend.__doc__
    
    def sub_graph(self, vids):
        """
        """
        from copy import deepcopy
        vids = set(vids)
        
        result = deepcopy(self)
        result._vertices.clear()
        result._edges.clear()
        
        for key, edges in self._vertices.items():
            if key in vids:
                inedges, outedges = edges
                sortedinedges = set([eid for eid in inedges if self.source(eid) in vids])
                sortedoutedges = set([eid for eid in outedges if self.target(eid) in vids])
                result._vertices.add((sortedinedges,sortedoutedges), key)
                for eid in sortedoutedges:
                    result._edges.add(self._edges[eid], eid)
        
        return result