Ticket #7571: trac_7571.patch

File trac_7571.patch, 6.5 KB (added by ylchapuy, 7 years ago)
  • sage/graphs/graph.py

    # HG changeset patch
    # User Yann Laigle-Chapuy <yannlaiglechapuy@gmail.com>
    # Date 1259682400 -3600
    # Node ID 1244ebc79c9fe270a2d7a9da936bde1e94aaafb7
    # Parent  6e1d0fcde31742fb9c905a7b01f6364baf06e242
    use more dicts in graph.py
    
    diff -r 6e1d0fcde317 -r 1244ebc79c9f sage/graphs/graph.py
    a b  
    28852885            sage: D.connected_components()
    28862886            [[0, 1, 2, 3], [4, 5, 6]]
    28872887        """
    2888         seen = []
     2888        seen = set()
    28892889        components = []
    28902890        for v in self:
    28912891            if v not in seen:
    2892                 c = list(self.breadth_first_search(v, ignore_direction=True))
    2893                 c.sort()
    2894                 seen.extend(c)
     2892                c = self.connected_component_containing_vertex(v)
     2893                seen.update(c)
    28952894                components.append(c)
    28962895        components.sort(lambda comp1, comp2: cmp(len(comp2), len(comp1)))
    28972896        return components
     
    29792978            sage: graphs.StarGraph(3).blocks_and_cut_vertices()
    29802979            ([[1, 0], [2, 0], [3, 0]], [0])
    29812980       
     2981        TESTS::
     2982
     2983            sage: Graph(0).blocks_and_cut_vertices()
     2984            ([], [])
     2985            sage: Graph(1).blocks_and_cut_vertices()
     2986            ([0], [0])
     2987            sage: Graph(2).blocks_and_cut_vertices()
     2988            Traceback (most recent call last):
     2989            ...
     2990            NotImplementedError: ...
     2991
    29822992        ALGORITHM: 8.3.8 in [1]. Notice that the termination condition on
    29832993        line (23) of the algorithm uses "p[v] == 0" which in the book
    29842994        means that the parent is undefined; in this case, v must be the
     
    29913001        - [1] D. Jungnickel, Graphs, Networks and Algorithms,
    29923002          Springer, 2005.
    29933003        """
    2994         G = self.to_undirected()
    2995         map_to_ints = G.relabel(return_map=True)
    2996         s = G.vertex_iterator().next()
    2997         nr = [0]*G.num_verts()
    2998         p = [None]*G.num_verts()  # no vertex has a parent until visited
    2999         L = [0]*G.num_verts()
    3000         edges = {}
    3001         for u,v in G.edges(labels=False):
    3002             edges[(u,v)] = False
    3003             edges[(v,u)] = False
     3004        if not self: # empty graph
     3005            return [],[]
     3006       
     3007        s = self.vertex_iterator().next() # source
     3008
     3009        if len(self) == 1: # only one vertex
     3010            return [s],[s]
     3011
     3012        if not self.is_connected():
     3013            raise NotImplementedError("Blocks and cut vertices is currently only implemented for connected graphs.")
     3014
     3015        nr = {} # enumerate
     3016        p = {} # predecessors
     3017        L = {}
     3018        visited_edges = set()
    30043019        i = 1
    3005         v = s
    3006         nr[s] = 1
     3020        v = s # visited
     3021        nr[s] = 1 
    30073022        L[s] = 1
    3008         C = []
    3009         B = []
    3010         S = [s]
     3023        C = [] # cuts
     3024        B = [] # blocks
     3025        S = [s] #stack
     3026        its = {}
    30113027        while True:
    30123028            while True:
    3013                 u = -1
    3014                 for u in G.neighbor_iterator(v):
    3015                     if not edges[(v,u)]: break
    3016                 if u == -1: break
    3017                 if edges[(v,u)]: break
    3018                 edges[(v,u)] = True
    3019                 edges[(u,v)] = True
    3020                 if nr[u] == 0:
     3029                for u in self.neighbor_iterator(v):
     3030                    if not (v,u) in visited_edges: break
     3031                else:
     3032                    break
     3033                visited_edges.add((v,u))
     3034                visited_edges.add((u,v))
     3035                if u not in nr:
    30213036                    p[u] = v
    30223037                    i += 1
    30233038                    nr[u] = i
     
    30253040                    S.append(u)
    30263041                    v = u
    30273042                else:
    3028                     L[v] = min([ L[v], nr[u] ])
    3029             if p[v] != s:
    3030                 if L[v] < nr[p[v]]:
    3031                     L[p[v]] = min([ L[p[v]], L[v] ])
    3032                 else:
    3033                     if p[v] not in C:
    3034                         C.append(p[v])
    3035                     B_k = []
    3036                     while True:
    3037                         u = S.pop(-1)
    3038                         B_k.append(u)
    3039                         if u == v: break
    3040                     B_k.append(p[v])
    3041                     B.append(B_k)
    3042             else:
    3043                 if any([ not edges[(s,u)] for u in G.neighbors(s)]) and p[v] not in C:
    3044                     C.append(s)
    3045                 B_k = []
    3046                 while True:
    3047                     u = S.pop(-1)
    3048                     B_k.append(u)
    3049                     if u == v: break
    3050                 B_k.append(s)
    3051                 B.append(B_k)
    3052             v = p[v]
    3053             if v == s and all([edges[(v,u)] for u in G.neighbors(v)]):
     3043                    L[v] = min( L[v], nr[u] )
     3044
     3045            if v is s:
    30543046                break
     3047
     3048            pv = p[v]
     3049            if L[v] < nr[pv]:
     3050                L[pv] = min( L[pv], L[v] )
     3051                v = pv
     3052                continue
     3053           
     3054            if pv not in C:
     3055                if pv is not s or\
     3056                        not all([(s,u) in visited_edges for u in self.neighbor_iterator(s)]):
     3057                    C.append(pv)
     3058
     3059            B_k = []
     3060            while True:
     3061                u = S.pop()
     3062                B_k.append(u)
     3063                if u == v: break
     3064            B_k.append(pv)
     3065            B.append(B_k)
     3066
     3067            v = pv
    30553068        return B, C
    30563069
    30573070    ### Vertex handlers
     
    55685581            sage: graphs.trees(9).next().girth()
    55695582            +Infinity
    55705583        """
    5571         G = self.to_undirected()
    5572         G.relabel() # vertices are now {0, ..., n-1}
    5573         n = G.num_verts()
     5584        n = self.num_verts()
    55745585        best = n+1
    5575         for i in range(n-2):
    5576             span = [0]*n
    5577             span[i] = 1
     5586        for i in self.vertex_iterator():
     5587            span = set([i])
    55785588            depth = 1
    5579             thisList = [i]
     5589            thisList = set([i])
    55805590            while 2*depth <= best and 3 < best:
    5581                 nextList = []
     5591                nextList = set()
    55825592                for v in thisList:
    5583                     for u in G.neighbors(v):
    5584                         if not span[u]:
    5585                             span[u] = 1
    5586                             nextList.append(u)
     5593                    for u in self.neighbors(v):
     5594                        if not u in span:
     5595                            span.add(u)
     5596                            nextList.add(u)
    55875597                        else:
    55885598                            if u in thisList:
    55895599                                best = depth*2-1