Commits (3)
 ... ... @@ -1757,6 +1757,11 @@ REFERENCES: algorithms," in "Algebra, geometry, and software systems" (2003), 177-206. .. [DHV2018] Feodor Dragan, Michel Habib, Laurent Viennot. Revisiting Radius, Diameter, and all Eccentricity Computation in Graphs through Certificates. :arxiv:`1803.04660v1` .. [DI1989] Dan Gusfield and Robert W. Irving. *The stable marriage problem: structure and algorithms*. Vol. 54. Cambridge: MIT press, 1989. ... ...
 ... ... @@ -1659,3 +1659,175 @@ def floyd_warshall(gg, paths=True, distances=False): return d_prec if distances: return d_dist ########## # radius # ########## cdef uint32_t radius_certificate(short_digraph g): """ Compute the radius of the input Graph using the algorithm. The ``radius-certificate`` algorithm calculates the exact value of the radius of a unweighted undirected graph [DHV2018]_. THis algorithm maintains lower bounds on eccentricities of all nodes and performs one-to-all distance queries from nodes with minimal lower bound. It then performs one-to-all distance queries from antipodes of the previous query source, which it uses to update the lower bound. It iterates until an exact solution is obtained. It can be very fast in practice. See the code's documentation and [DHV2018]_ for more details. INPUT: - ``g`` -- a short_digraph """ cdef uint32_t i, LB cdef uint32_t n = g.n # L is the lower certificate L = [] # K is the antipode inverse list. # for all i, vertex L[i] is the antipode of vertex K[i] K = [] # allocate some arrays for BFS cdef MemoryAllocator mem = MemoryAllocator() cdef bitset_t seen bitset_init(seen, n) cdef uint32_t * distances = mem.malloc(4 * n * sizeof(uint32_t)) if not distances: bitset_free(seen) raise MemoryError() cdef uint32_t * waiting_list = distances + n # e_L[i] lowerbound on eccentricity of vertex i cdef uint32_t* e_L = distances + 2 * n memset(e_L, 0, n*sizeof(uint32_t)) # e[i] is the exact eccentricity of vertex i, for i in set K cdef uint32_t* e = distances + 3 * n memset(e, 0, n*sizeof(uint32_t)) # if graph is unconnected, radius is infinity LB = simple_BFS(g, 0, distances, NULL, waiting_list, seen) if(LB==UINT32_MAX): bitset_free(seen) return LB while True: # select vertex u with a minimal eccentricity lower bound min_e_L = UINT32_MAX u = 0 for i in range(n): if(min_e_L>e_L[i]): min_e_L = e_L[i] u = i # find the exact eccentricity of vertex u e[u] = simple_BFS(g, u, distances, NULL, waiting_list, seen) # if the exact eccentricity of u equals the minimal lower bound of # eccentricities, terminate and return eccentricity of u as radius since # the radius can't be any lower than the minimal lower bound. if(e[u]==e_L[u]): bitset_free(seen) return e[u] # if the eccentricity lower bounds are not tight, we try to improve # them else: max_Duv = 0 a = 0 # select any vertex a, such that dist(u,a) = eccentricity(u) # thus a is the antipode of u for i in range(n): if(max_Duv n: from sage.rings.infinity import Infinity return +Infinity else: return int(LB)
 ... ... @@ -14742,8 +14742,14 @@ class GenericGraph(GenericGraph_pyx): - ``by_weight`` -- boolean (default: ``False``); if ``True``, edge weights are taken into account; if False, all edges have weight 1 - ``algorithm`` -- string (default: ``None``); see method :meth:`eccentricity` for the list of available algorithms - ``algorithm`` -- string (default: ``None``); in addition to the list of algorithms in method :meth:`eccentricity`, the following algorithms are available: - ``'radius-certificate'``: this algorithm is implemented in :func:`sage.graphs.distances_all_pairs.radius` It works only if ``by_weight==False`` and graph is undirected. See the function documentation for more information. - ``weight_function`` -- function (default: ``None``); a function that takes as input an edge ``(u, v, l)`` and outputs its weight. If not ... ... @@ -14783,6 +14789,19 @@ class GenericGraph(GenericGraph_pyx): if not self.order(): raise ValueError("radius is not defined for the empty graph") if weight_function is not None: by_weight = True if algorithm in ['radius-certificate']: if by_weight: raise ValueError("algorithm '" + algorithm + "' does not work" + " on weighted graphs") if self.is_directed(): raise ValueError("algorithm '" + algorithm + "' does not work" + " on directed graphs") from sage.graphs.distances_all_pairs import radius return radius(self, algorithm=algorithm) return min(self.eccentricity(v=list(self), by_weight=by_weight, weight_function=weight_function, check_weight=check_weight, ... ...