# HG changeset patch
# User Diego de Estrada <destrada@dc.uba.ar>
# Date 1315290554 10800
# Node ID 4a4d5218c2814646f948e002476e1c4173faed28
# Parent 2a2abbcad325ccca9399981ceddf5897eb467e64
Implementation of lex_BFS() in linear time.
diff r 2a2abbcad325 r 4a4d5218c281 sage/graphs/generic_graph.py
a

b


9387  9387  for each vertex `v` the subgraph induces by its nondeleted neighbors, 
9388  9388  then testing whether this graph is complete. 
9389  9389  
9390   This problem can be solved in `O(m)` [Rose75]_ ( where `m` is the number 
9391   of edges in the graph ) but this implementation is not linear because of 
9392   the complexity of Lex BFS. Improving Lex BFS to linear complexity would 
9393   make this algorithm linear. 
9394   
9395  9390  The complexity of this algorithm is equal to the complexity of the 
9396   implementation of Lex BFS. 
 9391  implementation of Lex BFS [Rose75]_, which is linear in the size of the 
 9392  graph. 
9397  9393  
9398  9394  EXAMPLES: 
9399  9395  
… 
… 

11535  11531  vertex of maximal code ( according to the lexicographic 
11536  11532  order ) is then removed, and the codes are updated. 
11537  11533  
11538   This algorithm runs in time `O(n^2)` ( where `n` is the 
11539   number of vertices in the graph ), which is not optimal. 
11540   An optimal algorithm would run in time `O(m)` ( where `m` 
11541   is the number of edges in the graph ), and require the use 
11542   of a doublylinked list which are not available in python 
11543   and can not really be written efficiently. This could be 
11544   done in Cython, though. 
 11534  This algorithm runs in time `O(n+m)` ( where `n` is the 
 11535  number of vertices in the graph and `m` is the number of 
 11536  edges in the graph ). 
11545  11537  
11546  11538  EXAMPLE: 
11547  11539  
… 
… 

11571  11563  True 
11572  11564  
11573  11565  """ 
11574   id_inv = dict([(i,v) for (v,i) in zip(self.vertices(),range(self.order()))]) 
11575   code = [[] for i in range(self.order())] 
11576   m = self.am() 
11577   
11578   l = lambda x : code[x] 
11579   vertices = set(range(self.order())) 
11580   
11581   value = [] 
11582   pred = [1]*self.order() 
11583   
11584   add_element = (lambda y:value.append(id_inv[y])) if not reverse else (lambda y: value.insert(0,id_inv[y])) 
11585   
11586   # Should we take care of the first vertex we pick ? 
11587   first = True if initial_vertex is not None else False 
11588   
11589   
11590   while vertices: 
11591   
11592   if not first: 
11593   v = max(vertices,key=l) 
11594   else: 
11595   v = self.vertices().index(initial_vertex) 
11596   first = False 
11597   
11598   vertices.remove(v) 
11599   vector = m.column(v) 
11600   for i in vertices: 
11601   code[i].append(vector[i]) 
11602   if vector[i]: 
11603   pred[i] = v 
11604   add_element(v) 
11605   
 11566  n = self.order() 
 11567  perm_inv = self.vertices() 
 11568  perm = dict(zip(perm_inv,range(n))) 
 11569  
 11570  if initial_vertex is not None: 
 11571  i = perm[initial_vertex] 
 11572  if i != 0: 
 11573  v = perm_inv[0] 
 11574  perm[initial_vertex], perm[v] = 0, i 
 11575  perm_inv[i], perm_inv[0] = v, initial_vertex 
 11576  
 11577  slice_of = [0]*n 
 11578  slice_head = [0]*n 
 11579  subslice = [1]*n 
 11580  pred = {} 
 11581  
 11582  k = 1 
 11583  for i in range(n): 
 11584  old_k = k 
 11585  v = perm_inv[i] 
 11586  for w in self.neighbors(v): 
 11587  j = perm[w] 
 11588  if j <= i: 
 11589  continue 
 11590  a = slice_of[j] 
 11591  if slice_head[a] <= i: 
 11592  slice_head[a] = i+1 
 11593  l = slice_head[a] 
 11594  if l < n1 and slice_of[l+1] != a: 
 11595  continue 
 11596  u = perm_inv[l] 
 11597  if l != j: 
 11598  perm[w], perm[u] = l, j 
 11599  perm_inv[j], perm_inv[l] = u, w 
 11600  slice_head[a] += 1 
 11601  if subslice[a] < old_k: 
 11602  subslice[a] = k 
 11603  slice_head[k] = l 
 11604  k += 1 
 11605  slice_of[l] = subslice[a] 
 11606  pred[u] = v 
 11607  
 11608  if reverse: 
 11609  perm_inv.reverse() 
11606  11610  if tree: 
11607  11611  from sage.graphs.digraph import DiGraph 
11608  11612  g = DiGraph(sparse=True) 
11609   edges = [(id_inv[i], id_inv[pred[i]]) for i in range(self.order()) if pred[i]!=1] 
11610   g.add_edges(edges) 
11611   return value, g 
11612   
11613   else: 
11614   return value 
11615   
 11613  g.add_edges(pred.items()) 
 11614  return perm_inv, g 
 11615  return perm_inv 
 11616  
11616  11617  ### Constructors 
11617  11618  
11618  11619  def add_cycle(self, vertices): 