Ticket #12306: trac_12306_doc.patch

File trac_12306_doc.patch, 13.0 KB (added by ncohen, 9 years ago)
  • sage/graphs/distances_all_pairs.pyx

    # HG changeset patch
    # User Nathann Cohen <nathann.cohen@gmail.com>
    # Date 1328543944 -3600
    # Node ID 5801d5b792d7e74db75dc7a17ef30f952a1e7a58
    # Parent  0496509fc841807607b539df67804bbef9695afd
    trac 12306 -- Static sparse graphs for fast low-level computations -- documentation
    
    diff --git a/sage/graphs/distances_all_pairs.pyx b/sage/graphs/distances_all_pairs.pyx
    a b  
    44This module implements a few functions that deal with the computation of
    55distances or shortest paths between all pairs of vertices.
    66
    7 Because these functions involve listing many times the (out)-neighborhoods of
    8 (di)-graphs, it is useful in terms of efficiency to build a temporary copy of
    9 the graph in a data structure that makes it easy to compute quickly. These
    10 functions also work on large volume of data, typically dense matrices of size
    11 `n^2`, and are expected to return corresponding dictionaries of size `n^2`,
    12 where the integers corresponding to the vertices have first been converted to
    13 the vertices' labels. Sadly, this last translating operation turns out to be the
    14 most time-consuming, and for this reason it is also nice to have a Cython
    15 module, and version of these functions that return C arrays, in order to avoid
    16 these operations when they are not necessary.
     7**Efficiency** : Because these functions involve listing many times the
     8(out)-neighborhoods of (di)-graphs, it is useful in terms of efficiency to build
     9a temporary copy of the graph in a data structure that makes it easy to compute
     10quickly. These functions also work on large volume of data, typically dense
     11matrices of size `n^2`, and are expected to return corresponding dictionaries of
     12size `n^2`, where the integers corresponding to the vertices have first been
     13converted to the vertices' labels. Sadly, this last translating operation turns
     14out to be the most time-consuming, and for this reason it is also nice to have a
     15Cython module, and version of these functions that return C arrays, in order to
     16avoid these operations when they are not necessary.
     17
     18**Memory cost** : The methods implemented in the current module sometimes need large
     19amounts of memory to return their result. Storing the distances between all
     20pairs of vertices in a graph on `1500` vertices as a dictionary of dictionaries
     21takes around 200MB, while storing the same information as a C array requires
     224MB.
     23
    1724
    1825The module's main function
    1926--------------------------
     
    5158    - ``gg`` a (Di)Graph.
    5259
    5360    - ``unsigned short * predecessors`` -- a pointer toward an array of size
    54       `n^2\text{sizeof(unsigned short)}`. Set to ``NULL`` if you do not want to
    55       compute the predecessors.
     61      `n^2\cdot\text{sizeof(unsigned short)}`. Set to ``NULL`` if you do not
     62      want to compute the predecessors.
    5663
    5764    - ``unsigned short * distances`` -- a pointer toward an array of size
    58       `n^2\text{sizeof(unsigned short)}`. The computation of the distances is
    59       necessary for the algorithm, so this value can **not** be set to ``NULL``.
     65      `n^2\cdot\text{sizeof(unsigned short)}`. The computation of the distances
     66      is necessary for the algorithm, so this value can **not** be set to
     67      ``NULL``.
    6068
    6169    - ``unsigned short * eccentricity`` -- a pointer toward an array of size
    62       `n\text{sizeof(unsigned short)}`. Set to ``NULL`` if you do not want to
    63       compute the eccentricity.
     70      `n\cdot\text{sizeof(unsigned short)}`. Set to ``NULL`` if you do not want
     71      to compute the eccentricity.
    6472
    6573**Technical details**
    6674
     
    108116#                  http://www.gnu.org/licenses/
    109117##############################################################################
    110118
    111 include "../misc/bitset_pxd.pxi" 
     119include "../misc/bitset_pxd.pxi"
    112120include "../misc/bitset.pxi"
    113121from sage.graphs.base.c_graph cimport CGraph
    114122from sage.graphs.base.c_graph cimport vertex_label
     
    130138
    131139    cdef list int_to_vertex = gg.vertices()
    132140    cdef int i
    133    
     141
    134142    cdef int n = len(int_to_vertex)
    135143
    136144    if n > <unsigned short> -1:
     
    178186    # left to right The list of the first vertex's outneighbors, then the
    179187    # second's, then the third's, ...
    180188    #
    181     # The outneighbors of vertex i are enumerated from 
     189    # The outneighbors of vertex i are enumerated from
    182190    #
    183191    # p_vertices[i] to p_vertices[i+1] - 1
    184192    # (if p_vertices[i] is equal to p_vertices[i+1], then i has no outneighbours)
    185193    #
    186     # This data structure is well documented in the module 
     194    # This data structure is well documented in the module
    187195    # sage.graphs.base.static_sparse_graph
    188196
    189197    cdef short_digraph sd
     
    320328    """
    321329
    322330    cdef int n = G.order()
    323    
     331
    324332    if n == 0:
    325333        return {}
    326334
     
    348356
    349357        d_tmp[int_to_vertex[j]] = None
    350358        d[int_to_vertex[j]] = d_tmp
    351        
     359
    352360        c_predecessors += n
    353        
     361
    354362    sage_free(predecessors)
    355363    return d
    356364
     
    385393        sage: from sage.graphs.distances_all_pairs import distances_all_pairs
    386394        sage: g = graphs.PetersenGraph()
    387395        sage: distances_all_pairs(g)
    388         {0: {0: 0, 1: 1, 2: 2, 3: 2, 4: 1, 5: 1, 6: 2, 7: 2, 8: 2, 9: 2}, 
    389         1: {0: 1, 1: 0, 2: 1, 3: 2, 4: 2, 5: 2, 6: 1, 7: 2, 8: 2, 9: 2}, 
    390         2: {0: 2, 1: 1, 2: 0, 3: 1, 4: 2, 5: 2, 6: 2, 7: 1, 8: 2, 9: 2}, 
    391         3: {0: 2, 1: 2, 2: 1, 3: 0, 4: 1, 5: 2, 6: 2, 7: 2, 8: 1, 9: 2}, 
    392         4: {0: 1, 1: 2, 2: 2, 3: 1, 4: 0, 5: 2, 6: 2, 7: 2, 8: 2, 9: 1}, 
    393         5: {0: 1, 1: 2, 2: 2, 3: 2, 4: 2, 5: 0, 6: 2, 7: 1, 8: 1, 9: 2}, 
    394         6: {0: 2, 1: 1, 2: 2, 3: 2, 4: 2, 5: 2, 6: 0, 7: 2, 8: 1, 9: 1}, 
    395         7: {0: 2, 1: 2, 2: 1, 3: 2, 4: 2, 5: 1, 6: 2, 7: 0, 8: 2, 9: 1}, 
    396         8: {0: 2, 1: 2, 2: 2, 3: 1, 4: 2, 5: 1, 6: 1, 7: 2, 8: 0, 9: 2}, 
     396        {0: {0: 0, 1: 1, 2: 2, 3: 2, 4: 1, 5: 1, 6: 2, 7: 2, 8: 2, 9: 2},
     397        1: {0: 1, 1: 0, 2: 1, 3: 2, 4: 2, 5: 2, 6: 1, 7: 2, 8: 2, 9: 2},
     398        2: {0: 2, 1: 1, 2: 0, 3: 1, 4: 2, 5: 2, 6: 2, 7: 1, 8: 2, 9: 2},
     399        3: {0: 2, 1: 2, 2: 1, 3: 0, 4: 1, 5: 2, 6: 2, 7: 2, 8: 1, 9: 2},
     400        4: {0: 1, 1: 2, 2: 2, 3: 1, 4: 0, 5: 2, 6: 2, 7: 2, 8: 2, 9: 1},
     401        5: {0: 1, 1: 2, 2: 2, 3: 2, 4: 2, 5: 0, 6: 2, 7: 1, 8: 1, 9: 2},
     402        6: {0: 2, 1: 1, 2: 2, 3: 2, 4: 2, 5: 2, 6: 0, 7: 2, 8: 1, 9: 1},
     403        7: {0: 2, 1: 2, 2: 1, 3: 2, 4: 2, 5: 1, 6: 2, 7: 0, 8: 2, 9: 1},
     404        8: {0: 2, 1: 2, 2: 2, 3: 1, 4: 2, 5: 1, 6: 1, 7: 2, 8: 0, 9: 2},
    397405        9: {0: 2, 1: 2, 2: 2, 3: 2, 4: 1, 5: 2, 6: 1, 7: 1, 8: 2, 9: 0}}
    398406    """
    399407
     
    423431
    424432
    425433        d[int_to_vertex[j]] = d_tmp
    426        
     434
    427435        c_distances += n
    428        
     436
    429437    sage_free(distances)
    430438    return d
    431439
     
    457465        sage: from sage.graphs.distances_all_pairs import distances_and_predecessors_all_pairs
    458466        sage: g = graphs.PetersenGraph()
    459467        sage: distances_and_predecessors_all_pairs(g)
    460         ({0: {0: 0, 1: 1, 2: 2, 3: 2, 4: 1, 5: 1, 6: 2, 7: 2, 8: 2, 9: 2}, 
    461           1: {0: 1, 1: 0, 2: 1, 3: 2, 4: 2, 5: 2, 6: 1, 7: 2, 8: 2, 9: 2}, 
    462           2: {0: 2, 1: 1, 2: 0, 3: 1, 4: 2, 5: 2, 6: 2, 7: 1, 8: 2, 9: 2}, 
    463           3: {0: 2, 1: 2, 2: 1, 3: 0, 4: 1, 5: 2, 6: 2, 7: 2, 8: 1, 9: 2}, 
    464           4: {0: 1, 1: 2, 2: 2, 3: 1, 4: 0, 5: 2, 6: 2, 7: 2, 8: 2, 9: 1}, 
    465           5: {0: 1, 1: 2, 2: 2, 3: 2, 4: 2, 5: 0, 6: 2, 7: 1, 8: 1, 9: 2}, 
    466           6: {0: 2, 1: 1, 2: 2, 3: 2, 4: 2, 5: 2, 6: 0, 7: 2, 8: 1, 9: 1}, 
    467           7: {0: 2, 1: 2, 2: 1, 3: 2, 4: 2, 5: 1, 6: 2, 7: 0, 8: 2, 9: 1}, 
    468           8: {0: 2, 1: 2, 2: 2, 3: 1, 4: 2, 5: 1, 6: 1, 7: 2, 8: 0, 9: 2}, 
     468        ({0: {0: 0, 1: 1, 2: 2, 3: 2, 4: 1, 5: 1, 6: 2, 7: 2, 8: 2, 9: 2},
     469          1: {0: 1, 1: 0, 2: 1, 3: 2, 4: 2, 5: 2, 6: 1, 7: 2, 8: 2, 9: 2},
     470          2: {0: 2, 1: 1, 2: 0, 3: 1, 4: 2, 5: 2, 6: 2, 7: 1, 8: 2, 9: 2},
     471          3: {0: 2, 1: 2, 2: 1, 3: 0, 4: 1, 5: 2, 6: 2, 7: 2, 8: 1, 9: 2},
     472          4: {0: 1, 1: 2, 2: 2, 3: 1, 4: 0, 5: 2, 6: 2, 7: 2, 8: 2, 9: 1},
     473          5: {0: 1, 1: 2, 2: 2, 3: 2, 4: 2, 5: 0, 6: 2, 7: 1, 8: 1, 9: 2},
     474          6: {0: 2, 1: 1, 2: 2, 3: 2, 4: 2, 5: 2, 6: 0, 7: 2, 8: 1, 9: 1},
     475          7: {0: 2, 1: 2, 2: 1, 3: 2, 4: 2, 5: 1, 6: 2, 7: 0, 8: 2, 9: 1},
     476          8: {0: 2, 1: 2, 2: 2, 3: 1, 4: 2, 5: 1, 6: 1, 7: 2, 8: 0, 9: 2},
    469477          9: {0: 2, 1: 2, 2: 2, 3: 2, 4: 1, 5: 2, 6: 1, 7: 1, 8: 2, 9: 0}},
    470          {0: {0: None, 1: 0, 2: 1, 3: 4, 4: 0, 5: 0, 6: 1, 7: 5, 8: 5, 9: 4}, 
    471           1: {0: 1, 1: None, 2: 1, 3: 2, 4: 0, 5: 0, 6: 1, 7: 2, 8: 6, 9: 6}, 
    472           2: {0: 1, 1: 2, 2: None, 3: 2, 4: 3, 5: 7, 6: 1, 7: 2, 8: 3, 9: 7}, 
    473           3: {0: 4, 1: 2, 2: 3, 3: None, 4: 3, 5: 8, 6: 8, 7: 2, 8: 3, 9: 4}, 
    474           4: {0: 4, 1: 0, 2: 3, 3: 4, 4: None, 5: 0, 6: 9, 7: 9, 8: 3, 9: 4}, 
    475           5: {0: 5, 1: 0, 2: 7, 3: 8, 4: 0, 5: None, 6: 8, 7: 5, 8: 5, 9: 7}, 
    476           6: {0: 1, 1: 6, 2: 1, 3: 8, 4: 9, 5: 8, 6: None, 7: 9, 8: 6, 9: 6}, 
    477           7: {0: 5, 1: 2, 2: 7, 3: 2, 4: 9, 5: 7, 6: 9, 7: None, 8: 5, 9: 7}, 
    478           8: {0: 5, 1: 6, 2: 3, 3: 8, 4: 3, 5: 8, 6: 8, 7: 5, 8: None, 9: 6}, 
     478         {0: {0: None, 1: 0, 2: 1, 3: 4, 4: 0, 5: 0, 6: 1, 7: 5, 8: 5, 9: 4},
     479          1: {0: 1, 1: None, 2: 1, 3: 2, 4: 0, 5: 0, 6: 1, 7: 2, 8: 6, 9: 6},
     480          2: {0: 1, 1: 2, 2: None, 3: 2, 4: 3, 5: 7, 6: 1, 7: 2, 8: 3, 9: 7},
     481          3: {0: 4, 1: 2, 2: 3, 3: None, 4: 3, 5: 8, 6: 8, 7: 2, 8: 3, 9: 4},
     482          4: {0: 4, 1: 0, 2: 3, 3: 4, 4: None, 5: 0, 6: 9, 7: 9, 8: 3, 9: 4},
     483          5: {0: 5, 1: 0, 2: 7, 3: 8, 4: 0, 5: None, 6: 8, 7: 5, 8: 5, 9: 7},
     484          6: {0: 1, 1: 6, 2: 1, 3: 8, 4: 9, 5: 8, 6: None, 7: 9, 8: 6, 9: 6},
     485          7: {0: 5, 1: 2, 2: 7, 3: 2, 4: 9, 5: 7, 6: 9, 7: None, 8: 5, 9: 7},
     486          8: {0: 5, 1: 6, 2: 3, 3: 8, 4: 3, 5: 8, 6: 8, 7: 5, 8: None, 9: 6},
    479487          9: {0: 4, 1: 6, 2: 7, 3: 4, 4: 9, 5: 7, 6: 9, 7: 9, 8: 6, 9: None}})
    480488    """
    481489
    482490    from sage.rings.infinity import Infinity
    483491    cdef int n = G.order()
    484    
     492
    485493    if n == 0:
    486494        return {}, {}
    487495
     
    518526
    519527        d_distance[int_to_vertex[j]] = t_distance
    520528        d_predecessor[int_to_vertex[j]] = t_predecessor
    521        
     529
    522530        c_distances += n
    523531        c_predecessor += n
    524532
     
    599607# Wiener index #
    600608################
    601609
    602 def wiener_index(G): 
    603     r""" 
    604     Returns the Wiener index of the graph. 
    605    
    606     The Wiener index of a graph `G` can be defined in two equivalent 
    607     ways [KRG96b]_ : 
    608  
     610def wiener_index(G):
     611    r"""
     612    Returns the Wiener index of the graph.
     613
     614    The Wiener index of a graph `G` can be defined in two equivalent
     615    ways [KRG96b]_ :
     616
    609617    - `W(G) = \frac 1 2 \sum_{u,v\in G} d(u,v)` where `d(u,v)` denotes the
    610       distance between vertices `u` and `v`. 
    611  
    612     - Let `\Omega` be a set of `\frac {n(n-1)} 2` paths in `G` such that `\Omega` 
     618      distance between vertices `u` and `v`.
     619
     620    - Let `\Omega` be a set of `\frac {n(n-1)} 2` paths in `G` such that `\Omega`
    613621      contains exactly one shortest `u-v` path for each set `\{u,v\}` of
    614       vertices in `G`. Besides, `\forall e\in E(G)`, let `\Omega(e)` denote the 
    615       paths from `\Omega` containing `e`. We then have 
     622      vertices in `G`. Besides, `\forall e\in E(G)`, let `\Omega(e)` denote the
     623      paths from `\Omega` containing `e`. We then have
    616624      `W(G) = \sum_{e\in E(G)}|\Omega(e)|`.
    617          
    618     EXAMPLE:
    619          
    620     From [GYLL93c]_, cited in [KRG96b]_::
    621  
    622         sage: g=graphs.PathGraph(10)
    623         sage: w=lambda x: (x*(x*x -1)/6)
    624         sage: g.wiener_index()==w(10)
    625         True
    626  
    627     REFERENCE:
    628625
    629     .. [KRG96b] S. Klavzar, A. Rajapakse, and I. Gutman. The Szeged and the
     626    EXAMPLE:
     627
     628    From [GYLL93c]_, cited in [KRG96b]_::
     629
     630        sage: g=graphs.PathGraph(10)
     631        sage: w=lambda x: (x*(x*x -1)/6)
     632        sage: g.wiener_index()==w(10)
     633        True
     634
     635    REFERENCE:
     636
     637    .. [KRG96b] S. Klavzar, A. Rajapakse, and I. Gutman. The Szeged and the
    630638      Wiener index of graphs. *Applied Mathematics Letters*, 9(5):45--49, 1996.
    631  
    632     .. [GYLL93c] I. Gutman, Y.-N. Yeh, S.-L. Lee, and Y.-L. Luo. Some recent 
     639
     640    .. [GYLL93c] I. Gutman, Y.-N. Yeh, S.-L. Lee, and Y.-L. Luo. Some recent
    633641      results in the theory of the Wiener number. *Indian Journal of
    634       Chemistry*, 32A:651--661, 1993. 
     642      Chemistry*, 32A:651--661, 1993.
    635643    """
    636     if not G.is_connected(): 
    637         from sage.rings.infinity import Infinity 
    638         return +Infinity 
     644    if not G.is_connected():
     645        from sage.rings.infinity import Infinity
     646        return +Infinity
    639647
    640648    cdef unsigned short * distances = c_distances_all_pairs(G)
    641649    cdef int NN = G.order()*G.order()
     
    645653        s += distances[i]
    646654    sage_free(distances)
    647655    return s/2
    648    
     656
    649657
    650658
    651659##################
     
    732740
    733741        sage: g = graphs.DiamondGraph()
    734742        sage: floyd_warshall(g, paths = False, distances = True)
    735         {0: {0: 0, 1: 1, 2: 1, 3: 2}, 
    736          1: {0: 1, 1: 0, 2: 1, 3: 1}, 
    737          2: {0: 1, 1: 1, 2: 0, 3: 1}, 
     743        {0: {0: 0, 1: 1, 2: 1, 3: 2},
     744         1: {0: 1, 1: 0, 2: 1, 3: 1},
     745         2: {0: 1, 1: 1, 2: 0, 3: 1},
    738746         3: {0: 2, 1: 1, 2: 1, 3: 0}}
    739747
    740748    TESTS: