passagemath-graphs 10.5.43__cp312-cp312-macosx_14_0_arm64.whl → 10.6.1rc2__cp312-cp312-macosx_14_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {passagemath_graphs-10.5.43.dist-info → passagemath_graphs-10.6.1rc2.dist-info}/METADATA +5 -6
- {passagemath_graphs-10.5.43.dist-info → passagemath_graphs-10.6.1rc2.dist-info}/RECORD +132 -130
- sage/combinat/abstract_tree.py +188 -17
- sage/combinat/cluster_algebra_quiver/interact.py +1 -2
- sage/combinat/cluster_algebra_quiver/mutation_type.py +518 -519
- sage/combinat/cluster_algebra_quiver/quiver.py +233 -205
- sage/combinat/designs/covering_design.py +2 -6
- sage/combinat/designs/database.py +11 -10
- sage/combinat/designs/designs_pyx.cpython-312-darwin.so +0 -0
- sage/combinat/designs/designs_pyx.pyx +2 -2
- sage/combinat/designs/evenly_distributed_sets.cpython-312-darwin.so +0 -0
- sage/combinat/designs/evenly_distributed_sets.pyx +4 -4
- sage/combinat/designs/gen_quadrangles_with_spread.cpython-312-darwin.so +0 -0
- sage/combinat/designs/latin_squares.py +53 -20
- sage/combinat/designs/orthogonal_arrays.py +2 -1
- sage/combinat/designs/orthogonal_arrays_find_recursive.cpython-312-darwin.so +0 -0
- sage/combinat/designs/orthogonal_arrays_find_recursive.pyx +22 -21
- sage/combinat/designs/resolvable_bibd.py +191 -157
- sage/combinat/designs/subhypergraph_search.cpython-312-darwin.so +0 -0
- sage/combinat/designs/subhypergraph_search.pyx +4 -4
- sage/combinat/designs/twographs.py +2 -2
- sage/combinat/finite_state_machine.py +6 -6
- sage/combinat/posets/bubble_shuffle.py +247 -0
- sage/combinat/posets/d_complete.py +3 -3
- sage/combinat/posets/elements.py +3 -3
- sage/combinat/posets/hasse_cython.cpython-312-darwin.so +0 -0
- sage/combinat/posets/hasse_cython.pyx +1 -1
- sage/combinat/posets/hasse_diagram.py +16 -22
- sage/combinat/posets/hochschild_lattice.py +158 -0
- sage/combinat/posets/incidence_algebras.py +14 -16
- sage/combinat/posets/lattices.py +51 -53
- sage/combinat/posets/linear_extension_iterator.cpython-312-darwin.so +0 -0
- sage/combinat/posets/linear_extensions.py +10 -12
- sage/combinat/posets/moebius_algebra.py +4 -4
- sage/combinat/posets/poset_examples.py +70 -23
- sage/combinat/posets/posets.py +294 -103
- sage/databases/knotinfo_db.py +2 -1
- sage/graphs/asteroidal_triples.cpython-312-darwin.so +0 -0
- sage/graphs/asteroidal_triples.pyx +24 -3
- sage/graphs/base/boost_graph.cpython-312-darwin.so +0 -0
- sage/graphs/base/boost_graph.pxd +3 -3
- sage/graphs/base/c_graph.cpython-312-darwin.so +0 -0
- sage/graphs/base/c_graph.pyx +1 -1
- sage/graphs/base/dense_graph.cpython-312-darwin.so +0 -0
- sage/graphs/base/dense_graph.pxd +5 -3
- sage/graphs/base/dense_graph.pyx +44 -0
- sage/graphs/base/graph_backends.cpython-312-darwin.so +0 -0
- sage/graphs/base/sparse_graph.cpython-312-darwin.so +0 -0
- sage/graphs/base/static_dense_graph.cpython-312-darwin.so +0 -0
- sage/graphs/base/static_sparse_backend.cpython-312-darwin.so +0 -0
- sage/graphs/base/static_sparse_backend.pyx +8 -5
- sage/graphs/base/static_sparse_graph.cpython-312-darwin.so +0 -0
- sage/graphs/base/static_sparse_graph.pyx +86 -15
- sage/graphs/bipartite_graph.py +59 -36
- sage/graphs/centrality.cpython-312-darwin.so +0 -0
- sage/graphs/centrality.pyx +82 -9
- sage/graphs/cographs.py +1 -1
- sage/graphs/comparability.cpython-312-darwin.so +0 -0
- sage/graphs/comparability.pyx +64 -26
- sage/graphs/connectivity.cpython-312-darwin.so +0 -0
- sage/graphs/convexity_properties.cpython-312-darwin.so +0 -0
- sage/graphs/convexity_properties.pyx +52 -9
- sage/graphs/digraph.py +439 -95
- sage/graphs/digraph_generators.py +174 -102
- sage/graphs/distances_all_pairs.cpython-312-darwin.so +0 -0
- sage/graphs/dot2tex_utils.py +1 -1
- sage/graphs/edge_connectivity.cpython-312-darwin.so +0 -0
- sage/graphs/generators/basic.py +1 -1
- sage/graphs/generators/distance_regular.cpython-312-darwin.so +0 -0
- sage/graphs/generators/distance_regular.pyx +1 -1
- sage/graphs/generators/families.py +37 -27
- sage/graphs/generators/random.py +2 -2
- sage/graphs/generators/smallgraphs.py +3 -3
- sage/graphs/generic_graph.py +558 -86
- sage/graphs/generic_graph_pyx.cpython-312-darwin.so +0 -0
- sage/graphs/generic_graph_pyx.pyx +58 -11
- sage/graphs/genus.cpython-312-darwin.so +0 -0
- sage/graphs/genus.pyx +3 -4
- sage/graphs/graph.py +291 -8
- sage/graphs/graph_coloring.cpython-312-darwin.so +0 -0
- sage/graphs/graph_database.py +67 -12
- sage/graphs/graph_decompositions/bandwidth.cpython-312-darwin.so +0 -0
- sage/graphs/graph_decompositions/clique_separators.cpython-312-darwin.so +0 -0
- sage/graphs/graph_decompositions/clique_separators.pyx +24 -3
- sage/graphs/graph_decompositions/cutwidth.cpython-312-darwin.so +0 -0
- sage/graphs/graph_decompositions/fast_digraph.cpython-312-darwin.so +0 -0
- sage/graphs/graph_decompositions/fast_digraph.pyx +1 -1
- sage/graphs/graph_decompositions/graph_products.cpython-312-darwin.so +0 -0
- sage/graphs/graph_decompositions/graph_products.pyx +67 -21
- sage/graphs/graph_decompositions/modular_decomposition.cpython-312-darwin.so +0 -0
- sage/graphs/graph_decompositions/slice_decomposition.cpython-312-darwin.so +0 -0
- sage/graphs/graph_decompositions/slice_decomposition.pyx +34 -8
- sage/graphs/graph_decompositions/tree_decomposition.cpython-312-darwin.so +0 -0
- sage/graphs/graph_decompositions/vertex_separation.cpython-312-darwin.so +0 -0
- sage/graphs/graph_generators.py +45 -32
- sage/graphs/graph_generators_pyx.cpython-312-darwin.so +0 -0
- sage/graphs/graph_generators_pyx.pyx +15 -15
- sage/graphs/graph_latex.py +1 -1
- sage/graphs/graph_list.py +52 -9
- sage/graphs/graph_plot.py +7 -0
- sage/graphs/hyperbolicity.cpython-312-darwin.so +0 -0
- sage/graphs/hyperbolicity.pyx +2 -0
- sage/graphs/independent_sets.cpython-312-darwin.so +0 -0
- sage/graphs/isoperimetric_inequalities.cpython-312-darwin.so +0 -0
- sage/graphs/isoperimetric_inequalities.pyx +42 -6
- sage/graphs/line_graph.cpython-312-darwin.so +0 -0
- sage/graphs/line_graph.pyx +153 -37
- sage/graphs/matching_covered_graph.py +84 -60
- sage/graphs/orientations.py +3 -18
- sage/graphs/path_enumeration.cpython-312-darwin.so +0 -0
- sage/graphs/path_enumeration.pyx +2 -2
- sage/graphs/spanning_tree.cpython-312-darwin.so +0 -0
- sage/graphs/strongly_regular_db.cpython-312-darwin.so +0 -0
- sage/graphs/strongly_regular_db.pyx +15 -15
- sage/graphs/traversals.cpython-312-darwin.so +0 -0
- sage/graphs/traversals.pyx +13 -12
- sage/graphs/trees.cpython-312-darwin.so +0 -0
- sage/graphs/tutte_polynomial.py +1 -1
- sage/graphs/views.cpython-312-darwin.so +0 -0
- sage/graphs/weakly_chordal.cpython-312-darwin.so +0 -0
- sage/graphs/weakly_chordal.pyx +50 -8
- sage/groups/perm_gps/partn_ref/refinement_graphs.cpython-312-darwin.so +0 -0
- sage/knots/free_knotinfo_monoid.py +3 -3
- sage/knots/knotinfo.py +102 -82
- sage/knots/link.py +72 -39
- sage/topology/cubical_complex.py +4 -5
- sage/topology/delta_complex.py +4 -4
- sage/topology/simplicial_complex.py +0 -1
- sage/topology/simplicial_complex_catalog.py +6 -0
- sage/topology/simplicial_complex_examples.py +4 -16
- {passagemath_graphs-10.5.43.dist-info → passagemath_graphs-10.6.1rc2.dist-info}/WHEEL +0 -0
- {passagemath_graphs-10.5.43.dist-info → passagemath_graphs-10.6.1rc2.dist-info}/top_level.txt +0 -0
sage/graphs/centrality.pyx
CHANGED
@@ -24,6 +24,8 @@ from cysignals.signals cimport sig_check
|
|
24
24
|
from memory_allocator cimport MemoryAllocator
|
25
25
|
|
26
26
|
from sage.data_structures.bitset_base cimport *
|
27
|
+
from sage.graphs.base.static_sparse_backend cimport StaticSparseCGraph
|
28
|
+
from sage.graphs.base.static_sparse_backend cimport StaticSparseBackend
|
27
29
|
from sage.graphs.base.static_sparse_graph cimport *
|
28
30
|
from sage.libs.gmp.mpq cimport *
|
29
31
|
from sage.rings.rational cimport Rational
|
@@ -116,6 +118,19 @@ def centrality_betweenness(G, bint exact=False, bint normalize=True):
|
|
116
118
|
{0: 0.0, 1: 0.0}
|
117
119
|
sage: centrality_betweenness(Graph(2), exact=1)
|
118
120
|
{0: 0, 1: 0}
|
121
|
+
|
122
|
+
The method is valid for immutable graphs::
|
123
|
+
|
124
|
+
sage: G = graphs.RandomGNP(10, .7)
|
125
|
+
sage: G._backend
|
126
|
+
<sage.graphs.base.sparse_graph.SparseGraphBackend ...>
|
127
|
+
sage: H = Graph(G, immutable=True)
|
128
|
+
sage: H._backend
|
129
|
+
<sage.graphs.base.static_sparse_backend.StaticSparseBackend ...>
|
130
|
+
sage: G.centrality_betweenness() == H.centrality_betweenness()
|
131
|
+
True
|
132
|
+
sage: G.centrality_betweenness(exact=True) == H.centrality_betweenness(exact=True)
|
133
|
+
True
|
119
134
|
"""
|
120
135
|
if exact:
|
121
136
|
return centrality_betweenness_C(G, <mpq_t> 0, normalize=normalize)
|
@@ -147,12 +162,13 @@ cdef dict centrality_betweenness_C(G, numerical_type _, bint normalize=True):
|
|
147
162
|
return {v: zero for v in G}
|
148
163
|
|
149
164
|
# A copy of G, for faster neighbor enumeration
|
165
|
+
cdef StaticSparseCGraph cg
|
150
166
|
cdef short_digraph g
|
151
167
|
|
152
168
|
# A second copy, to remember the edges used during the BFS (see doc)
|
153
169
|
cdef short_digraph bfs_dag
|
154
170
|
|
155
|
-
cdef list int_to_vertex
|
171
|
+
cdef list int_to_vertex
|
156
172
|
|
157
173
|
cdef int n = G.order()
|
158
174
|
|
@@ -179,7 +195,14 @@ cdef dict centrality_betweenness_C(G, numerical_type _, bint normalize=True):
|
|
179
195
|
mpq_init(mpq_tmp)
|
180
196
|
|
181
197
|
try:
|
182
|
-
|
198
|
+
if isinstance(G, StaticSparseBackend):
|
199
|
+
cg = <StaticSparseCGraph> G._cg
|
200
|
+
g = <short_digraph> cg.g
|
201
|
+
int_to_vertex = cg._vertex_to_labels
|
202
|
+
else:
|
203
|
+
int_to_vertex = list(G)
|
204
|
+
init_short_digraph(g, G, edge_labelled=False, vertex_list=int_to_vertex)
|
205
|
+
|
183
206
|
init_reverse(bfs_dag, g)
|
184
207
|
|
185
208
|
queue = <uint32_t*> check_allocarray(n, sizeof(uint32_t))
|
@@ -305,7 +328,8 @@ cdef dict centrality_betweenness_C(G, numerical_type _, bint normalize=True):
|
|
305
328
|
mpq_clear(mpq_tmp)
|
306
329
|
|
307
330
|
finally:
|
308
|
-
|
331
|
+
if not isinstance(G, StaticSparseBackend):
|
332
|
+
free_short_digraph(g)
|
309
333
|
free_short_digraph(bfs_dag)
|
310
334
|
bitset_free(seen)
|
311
335
|
bitset_free(next_layer)
|
@@ -459,6 +483,8 @@ cdef void _estimate_reachable_vertices_dir(short_digraph g, int* reachL, int* re
|
|
459
483
|
reachL[i] = reachL_scc[scc[i]]
|
460
484
|
reachU[i] = min(<int>reachU_scc[scc[i]], g.n)
|
461
485
|
|
486
|
+
free_short_digraph(sccgraph)
|
487
|
+
|
462
488
|
|
463
489
|
cdef void _compute_reachable_vertices_undir(short_digraph g, int* reachable) noexcept:
|
464
490
|
r"""
|
@@ -668,6 +694,19 @@ def centrality_closeness_top_k(G, int k=1, int verbose=0):
|
|
668
694
|
True
|
669
695
|
sage: all(abs(topk[i][0] - sorted_centr[i]) < 1e-12 for i in range(len(topk)))
|
670
696
|
True
|
697
|
+
|
698
|
+
Immutable graphs::
|
699
|
+
|
700
|
+
sage: from sage.graphs.centrality import centrality_closeness_top_k
|
701
|
+
sage: G = graphs.RandomGNP(10, .7)
|
702
|
+
sage: G._backend
|
703
|
+
<sage.graphs.base.sparse_graph.SparseGraphBackend ...>
|
704
|
+
sage: H = Graph(G, immutable=True)
|
705
|
+
sage: H._backend
|
706
|
+
<sage.graphs.base.static_sparse_backend.StaticSparseBackend ...>
|
707
|
+
sage: k = randint(1, 10)
|
708
|
+
sage: centrality_closeness_top_k(G, k) == centrality_closeness_top_k(H, k)
|
709
|
+
True
|
671
710
|
"""
|
672
711
|
cdef list res
|
673
712
|
if k >= G.order():
|
@@ -685,12 +724,19 @@ def centrality_closeness_top_k(G, int k=1, int verbose=0):
|
|
685
724
|
return []
|
686
725
|
|
687
726
|
cdef MemoryAllocator mem = MemoryAllocator()
|
727
|
+
cdef StaticSparseCGraph cg
|
688
728
|
cdef short_digraph sd
|
689
729
|
# Copying the whole graph to obtain the list of neighbors quicker than by
|
690
730
|
# calling out_neighbors. This data structure is well documented in the
|
691
731
|
# module sage.graphs.base.static_sparse_graph
|
692
|
-
cdef list V
|
693
|
-
|
732
|
+
cdef list V
|
733
|
+
if isinstance(G, StaticSparseBackend):
|
734
|
+
cg = <StaticSparseCGraph> G._cg
|
735
|
+
sd = <short_digraph> cg.g
|
736
|
+
V = cg._vertex_to_labels
|
737
|
+
else:
|
738
|
+
V = list(G)
|
739
|
+
init_short_digraph(sd, G, edge_labelled=False, vertex_list=V)
|
694
740
|
cdef int n = sd.n
|
695
741
|
cdef int* reachL = <int*> mem.malloc(n * sizeof(int))
|
696
742
|
cdef int* reachU
|
@@ -825,6 +871,9 @@ def centrality_closeness_top_k(G, int k=1, int verbose=0):
|
|
825
871
|
if verbose > 0:
|
826
872
|
print("Final performance ratio: {}".format(visited / (n * <double> (sd.neighbors[sd.n] - sd.edges))))
|
827
873
|
|
874
|
+
if not isinstance(G, StaticSparseBackend):
|
875
|
+
free_short_digraph(sd)
|
876
|
+
|
828
877
|
res = [(1.0 / farness[v], V[v]) for v in topk[:k] if v != -1]
|
829
878
|
try:
|
830
879
|
res = sorted(res, reverse=True)
|
@@ -885,6 +934,18 @@ def centrality_closeness_random_k(G, int k=1):
|
|
885
934
|
Traceback (most recent call last):
|
886
935
|
...
|
887
936
|
ValueError: G must be an undirected Graph
|
937
|
+
|
938
|
+
The method is valid for immutable graphs::
|
939
|
+
|
940
|
+
sage: from sage.graphs.centrality import centrality_closeness_random_k
|
941
|
+
sage: G = graphs.RandomGNP(10, .7)
|
942
|
+
sage: G._backend
|
943
|
+
<sage.graphs.base.sparse_graph.SparseGraphBackend ...>
|
944
|
+
sage: H = Graph(G, immutable=True)
|
945
|
+
sage: H._backend
|
946
|
+
<sage.graphs.base.static_sparse_backend.StaticSparseBackend ...>
|
947
|
+
sage: centrality_closeness_random_k(G, 10) == centrality_closeness_random_k(H, 10)
|
948
|
+
True
|
888
949
|
"""
|
889
950
|
G._scream_if_not_simple()
|
890
951
|
if G.is_directed():
|
@@ -906,13 +967,21 @@ def centrality_closeness_random_k(G, int k=1):
|
|
906
967
|
cdef double* partial_farness = <double*> mem.malloc(n * sizeof(double))
|
907
968
|
cdef uint32_t* distance
|
908
969
|
cdef uint32_t* waiting_list
|
970
|
+
cdef StaticSparseCGraph cg
|
909
971
|
cdef short_digraph sd
|
910
972
|
cdef bitset_t seen
|
911
973
|
cdef double farness
|
912
974
|
cdef int i, j
|
913
975
|
cdef dict closeness_centrality_array = {}
|
914
|
-
cdef list int_to_vertex
|
915
|
-
cdef dict vertex_to_int
|
976
|
+
cdef list int_to_vertex
|
977
|
+
cdef dict vertex_to_int
|
978
|
+
if isinstance(G, StaticSparseBackend):
|
979
|
+
cg = <StaticSparseCGraph> G._cg
|
980
|
+
int_to_vertex = cg._vertex_to_labels
|
981
|
+
vertex_to_int = cg._vertex_to_int
|
982
|
+
else:
|
983
|
+
int_to_vertex = list(G)
|
984
|
+
vertex_to_int = {v: i for i, v in enumerate(int_to_vertex)}
|
916
985
|
|
917
986
|
# Initialize
|
918
987
|
for i in range(n):
|
@@ -940,7 +1009,10 @@ def centrality_closeness_random_k(G, int k=1):
|
|
940
1009
|
# Copying the whole graph as a static_sparse_graph for fast shortest
|
941
1010
|
# paths computation in unweighted graph. This data structure is well
|
942
1011
|
# documented in module sage.graphs.base.static_sparse_graph
|
943
|
-
|
1012
|
+
if isinstance(G, StaticSparseBackend):
|
1013
|
+
sd = <short_digraph> cg.g
|
1014
|
+
else:
|
1015
|
+
init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_vertex)
|
944
1016
|
distance = <uint32_t*> mem.malloc(n * sizeof(uint32_t))
|
945
1017
|
waiting_list = <uint32_t*> mem.malloc(n * sizeof(uint32_t))
|
946
1018
|
bitset_init(seen, n)
|
@@ -956,7 +1028,8 @@ def centrality_closeness_random_k(G, int k=1):
|
|
956
1028
|
closeness_centrality_array[int_to_vertex[V[i]]] = (n - 1) / farness
|
957
1029
|
|
958
1030
|
bitset_free(seen)
|
959
|
-
|
1031
|
+
if not isinstance(G, StaticSparseBackend):
|
1032
|
+
free_short_digraph(sd)
|
960
1033
|
|
961
1034
|
# Estimate the closeness centrality for remaining n-k vertices.
|
962
1035
|
for i in range(k, n):
|
sage/graphs/cographs.py
CHANGED
@@ -399,7 +399,7 @@ def change_label(tree, status, counter):
|
|
399
399
|
|
400
400
|
- ``tree`` -- the tree to relabel
|
401
401
|
|
402
|
-
- ``status`` -- boolean; used to
|
402
|
+
- ``status`` -- boolean; used to detect series (``True``) and parallel
|
403
403
|
(``False``) internal nodes
|
404
404
|
|
405
405
|
- ``counter`` -- list; the first integer of the list is used to assign a
|
Binary file
|
sage/graphs/comparability.pyx
CHANGED
@@ -200,8 +200,18 @@ Methods
|
|
200
200
|
# https://www.gnu.org/licenses/
|
201
201
|
# ****************************************************************************
|
202
202
|
|
203
|
-
from
|
204
|
-
from
|
203
|
+
from libc.stdint cimport uint32_t
|
204
|
+
from memory_allocator cimport MemoryAllocator
|
205
|
+
|
206
|
+
from sage.data_structures.bitset_base cimport *
|
207
|
+
from sage.graphs.base.static_sparse_backend cimport StaticSparseCGraph
|
208
|
+
from sage.graphs.base.static_sparse_backend cimport StaticSparseBackend
|
209
|
+
from sage.graphs.base.static_sparse_graph cimport (short_digraph,
|
210
|
+
init_short_digraph,
|
211
|
+
free_short_digraph,
|
212
|
+
simple_BFS,
|
213
|
+
out_degree)
|
214
|
+
|
205
215
|
from copy import copy
|
206
216
|
|
207
217
|
|
@@ -748,14 +758,17 @@ def is_permutation(g, algorithm='greedy', certificate=False, check=True,
|
|
748
758
|
|
749
759
|
def is_transitive(g, certificate=False):
|
750
760
|
r"""
|
751
|
-
|
761
|
+
Check whether the digraph is transitive.
|
752
762
|
|
753
763
|
A digraph is transitive if for any pair of vertices `u,v\in G` linked by a
|
754
764
|
`uv`-path the edge `uv` belongs to `G`.
|
755
765
|
|
756
766
|
INPUT:
|
757
767
|
|
758
|
-
- ``
|
768
|
+
- ``g`` -- a digraph
|
769
|
+
|
770
|
+
- ``certificate`` -- boolean (default: ``False``); whether to return a
|
771
|
+
certificate for negative answers
|
759
772
|
|
760
773
|
- If ``certificate = False`` (default), this method returns ``True`` or
|
761
774
|
``False`` according to the graph.
|
@@ -784,30 +797,55 @@ def is_transitive(g, certificate=False):
|
|
784
797
|
True
|
785
798
|
"""
|
786
799
|
cdef int n = g.order()
|
787
|
-
|
788
800
|
if n <= 2:
|
789
801
|
return True
|
790
802
|
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
cdef
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
803
|
+
# Copying the whole graph to obtain the list of neighbors quicker than by
|
804
|
+
# calling out_neighbors. This data structure is well documented in the
|
805
|
+
# module sage.graphs.base.static_sparse_graph
|
806
|
+
cdef list int_to_vertex
|
807
|
+
cdef StaticSparseCGraph cg
|
808
|
+
cdef short_digraph sd
|
809
|
+
if isinstance(g, StaticSparseBackend):
|
810
|
+
cg = <StaticSparseCGraph> g._cg
|
811
|
+
sd = <short_digraph> cg.g
|
812
|
+
int_to_vertex = cg._vertex_to_labels
|
813
|
+
else:
|
814
|
+
int_to_vertex = list(g)
|
815
|
+
init_short_digraph(sd, g, edge_labelled=False, vertex_list=int_to_vertex)
|
816
|
+
|
817
|
+
cdef MemoryAllocator mem = MemoryAllocator()
|
818
|
+
cdef uint32_t * distances = <uint32_t *> mem.malloc(n * sizeof(uint32_t))
|
819
|
+
cdef uint32_t * waiting_list = <uint32_t *> mem.malloc(n * sizeof(uint32_t))
|
820
|
+
cdef bitset_t seen
|
821
|
+
bitset_init(seen, n)
|
822
|
+
|
823
|
+
cdef uint32_t u, v
|
824
|
+
cdef int i
|
825
|
+
|
826
|
+
for u in range(n):
|
827
|
+
|
828
|
+
# 1. perform a breadth first search from u
|
829
|
+
_ = simple_BFS(sd, u, distances, NULL, waiting_list, seen)
|
830
|
+
|
831
|
+
# 2. Check whether the BFS reaches vertices that are not in the closed
|
832
|
+
# neighborhood of u.
|
833
|
+
if bitset_len(seen) != out_degree(sd, u) + 1:
|
834
|
+
if certificate:
|
835
|
+
bitset_discard(seen, u)
|
836
|
+
for i in range(out_degree(sd, u)):
|
837
|
+
bitset_discard(seen, sd.neighbors[u][i])
|
838
|
+
v = bitset_first(seen)
|
839
|
+
|
840
|
+
bitset_free(seen)
|
841
|
+
if not isinstance(g, StaticSparseBackend):
|
842
|
+
free_short_digraph(sd)
|
843
|
+
if certificate:
|
844
|
+
return (int_to_vertex[u], int_to_vertex[v])
|
845
|
+
return False
|
846
|
+
|
847
|
+
bitset_free(seen)
|
848
|
+
if not isinstance(g, StaticSparseBackend):
|
849
|
+
free_short_digraph(sd)
|
811
850
|
|
812
|
-
sig_free(distances)
|
813
851
|
return True
|
Binary file
|
Binary file
|
@@ -41,6 +41,8 @@ from sage.graphs.distances_all_pairs cimport c_distances_all_pairs
|
|
41
41
|
from cysignals.memory cimport sig_free
|
42
42
|
from memory_allocator cimport MemoryAllocator
|
43
43
|
from libc.stdint cimport uint32_t
|
44
|
+
from sage.graphs.base.static_sparse_backend cimport StaticSparseCGraph
|
45
|
+
from sage.graphs.base.static_sparse_backend cimport StaticSparseBackend
|
44
46
|
from sage.graphs.base.static_sparse_graph cimport (short_digraph,
|
45
47
|
init_short_digraph,
|
46
48
|
free_short_digraph,
|
@@ -573,6 +575,17 @@ def geodetic_closure(G, S):
|
|
573
575
|
Traceback (most recent call last):
|
574
576
|
...
|
575
577
|
NotImplementedError: the geodetic closure of digraphs has not been implemented yet
|
578
|
+
|
579
|
+
The method is valid for immutable graphs::
|
580
|
+
|
581
|
+
sage: G = graphs.RandomGNP(10, .7)
|
582
|
+
sage: G._backend
|
583
|
+
<sage.graphs.base.sparse_graph.SparseGraphBackend ...>
|
584
|
+
sage: H = Graph(G, immutable=True)
|
585
|
+
sage: H._backend
|
586
|
+
<sage.graphs.base.static_sparse_backend.StaticSparseBackend ...>
|
587
|
+
sage: geodetic_closure(G, [0, 3]) == geodetic_closure(H, [0, 3])
|
588
|
+
True
|
576
589
|
"""
|
577
590
|
if G.is_directed():
|
578
591
|
raise NotImplementedError("the geodetic closure of digraphs has not been implemented yet")
|
@@ -592,13 +605,23 @@ def geodetic_closure(G, S):
|
|
592
605
|
|
593
606
|
cdef int n = G.order()
|
594
607
|
cdef int nS = len(S)
|
595
|
-
cdef list int_to_vertex
|
596
|
-
cdef dict vertex_to_int
|
597
|
-
cdef list S_int = [vertex_to_int[u] for u in S]
|
608
|
+
cdef list int_to_vertex
|
609
|
+
cdef dict vertex_to_int
|
598
610
|
|
599
611
|
# Copy the graph as a short digraph
|
612
|
+
cdef StaticSparseCGraph cg
|
600
613
|
cdef short_digraph sd
|
601
|
-
|
614
|
+
if isinstance(G, StaticSparseBackend):
|
615
|
+
cg = <StaticSparseCGraph> G._cg
|
616
|
+
sd = <short_digraph> cg.g
|
617
|
+
int_to_vertex = cg._vertex_to_labels
|
618
|
+
vertex_to_int = cg._vertex_to_int
|
619
|
+
else:
|
620
|
+
int_to_vertex = list(G)
|
621
|
+
vertex_to_int = {u: i for i, u in enumerate(int_to_vertex)}
|
622
|
+
init_short_digraph(sd, G, edge_labelled=False, vertex_list=int_to_vertex)
|
623
|
+
|
624
|
+
cdef list S_int = [vertex_to_int[u] for u in S]
|
602
625
|
|
603
626
|
# Allocate some data structures
|
604
627
|
cdef MemoryAllocator mem = MemoryAllocator()
|
@@ -669,7 +692,8 @@ def geodetic_closure(G, S):
|
|
669
692
|
bitset_free(seen)
|
670
693
|
bitset_free(visited)
|
671
694
|
bitset_free(closure)
|
672
|
-
|
695
|
+
if not isinstance(G, StaticSparseBackend):
|
696
|
+
free_short_digraph(sd)
|
673
697
|
|
674
698
|
return ret
|
675
699
|
|
@@ -746,6 +770,17 @@ def is_geodetic(G):
|
|
746
770
|
sage: G.add_edge(G.random_edge())
|
747
771
|
sage: G.is_geodetic()
|
748
772
|
False
|
773
|
+
|
774
|
+
The method is valid for immutable graphs::
|
775
|
+
|
776
|
+
sage: G = graphs.RandomGNP(10, .7)
|
777
|
+
sage: G._backend
|
778
|
+
<sage.graphs.base.sparse_graph.SparseGraphBackend ...>
|
779
|
+
sage: H = Graph(G, immutable=True)
|
780
|
+
sage: H._backend
|
781
|
+
<sage.graphs.base.static_sparse_backend.StaticSparseBackend ...>
|
782
|
+
sage: G.is_geodetic() == H.is_geodetic()
|
783
|
+
True
|
749
784
|
"""
|
750
785
|
if G.has_multiple_edges():
|
751
786
|
return False
|
@@ -755,15 +790,21 @@ def is_geodetic(G):
|
|
755
790
|
|
756
791
|
# Copy the graph as a short digraph
|
757
792
|
cdef int n = G.order()
|
793
|
+
cdef StaticSparseCGraph cg
|
758
794
|
cdef short_digraph sd
|
759
|
-
|
795
|
+
if isinstance(G, StaticSparseBackend):
|
796
|
+
cg = <StaticSparseCGraph> G._cg
|
797
|
+
sd = <short_digraph> cg.g
|
798
|
+
else:
|
799
|
+
init_short_digraph(sd, G, edge_labelled=False, vertex_list=list(G))
|
760
800
|
|
761
801
|
# Allocate some data structures
|
762
802
|
cdef MemoryAllocator mem = MemoryAllocator()
|
763
803
|
cdef uint32_t * distances = <uint32_t *> mem.malloc(n * sizeof(uint32_t))
|
764
804
|
cdef uint32_t * waiting_list = <uint32_t *> mem.malloc(n * sizeof(uint32_t))
|
765
805
|
if not distances or not waiting_list:
|
766
|
-
|
806
|
+
if not isinstance(G, StaticSparseBackend):
|
807
|
+
free_short_digraph(sd)
|
767
808
|
raise MemoryError()
|
768
809
|
cdef bitset_t seen
|
769
810
|
bitset_init(seen, n)
|
@@ -812,7 +853,8 @@ def is_geodetic(G):
|
|
812
853
|
elif distances[u] == distances[v] + 1:
|
813
854
|
# G is not geodetic
|
814
855
|
bitset_free(seen)
|
815
|
-
|
856
|
+
if not isinstance(G, StaticSparseBackend):
|
857
|
+
free_short_digraph(sd)
|
816
858
|
return False
|
817
859
|
|
818
860
|
p_tmp += 1
|
@@ -821,7 +863,8 @@ def is_geodetic(G):
|
|
821
863
|
waiting_beginning += 1
|
822
864
|
|
823
865
|
bitset_free(seen)
|
824
|
-
|
866
|
+
if not isinstance(G, StaticSparseBackend):
|
867
|
+
free_short_digraph(sd)
|
825
868
|
|
826
869
|
# The graph is geodetic
|
827
870
|
return True
|