# HG changeset patch
# User YLC <y@l.c>
# Date 1299781042 3600
# Node ID e48617ca9b33093a267897cddb601892f91d5948
# Parent a89bf1d7cfa850a31a9785bbfa64d449c5a2b1b5
#10885  reviewer efficiency improvment
diff r a89bf1d7cfa8 r e48617ca9b33 sage/graphs/base/c_graph.pyx
a

b


2504  2504  return list(a & b) 
2505  2505  
2506  2506  def floyd_warshall(gg, paths = True, distances = False): 
2507   r""" 
 2507  r""" 
2508  2508  Computes the shortest path/distances between all pairs of vertices. 
2509  2509  
2510  2510  For more information on the FloydWarshall algorithm, see the `Wikipedia 
… 
… 

2525  2525  
2526  2526  Depending on the input, this function return the dictionary of paths, 
2527  2527  the dictionary of distances, or a pair of dictionaries 
2528   ``(distances,paths)`` where ``distance[u][v]`` denotes the distance of a 
 2528  ``(distances, paths)`` where ``distance[u][v]`` denotes the distance of a 
2529  2529  shortest path from `u` to `v` and ``paths[u][v]`` denotes an inneighbor 
2530  2530  `w` of `v` such that `dist(u,v)= 1 + dist(u,w)`. 
2531  2531  
… 
… 

2570  2570  sage: len(p) == dist[u][v] + 2 
2571  2571  True 
2572  2572  """ 
2573   from sage.rings.infinity import Infinity 
 2573  from sage.rings.infinity import Infinity 
2574  2574  cdef CGraph g = <CGraph> gg._backend._cg 
2575   cdef int n = max(g.verts())+1 
 2575  
 2576  cdef list gverts = g.verts() 
 2577  
 2578  cdef int n = max(gverts) + 1 
2576  2579  
2577  2580  if n > <unsigned short> 1: 
2578  2581  raise ValueError("The graph backend contains more than "+(<unsigned short> 1)+" nodes") 
2579  2582  
2580   # Dictionaries of distance, precedent element, and integers 
2581   cdef dict d_prec = dict() 
2582   cdef dict d_dist = dict() 
2583   cdef dict tmp 
2584   
 2583  # All this just creates two tables prec[n][n] and dist[n][n] 
 2584  cdef unsigned short * t_prec 
 2585  cdef unsigned short * t_dist 
 2586  cdef unsigned short ** prec 
 2587  cdef unsigned short ** dist 
 2588  
 2589  cdef int i 
2585  2590  cdef int v_int 
2586  2591  cdef int u_int 
2587  2592  cdef int w_int 
2588   cdef int i 
2589   
2590   # All this just creates two tables prec[n][n] and dist[n][n] 
2591   cdef unsigned short * t_prec = <unsigned short *> sage_malloc(n*n*sizeof(short)) 
2592   cdef unsigned short * t_dist = <unsigned short *> sage_malloc(n*n*sizeof(short)) 
2593   cdef unsigned short ** prec = <unsigned short **> sage_malloc(n*sizeof(short *)) 
2594   cdef unsigned short ** dist = <unsigned short **> sage_malloc(n*sizeof(short *)) 
2595   prec[0] = t_prec 
 2593  
 2594  # init dist 
 2595  t_dist = <unsigned short *> sage_malloc(n*n*sizeof(short)) 
 2596  dist = <unsigned short **> sage_malloc(n*sizeof(short *)) 
2596  2597  dist[0] = t_dist 
2597   
2598  2598  for 1 <= i< n: 
2599   prec[i] = prec[i1] + n 
2600  2599  dist[i] = dist[i1] + n 
2601   
2602   # Initializing prec and dist 
2603   memset(t_prec, 0, n*n*sizeof(short)) 
2604  2600  memset(t_dist, 1, n*n*sizeof(short)) 
2605   
2606  2601  # Copying the adjacency matrix (vertices at distance 1) 
2607   for v_int in g.verts(): 
2608   prec[v_int][v_int] = v_int 
 2602  for v_int in gverts: 
2609  2603  dist[v_int][v_int] = 0 
2610  2604  for u_int in g.out_neighbors(v_int): 
2611  2605  dist[v_int][u_int] = 1 
2612   prec[v_int][u_int] = v_int 
 2606  
 2607  if paths: 
 2608  # init prec 
 2609  t_prec = <unsigned short *> sage_malloc(n*n*sizeof(short)) 
 2610  prec = <unsigned short **> sage_malloc(n*sizeof(short *)) 
 2611  prec[0] = t_prec 
 2612  for 1 <= i< n: 
 2613  prec[i] = prec[i1] + n 
 2614  memset(t_prec, 0, n*n*sizeof(short)) 
 2615  # Copying the adjacency matrix (vertices at distance 1) 
 2616  for v_int in gverts: 
 2617  prec[v_int][v_int] = v_int 
 2618  for u_int in g.out_neighbors(v_int): 
 2619  prec[v_int][u_int] = v_int 
2613  2620  
2614  2621  # The algorithm itself. 
2615   
2616   for w_int in g.verts(): 
2617   for v_int in g.verts(): 
2618   for u_int in g.verts(): 
2619   
 2622  cdef unsigned short *dv, *dw 
 2623  cdef int dvw 
 2624  cdef int val 
 2625  
 2626  for w_int in gverts: 
 2627  dw = dist[w_int] 
 2628  for v_int in gverts: 
 2629  dv = dist[v_int] 
 2630  dvw = dv[w_int] 
 2631  for u_int in gverts: 
 2632  val = dvw + dw[u_int] 
2620  2633  # If it is shorter to go from u to v through w, do it 
2621   if dist[v_int][u_int] > dist[v_int][w_int] + dist[w_int][u_int]: 
2622   dist[v_int][u_int] = dist[v_int][w_int] + dist[w_int][u_int] 
2623   prec[v_int][u_int] = prec[w_int][u_int] 
2624   
2625   # If the paths are to be returned 
 2634  if dv[u_int] > val: 
 2635  dv[u_int] = val 
 2636  if paths: 
 2637  prec[v_int][u_int] = prec[w_int][u_int] 
 2638  
 2639  # Dictionaries of distance, precedent element, and integers 
 2640  cdef dict d_prec 
 2641  cdef dict d_dist 
 2642  cdef dict tmp_prec 
 2643  cdef dict tmp_dist 
 2644  
 2645  cdef dict ggbvi = gg._backend.vertex_ints 
 2646  cdef dict ggbvl = gg._backend.vertex_labels 
 2647  
 2648  if paths: d_prec = {} 
 2649  if distances: d_dist = {} 
 2650  for v_int in gverts: 
 2651  if paths: tmp_prec = {} 
 2652  if distances: tmp_dist = {} 
 2653  v = vertex_label(v_int, ggbvi, ggbvl, g) 
 2654  for u_int in gverts: 
 2655  u = vertex_label(u_int, ggbvi, ggbvl, g) 
 2656  if paths: 
 2657  tmp_prec[u] = (None if v == u 
 2658  else vertex_label(prec[v_int][u_int], ggbvi, ggbvl, g)) 
 2659  if distances: 
 2660  tmp_dist[u] = (dv[u_int] if (dv[u_int] != <unsigned short> 1) 
 2661  else Infinity) 
 2662  if paths: d_prec[v] = tmp_prec 
 2663  if distances: d_dist[v] = tmp_dist 
 2664  
2626  2665  if paths: 
2627   for v_int in g.verts(): 
2628   tmp = dict() 
2629   v = vertex_label(v_int, gg._backend.vertex_ints, gg._backend.vertex_labels, gg._backend._cg) 
2630   
2631   for u_int in g.verts(): 
2632   u = vertex_label(u_int, gg._backend.vertex_ints, gg._backend.vertex_labels, gg._backend._cg) 
2633   w = (None if v == u 
2634   else vertex_label(prec[v_int][u_int], gg._backend.vertex_ints, gg._backend.vertex_labels, gg._backend._cg)) 
2635   tmp[u] = w 
2636   
2637   d_prec[v] = tmp 
2638   
2639   sage_free(t_prec) 
2640   sage_free(prec) 
2641   
2642   # If the distances are to be returned 
2643   if distances: 
2644   for v_int in g.verts(): 
2645   tmp = dict() 
2646   v = vertex_label(v_int, gg._backend.vertex_ints, gg._backend.vertex_labels, gg._backend._cg) 
2647   
2648   for u_int in g.verts(): 
2649   u = vertex_label(u_int, gg._backend.vertex_ints, gg._backend.vertex_labels, gg._backend._cg) 
2650   
2651   tmp[u] = dist[v_int][u_int] if (dist[v_int][u_int] != <unsigned short> 1) else Infinity 
2652   
2653   d_dist[v] = tmp 
 2666  sage_free(t_prec) 
 2667  sage_free(prec) 
2654  2668  
2655  2669  sage_free(t_dist) 
2656  2670  sage_free(dist) 
2657  2671  
2658  2672  if distances and paths: 
2659  2673  return d_dist, d_prec 
2660   elif paths: 
 2674  if paths: 
2661  2675  return d_prec 
2662   else: 
 2676  if distances: 
2663  2677  return d_dist 
2664  2678  
2665  2679  cdef class Search_iterator: 
diff r a89bf1d7cfa8 r e48617ca9b33 sage/graphs/generic_graph.py
a

b


10420  10420  pred = {} 
10421  10421  verts = self.vertices() 
10422  10422  for u in verts: 
10423   dist[u] = {} 
10424   pred[u] = {} 
 10423  du = {} 
 10424  pu = {} 
10425  10425  for v in verts: 
10426  10426  if self.has_edge(u, v): 
10427  10427  if by_weight is False: 
10428   dist[u][v] = 1 
10429   elif self.edge_label(u, v) is None or self.edge_label(u, v) == {}: 
10430   dist[u][v] = default_weight 
 10428  du[v] = 1 
10431  10429  else: 
10432   dist[u][v] = self.edge_label(u, v) 
10433   pred[u][v] = u 
 10430  edge_label = self.edge_label(u, v) 
 10431  if edge_label is None or edge_label == {}: 
 10432  du[v] = default_weight 
 10433  else: 
 10434  du[v] = edge_label 
 10435  pu[v] = u 
10434  10436  else: 
10435   dist[u][v] = Infinity 
10436   pred[u][v] = None 
10437   dist[u][u] = 0 
 10437  du[v] = Infinity 
 10438  pu[v] = None 
 10439  du[u] = 0 
 10440  dist[u] = du 
 10441  pred[u] = pu 
10438  10442  
10439  10443  for w in verts: 
 10444  dw = dist[w] 
10440  10445  for u in verts: 
 10446  du = dist[u] 
10441  10447  for v in verts: 
10442   if dist[u][v] > dist[u][w] + dist[w][v]: 
10443   dist[u][v] = dist[u][w] + dist[w][v] 
 10448  if du[v] > du[w] + dw[v]: 
 10449  du[v] = du[w] + dw[v] 
10444  10450  pred[u][v] = pred[w][v] 
10445   
 10451  
10446  10452  return dist, pred 
10447  10453  
10448  10454  def wiener_index(self): 