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.
Files changed (140) hide show
  1. {passagemath_graphs-10.5.10.dist-info → passagemath_graphs-10.5.43.dist-info}/METADATA +126 -30
  2. passagemath_graphs-10.5.43.dist-info/RECORD +256 -0
  3. {passagemath_graphs-10.5.10.dist-info → passagemath_graphs-10.5.43.dist-info}/WHEEL +2 -1
  4. passagemath_graphs.dylibs/libgmp.10.dylib +0 -0
  5. sage/all__sagemath_graphs.py +5 -0
  6. sage/combinat/abstract_tree.py +1 -1
  7. sage/combinat/binary_tree.py +1 -1
  8. sage/combinat/cluster_algebra_quiver/all.py +1 -1
  9. sage/combinat/cluster_algebra_quiver/cluster_seed.py +28 -24
  10. sage/combinat/cluster_algebra_quiver/interact.py +4 -0
  11. sage/combinat/designs/MOLS_handbook_data.py +5 -5
  12. sage/combinat/designs/bibd.py +10 -9
  13. sage/combinat/designs/covering_array.py +3 -3
  14. sage/combinat/designs/covering_design.py +2 -1
  15. sage/combinat/designs/database.py +11 -10
  16. sage/combinat/designs/designs_pyx.cpython-39-darwin.so +0 -0
  17. sage/combinat/designs/designs_pyx.pyx +13 -45
  18. sage/combinat/designs/difference_family.py +6 -6
  19. sage/combinat/designs/difference_matrices.py +1 -1
  20. sage/combinat/designs/evenly_distributed_sets.cpython-39-darwin.so +0 -0
  21. sage/combinat/designs/evenly_distributed_sets.pyx +15 -22
  22. sage/combinat/designs/ext_rep.py +9 -14
  23. sage/combinat/designs/gen_quadrangles_with_spread.cpython-39-darwin.so +0 -0
  24. sage/combinat/designs/gen_quadrangles_with_spread.pyx +1 -1
  25. sage/combinat/designs/group_divisible_designs.py +1 -1
  26. sage/combinat/designs/incidence_structures.py +8 -8
  27. sage/combinat/designs/latin_squares.py +1 -1
  28. sage/combinat/designs/orthogonal_arrays_build_recursive.py +8 -7
  29. sage/combinat/designs/orthogonal_arrays_find_recursive.cpython-39-darwin.so +0 -0
  30. sage/combinat/designs/resolvable_bibd.py +1 -1
  31. sage/combinat/designs/steiner_quadruple_systems.py +1 -1
  32. sage/combinat/designs/subhypergraph_search.cpython-39-darwin.so +0 -0
  33. sage/combinat/designs/subhypergraph_search.pyx +9 -9
  34. sage/combinat/finite_state_machine_generators.py +2 -2
  35. sage/combinat/graph_path.py +3 -3
  36. sage/combinat/interval_posets.py +10 -10
  37. sage/combinat/ordered_tree.py +1 -1
  38. sage/combinat/posets/cartesian_product.py +1 -1
  39. sage/combinat/posets/d_complete.py +1 -1
  40. sage/combinat/posets/forest.py +1 -1
  41. sage/combinat/posets/hasse_cython.cpython-39-darwin.so +0 -0
  42. sage/combinat/posets/hasse_diagram.py +8 -6
  43. sage/combinat/posets/incidence_algebras.py +8 -8
  44. sage/combinat/posets/lattices.py +28 -4
  45. sage/combinat/posets/linear_extension_iterator.cpython-39-darwin.so +0 -0
  46. sage/combinat/posets/linear_extension_iterator.pyx +2 -0
  47. sage/combinat/posets/linear_extensions.py +7 -16
  48. sage/combinat/posets/moebius_algebra.py +1 -1
  49. sage/combinat/posets/poset_examples.py +1 -1
  50. sage/combinat/posets/posets.py +54 -56
  51. sage/combinat/rooted_tree.py +3 -3
  52. sage/combinat/tamari_lattices.py +1 -1
  53. sage/ext_data/kenzo/CP2.txt +45 -0
  54. sage/ext_data/kenzo/CP3.txt +349 -0
  55. sage/ext_data/kenzo/CP4.txt +4774 -0
  56. sage/ext_data/kenzo/README.txt +49 -0
  57. sage/ext_data/kenzo/S4.txt +20 -0
  58. sage/graphs/asteroidal_triples.cpython-39-darwin.so +0 -0
  59. sage/graphs/base/boost_graph.cpython-39-darwin.so +0 -0
  60. sage/graphs/base/boost_graph.pxd +1 -1
  61. sage/graphs/base/boost_graph.pyx +1 -1
  62. sage/graphs/base/c_graph.cpython-39-darwin.so +0 -0
  63. sage/graphs/base/c_graph.pxd +4 -4
  64. sage/graphs/base/c_graph.pyx +270 -184
  65. sage/graphs/base/dense_graph.cpython-39-darwin.so +0 -0
  66. sage/graphs/base/graph_backends.cpython-39-darwin.so +0 -0
  67. sage/graphs/base/sparse_graph.cpython-39-darwin.so +0 -0
  68. sage/graphs/base/static_dense_graph.cpython-39-darwin.so +0 -0
  69. sage/graphs/base/static_sparse_backend.cpython-39-darwin.so +0 -0
  70. sage/graphs/base/static_sparse_backend.pyx +93 -6
  71. sage/graphs/base/static_sparse_graph.cpython-39-darwin.so +0 -0
  72. sage/graphs/base/static_sparse_graph.pyx +1 -1
  73. sage/graphs/bipartite_graph.py +0 -1
  74. sage/graphs/centrality.cpython-39-darwin.so +0 -0
  75. sage/graphs/centrality.pyx +0 -0
  76. sage/graphs/comparability.cpython-39-darwin.so +0 -0
  77. sage/graphs/comparability.pyx +172 -138
  78. sage/graphs/connectivity.cpython-39-darwin.so +0 -0
  79. sage/graphs/connectivity.pyx +194 -18
  80. sage/graphs/convexity_properties.cpython-39-darwin.so +0 -0
  81. sage/graphs/digraph_generators.py +118 -74
  82. sage/graphs/distances_all_pairs.cpython-39-darwin.so +0 -0
  83. sage/graphs/distances_all_pairs.pyx +145 -27
  84. sage/graphs/edge_connectivity.cpython-39-darwin.so +0 -0
  85. sage/graphs/generators/basic.py +471 -130
  86. sage/graphs/generators/distance_regular.cpython-39-darwin.so +0 -0
  87. sage/graphs/generators/distance_regular.pyx +12 -12
  88. sage/graphs/generators/families.py +2 -2
  89. sage/graphs/generators/random.py +8 -13
  90. sage/graphs/generators/smallgraphs.py +12 -11
  91. sage/graphs/generic_graph.py +687 -265
  92. sage/graphs/generic_graph_pyx.cpython-39-darwin.so +0 -0
  93. sage/graphs/genus.cpython-39-darwin.so +0 -0
  94. sage/graphs/graph.py +12 -46
  95. sage/graphs/graph_coloring.cpython-39-darwin.so +0 -0
  96. sage/graphs/graph_database.py +1 -1
  97. sage/graphs/graph_decompositions/bandwidth.cpython-39-darwin.so +0 -0
  98. sage/graphs/graph_decompositions/clique_separators.cpython-39-darwin.so +0 -0
  99. sage/graphs/graph_decompositions/cutwidth.cpython-39-darwin.so +0 -0
  100. sage/graphs/graph_decompositions/fast_digraph.cpython-39-darwin.so +0 -0
  101. sage/graphs/graph_decompositions/graph_products.cpython-39-darwin.so +0 -0
  102. sage/graphs/graph_decompositions/modular_decomposition.cpython-39-darwin.so +0 -0
  103. sage/graphs/graph_decompositions/slice_decomposition.cpython-39-darwin.so +0 -0
  104. sage/graphs/graph_decompositions/tree_decomposition.cpython-39-darwin.so +0 -0
  105. sage/graphs/graph_decompositions/vertex_separation.cpython-39-darwin.so +0 -0
  106. sage/graphs/graph_generators.py +110 -55
  107. sage/graphs/graph_generators_pyx.cpython-39-darwin.so +0 -0
  108. sage/graphs/graph_latex.py +1 -1
  109. sage/graphs/graph_list.py +2 -3
  110. sage/graphs/graph_plot.py +225 -30
  111. sage/graphs/hyperbolicity.cpython-39-darwin.so +0 -0
  112. sage/graphs/independent_sets.cpython-39-darwin.so +0 -0
  113. sage/graphs/isgci.py +3 -8
  114. sage/graphs/isoperimetric_inequalities.cpython-39-darwin.so +0 -0
  115. sage/graphs/line_graph.cpython-39-darwin.so +0 -0
  116. sage/graphs/matching.py +14 -25
  117. sage/graphs/matching_covered_graph.py +871 -60
  118. sage/graphs/orientations.py +190 -134
  119. sage/graphs/path_enumeration.cpython-39-darwin.so +0 -0
  120. sage/graphs/path_enumeration.pyx +25 -25
  121. sage/graphs/spanning_tree.cpython-39-darwin.so +0 -0
  122. sage/graphs/strongly_regular_db.cpython-39-darwin.so +0 -0
  123. sage/graphs/strongly_regular_db.pyx +54 -52
  124. sage/graphs/traversals.cpython-39-darwin.so +0 -0
  125. sage/graphs/traversals.pyx +114 -46
  126. sage/graphs/trees.cpython-39-darwin.so +0 -0
  127. sage/graphs/views.cpython-39-darwin.so +0 -0
  128. sage/graphs/weakly_chordal.cpython-39-darwin.so +0 -0
  129. sage/groups/perm_gps/partn_ref/refinement_graphs.cpython-39-darwin.so +0 -0
  130. sage/knots/free_knotinfo_monoid.py +2 -3
  131. sage/knots/knot.py +1 -1
  132. sage/knots/knotinfo.py +4 -4
  133. sage/knots/link.py +58 -57
  134. sage/sandpiles/sandpile.py +2 -3
  135. sage/topology/cell_complex.py +1 -1
  136. sage/topology/cubical_complex.py +7 -7
  137. sage/topology/delta_complex.py +4 -4
  138. sage/topology/simplicial_complex.py +7 -22
  139. passagemath_graphs-10.5.10.dist-info/RECORD +0 -251
  140. {passagemath_graphs-10.5.10.dist-info → passagemath_graphs-10.5.43.dist-info}/top_level.txt +0 -0
@@ -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(G)` | Return a DiGraph which is an Eulerian orientation of the graph `G`.
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
- D = DiGraph([G, edges], format='vertices_and_edges',
204
- data_structure=data_structure,
205
- loops=G.allows_loops(),
206
- multiedges=G.allows_multiple_edges(),
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 specify both 'sparse' and 'data_structure'
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
- D = DiGraph(data=[G, []],
361
- format='vertices_and_edges',
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
- D = DiGraph(data=[G, edges],
377
- format='vertices_and_edges',
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
- D = DiGraph([(u, v) if label else (v, u) for (u, v), label in orientation.items()])
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
- d = DiGraph(multiedges=G.allows_multiple_edges())
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
- return D
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
- # All the edges from G are doubled in O ( one in each direction )
1158
- O = DiGraph(G)
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
- for u in [x for x in range(n) if x in flow]:
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 a DiGraph which is an Eulerian orientation of the graph `G`.
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 = DiGraph([G, []], format='vertices_and_edges')
1463
+ d = _initialize_digraph(G, [], sparse=True, immutable=False)
1408
1464
 
1409
1465
  if not G.size():
1410
1466
  return d
@@ -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, 4), (4, 5)]), (2, [(1, 3), (3, 5)]), (2, [(1, 2), (2, 5)])]
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, 7, 8, 5],
437
- [1, 6, 9, 5],
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, 3, 4, 5],
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, 4, 5], [1, 3, 5], [1, 2, 5]]
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, 4, 30), (4, 5, 30)], [(1, 3, 10), (3, 5, 10)], [(1, 2, 20), (2, 5, 20)]]
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, 4, 5, 6], [1, 3, 5, 6], [1, 2, 5, 6]]
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, 4, 30), (4, 5, 30), (5, 6, 5)]),
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, 2, 20), (2, 5, 20), (5, 6, 5)])]
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, 8, 9, 6],
1035
+ [[1, 2, 3, 4, 5, 6],
1036
1036
  [1, 2, 3, 4, 7, 6],
1037
- [1, 2, 3, 4, 5, 6],
1038
- [1, 2, 3, 8, 9, 10, 6],
1039
- [1, 2, 3, 8, 9, 11, 6]]
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, 7, 8, 5],
1047
- [1, 6, 9, 5],
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, 3, 4, 5],
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)])