passagemath-graphs 10.6.1rc1__cp310-cp310-musllinux_1_2_aarch64.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.6.1rc1.dist-info/METADATA +292 -0
- passagemath_graphs-10.6.1rc1.dist-info/RECORD +260 -0
- passagemath_graphs-10.6.1rc1.dist-info/WHEEL +5 -0
- passagemath_graphs-10.6.1rc1.dist-info/top_level.txt +2 -0
- passagemath_graphs.libs/libgcc_s-69c45f16.so.1 +0 -0
- passagemath_graphs.libs/libgmp-8e78bd9b.so.10.5.0 +0 -0
- passagemath_graphs.libs/libstdc++-1f1a71be.so.6.0.33 +0 -0
- sage/all__sagemath_graphs.py +39 -0
- sage/combinat/abstract_tree.py +2723 -0
- sage/combinat/all__sagemath_graphs.py +34 -0
- sage/combinat/binary_tree.py +5306 -0
- sage/combinat/cluster_algebra_quiver/all.py +22 -0
- sage/combinat/cluster_algebra_quiver/cluster_seed.py +5208 -0
- sage/combinat/cluster_algebra_quiver/interact.py +124 -0
- sage/combinat/cluster_algebra_quiver/mutation_class.py +625 -0
- sage/combinat/cluster_algebra_quiver/mutation_type.py +1555 -0
- sage/combinat/cluster_algebra_quiver/quiver.py +2290 -0
- sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py +2468 -0
- sage/combinat/designs/MOLS_handbook_data.py +570 -0
- sage/combinat/designs/all.py +58 -0
- sage/combinat/designs/bibd.py +1655 -0
- sage/combinat/designs/block_design.py +1071 -0
- sage/combinat/designs/covering_array.py +269 -0
- sage/combinat/designs/covering_design.py +530 -0
- sage/combinat/designs/database.py +5615 -0
- sage/combinat/designs/design_catalog.py +122 -0
- sage/combinat/designs/designs_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/designs_pyx.pxd +21 -0
- sage/combinat/designs/designs_pyx.pyx +993 -0
- sage/combinat/designs/difference_family.py +3951 -0
- sage/combinat/designs/difference_matrices.py +279 -0
- sage/combinat/designs/evenly_distributed_sets.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/evenly_distributed_sets.pyx +661 -0
- sage/combinat/designs/ext_rep.py +1064 -0
- sage/combinat/designs/gen_quadrangles_with_spread.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/gen_quadrangles_with_spread.pyx +339 -0
- sage/combinat/designs/group_divisible_designs.py +361 -0
- sage/combinat/designs/incidence_structures.py +2357 -0
- sage/combinat/designs/latin_squares.py +581 -0
- sage/combinat/designs/orthogonal_arrays.py +2244 -0
- sage/combinat/designs/orthogonal_arrays_build_recursive.py +1780 -0
- sage/combinat/designs/orthogonal_arrays_find_recursive.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/orthogonal_arrays_find_recursive.pyx +967 -0
- sage/combinat/designs/resolvable_bibd.py +815 -0
- sage/combinat/designs/steiner_quadruple_systems.py +1306 -0
- sage/combinat/designs/subhypergraph_search.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/subhypergraph_search.pyx +530 -0
- sage/combinat/designs/twographs.py +306 -0
- sage/combinat/finite_state_machine.py +14874 -0
- sage/combinat/finite_state_machine_generators.py +2006 -0
- sage/combinat/graph_path.py +448 -0
- sage/combinat/interval_posets.py +3908 -0
- sage/combinat/nu_tamari_lattice.py +269 -0
- sage/combinat/ordered_tree.py +1446 -0
- sage/combinat/posets/all.py +46 -0
- sage/combinat/posets/bubble_shuffle.py +247 -0
- sage/combinat/posets/cartesian_product.py +493 -0
- sage/combinat/posets/d_complete.py +182 -0
- sage/combinat/posets/elements.py +273 -0
- sage/combinat/posets/forest.py +30 -0
- sage/combinat/posets/hasse_cython.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/posets/hasse_cython.pyx +174 -0
- sage/combinat/posets/hasse_diagram.py +3672 -0
- sage/combinat/posets/hochschild_lattice.py +158 -0
- sage/combinat/posets/incidence_algebras.py +794 -0
- sage/combinat/posets/lattices.py +5117 -0
- sage/combinat/posets/linear_extension_iterator.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/posets/linear_extension_iterator.pyx +292 -0
- sage/combinat/posets/linear_extensions.py +1037 -0
- sage/combinat/posets/mobile.py +275 -0
- sage/combinat/posets/moebius_algebra.py +776 -0
- sage/combinat/posets/poset_examples.py +2178 -0
- sage/combinat/posets/posets.py +9360 -0
- sage/combinat/rooted_tree.py +1070 -0
- sage/combinat/shard_order.py +239 -0
- sage/combinat/tamari_lattices.py +384 -0
- sage/combinat/yang_baxter_graph.py +923 -0
- sage/databases/all__sagemath_graphs.py +1 -0
- sage/databases/knotinfo_db.py +1231 -0
- sage/ext_data/all__sagemath_graphs.py +1 -0
- sage/ext_data/graphs/graph_plot_js.html +330 -0
- sage/ext_data/kenzo/CP2.txt +45 -0
- sage/ext_data/kenzo/CP3.txt +349 -0
- sage/ext_data/kenzo/CP4.txt +4774 -0
- sage/ext_data/kenzo/README.txt +49 -0
- sage/ext_data/kenzo/S4.txt +20 -0
- sage/graphs/all.py +42 -0
- sage/graphs/asteroidal_triples.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/asteroidal_triples.pyx +320 -0
- sage/graphs/base/all.py +1 -0
- sage/graphs/base/boost_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/boost_graph.pxd +106 -0
- sage/graphs/base/boost_graph.pyx +3045 -0
- sage/graphs/base/c_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/c_graph.pxd +106 -0
- sage/graphs/base/c_graph.pyx +5096 -0
- sage/graphs/base/dense_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/dense_graph.pxd +28 -0
- sage/graphs/base/dense_graph.pyx +801 -0
- sage/graphs/base/graph_backends.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/graph_backends.pxd +5 -0
- sage/graphs/base/graph_backends.pyx +797 -0
- sage/graphs/base/overview.py +85 -0
- sage/graphs/base/sparse_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/sparse_graph.pxd +90 -0
- sage/graphs/base/sparse_graph.pyx +1653 -0
- sage/graphs/base/static_dense_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/static_dense_graph.pxd +5 -0
- sage/graphs/base/static_dense_graph.pyx +1032 -0
- sage/graphs/base/static_sparse_backend.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/static_sparse_backend.pxd +27 -0
- sage/graphs/base/static_sparse_backend.pyx +1583 -0
- sage/graphs/base/static_sparse_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/static_sparse_graph.pxd +37 -0
- sage/graphs/base/static_sparse_graph.pyx +1375 -0
- sage/graphs/bipartite_graph.py +2732 -0
- sage/graphs/centrality.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/centrality.pyx +1038 -0
- sage/graphs/cographs.py +519 -0
- sage/graphs/comparability.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/comparability.pyx +851 -0
- sage/graphs/connectivity.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/connectivity.pxd +157 -0
- sage/graphs/connectivity.pyx +4813 -0
- sage/graphs/convexity_properties.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/convexity_properties.pxd +16 -0
- sage/graphs/convexity_properties.pyx +870 -0
- sage/graphs/digraph.py +4754 -0
- sage/graphs/digraph_generators.py +1993 -0
- sage/graphs/distances_all_pairs.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/distances_all_pairs.pxd +12 -0
- sage/graphs/distances_all_pairs.pyx +2938 -0
- sage/graphs/domination.py +1363 -0
- sage/graphs/dot2tex_utils.py +100 -0
- sage/graphs/edge_connectivity.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/edge_connectivity.pyx +1215 -0
- sage/graphs/generators/all.py +1 -0
- sage/graphs/generators/basic.py +1769 -0
- sage/graphs/generators/chessboard.py +538 -0
- sage/graphs/generators/classical_geometries.py +1611 -0
- sage/graphs/generators/degree_sequence.py +235 -0
- sage/graphs/generators/distance_regular.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/generators/distance_regular.pyx +2846 -0
- sage/graphs/generators/families.py +4759 -0
- sage/graphs/generators/intersection.py +565 -0
- sage/graphs/generators/platonic_solids.py +262 -0
- sage/graphs/generators/random.py +2623 -0
- sage/graphs/generators/smallgraphs.py +5741 -0
- sage/graphs/generators/world_map.py +724 -0
- sage/graphs/generic_graph.py +26867 -0
- sage/graphs/generic_graph_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/generic_graph_pyx.pxd +34 -0
- sage/graphs/generic_graph_pyx.pyx +1673 -0
- sage/graphs/genus.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/genus.pyx +622 -0
- sage/graphs/graph.py +9645 -0
- sage/graphs/graph_coloring.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_coloring.pyx +2284 -0
- sage/graphs/graph_database.py +1177 -0
- sage/graphs/graph_decompositions/all.py +1 -0
- sage/graphs/graph_decompositions/bandwidth.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/bandwidth.pyx +428 -0
- sage/graphs/graph_decompositions/clique_separators.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/clique_separators.pyx +616 -0
- sage/graphs/graph_decompositions/cutwidth.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/cutwidth.pyx +753 -0
- sage/graphs/graph_decompositions/fast_digraph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/fast_digraph.pxd +13 -0
- sage/graphs/graph_decompositions/fast_digraph.pyx +212 -0
- sage/graphs/graph_decompositions/graph_products.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/graph_products.pyx +508 -0
- sage/graphs/graph_decompositions/modular_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/modular_decomposition.pxd +27 -0
- sage/graphs/graph_decompositions/modular_decomposition.pyx +1536 -0
- sage/graphs/graph_decompositions/slice_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/slice_decomposition.pxd +18 -0
- sage/graphs/graph_decompositions/slice_decomposition.pyx +1106 -0
- sage/graphs/graph_decompositions/tree_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/tree_decomposition.pxd +17 -0
- sage/graphs/graph_decompositions/tree_decomposition.pyx +1996 -0
- sage/graphs/graph_decompositions/vertex_separation.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/vertex_separation.pxd +5 -0
- sage/graphs/graph_decompositions/vertex_separation.pyx +1963 -0
- sage/graphs/graph_editor.py +82 -0
- sage/graphs/graph_generators.py +3314 -0
- sage/graphs/graph_generators_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_generators_pyx.pyx +95 -0
- sage/graphs/graph_input.py +812 -0
- sage/graphs/graph_latex.py +2064 -0
- sage/graphs/graph_list.py +410 -0
- sage/graphs/graph_plot.py +1756 -0
- sage/graphs/graph_plot_js.py +338 -0
- sage/graphs/hyperbolicity.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/hyperbolicity.pyx +1704 -0
- sage/graphs/hypergraph_generators.py +364 -0
- sage/graphs/independent_sets.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/independent_sets.pxd +13 -0
- sage/graphs/independent_sets.pyx +402 -0
- sage/graphs/isgci.py +1033 -0
- sage/graphs/isoperimetric_inequalities.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/isoperimetric_inequalities.pyx +489 -0
- sage/graphs/line_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/line_graph.pyx +743 -0
- sage/graphs/lovasz_theta.py +77 -0
- sage/graphs/matching.py +1633 -0
- sage/graphs/matching_covered_graph.py +3590 -0
- sage/graphs/orientations.py +1489 -0
- sage/graphs/partial_cube.py +459 -0
- sage/graphs/path_enumeration.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/path_enumeration.pyx +2040 -0
- sage/graphs/pq_trees.py +1129 -0
- sage/graphs/print_graphs.py +201 -0
- sage/graphs/schnyder.py +865 -0
- sage/graphs/spanning_tree.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/spanning_tree.pyx +1457 -0
- sage/graphs/strongly_regular_db.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/strongly_regular_db.pyx +3340 -0
- sage/graphs/traversals.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/traversals.pxd +9 -0
- sage/graphs/traversals.pyx +1872 -0
- sage/graphs/trees.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/trees.pxd +15 -0
- sage/graphs/trees.pyx +310 -0
- sage/graphs/tutte_polynomial.py +713 -0
- sage/graphs/views.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/views.pyx +794 -0
- sage/graphs/weakly_chordal.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/weakly_chordal.pyx +604 -0
- sage/groups/all__sagemath_graphs.py +1 -0
- sage/groups/perm_gps/all__sagemath_graphs.py +1 -0
- sage/groups/perm_gps/partn_ref/all__sagemath_graphs.py +1 -0
- sage/groups/perm_gps/partn_ref/refinement_graphs.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_graphs.pxd +38 -0
- sage/groups/perm_gps/partn_ref/refinement_graphs.pyx +1666 -0
- sage/knots/all.py +6 -0
- sage/knots/free_knotinfo_monoid.py +507 -0
- sage/knots/gauss_code.py +291 -0
- sage/knots/knot.py +682 -0
- sage/knots/knot_table.py +284 -0
- sage/knots/knotinfo.py +2900 -0
- sage/knots/link.py +4715 -0
- sage/sandpiles/all.py +13 -0
- sage/sandpiles/examples.py +225 -0
- sage/sandpiles/sandpile.py +6365 -0
- sage/topology/all.py +22 -0
- sage/topology/cell_complex.py +1214 -0
- sage/topology/cubical_complex.py +1976 -0
- sage/topology/delta_complex.py +1806 -0
- sage/topology/filtered_simplicial_complex.py +744 -0
- sage/topology/moment_angle_complex.py +823 -0
- sage/topology/simplicial_complex.py +5160 -0
- sage/topology/simplicial_complex_catalog.py +92 -0
- sage/topology/simplicial_complex_examples.py +1680 -0
- sage/topology/simplicial_complex_homset.py +205 -0
- sage/topology/simplicial_complex_morphism.py +836 -0
- sage/topology/simplicial_set.py +4102 -0
- sage/topology/simplicial_set_catalog.py +55 -0
- sage/topology/simplicial_set_constructions.py +2954 -0
- sage/topology/simplicial_set_examples.py +865 -0
- sage/topology/simplicial_set_morphism.py +1464 -0
@@ -0,0 +1,801 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-graphs
|
2
|
+
r"""
|
3
|
+
Fast dense graphs
|
4
|
+
|
5
|
+
For an overview of graph data structures in sage, see
|
6
|
+
:mod:`~sage.graphs.base.overview`.
|
7
|
+
|
8
|
+
Usage Introduction
|
9
|
+
------------------
|
10
|
+
|
11
|
+
::
|
12
|
+
|
13
|
+
sage: from sage.graphs.base.dense_graph import DenseGraph
|
14
|
+
|
15
|
+
Dense graphs are initialized as follows::
|
16
|
+
|
17
|
+
sage: D = DenseGraph(nverts=10, extra_vertices=10)
|
18
|
+
|
19
|
+
This example initializes a dense graph with room for twenty vertices, the first
|
20
|
+
ten of which are in the graph. In general, the first ``nverts`` are "active."
|
21
|
+
For example, see that 9 is already in the graph::
|
22
|
+
|
23
|
+
sage: D.verts()
|
24
|
+
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
25
|
+
sage: D.add_vertex(9)
|
26
|
+
9
|
27
|
+
sage: D.verts()
|
28
|
+
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
29
|
+
|
30
|
+
But 10 is not, until we add it::
|
31
|
+
|
32
|
+
sage: D.add_vertex(10)
|
33
|
+
10
|
34
|
+
sage: D.verts()
|
35
|
+
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
36
|
+
|
37
|
+
You can begin working right away as follows::
|
38
|
+
|
39
|
+
sage: D.add_arc(0, 1)
|
40
|
+
sage: D.add_arc(1, 2)
|
41
|
+
sage: D.add_arc(1, 0)
|
42
|
+
sage: D.has_arc(7, 3)
|
43
|
+
False
|
44
|
+
sage: D.has_arc(0, 1)
|
45
|
+
True
|
46
|
+
sage: D.in_neighbors(1)
|
47
|
+
[0]
|
48
|
+
sage: D.out_neighbors(1)
|
49
|
+
[0, 2]
|
50
|
+
sage: D.del_all_arcs(0, 1)
|
51
|
+
sage: D.has_arc(0, 1)
|
52
|
+
False
|
53
|
+
sage: D.has_arc(1, 2)
|
54
|
+
True
|
55
|
+
sage: D.del_vertex(7)
|
56
|
+
sage: D.has_arc(7, 3)
|
57
|
+
False
|
58
|
+
|
59
|
+
Dense graphs do not support multiple or labeled edges.
|
60
|
+
|
61
|
+
::
|
62
|
+
|
63
|
+
sage: T = DenseGraph(nverts=3, extra_vertices=2)
|
64
|
+
sage: T.add_arc(0, 1)
|
65
|
+
sage: T.add_arc(1, 2)
|
66
|
+
sage: T.add_arc(2, 0)
|
67
|
+
sage: T.has_arc(0, 1)
|
68
|
+
True
|
69
|
+
|
70
|
+
::
|
71
|
+
|
72
|
+
sage: for _ in range(10): D.add_arc(5, 4)
|
73
|
+
sage: D.has_arc(5,4 )
|
74
|
+
True
|
75
|
+
|
76
|
+
Dense graphs are by their nature directed. As of this writing, you need to do
|
77
|
+
operations in pairs to treat the undirected case (or use a backend or a Sage
|
78
|
+
graph)::
|
79
|
+
|
80
|
+
sage: T.has_arc(1, 0)
|
81
|
+
False
|
82
|
+
|
83
|
+
The curious developer is encouraged to check out the ``unsafe`` functions,
|
84
|
+
which do not check input but which run in pure C.
|
85
|
+
|
86
|
+
Underlying Data Structure
|
87
|
+
-------------------------
|
88
|
+
|
89
|
+
The class ``DenseGraph`` contains the following variables which are inherited
|
90
|
+
from ``CGraph`` (for explanation, refer to the documentation there)::
|
91
|
+
|
92
|
+
cdef int num_verts
|
93
|
+
cdef int num_arcs
|
94
|
+
cdef int *in_degrees
|
95
|
+
cdef int *out_degrees
|
96
|
+
cdef bitset_t active_vertices
|
97
|
+
|
98
|
+
It also contains the following variables::
|
99
|
+
|
100
|
+
cdef binary_matrix_t edges
|
101
|
+
|
102
|
+
.. NOTE::
|
103
|
+
|
104
|
+
As the edges are stored as the adjacency matrix of the graph, enumerating
|
105
|
+
the edges of the graph has complexity `O(n^2)` and enumerating the neighbors
|
106
|
+
of a vertex has complexity `O(n)` (where `n` in the size of the bitset
|
107
|
+
active_vertices).
|
108
|
+
So, the class ``DenseGraph`` should be used for graphs such that the number
|
109
|
+
of edges is close to the square of the number of vertices.
|
110
|
+
|
111
|
+
"""
|
112
|
+
|
113
|
+
# ****************************************************************************
|
114
|
+
# Copyright (C) 2008-9 Robert L. Miller <rlmillster@gmail.com>
|
115
|
+
#
|
116
|
+
# This program is free software: you can redistribute it and/or modify
|
117
|
+
# it under the terms of the GNU General Public License as published by
|
118
|
+
# the Free Software Foundation, either version 2 of the License, or
|
119
|
+
# (at your option) any later version.
|
120
|
+
# https://www.gnu.org/licenses/
|
121
|
+
# ****************************************************************************
|
122
|
+
|
123
|
+
from sage.data_structures.bitset_base cimport *
|
124
|
+
|
125
|
+
from cysignals.memory cimport sig_calloc, sig_realloc, sig_free
|
126
|
+
from sage.data_structures.binary_matrix cimport *
|
127
|
+
from libc.string cimport memcpy
|
128
|
+
|
129
|
+
|
130
|
+
cdef extern from "Python.h":
|
131
|
+
int unlikely(int) nogil # Defined by Cython
|
132
|
+
|
133
|
+
|
134
|
+
cdef class DenseGraph(CGraph):
|
135
|
+
"""
|
136
|
+
Compiled dense graphs.
|
137
|
+
|
138
|
+
::
|
139
|
+
|
140
|
+
sage: from sage.graphs.base.dense_graph import DenseGraph
|
141
|
+
|
142
|
+
Dense graphs are initialized as follows::
|
143
|
+
|
144
|
+
sage: D = DenseGraph(nverts=10, extra_vertices=10)
|
145
|
+
|
146
|
+
INPUT:
|
147
|
+
|
148
|
+
- ``nverts`` -- nonnegative integer; the number of vertices
|
149
|
+
- ``extra_vertices`` -- nonnegative integer (default: 10); how many extra
|
150
|
+
vertices to allocate
|
151
|
+
- ``verts`` -- list (default: ``None``); optional list of vertices to add
|
152
|
+
- ``arcs`` -- list (default: ``None``); optional list of arcs to add
|
153
|
+
- ``directed`` -- boolean (default: ``None``); whether the graph is directed
|
154
|
+
|
155
|
+
The first ``nverts`` are created as vertices of the graph, and the next
|
156
|
+
``extra_vertices`` can be freely added without reallocation. See top level
|
157
|
+
documentation for more details. The input ``verts`` and ``arcs`` are mainly
|
158
|
+
for use in pickling.
|
159
|
+
"""
|
160
|
+
def __cinit__(self, int nverts, int extra_vertices=10, verts=None, arcs=None, directed=True):
|
161
|
+
"""
|
162
|
+
Allocation and initialization happen in one place.
|
163
|
+
|
164
|
+
Memory usage is ``O((nverts + extra_vertices)^2)``.
|
165
|
+
|
166
|
+
EXAMPLES::
|
167
|
+
|
168
|
+
sage: from sage.graphs.base.dense_graph import DenseGraph
|
169
|
+
sage: D = DenseGraph(nverts=10, extra_vertices=10)
|
170
|
+
"""
|
171
|
+
if not nverts and not extra_vertices:
|
172
|
+
raise RuntimeError('dense graphs must allocate space for vertices')
|
173
|
+
|
174
|
+
self.num_verts = nverts
|
175
|
+
self.num_arcs = 0
|
176
|
+
cdef int total_verts = nverts + extra_vertices
|
177
|
+
self._directed = directed
|
178
|
+
|
179
|
+
binary_matrix_init(self.edges, total_verts, total_verts)
|
180
|
+
self.in_degrees = <int *> sig_calloc(total_verts, sizeof(int))
|
181
|
+
self.out_degrees = <int *> sig_calloc(total_verts, sizeof(int))
|
182
|
+
|
183
|
+
if not self.in_degrees or not self.out_degrees:
|
184
|
+
sig_free(self.in_degrees)
|
185
|
+
sig_free(self.out_degrees)
|
186
|
+
binary_matrix_free(self.edges)
|
187
|
+
raise MemoryError
|
188
|
+
|
189
|
+
bitset_init(self.active_vertices, total_verts)
|
190
|
+
bitset_set_first_n(self.active_vertices, self.num_verts)
|
191
|
+
|
192
|
+
if verts is not None:
|
193
|
+
self.add_vertices(verts)
|
194
|
+
|
195
|
+
if arcs is not None:
|
196
|
+
for u, v in arcs:
|
197
|
+
self.add_arc(u, v)
|
198
|
+
|
199
|
+
def __dealloc__(self):
|
200
|
+
"""
|
201
|
+
New and dealloc are both tested at class level.
|
202
|
+
"""
|
203
|
+
binary_matrix_free(self.edges)
|
204
|
+
sig_free(self.in_degrees)
|
205
|
+
sig_free(self.out_degrees)
|
206
|
+
bitset_free(self.active_vertices)
|
207
|
+
|
208
|
+
cpdef realloc(self, int total_verts):
|
209
|
+
"""
|
210
|
+
Reallocate the number of vertices to use, without actually adding any.
|
211
|
+
|
212
|
+
INPUT:
|
213
|
+
|
214
|
+
- ``total`` -- integer; the total size to make the array
|
215
|
+
|
216
|
+
Returns -1 and fails if reallocation would destroy any active vertices.
|
217
|
+
|
218
|
+
EXAMPLES::
|
219
|
+
|
220
|
+
sage: from sage.graphs.base.dense_graph import DenseGraph
|
221
|
+
sage: D = DenseGraph(nverts=4, extra_vertices=4)
|
222
|
+
sage: D.current_allocation()
|
223
|
+
8
|
224
|
+
sage: D.add_vertex(6)
|
225
|
+
6
|
226
|
+
sage: D.current_allocation()
|
227
|
+
8
|
228
|
+
sage: D.add_vertex(10)
|
229
|
+
10
|
230
|
+
sage: D.current_allocation()
|
231
|
+
16
|
232
|
+
sage: D.add_vertex(40)
|
233
|
+
Traceback (most recent call last):
|
234
|
+
...
|
235
|
+
RuntimeError: requested vertex is past twice the allocated range: use realloc
|
236
|
+
sage: D.realloc(50)
|
237
|
+
sage: D.add_vertex(40)
|
238
|
+
40
|
239
|
+
sage: D.current_allocation()
|
240
|
+
50
|
241
|
+
sage: D.realloc(30)
|
242
|
+
-1
|
243
|
+
sage: D.current_allocation()
|
244
|
+
50
|
245
|
+
sage: D.del_vertex(40)
|
246
|
+
sage: D.realloc(30)
|
247
|
+
sage: D.current_allocation()
|
248
|
+
30
|
249
|
+
"""
|
250
|
+
cdef int i
|
251
|
+
if not total_verts:
|
252
|
+
raise RuntimeError('dense graphs must allocate space for vertices')
|
253
|
+
|
254
|
+
cdef bitset_t bits
|
255
|
+
cdef int min_verts
|
256
|
+
if <size_t>total_verts < self.active_vertices.size:
|
257
|
+
min_verts = total_verts
|
258
|
+
bitset_init(bits, self.active_vertices.size)
|
259
|
+
bitset_set_first_n(bits, total_verts)
|
260
|
+
if not bitset_issubset(self.active_vertices, bits):
|
261
|
+
bitset_free(bits)
|
262
|
+
return -1
|
263
|
+
bitset_free(bits)
|
264
|
+
else:
|
265
|
+
min_verts = self.active_vertices.size
|
266
|
+
|
267
|
+
# Resize of self.edges
|
268
|
+
binary_matrix_realloc(self.edges, total_verts, total_verts)
|
269
|
+
|
270
|
+
self.in_degrees = <int *> sig_realloc(self.in_degrees, total_verts * sizeof(int))
|
271
|
+
self.out_degrees = <int *> sig_realloc(self.out_degrees, total_verts * sizeof(int))
|
272
|
+
|
273
|
+
for i in range(self.active_vertices.size, total_verts):
|
274
|
+
self.in_degrees[i] = 0
|
275
|
+
self.out_degrees[i] = 0
|
276
|
+
|
277
|
+
bitset_realloc(self.active_vertices, total_verts)
|
278
|
+
|
279
|
+
###################################
|
280
|
+
# Arc functions
|
281
|
+
###################################
|
282
|
+
|
283
|
+
cdef inline int _add_arc_unsafe(self, int u, int v) except -1:
|
284
|
+
"""
|
285
|
+
.. WARNING::
|
286
|
+
|
287
|
+
This method is for internal use only. Use :meth:`add_arc_label_unsafe` instead.
|
288
|
+
|
289
|
+
Add arc (u, v) with label l in only one direction.
|
290
|
+
"""
|
291
|
+
if not binary_matrix_get(self.edges, u, v):
|
292
|
+
self.in_degrees[v] += 1
|
293
|
+
self.out_degrees[u] += 1
|
294
|
+
self.num_arcs += 1
|
295
|
+
binary_matrix_set1(self.edges, u, v)
|
296
|
+
|
297
|
+
cdef int add_arc_label_unsafe(self, int u, int v, int l) except -1:
|
298
|
+
"""
|
299
|
+
Add arc ``(u, v)`` to the graph.
|
300
|
+
|
301
|
+
INPUT:
|
302
|
+
|
303
|
+
- ``u``, ``v`` -- nonnegative integers
|
304
|
+
"""
|
305
|
+
if unlikely(l):
|
306
|
+
raise ValueError("cannot add a labeled arc to an unlabeled graph")
|
307
|
+
|
308
|
+
self._add_arc_unsafe(u, v)
|
309
|
+
if u != v and not self._directed:
|
310
|
+
self._add_arc_unsafe(v, u)
|
311
|
+
|
312
|
+
cdef int has_arc_label_unsafe(self, int u, int v, int l) except -1:
|
313
|
+
"""
|
314
|
+
Check whether arc ``(u, v)`` is in the graph.
|
315
|
+
|
316
|
+
INPUT:
|
317
|
+
|
318
|
+
- ``u``, ``v`` -- nonnegative integers, must be in self
|
319
|
+
|
320
|
+
- ``l`` -- positive integer label, or zero for no label, or ``-1`` for any label
|
321
|
+
|
322
|
+
OUTPUT:
|
323
|
+
|
324
|
+
- 0 -- False
|
325
|
+
- 1 -- True
|
326
|
+
"""
|
327
|
+
if unlikely(l > 0):
|
328
|
+
raise ValueError("cannot locate labeled arc in unlabeled graph")
|
329
|
+
return binary_matrix_get(self.edges, u, v)
|
330
|
+
|
331
|
+
cdef inline int _del_arc_unsafe(self, int u, int v) except -1:
|
332
|
+
"""
|
333
|
+
.. WARNING::
|
334
|
+
|
335
|
+
This method is for internal use only. Use :meth:`add_arc_label_unsafe` instead.
|
336
|
+
|
337
|
+
Remove arc (u, v) with label l in only one direction.
|
338
|
+
"""
|
339
|
+
if binary_matrix_get(self.edges, u, v):
|
340
|
+
self.in_degrees[v] -= 1
|
341
|
+
self.out_degrees[u] -= 1
|
342
|
+
self.num_arcs -= 1
|
343
|
+
binary_matrix_set0(self.edges, u, v)
|
344
|
+
|
345
|
+
cdef int del_arc_unsafe(self, int u, int v) except -1:
|
346
|
+
"""
|
347
|
+
Delete the arc from ``u`` to ``v``, if it exists.
|
348
|
+
|
349
|
+
INPUT:
|
350
|
+
|
351
|
+
- ``u``, ``v`` -- nonnegative integers, must be in self
|
352
|
+
"""
|
353
|
+
self._del_arc_unsafe(u, v)
|
354
|
+
if u != v and not self._directed:
|
355
|
+
self._del_arc_unsafe(v, u)
|
356
|
+
|
357
|
+
cdef inline int del_arc_label_unsafe(self, int u, int v, int l) except -1:
|
358
|
+
if unlikely(l):
|
359
|
+
raise ValueError("cannot delete labeled arc in unlabeled graph")
|
360
|
+
return self.del_arc_unsafe(u, v)
|
361
|
+
|
362
|
+
cdef inline int arc_label_unsafe(self, int u, int v) except -1:
|
363
|
+
return 0
|
364
|
+
|
365
|
+
cdef int all_arcs_unsafe(self, int u, int v, int* labels, int size) except -1:
|
366
|
+
"""
|
367
|
+
Give the labels of all arcs (u, v).
|
368
|
+
|
369
|
+
INPUT:
|
370
|
+
|
371
|
+
- ``u``, ``v`` -- integers from `0`, ..., `n-1`, where `n` is the
|
372
|
+
number of vertices
|
373
|
+
- ``labels`` -- must be a pointer to an (allocated) integer array
|
374
|
+
- ``size`` -- the length of the array
|
375
|
+
|
376
|
+
OUTPUT: integer; the number of arcs ``(u, v)``.
|
377
|
+
``-1`` -- indicates that the array has been filled with labels, but
|
378
|
+
there were more.
|
379
|
+
"""
|
380
|
+
if self.has_arc_unsafe(u, v):
|
381
|
+
if size > 0:
|
382
|
+
labels[0] = 0
|
383
|
+
return 1
|
384
|
+
else:
|
385
|
+
return -1
|
386
|
+
return 0
|
387
|
+
|
388
|
+
def complement(self):
|
389
|
+
r"""
|
390
|
+
Replace the graph with its complement.
|
391
|
+
|
392
|
+
.. NOTE::
|
393
|
+
|
394
|
+
Assumes that the graph has no loop.
|
395
|
+
|
396
|
+
EXAMPLES::
|
397
|
+
|
398
|
+
sage: from sage.graphs.base.dense_graph import DenseGraph
|
399
|
+
sage: G = DenseGraph(5)
|
400
|
+
sage: G.add_arc(0, 1)
|
401
|
+
sage: G.has_arc(0, 1)
|
402
|
+
True
|
403
|
+
sage: G.complement()
|
404
|
+
sage: G.has_arc(0, 1)
|
405
|
+
False
|
406
|
+
"""
|
407
|
+
cdef int num_arcs_old = self.num_arcs
|
408
|
+
|
409
|
+
cdef size_t i
|
410
|
+
i = bitset_next(self.active_vertices, 0)
|
411
|
+
while i != -1:
|
412
|
+
self.add_arc_unsafe(i, i)
|
413
|
+
bitset_xor(self.edges.rows[i], self.edges.rows[i], self.active_vertices)
|
414
|
+
self.in_degrees[i] = self.num_verts-self.in_degrees[i]
|
415
|
+
self.out_degrees[i] = self.num_verts-self.out_degrees[i]
|
416
|
+
i = bitset_next(self.active_vertices, i + 1)
|
417
|
+
|
418
|
+
self.num_arcs = self.num_verts*(self.num_verts - 1) - num_arcs_old
|
419
|
+
|
420
|
+
###################################
|
421
|
+
# Neighbor functions
|
422
|
+
###################################
|
423
|
+
|
424
|
+
cdef inline int next_out_neighbor_unsafe(self, int u, int v, int* l) except -2:
|
425
|
+
"""
|
426
|
+
Return the next out-neighbor of ``u`` that is greater than ``v``.
|
427
|
+
|
428
|
+
If ``v`` is ``-1`` return the first neighbor of ``u``.
|
429
|
+
|
430
|
+
Return ``-1`` in case there does not exist such an out-neighbor.
|
431
|
+
|
432
|
+
Set ``l`` to be the label of the first arc.
|
433
|
+
"""
|
434
|
+
l[0] = 0
|
435
|
+
return bitset_next(self.edges.rows[u], v + 1)
|
436
|
+
|
437
|
+
cdef inline int next_in_neighbor_unsafe(self, int v, int u, int* l) except -2:
|
438
|
+
"""
|
439
|
+
Return the next in-neighbor of ``v`` that is greater or equal to ``u``.
|
440
|
+
|
441
|
+
If ``u`` is ``-1`` return the first neighbor of ``v``.
|
442
|
+
|
443
|
+
Return ``-1`` in case there does not exist such a in-neighbor.
|
444
|
+
|
445
|
+
Set ``l`` to be the label of the first arc.
|
446
|
+
"""
|
447
|
+
l[0] = 0
|
448
|
+
cdef size_t i
|
449
|
+
i = bitset_next(self.active_vertices, u + 1)
|
450
|
+
while i != -1:
|
451
|
+
if binary_matrix_get(self.edges, i, v):
|
452
|
+
return i
|
453
|
+
i = bitset_next(self.active_vertices, i + 1)
|
454
|
+
return -1
|
455
|
+
|
456
|
+
cpdef int out_degree(self, int u) noexcept:
|
457
|
+
"""
|
458
|
+
Return the out-degree of ``v``
|
459
|
+
|
460
|
+
INPUT:
|
461
|
+
|
462
|
+
- ``u`` -- integer
|
463
|
+
|
464
|
+
EXAMPLES::
|
465
|
+
|
466
|
+
sage: from sage.graphs.base.dense_graph import DenseGraph
|
467
|
+
sage: G = DenseGraph(5)
|
468
|
+
sage: G.add_arc(0,1)
|
469
|
+
sage: G.add_arc(1,2)
|
470
|
+
sage: G.add_arc(1,3)
|
471
|
+
sage: G.out_degree(0)
|
472
|
+
1
|
473
|
+
sage: G.out_degree(1)
|
474
|
+
2
|
475
|
+
"""
|
476
|
+
return self.out_degrees[u]
|
477
|
+
|
478
|
+
cpdef int in_degree(self, int v) noexcept:
|
479
|
+
"""
|
480
|
+
Return the in-degree of ``v``
|
481
|
+
|
482
|
+
INPUT:
|
483
|
+
|
484
|
+
- ``v`` -- integer
|
485
|
+
|
486
|
+
EXAMPLES::
|
487
|
+
|
488
|
+
sage: from sage.graphs.base.dense_graph import DenseGraph
|
489
|
+
sage: G = DenseGraph(5)
|
490
|
+
sage: G.add_arc(0,1)
|
491
|
+
sage: G.add_arc(1,2)
|
492
|
+
sage: G.add_arc(1,3)
|
493
|
+
sage: G.in_degree(0)
|
494
|
+
0
|
495
|
+
sage: G.in_degree(1)
|
496
|
+
1
|
497
|
+
"""
|
498
|
+
return self.in_degrees[v]
|
499
|
+
|
500
|
+
|
501
|
+
cdef int copy_dense_graph(DenseGraph dest, DenseGraph src) except -1:
|
502
|
+
r"""
|
503
|
+
Unsafely copy ``dest`` over ``src``.
|
504
|
+
|
505
|
+
.. NOTE::
|
506
|
+
|
507
|
+
``dest.active_vertices`` and ``src.active_vertices`` must be of same size!
|
508
|
+
"""
|
509
|
+
if unlikely(dest.active_vertices.size != src.active_vertices.size):
|
510
|
+
raise ValueError("``dest.active_vertices`` and ``src.active_vertices`` must be of same size")
|
511
|
+
if unlikely(dest.edges.n_rows != src.edges.n_rows or dest.edges.n_cols != src.edges.n_cols):
|
512
|
+
raise ValueError("the edges are not of same size")
|
513
|
+
memcpy(dest.in_degrees, src.in_degrees, src.active_vertices.size * sizeof(int))
|
514
|
+
memcpy(dest.out_degrees, src.out_degrees, src.active_vertices.size * sizeof(int))
|
515
|
+
binary_matrix_copy(dest.edges, src.edges)
|
516
|
+
bitset_copy(dest.active_vertices, src.active_vertices)
|
517
|
+
dest.num_verts = src.num_verts
|
518
|
+
dest.num_arcs = src.num_arcs
|
519
|
+
|
520
|
+
|
521
|
+
##############################
|
522
|
+
# Further tests. Unit tests for methods, functions, classes defined with cdef.
|
523
|
+
##############################
|
524
|
+
|
525
|
+
def _test_adjacency_sequence_out():
|
526
|
+
"""
|
527
|
+
Randomly test the method ``DenseGraph.adjacency_sequence_out()``. No output
|
528
|
+
indicates that no errors were found.
|
529
|
+
|
530
|
+
TESTS::
|
531
|
+
|
532
|
+
sage: from sage.graphs.base.dense_graph import _test_adjacency_sequence_out
|
533
|
+
sage: _test_adjacency_sequence_out() # long time
|
534
|
+
"""
|
535
|
+
from sage.graphs.digraph import DiGraph
|
536
|
+
from sage.graphs.graph_generators import GraphGenerators
|
537
|
+
from sage.misc.prandom import randint, random
|
538
|
+
low = 0
|
539
|
+
high = 500
|
540
|
+
randg = DiGraph(GraphGenerators().RandomGNP(randint(low, high), random()))
|
541
|
+
n = randg.order()
|
542
|
+
while n <= 1:
|
543
|
+
randg = DiGraph(GraphGenerators().RandomGNP(randint(low, high), random()))
|
544
|
+
n = randg.order()
|
545
|
+
|
546
|
+
cdef DenseGraph g = DenseGraph(n,
|
547
|
+
verts=randg.vertex_iterator(),
|
548
|
+
arcs=randg.edge_iterator(labels=False))
|
549
|
+
assert g.num_verts == randg.order(), (
|
550
|
+
"Graph order mismatch: %s vs. %s" % (g.num_verts, randg.order()))
|
551
|
+
assert g.num_arcs == randg.size(), (
|
552
|
+
"Graph size mismatch: %s vs. %s" % (g.num_arcs, randg.size()))
|
553
|
+
M = randg.adjacency_matrix()
|
554
|
+
cdef int *V = <int *>sig_malloc(n * sizeof(int))
|
555
|
+
cdef int i = 0
|
556
|
+
for v in randg.vertex_iterator():
|
557
|
+
V[i] = v
|
558
|
+
i += 1
|
559
|
+
cdef int *seq = <int *> sig_malloc(n * sizeof(int))
|
560
|
+
for i in range(randint(50, 101)):
|
561
|
+
u = randint(low, n - 1)
|
562
|
+
g.adjacency_sequence_out(n, V, u, seq)
|
563
|
+
A = [seq[k] for k in range(n)]
|
564
|
+
try:
|
565
|
+
assert A == list(M[u])
|
566
|
+
except AssertionError:
|
567
|
+
sig_free(V)
|
568
|
+
sig_free(seq)
|
569
|
+
raise AssertionError("graph adjacency mismatch")
|
570
|
+
sig_free(seq)
|
571
|
+
sig_free(V)
|
572
|
+
|
573
|
+
|
574
|
+
###########################################
|
575
|
+
# Dense Graph Backend
|
576
|
+
###########################################
|
577
|
+
|
578
|
+
cdef class DenseGraphBackend(CGraphBackend):
|
579
|
+
"""
|
580
|
+
Backend for Sage graphs using DenseGraphs.
|
581
|
+
|
582
|
+
::
|
583
|
+
|
584
|
+
sage: from sage.graphs.base.dense_graph import DenseGraphBackend
|
585
|
+
|
586
|
+
This class is only intended for use by the Sage Graph and DiGraph class.
|
587
|
+
If you are interested in using a DenseGraph, you probably want to do
|
588
|
+
something like the following example, which creates a Sage Graph instance
|
589
|
+
which wraps a ``DenseGraph`` object::
|
590
|
+
|
591
|
+
sage: G = Graph(30, sparse=False)
|
592
|
+
sage: G.add_edges([(0, 1), (0, 3), (4, 5), (9, 23)])
|
593
|
+
sage: G.edges(sort=True, labels=False)
|
594
|
+
[(0, 1), (0, 3), (4, 5), (9, 23)]
|
595
|
+
|
596
|
+
Note that Sage graphs using the backend are more flexible than DenseGraphs
|
597
|
+
themselves. This is because DenseGraphs (by design) do not deal with Python
|
598
|
+
objects::
|
599
|
+
|
600
|
+
sage: G.add_vertex((0, 1, 2))
|
601
|
+
sage: sorted(list(G),
|
602
|
+
....: key=lambda x: (isinstance(x, tuple), x))
|
603
|
+
[0,
|
604
|
+
...
|
605
|
+
29,
|
606
|
+
(0, 1, 2)]
|
607
|
+
sage: from sage.graphs.base.dense_graph import DenseGraph
|
608
|
+
sage: DG = DenseGraph(30)
|
609
|
+
sage: DG.add_vertex((0, 1, 2))
|
610
|
+
Traceback (most recent call last):
|
611
|
+
...
|
612
|
+
TypeError: an integer is required
|
613
|
+
"""
|
614
|
+
|
615
|
+
def __init__(self, n, directed=True):
|
616
|
+
"""
|
617
|
+
Initialize a dense graph with ``n`` vertices.
|
618
|
+
|
619
|
+
EXAMPLES::
|
620
|
+
|
621
|
+
sage: D = sage.graphs.base.dense_graph.DenseGraphBackend(9)
|
622
|
+
sage: D.add_edge(0, 1, None, False)
|
623
|
+
sage: list(D.iterator_edges(range(9), True))
|
624
|
+
[(0, 1, None)]
|
625
|
+
"""
|
626
|
+
self._cg = DenseGraph(n, directed=directed)
|
627
|
+
self._directed = directed
|
628
|
+
self.vertex_labels = {}
|
629
|
+
self.vertex_ints = {}
|
630
|
+
|
631
|
+
cdef bint _delete_edge_before_adding(self) noexcept:
|
632
|
+
"""
|
633
|
+
Return whether we should delete edges before adding any.
|
634
|
+
|
635
|
+
As dense graphs do not support multiple edges, this is never required.
|
636
|
+
"""
|
637
|
+
return False
|
638
|
+
|
639
|
+
cdef inline int new_edge_label(self, object l) except -1:
|
640
|
+
"""
|
641
|
+
Any label is ignored.
|
642
|
+
"""
|
643
|
+
return 0
|
644
|
+
|
645
|
+
cdef inline int free_edge_label(self, int l_int) except -1:
|
646
|
+
"""
|
647
|
+
Free the label corresponding to ``l_int``.
|
648
|
+
|
649
|
+
As the backend does not support labels this raises an error
|
650
|
+
if ``l_int`` is non-trivial.
|
651
|
+
"""
|
652
|
+
if unlikely(l_int):
|
653
|
+
raise ValueError("backend does not support labels")
|
654
|
+
|
655
|
+
def add_edges(self, object edges, bint directed, bint remove_loops=False):
|
656
|
+
"""
|
657
|
+
Add edges from a list.
|
658
|
+
|
659
|
+
INPUT:
|
660
|
+
|
661
|
+
- ``edges`` -- an iterable of edges to be added; each edge can either be
|
662
|
+
of the form ``(u, v)`` or ``(u, v, l)``
|
663
|
+
|
664
|
+
- ``directed`` -- if ``False``, adds ``(v, u)`` as well as ``(u, v)``
|
665
|
+
|
666
|
+
- ``remove_loops`` -- if ``True``, remove loops
|
667
|
+
|
668
|
+
EXAMPLES::
|
669
|
+
|
670
|
+
sage: D = sage.graphs.base.dense_graph.DenseGraphBackend(9)
|
671
|
+
sage: D.add_edges([(0, 1), (2, 3), (4, 5), (5, 6)], False)
|
672
|
+
sage: list(D.iterator_edges(range(9), True))
|
673
|
+
[(0, 1, None),
|
674
|
+
(2, 3, None),
|
675
|
+
(4, 5, None),
|
676
|
+
(5, 6, None)]
|
677
|
+
"""
|
678
|
+
for e in edges:
|
679
|
+
u, v = e[:2]
|
680
|
+
if unlikely(remove_loops and u == v):
|
681
|
+
continue
|
682
|
+
self.add_edge(u, v, None, directed)
|
683
|
+
|
684
|
+
def get_edge_label(self, object u, object v):
|
685
|
+
"""
|
686
|
+
Return the edge label for ``(u, v)``.
|
687
|
+
|
688
|
+
Always ``None``, since dense graphs do not support edge labels.
|
689
|
+
|
690
|
+
INPUT:
|
691
|
+
|
692
|
+
- ``u``, ``v`` -- the vertices of the edge
|
693
|
+
|
694
|
+
EXAMPLES::
|
695
|
+
|
696
|
+
sage: D = sage.graphs.base.dense_graph.DenseGraphBackend(9)
|
697
|
+
sage: D.add_edges([(0, 1), (2, 3, 7), (4, 5), (5, 6)], False)
|
698
|
+
sage: list(D.iterator_edges(range(9), True))
|
699
|
+
[(0, 1, None),
|
700
|
+
(2, 3, None),
|
701
|
+
(4, 5, None),
|
702
|
+
(5, 6, None)]
|
703
|
+
sage: D.del_edge(0, 1, None, True)
|
704
|
+
sage: list(D.iterator_out_edges(range(9), True))
|
705
|
+
[(1, 0, None),
|
706
|
+
(2, 3, None),
|
707
|
+
(3, 2, None),
|
708
|
+
(4, 5, None),
|
709
|
+
(5, 4, None),
|
710
|
+
(5, 6, None),
|
711
|
+
(6, 5, None)]
|
712
|
+
sage: D.get_edge_label(2, 3)
|
713
|
+
sage: D.get_edge_label(2, 4)
|
714
|
+
Traceback (most recent call last):
|
715
|
+
...
|
716
|
+
LookupError: (2, 4) is not an edge of the graph
|
717
|
+
"""
|
718
|
+
if not self.has_edge(u, v, None):
|
719
|
+
raise LookupError("({0}, {1}) is not an edge of the graph".format(repr(u), repr(v)))
|
720
|
+
return None
|
721
|
+
|
722
|
+
def has_edge(self, object u, object v, object l):
|
723
|
+
"""
|
724
|
+
Check whether this graph has edge ``(u, v)``.
|
725
|
+
|
726
|
+
.. NOTE::
|
727
|
+
|
728
|
+
The input ``l`` is for consistency with other backends.
|
729
|
+
|
730
|
+
INPUT:
|
731
|
+
|
732
|
+
- ``u``, ``v`` -- the vertices of the edge
|
733
|
+
|
734
|
+
- ``l`` -- the edge label (ignored)
|
735
|
+
|
736
|
+
EXAMPLES::
|
737
|
+
|
738
|
+
sage: D = sage.graphs.base.dense_graph.DenseGraphBackend(9)
|
739
|
+
sage: D.add_edges([(0, 1), (2, 3), (4, 5), (5, 6)], False)
|
740
|
+
sage: D.has_edge(0, 1, None)
|
741
|
+
True
|
742
|
+
"""
|
743
|
+
cdef int u_int = self.get_vertex_checked(u)
|
744
|
+
cdef int v_int = self.get_vertex_checked(v)
|
745
|
+
if u_int == -1 or v_int == -1:
|
746
|
+
return False
|
747
|
+
return self._has_labeled_edge_unsafe(u_int, v_int, None)
|
748
|
+
|
749
|
+
cdef inline bint _has_labeled_edge_unsafe(self, int u_int, int v_int, object l) except -1:
|
750
|
+
"""
|
751
|
+
Return whether ``self`` has an arc specified by indices of the vertices
|
752
|
+
and an arc label.
|
753
|
+
"""
|
754
|
+
return 1 == self.cg().has_arc_unsafe(u_int, v_int)
|
755
|
+
|
756
|
+
def multiple_edges(self, new):
|
757
|
+
"""
|
758
|
+
Get/set whether or not ``self`` allows multiple edges.
|
759
|
+
|
760
|
+
INPUT:
|
761
|
+
|
762
|
+
- ``new`` -- boolean (to set) or ``None`` (to get)
|
763
|
+
|
764
|
+
EXAMPLES::
|
765
|
+
|
766
|
+
sage: import sage.graphs.base.dense_graph
|
767
|
+
sage: G = sage.graphs.base.dense_graph.DenseGraphBackend(9)
|
768
|
+
sage: G.multiple_edges(True)
|
769
|
+
Traceback (most recent call last):
|
770
|
+
...
|
771
|
+
NotImplementedError: dense graphs do not support multiple edges
|
772
|
+
sage: G.multiple_edges(None)
|
773
|
+
False
|
774
|
+
"""
|
775
|
+
if new is None:
|
776
|
+
return False
|
777
|
+
if new:
|
778
|
+
raise NotImplementedError("dense graphs do not support multiple edges")
|
779
|
+
|
780
|
+
def set_edge_label(self, object u, object v, object l, bint directed):
|
781
|
+
"""
|
782
|
+
Label the edge ``(u, v)`` by ``l``.
|
783
|
+
|
784
|
+
INPUT:
|
785
|
+
|
786
|
+
- ``u``, ``v`` -- the vertices of the edge
|
787
|
+
|
788
|
+
- ``l`` -- the edge label
|
789
|
+
|
790
|
+
- ``directed`` -- if ``False``, also set ``(v, u)`` with label ``l``
|
791
|
+
|
792
|
+
EXAMPLES::
|
793
|
+
|
794
|
+
sage: import sage.graphs.base.dense_graph
|
795
|
+
sage: G = sage.graphs.base.dense_graph.DenseGraphBackend(9)
|
796
|
+
sage: G.set_edge_label(1, 2, 'a', True)
|
797
|
+
Traceback (most recent call last):
|
798
|
+
...
|
799
|
+
NotImplementedError: dense graphs do not support edge labels
|
800
|
+
"""
|
801
|
+
raise NotImplementedError("dense graphs do not support edge labels")
|