# 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 Floyd-Warshall 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[i-1] + n |
2600 | 2599 | dist[i] = dist[i-1] + 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[i-1] + 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): |