Ticket #7571: trac_7571.patch

File trac_7571.patch, 6.5 KB (added by ylchapuy, 4 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