# HG changeset patch
# User Yann LaigleChapuy <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


2885  2885  sage: D.connected_components() 
2886  2886  [[0, 1, 2, 3], [4, 5, 6]] 
2887  2887  """ 
2888   seen = [] 
 2888  seen = set() 
2889  2889  components = [] 
2890  2890  for v in self: 
2891  2891  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) 
2895  2894  components.append(c) 
2896  2895  components.sort(lambda comp1, comp2: cmp(len(comp2), len(comp1))) 
2897  2896  return components 
… 
… 

2979  2978  sage: graphs.StarGraph(3).blocks_and_cut_vertices() 
2980  2979  ([[1, 0], [2, 0], [3, 0]], [0]) 
2981  2980  
 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  
2982  2992  ALGORITHM: 8.3.8 in [1]. Notice that the termination condition on 
2983  2993  line (23) of the algorithm uses "p[v] == 0" which in the book 
2984  2994  means that the parent is undefined; in this case, v must be the 
… 
… 

2991  3001   [1] D. Jungnickel, Graphs, Networks and Algorithms, 
2992  3002  Springer, 2005. 
2993  3003  """ 
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() 
3004  3019  i = 1 
3005   v = s 
3006   nr[s] = 1 
 3020  v = s # visited 
 3021  nr[s] = 1 
3007  3022  L[s] = 1 
3008   C = [] 
3009   B = [] 
3010   S = [s] 
 3023  C = [] # cuts 
 3024  B = [] # blocks 
 3025  S = [s] #stack 
 3026  its = {} 
3011  3027  while True: 
3012  3028  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: 
3021  3036  p[u] = v 
3022  3037  i += 1 
3023  3038  nr[u] = i 
… 
… 

3025  3040  S.append(u) 
3026  3041  v = u 
3027  3042  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: 
3054  3046  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 
3055  3068  return B, C 
3056  3069  
3057  3070  ### Vertex handlers 
… 
… 

5568  5581  sage: graphs.trees(9).next().girth() 
5569  5582  +Infinity 
5570  5583  """ 
5571   G = self.to_undirected() 
5572   G.relabel() # vertices are now {0, ..., n1} 
5573   n = G.num_verts() 
 5584  n = self.num_verts() 
5574  5585  best = n+1 
5575   for i in range(n2): 
5576   span = [0]*n 
5577   span[i] = 1 
 5586  for i in self.vertex_iterator(): 
 5587  span = set([i]) 
5578  5588  depth = 1 
5579   thisList = [i] 
 5589  thisList = set([i]) 
5580  5590  while 2*depth <= best and 3 < best: 
5581   nextList = [] 
 5591  nextList = set() 
5582  5592  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) 
5587  5597  else: 
5588  5598  if u in thisList: 
5589  5599  best = depth*21 