passagemath-graphs 10.5.10__cp39-cp39-macosx_14_0_arm64.whl → 10.5.43__cp39-cp39-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.10.dist-info → passagemath_graphs-10.5.43.dist-info}/METADATA +126 -30
- passagemath_graphs-10.5.43.dist-info/RECORD +256 -0
- {passagemath_graphs-10.5.10.dist-info → passagemath_graphs-10.5.43.dist-info}/WHEEL +2 -1
- passagemath_graphs.dylibs/libgmp.10.dylib +0 -0
- sage/all__sagemath_graphs.py +5 -0
- sage/combinat/abstract_tree.py +1 -1
- sage/combinat/binary_tree.py +1 -1
- sage/combinat/cluster_algebra_quiver/all.py +1 -1
- sage/combinat/cluster_algebra_quiver/cluster_seed.py +28 -24
- sage/combinat/cluster_algebra_quiver/interact.py +4 -0
- sage/combinat/designs/MOLS_handbook_data.py +5 -5
- sage/combinat/designs/bibd.py +10 -9
- sage/combinat/designs/covering_array.py +3 -3
- sage/combinat/designs/covering_design.py +2 -1
- sage/combinat/designs/database.py +11 -10
- sage/combinat/designs/designs_pyx.cpython-39-darwin.so +0 -0
- sage/combinat/designs/designs_pyx.pyx +13 -45
- sage/combinat/designs/difference_family.py +6 -6
- sage/combinat/designs/difference_matrices.py +1 -1
- sage/combinat/designs/evenly_distributed_sets.cpython-39-darwin.so +0 -0
- sage/combinat/designs/evenly_distributed_sets.pyx +15 -22
- sage/combinat/designs/ext_rep.py +9 -14
- sage/combinat/designs/gen_quadrangles_with_spread.cpython-39-darwin.so +0 -0
- sage/combinat/designs/gen_quadrangles_with_spread.pyx +1 -1
- sage/combinat/designs/group_divisible_designs.py +1 -1
- sage/combinat/designs/incidence_structures.py +8 -8
- sage/combinat/designs/latin_squares.py +1 -1
- sage/combinat/designs/orthogonal_arrays_build_recursive.py +8 -7
- sage/combinat/designs/orthogonal_arrays_find_recursive.cpython-39-darwin.so +0 -0
- sage/combinat/designs/resolvable_bibd.py +1 -1
- sage/combinat/designs/steiner_quadruple_systems.py +1 -1
- sage/combinat/designs/subhypergraph_search.cpython-39-darwin.so +0 -0
- sage/combinat/designs/subhypergraph_search.pyx +9 -9
- sage/combinat/finite_state_machine_generators.py +2 -2
- sage/combinat/graph_path.py +3 -3
- sage/combinat/interval_posets.py +10 -10
- sage/combinat/ordered_tree.py +1 -1
- sage/combinat/posets/cartesian_product.py +1 -1
- sage/combinat/posets/d_complete.py +1 -1
- sage/combinat/posets/forest.py +1 -1
- sage/combinat/posets/hasse_cython.cpython-39-darwin.so +0 -0
- sage/combinat/posets/hasse_diagram.py +8 -6
- sage/combinat/posets/incidence_algebras.py +8 -8
- sage/combinat/posets/lattices.py +28 -4
- sage/combinat/posets/linear_extension_iterator.cpython-39-darwin.so +0 -0
- sage/combinat/posets/linear_extension_iterator.pyx +2 -0
- sage/combinat/posets/linear_extensions.py +7 -16
- sage/combinat/posets/moebius_algebra.py +1 -1
- sage/combinat/posets/poset_examples.py +1 -1
- sage/combinat/posets/posets.py +54 -56
- sage/combinat/rooted_tree.py +3 -3
- sage/combinat/tamari_lattices.py +1 -1
- 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/asteroidal_triples.cpython-39-darwin.so +0 -0
- sage/graphs/base/boost_graph.cpython-39-darwin.so +0 -0
- sage/graphs/base/boost_graph.pxd +1 -1
- sage/graphs/base/boost_graph.pyx +1 -1
- sage/graphs/base/c_graph.cpython-39-darwin.so +0 -0
- sage/graphs/base/c_graph.pxd +4 -4
- sage/graphs/base/c_graph.pyx +270 -184
- sage/graphs/base/dense_graph.cpython-39-darwin.so +0 -0
- sage/graphs/base/graph_backends.cpython-39-darwin.so +0 -0
- sage/graphs/base/sparse_graph.cpython-39-darwin.so +0 -0
- sage/graphs/base/static_dense_graph.cpython-39-darwin.so +0 -0
- sage/graphs/base/static_sparse_backend.cpython-39-darwin.so +0 -0
- sage/graphs/base/static_sparse_backend.pyx +93 -6
- sage/graphs/base/static_sparse_graph.cpython-39-darwin.so +0 -0
- sage/graphs/base/static_sparse_graph.pyx +1 -1
- sage/graphs/bipartite_graph.py +0 -1
- sage/graphs/centrality.cpython-39-darwin.so +0 -0
- sage/graphs/centrality.pyx +0 -0
- sage/graphs/comparability.cpython-39-darwin.so +0 -0
- sage/graphs/comparability.pyx +172 -138
- sage/graphs/connectivity.cpython-39-darwin.so +0 -0
- sage/graphs/connectivity.pyx +194 -18
- sage/graphs/convexity_properties.cpython-39-darwin.so +0 -0
- sage/graphs/digraph_generators.py +118 -74
- sage/graphs/distances_all_pairs.cpython-39-darwin.so +0 -0
- sage/graphs/distances_all_pairs.pyx +145 -27
- sage/graphs/edge_connectivity.cpython-39-darwin.so +0 -0
- sage/graphs/generators/basic.py +471 -130
- sage/graphs/generators/distance_regular.cpython-39-darwin.so +0 -0
- sage/graphs/generators/distance_regular.pyx +12 -12
- sage/graphs/generators/families.py +2 -2
- sage/graphs/generators/random.py +8 -13
- sage/graphs/generators/smallgraphs.py +12 -11
- sage/graphs/generic_graph.py +687 -265
- sage/graphs/generic_graph_pyx.cpython-39-darwin.so +0 -0
- sage/graphs/genus.cpython-39-darwin.so +0 -0
- sage/graphs/graph.py +12 -46
- sage/graphs/graph_coloring.cpython-39-darwin.so +0 -0
- sage/graphs/graph_database.py +1 -1
- sage/graphs/graph_decompositions/bandwidth.cpython-39-darwin.so +0 -0
- sage/graphs/graph_decompositions/clique_separators.cpython-39-darwin.so +0 -0
- sage/graphs/graph_decompositions/cutwidth.cpython-39-darwin.so +0 -0
- sage/graphs/graph_decompositions/fast_digraph.cpython-39-darwin.so +0 -0
- sage/graphs/graph_decompositions/graph_products.cpython-39-darwin.so +0 -0
- sage/graphs/graph_decompositions/modular_decomposition.cpython-39-darwin.so +0 -0
- sage/graphs/graph_decompositions/slice_decomposition.cpython-39-darwin.so +0 -0
- sage/graphs/graph_decompositions/tree_decomposition.cpython-39-darwin.so +0 -0
- sage/graphs/graph_decompositions/vertex_separation.cpython-39-darwin.so +0 -0
- sage/graphs/graph_generators.py +110 -55
- sage/graphs/graph_generators_pyx.cpython-39-darwin.so +0 -0
- sage/graphs/graph_latex.py +1 -1
- sage/graphs/graph_list.py +2 -3
- sage/graphs/graph_plot.py +225 -30
- sage/graphs/hyperbolicity.cpython-39-darwin.so +0 -0
- sage/graphs/independent_sets.cpython-39-darwin.so +0 -0
- sage/graphs/isgci.py +3 -8
- sage/graphs/isoperimetric_inequalities.cpython-39-darwin.so +0 -0
- sage/graphs/line_graph.cpython-39-darwin.so +0 -0
- sage/graphs/matching.py +14 -25
- sage/graphs/matching_covered_graph.py +871 -60
- sage/graphs/orientations.py +190 -134
- sage/graphs/path_enumeration.cpython-39-darwin.so +0 -0
- sage/graphs/path_enumeration.pyx +25 -25
- sage/graphs/spanning_tree.cpython-39-darwin.so +0 -0
- sage/graphs/strongly_regular_db.cpython-39-darwin.so +0 -0
- sage/graphs/strongly_regular_db.pyx +54 -52
- sage/graphs/traversals.cpython-39-darwin.so +0 -0
- sage/graphs/traversals.pyx +114 -46
- sage/graphs/trees.cpython-39-darwin.so +0 -0
- sage/graphs/views.cpython-39-darwin.so +0 -0
- sage/graphs/weakly_chordal.cpython-39-darwin.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_graphs.cpython-39-darwin.so +0 -0
- sage/knots/free_knotinfo_monoid.py +2 -3
- sage/knots/knot.py +1 -1
- sage/knots/knotinfo.py +4 -4
- sage/knots/link.py +58 -57
- sage/sandpiles/sandpile.py +2 -3
- sage/topology/cell_complex.py +1 -1
- sage/topology/cubical_complex.py +7 -7
- sage/topology/delta_complex.py +4 -4
- sage/topology/simplicial_complex.py +7 -22
- passagemath_graphs-10.5.10.dist-info/RECORD +0 -251
- {passagemath_graphs-10.5.10.dist-info → passagemath_graphs-10.5.43.dist-info}/top_level.txt +0 -0
sage/graphs/orientations.py
CHANGED
@@ -21,7 +21,7 @@ etc.). It also implements some iterators over all these orientations.
|
|
21
21
|
:meth:`random_orientation` | Return a random orientation of a graph `G`
|
22
22
|
:meth:`minimum_outdegree_orientation` | Return an orientation of `G` with the smallest possible maximum outdegree.
|
23
23
|
:meth:`bounded_outdegree_orientation` | Return an orientation of `G` such that every vertex `v` has out-degree less than `b(v)`.
|
24
|
-
:meth:`eulerian_orientation
|
24
|
+
:meth:`eulerian_orientation` | Return an Eulerian orientation of the graph `G`.
|
25
25
|
|
26
26
|
Authors
|
27
27
|
-------
|
@@ -49,6 +49,165 @@ from sage.graphs.digraph import DiGraph
|
|
49
49
|
from sage.graphs.generic_graph import _weight_if_real, _weight_1
|
50
50
|
|
51
51
|
|
52
|
+
def _initialize_digraph(G, edges, name=None, weighted=None, sparse=None,
|
53
|
+
data_structure=None, immutable=None, hash_labels=None):
|
54
|
+
r"""
|
55
|
+
Helper method to return a directed graph built from ``G``.
|
56
|
+
|
57
|
+
This method returns a digraph with the same set of vertices than the input
|
58
|
+
graph ``G`` and with specified edges. The data structure can be
|
59
|
+
specified. Furthermore, all attributes of the graph are copied to the
|
60
|
+
returned digraph.
|
61
|
+
|
62
|
+
INPUT:
|
63
|
+
|
64
|
+
- ``G`` -- a graph
|
65
|
+
|
66
|
+
- ``edges`` -- iterable; the edges of the digraph to return
|
67
|
+
|
68
|
+
- ``name`` -- string (default: ``None``); the name of the digraph to
|
69
|
+
return. By default (``None``), the returned digraph has the same name as
|
70
|
+
the input graph ``G``.
|
71
|
+
|
72
|
+
- ``weighted`` -- boolean (default: ``None``); weightedness for the oriented
|
73
|
+
digraph. By default (``None``), the graph and its orientation will behave
|
74
|
+
the same.
|
75
|
+
|
76
|
+
- ``sparse`` -- boolean (default: ``None``); ``sparse=True`` is an alias for
|
77
|
+
``data_structure="sparse"``, and ``sparse=False`` is an alias for
|
78
|
+
``data_structure="dense"``. Only used when ``data_structure=None``.
|
79
|
+
|
80
|
+
- ``data_structure`` -- string (default: ``None``); one of ``'sparse'``,
|
81
|
+
``'static_sparse'``, or ``'dense'``. See the documentation of
|
82
|
+
:class:`DiGraph`.
|
83
|
+
|
84
|
+
- ``immutable`` -- boolean (default: ``None``); whether to create a
|
85
|
+
mutable/immutable digraph. Only used when ``data_structure=None``.
|
86
|
+
|
87
|
+
* ``immutable=None`` (default) means that the graph and its orientation
|
88
|
+
will behave the same way.
|
89
|
+
|
90
|
+
* ``immutable=True`` is a shortcut for ``data_structure='static_sparse'``
|
91
|
+
|
92
|
+
* ``immutable=False`` means that the created digraph is mutable. When used
|
93
|
+
to orient an immutable graph, the data structure used is ``'sparse'``
|
94
|
+
unless anything else is specified.
|
95
|
+
|
96
|
+
- ``hash_labels`` -- boolean (default: ``None``); whether to include edge
|
97
|
+
labels during hashing of the oriented digraph. This parameter defaults to
|
98
|
+
``True`` if the graph is weighted. This parameter is ignored when
|
99
|
+
parameter ``immutable`` is not ``True``. Beware that trying to hash
|
100
|
+
unhashable labels will raise an error.
|
101
|
+
|
102
|
+
EXAMPLES::
|
103
|
+
|
104
|
+
sage: from sage.graphs.orientations import _initialize_digraph
|
105
|
+
sage: G = Graph([(1, 2)], immutable=True, loops=True, multiedges=True)
|
106
|
+
sage: D = _initialize_digraph(G, [])
|
107
|
+
sage: D.is_immutable()
|
108
|
+
True
|
109
|
+
sage: D.allows_loops()
|
110
|
+
True
|
111
|
+
sage: D.allows_multiple_edges()
|
112
|
+
True
|
113
|
+
sage: D.edges()
|
114
|
+
[]
|
115
|
+
sage: D.add_edge((2, 3))
|
116
|
+
Traceback (most recent call last):
|
117
|
+
...
|
118
|
+
ValueError: graph is immutable; please change a copy instead (use function copy())
|
119
|
+
sage: G = Graph([(1, 2)])
|
120
|
+
sage: D = _initialize_digraph(G, [])
|
121
|
+
sage: D.vertices()
|
122
|
+
[1, 2]
|
123
|
+
sage: D.edges()
|
124
|
+
[]
|
125
|
+
sage: D.add_edge((2, 3)); D.edges()
|
126
|
+
[(2, 3, None)]
|
127
|
+
|
128
|
+
TESTS::
|
129
|
+
|
130
|
+
sage: from sage.graphs.orientations import _initialize_digraph
|
131
|
+
sage: _initialize_digraph(Graph(), [], data_structure='sparse', immutable=False)
|
132
|
+
Traceback (most recent call last):
|
133
|
+
...
|
134
|
+
ValueError: you cannot define 'immutable' or 'sparse' when 'data_structure' has a value
|
135
|
+
sage: _initialize_digraph(Graph(), [], data_structure='sparse', sparse=True)
|
136
|
+
Traceback (most recent call last):
|
137
|
+
...
|
138
|
+
ValueError: you cannot define 'immutable' or 'sparse' when 'data_structure' has a value
|
139
|
+
"""
|
140
|
+
# Which data structure should be used ?
|
141
|
+
if data_structure is not None:
|
142
|
+
# data_structure is already defined so there is nothing left to do
|
143
|
+
# here. Did the user try to define too much ?
|
144
|
+
if immutable is not None or sparse is not None:
|
145
|
+
raise ValueError("you cannot define 'immutable' or 'sparse' "
|
146
|
+
"when 'data_structure' has a value")
|
147
|
+
# At this point, data_structure is None.
|
148
|
+
elif immutable is True:
|
149
|
+
data_structure = 'static_sparse'
|
150
|
+
if sparse is False:
|
151
|
+
raise ValueError("there is no dense immutable backend at the moment")
|
152
|
+
elif immutable is False:
|
153
|
+
# If the user requests a mutable digraph and input is immutable, we
|
154
|
+
# choose the 'sparse' cgraph backend. Unless the user explicitly
|
155
|
+
# asked for something different.
|
156
|
+
if G.is_immutable():
|
157
|
+
data_structure = 'dense' if sparse is False else 'sparse'
|
158
|
+
# At this point, data_structure and immutable are None.
|
159
|
+
elif sparse is True:
|
160
|
+
data_structure = "sparse"
|
161
|
+
elif sparse is False:
|
162
|
+
data_structure = "dense"
|
163
|
+
|
164
|
+
if data_structure is None:
|
165
|
+
from sage.graphs.base.dense_graph import DenseGraphBackend
|
166
|
+
from sage.graphs.base.sparse_graph import SparseGraphBackend
|
167
|
+
if isinstance(G._backend, DenseGraphBackend):
|
168
|
+
data_structure = "dense"
|
169
|
+
elif isinstance(G._backend, SparseGraphBackend):
|
170
|
+
data_structure = "sparse"
|
171
|
+
else:
|
172
|
+
data_structure = "static_sparse"
|
173
|
+
|
174
|
+
if name is None:
|
175
|
+
name = G.name()
|
176
|
+
if weighted is None:
|
177
|
+
weighted = G.weighted()
|
178
|
+
if hash_labels is None:
|
179
|
+
hash_labels = G._hash_labels
|
180
|
+
|
181
|
+
D = DiGraph(data=[G, edges],
|
182
|
+
format='vertices_and_edges',
|
183
|
+
data_structure=data_structure,
|
184
|
+
multiedges=G.allows_multiple_edges(),
|
185
|
+
loops=G.allows_loops(),
|
186
|
+
weighted=weighted,
|
187
|
+
pos=copy(G.get_pos()),
|
188
|
+
name=name,
|
189
|
+
hash_labels=hash_labels)
|
190
|
+
|
191
|
+
D.set_vertices(G.get_vertices())
|
192
|
+
|
193
|
+
attributes_to_copy = ('_assoc', '_embedding')
|
194
|
+
for attr in attributes_to_copy:
|
195
|
+
if hasattr(G, attr):
|
196
|
+
copy_attr = {}
|
197
|
+
old_attr = getattr(G, attr)
|
198
|
+
if isinstance(old_attr, dict):
|
199
|
+
for v, value in old_attr.items():
|
200
|
+
try:
|
201
|
+
copy_attr[v] = value.copy()
|
202
|
+
except AttributeError:
|
203
|
+
copy_attr[v] = copy(value)
|
204
|
+
setattr(D, attr, copy_attr)
|
205
|
+
else:
|
206
|
+
setattr(D, attr, copy(old_attr))
|
207
|
+
|
208
|
+
return D
|
209
|
+
|
210
|
+
|
52
211
|
def orient(G, f, weighted=None, data_structure=None, sparse=None,
|
53
212
|
immutable=None, hash_labels=None):
|
54
213
|
r"""
|
@@ -166,64 +325,11 @@ def orient(G, f, weighted=None, data_structure=None, sparse=None,
|
|
166
325
|
sage: H.orient(foo, data_structure=None, immutable=None, sparse=None)._backend
|
167
326
|
<sage.graphs.base.dense_graph.DenseGraphBackend object at ...>
|
168
327
|
"""
|
169
|
-
# Which data structure should be used ?
|
170
|
-
if data_structure is not None:
|
171
|
-
# data_structure is already defined so there is nothing left to do
|
172
|
-
# here. Did the user try to define too much ?
|
173
|
-
if immutable is not None or sparse is not None:
|
174
|
-
raise ValueError("you cannot define 'immutable' or 'sparse' "
|
175
|
-
"when 'data_structure' has a value")
|
176
|
-
# At this point, data_structure is None.
|
177
|
-
elif immutable is True:
|
178
|
-
data_structure = 'static_sparse'
|
179
|
-
if sparse is False:
|
180
|
-
raise ValueError("there is no dense immutable backend at the moment")
|
181
|
-
elif immutable is False:
|
182
|
-
# If the user requests a mutable digraph and input is immutable, we
|
183
|
-
# choose the 'sparse' cgraph backend. Unless the user explicitly
|
184
|
-
# asked for something different.
|
185
|
-
if G.is_immutable():
|
186
|
-
data_structure = 'dense' if sparse is False else 'sparse'
|
187
|
-
elif sparse is True:
|
188
|
-
data_structure = "sparse"
|
189
|
-
elif sparse is False:
|
190
|
-
data_structure = "dense"
|
191
|
-
|
192
|
-
if data_structure is None:
|
193
|
-
from sage.graphs.base.dense_graph import DenseGraphBackend
|
194
|
-
if isinstance(G._backend, DenseGraphBackend):
|
195
|
-
data_structure = "dense"
|
196
|
-
else:
|
197
|
-
data_structure = "sparse"
|
198
|
-
|
199
|
-
if weighted is None:
|
200
|
-
weighted = G.weighted()
|
201
|
-
|
202
328
|
edges = (f(e) for e in G.edge_iterator())
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
name=f"Orientation of {G.name()}",
|
208
|
-
pos=copy(G._pos), weighted=weighted,
|
209
|
-
hash_labels=hash_labels)
|
210
|
-
|
211
|
-
attributes_to_copy = ('_assoc', '_embedding')
|
212
|
-
for attr in attributes_to_copy:
|
213
|
-
if hasattr(G, attr):
|
214
|
-
copy_attr = {}
|
215
|
-
old_attr = getattr(G, attr)
|
216
|
-
if isinstance(old_attr, dict):
|
217
|
-
for v, value in old_attr.items():
|
218
|
-
try:
|
219
|
-
copy_attr[v] = value.copy()
|
220
|
-
except AttributeError:
|
221
|
-
copy_attr[v] = copy(value)
|
222
|
-
setattr(D, attr, copy_attr)
|
223
|
-
else:
|
224
|
-
setattr(D, attr, copy(old_attr))
|
225
|
-
|
226
|
-
return D
|
329
|
+
name = f"Orientation of {G.name()}"
|
330
|
+
return _initialize_digraph(G, edges, name=name, weighted=weighted,
|
331
|
+
data_structure=data_structure, sparse=sparse,
|
332
|
+
immutable=immutable, hash_labels=hash_labels)
|
227
333
|
|
228
334
|
|
229
335
|
def orientations(G, data_structure=None, sparse=None):
|
@@ -312,7 +418,7 @@ def orientations(G, data_structure=None, sparse=None):
|
|
312
418
|
sage: next(G.orientations(data_structure='sparse', sparse=True))._backend
|
313
419
|
Traceback (most recent call last):
|
314
420
|
...
|
315
|
-
ValueError: cannot
|
421
|
+
ValueError: you cannot define 'immutable' or 'sparse' when 'data_structure' has a value
|
316
422
|
sage: next(G.orientations(sparse=True))._backend
|
317
423
|
<sage.graphs.base.sparse_graph.SparseGraphBackend object at ...>
|
318
424
|
sage: next(G.orientations(sparse=False))._backend
|
@@ -338,51 +444,21 @@ def orientations(G, data_structure=None, sparse=None):
|
|
338
444
|
sage: next(G.orientations()).get_embedding() == {}
|
339
445
|
True
|
340
446
|
"""
|
341
|
-
if sparse is not None:
|
342
|
-
if data_structure is not None:
|
343
|
-
raise ValueError("cannot specify both 'sparse' and 'data_structure'")
|
344
|
-
data_structure = "sparse" if sparse else "dense"
|
345
|
-
if data_structure is None:
|
346
|
-
from sage.graphs.base.dense_graph import DenseGraphBackend
|
347
|
-
from sage.graphs.base.sparse_graph import SparseGraphBackend
|
348
|
-
if isinstance(G._backend, DenseGraphBackend):
|
349
|
-
data_structure = "dense"
|
350
|
-
elif isinstance(G._backend, SparseGraphBackend):
|
351
|
-
data_structure = "sparse"
|
352
|
-
else:
|
353
|
-
data_structure = "static_sparse"
|
354
|
-
|
355
447
|
name = G.name()
|
356
448
|
if name:
|
357
449
|
name = 'An orientation of ' + name
|
358
450
|
|
359
451
|
if not G.size():
|
360
|
-
|
361
|
-
|
362
|
-
name=name,
|
363
|
-
pos=G._pos,
|
364
|
-
multiedges=G.allows_multiple_edges(),
|
365
|
-
loops=G.allows_loops(),
|
366
|
-
data_structure=data_structure)
|
367
|
-
if hasattr(G, '_embedding'):
|
368
|
-
D._embedding = copy(G._embedding)
|
369
|
-
yield D
|
452
|
+
yield _initialize_digraph(G, [], name=name,
|
453
|
+
data_structure=data_structure, sparse=sparse)
|
370
454
|
return
|
371
455
|
|
372
456
|
E = [[(u, v, label), (v, u, label)] if u != v else [(u, v, label)]
|
373
457
|
for u, v, label in G.edge_iterator()]
|
374
458
|
from itertools import product
|
375
459
|
for edges in product(*E):
|
376
|
-
|
377
|
-
|
378
|
-
name=name,
|
379
|
-
pos=G._pos,
|
380
|
-
multiedges=G.allows_multiple_edges(),
|
381
|
-
loops=G.allows_loops(),
|
382
|
-
data_structure=data_structure)
|
383
|
-
if hasattr(G, '_embedding'):
|
384
|
-
D._embedding = copy(G._embedding)
|
385
|
-
yield D
|
460
|
+
yield _initialize_digraph(G, edges, name=name,
|
461
|
+
data_structure=data_structure, sparse=sparse)
|
386
462
|
|
387
463
|
|
388
464
|
def acyclic_orientations(G):
|
@@ -646,7 +722,8 @@ def acyclic_orientations(G):
|
|
646
722
|
|
647
723
|
# Iterate over acyclic orientations and create relabeled graphs
|
648
724
|
for orientation in orientations:
|
649
|
-
|
725
|
+
edges = ((u, v) if label else (v, u) for (u, v), label in orientation.items())
|
726
|
+
D = _initialize_digraph(G, edges)
|
650
727
|
D.relabel(perm=reverse_vertex_labels, inplace=True)
|
651
728
|
yield D
|
652
729
|
|
@@ -713,7 +790,13 @@ def strong_orientation(G):
|
|
713
790
|
sage: g.strong_orientation()
|
714
791
|
Multi-digraph on 3 vertices
|
715
792
|
"""
|
716
|
-
|
793
|
+
from sage.graphs.base.dense_graph import DenseGraphBackend
|
794
|
+
if isinstance(G._backend, DenseGraphBackend):
|
795
|
+
data_structure = "dense"
|
796
|
+
else:
|
797
|
+
data_structure = "sparse"
|
798
|
+
d = _initialize_digraph(G, [], data_structure=data_structure)
|
799
|
+
|
717
800
|
i = 0
|
718
801
|
|
719
802
|
# The algorithm works through a depth-first search. Any edge used in the
|
@@ -1021,25 +1104,14 @@ def random_orientation(G):
|
|
1021
1104
|
if not isinstance(G, Graph):
|
1022
1105
|
raise ValueError("the input parameter must be a Graph")
|
1023
1106
|
|
1024
|
-
D = DiGraph(data=[G.vertices(sort=False), []],
|
1025
|
-
format='vertices_and_edges',
|
1026
|
-
multiedges=G.allows_multiple_edges(),
|
1027
|
-
loops=G.allows_loops(),
|
1028
|
-
weighted=G.weighted(),
|
1029
|
-
pos=G.get_pos(),
|
1030
|
-
name="Random orientation of {}".format(G.name()))
|
1031
|
-
if hasattr(G, '_embedding'):
|
1032
|
-
D._embedding = copy(G._embedding)
|
1033
|
-
|
1034
1107
|
from sage.misc.prandom import getrandbits
|
1035
1108
|
rbits = getrandbits(G.size())
|
1109
|
+
edges = []
|
1036
1110
|
for u, v, l in G.edge_iterator():
|
1037
|
-
if rbits % 2
|
1038
|
-
D.add_edge(u, v, l)
|
1039
|
-
else:
|
1040
|
-
D.add_edge(v, u, l)
|
1111
|
+
edges.append((u, v, l) if rbits % 2 else (v, u, l))
|
1041
1112
|
rbits >>= 1
|
1042
|
-
|
1113
|
+
|
1114
|
+
return _initialize_digraph(G, edges, name=f"Random orientation of {G.name()}")
|
1043
1115
|
|
1044
1116
|
|
1045
1117
|
def minimum_outdegree_orientation(G, use_edge_labels=False, solver=None, verbose=0,
|
@@ -1154,15 +1226,8 @@ def minimum_outdegree_orientation(G, use_edge_labels=False, solver=None, verbose
|
|
1154
1226
|
|
1155
1227
|
orientation = p.get_values(orientation, convert=bool, tolerance=integrality_tolerance)
|
1156
1228
|
|
1157
|
-
#
|
1158
|
-
|
1159
|
-
|
1160
|
-
# Builds the list of edges that should be removed
|
1161
|
-
edges = (e[::-1] if orientation[frozenset(e)] else e
|
1162
|
-
for e in G.edge_iterator(labels=False))
|
1163
|
-
O.delete_edges(edges)
|
1164
|
-
|
1165
|
-
return O
|
1229
|
+
# Return the resulting orientation
|
1230
|
+
return G.orient(lambda e: e if orientation[frozenset(e[:2])] else (e[1], e[0], e[2]))
|
1166
1231
|
|
1167
1232
|
|
1168
1233
|
def bounded_outdegree_orientation(G, bound, solver=None, verbose=False,
|
@@ -1327,27 +1392,18 @@ def bounded_outdegree_orientation(G, bound, solver=None, verbose=False,
|
|
1327
1392
|
if value != G.size():
|
1328
1393
|
raise ValueError("No orientation exists for the given bound")
|
1329
1394
|
|
1330
|
-
D = DiGraph()
|
1331
|
-
D.add_vertices(vertices)
|
1332
|
-
|
1333
1395
|
# The flow graph may not contain all the vertices, if they are
|
1334
1396
|
# not part of the flow...
|
1397
|
+
edges = ((vertices[u], vertices[vv if vv != u else uu])
|
1398
|
+
for u in (x for x in range(n) if x in flow)
|
1399
|
+
for uu, vv in flow.neighbors_out(u))
|
1335
1400
|
|
1336
|
-
|
1337
|
-
|
1338
|
-
for uu, vv in flow.neighbors_out(u):
|
1339
|
-
v = vv if vv != u else uu
|
1340
|
-
D.add_edge(vertices[u], vertices[v])
|
1341
|
-
|
1342
|
-
# I do not like when a method destroys the embedding ;-)
|
1343
|
-
D.set_pos(G.get_pos())
|
1344
|
-
|
1345
|
-
return D
|
1401
|
+
return _initialize_digraph(G, edges)
|
1346
1402
|
|
1347
1403
|
|
1348
1404
|
def eulerian_orientation(G):
|
1349
1405
|
r"""
|
1350
|
-
Return
|
1406
|
+
Return an Eulerian orientation of the graph `G`.
|
1351
1407
|
|
1352
1408
|
An Eulerian graph being a graph such that any vertex has an even degree, an
|
1353
1409
|
Eulerian orientation of a graph is an orientation of its edges such that
|
@@ -1404,7 +1460,7 @@ def eulerian_orientation(G):
|
|
1404
1460
|
sage: E4.eulerian_orientation()
|
1405
1461
|
Digraph on 4 vertices
|
1406
1462
|
"""
|
1407
|
-
d =
|
1463
|
+
d = _initialize_digraph(G, [], sparse=True, immutable=False)
|
1408
1464
|
|
1409
1465
|
if not G.size():
|
1410
1466
|
return d
|
Binary file
|
sage/graphs/path_enumeration.pyx
CHANGED
@@ -362,7 +362,7 @@ def shortest_simple_paths(self, source, target, weight_function=None,
|
|
362
362
|
....: report_edges=True, report_weight=True))
|
363
363
|
[(20, [(1, 3), (3, 5)]), (40, [(1, 2), (2, 5)]), (60, [(1, 4), (4, 5)])]
|
364
364
|
sage: list(g.shortest_simple_paths(1, 5, report_edges=True, report_weight=True))
|
365
|
-
[(2, [(1,
|
365
|
+
[(2, [(1, 2), (2, 5)]), (2, [(1, 3), (3, 5)]), (2, [(1, 4), (4, 5)])]
|
366
366
|
sage: list(g.shortest_simple_paths(1, 5, by_weight=True, report_edges=True))
|
367
367
|
[[(1, 3), (3, 5)], [(1, 2), (2, 5)], [(1, 4), (4, 5)]]
|
368
368
|
sage: list(g.shortest_simple_paths(1, 5, by_weight=True, algorithm='Feng',
|
@@ -433,12 +433,12 @@ def shortest_simple_paths(self, source, target, weight_function=None,
|
|
433
433
|
....: (6, 9, 1), (9, 5, 1), (4, 2, 1), (9, 3, 1),
|
434
434
|
....: (9, 10, 1), (10, 5, 1), (9, 11, 1), (11, 10, 1)])
|
435
435
|
sage: list(g.shortest_simple_paths(1, 5, algorithm='Feng'))
|
436
|
-
[[1,
|
437
|
-
[1,
|
438
|
-
[1, 6, 9, 10, 5],
|
436
|
+
[[1, 6, 9, 5],
|
437
|
+
[1, 7, 8, 5],
|
439
438
|
[1, 2, 3, 4, 5],
|
440
|
-
[1, 6, 9,
|
441
|
-
[1, 6, 9, 11, 10, 5]
|
439
|
+
[1, 6, 9, 10, 5],
|
440
|
+
[1, 6, 9, 11, 10, 5],
|
441
|
+
[1, 6, 9, 3, 4, 5]]
|
442
442
|
|
443
443
|
sage: # needs sage.combinat
|
444
444
|
sage: G = digraphs.DeBruijn(2, 3)
|
@@ -958,11 +958,11 @@ def feng_k_shortest_simple_paths(self, source, target, weight_function=None,
|
|
958
958
|
sage: list(feng_k_shortest_simple_paths(g, 1, 5, by_weight=True))
|
959
959
|
[[1, 3, 5], [1, 2, 5], [1, 4, 5]]
|
960
960
|
sage: list(feng_k_shortest_simple_paths(g, 1, 5))
|
961
|
-
[[1,
|
961
|
+
[[1, 2, 5], [1, 3, 5], [1, 4, 5]]
|
962
962
|
sage: list(feng_k_shortest_simple_paths(g, 1, 1))
|
963
963
|
[[1]]
|
964
964
|
sage: list(feng_k_shortest_simple_paths(g, 1, 5, report_edges=True, labels=True))
|
965
|
-
[[(1,
|
965
|
+
[[(1, 2, 20), (2, 5, 20)], [(1, 3, 10), (3, 5, 10)], [(1, 4, 30), (4, 5, 30)]]
|
966
966
|
sage: list(feng_k_shortest_simple_paths(g, 1, 5, report_edges=True, labels=True, by_weight=True))
|
967
967
|
[[(1, 3, 10), (3, 5, 10)], [(1, 2, 20), (2, 5, 20)], [(1, 4, 30), (4, 5, 30)]]
|
968
968
|
sage: list(feng_k_shortest_simple_paths(g, 1, 5, report_edges=True, labels=True, by_weight=True, report_weight=True))
|
@@ -975,7 +975,7 @@ def feng_k_shortest_simple_paths(self, source, target, weight_function=None,
|
|
975
975
|
sage: list(feng_k_shortest_simple_paths(g, 1, 6, by_weight = True))
|
976
976
|
[[1, 3, 5, 6], [1, 2, 5, 6], [1, 4, 5, 6], [1, 6]]
|
977
977
|
sage: list(feng_k_shortest_simple_paths(g, 1, 6))
|
978
|
-
[[1, 6], [1,
|
978
|
+
[[1, 6], [1, 2, 5, 6], [1, 3, 5, 6], [1, 4, 5, 6]]
|
979
979
|
sage: list(feng_k_shortest_simple_paths(g, 1, 6, report_edges=True, labels=True, by_weight=True, report_weight=True))
|
980
980
|
[(25, [(1, 3, 10), (3, 5, 10), (5, 6, 5)]),
|
981
981
|
(45, [(1, 2, 20), (2, 5, 20), (5, 6, 5)]),
|
@@ -983,9 +983,9 @@ def feng_k_shortest_simple_paths(self, source, target, weight_function=None,
|
|
983
983
|
(100, [(1, 6, 100)])]
|
984
984
|
sage: list(feng_k_shortest_simple_paths(g, 1, 6, report_edges=True, labels=True, report_weight=True))
|
985
985
|
[(1, [(1, 6, 100)]),
|
986
|
-
(3, [(1,
|
986
|
+
(3, [(1, 2, 20), (2, 5, 20), (5, 6, 5)]),
|
987
987
|
(3, [(1, 3, 10), (3, 5, 10), (5, 6, 5)]),
|
988
|
-
(3, [(1,
|
988
|
+
(3, [(1, 4, 30), (4, 5, 30), (5, 6, 5)])]
|
989
989
|
sage: from sage.graphs.path_enumeration import feng_k_shortest_simple_paths
|
990
990
|
sage: g = DiGraph([(1, 2, 5), (2, 3, 0), (1, 4, 2), (4, 5, 1), (5, 3, 0)])
|
991
991
|
sage: list(feng_k_shortest_simple_paths(g, 1, 3, by_weight=True))
|
@@ -1032,30 +1032,30 @@ def feng_k_shortest_simple_paths(self, source, target, weight_function=None,
|
|
1032
1032
|
(27, [(1, 2, 1), (2, 3, 1), (3, 8, 5), (8, 9, 2), (9, 11, 10), (11, 6, 8)]),
|
1033
1033
|
(105, [(1, 2, 1), (2, 3, 1), (3, 4, 1), (4, 5, 2), (5, 6, 100)])]
|
1034
1034
|
sage: list(feng_k_shortest_simple_paths(g, 1, 6))
|
1035
|
-
[[1, 2, 3,
|
1035
|
+
[[1, 2, 3, 4, 5, 6],
|
1036
1036
|
[1, 2, 3, 4, 7, 6],
|
1037
|
-
[1, 2, 3,
|
1038
|
-
[1, 2, 3, 8, 9,
|
1039
|
-
[1, 2, 3, 8, 9,
|
1037
|
+
[1, 2, 3, 8, 9, 6],
|
1038
|
+
[1, 2, 3, 8, 9, 11, 6],
|
1039
|
+
[1, 2, 3, 8, 9, 10, 6]]
|
1040
1040
|
sage: from sage.graphs.path_enumeration import feng_k_shortest_simple_paths
|
1041
1041
|
sage: g = DiGraph([(1, 2, 1), (2, 3, 1), (3, 4, 1), (4, 5, 1),
|
1042
1042
|
....: (1, 7, 1), (7, 8, 1), (8, 5, 1), (1, 6, 1),
|
1043
1043
|
....: (6, 9, 1), (9, 5, 1), (4, 2, 1), (9, 3, 1),
|
1044
1044
|
....: (9, 10, 1), (10, 5, 1), (9, 11, 1), (11, 10, 1)])
|
1045
1045
|
sage: list(feng_k_shortest_simple_paths(g, 1, 5))
|
1046
|
-
[[1,
|
1047
|
-
[1,
|
1048
|
-
[1, 6, 9, 10, 5],
|
1046
|
+
[[1, 6, 9, 5],
|
1047
|
+
[1, 7, 8, 5],
|
1049
1048
|
[1, 2, 3, 4, 5],
|
1050
|
-
[1, 6, 9, 3, 4, 5],
|
1051
|
-
[1, 6, 9, 11, 10, 5]]
|
1052
|
-
sage: list(feng_k_shortest_simple_paths(g, 1, 5, by_weight=True))
|
1053
|
-
[[1, 7, 8, 5],
|
1054
|
-
[1, 6, 9, 5],
|
1055
1049
|
[1, 6, 9, 10, 5],
|
1050
|
+
[1, 6, 9, 11, 10, 5],
|
1051
|
+
[1, 6, 9, 3, 4, 5]]
|
1052
|
+
sage: list(feng_k_shortest_simple_paths(g, 1, 5, by_weight=True))
|
1053
|
+
[[1, 6, 9, 5],
|
1054
|
+
[1, 7, 8, 5],
|
1056
1055
|
[1, 2, 3, 4, 5],
|
1057
|
-
[1, 6, 9,
|
1058
|
-
[1, 6, 9, 11, 10, 5]
|
1056
|
+
[1, 6, 9, 10, 5],
|
1057
|
+
[1, 6, 9, 11, 10, 5],
|
1058
|
+
[1, 6, 9, 3, 4, 5]]
|
1059
1059
|
sage: from sage.graphs.path_enumeration import feng_k_shortest_simple_paths
|
1060
1060
|
sage: g = DiGraph([(1, 2, 5), (6, 3, 0), (2, 6, 6), (1, 4, 15),
|
1061
1061
|
....: (4, 5, 1), (4, 3, 0), (7, 1, 2), (8, 7, 1)])
|
Binary file
|
Binary file
|