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
sage/graphs/views.pyx
ADDED
@@ -0,0 +1,794 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-graphs
|
2
|
+
r"""
|
3
|
+
View classes
|
4
|
+
|
5
|
+
This module implements views for (di)graphs. A view is a read-only iterable
|
6
|
+
container enabling operations like ``for e in E`` and ``e in E``. It is updated
|
7
|
+
as the graph is updated. Hence, the graph should not be updated while iterating
|
8
|
+
through a view. Views can be iterated multiple times.
|
9
|
+
|
10
|
+
.. TODO::
|
11
|
+
|
12
|
+
- View of neighborhood to get open/close neighborhood of a vertex/set of
|
13
|
+
vertices
|
14
|
+
|
15
|
+
Classes
|
16
|
+
-------
|
17
|
+
"""
|
18
|
+
# ****************************************************************************
|
19
|
+
# Copyright (C) 2019 David Coudert <david.coudert@inria.fr>
|
20
|
+
#
|
21
|
+
# This program is free software: you can redistribute it and/or modify
|
22
|
+
# it under the terms of the GNU General Public License as published by
|
23
|
+
# the Free Software Foundation, either version 2 of the License, or
|
24
|
+
# (at your option) any later version.
|
25
|
+
# https://www.gnu.org/licenses/
|
26
|
+
# ****************************************************************************
|
27
|
+
|
28
|
+
|
29
|
+
from itertools import islice
|
30
|
+
from sys import maxsize as sys_maxsize
|
31
|
+
from sage.graphs.generic_graph_pyx cimport GenericGraph_pyx
|
32
|
+
|
33
|
+
cdef class EdgesView:
|
34
|
+
r"""
|
35
|
+
EdgesView class.
|
36
|
+
|
37
|
+
This class implements a read-only iterable container of edges enabling
|
38
|
+
operations like ``for e in E`` and ``e in E``. An :class:`EdgesView` can be
|
39
|
+
iterated multiple times, and checking membership is done in constant
|
40
|
+
time. It avoids the construction of edge lists and so consumes little
|
41
|
+
memory. It is updated as the graph is updated. Hence, the graph should not
|
42
|
+
be updated while iterating through an :class:`EdgesView`.
|
43
|
+
|
44
|
+
INPUT:
|
45
|
+
|
46
|
+
- ``G`` -- a (di)graph
|
47
|
+
|
48
|
+
- ``vertices`` -- list (default: ``None``); an iterable container of
|
49
|
+
vertices or ``None``. When set, consider only edges incident to specified
|
50
|
+
vertices.
|
51
|
+
|
52
|
+
- ``vertices2`` -- list (default: ``None``); an iterable container of
|
53
|
+
vertices or ``None``. When set, consider only edges incident to specified
|
54
|
+
vertices. More precisely:
|
55
|
+
|
56
|
+
- When both ``vertices`` and ``vertices2`` are set, consider only edges
|
57
|
+
``(u, v, l)`` with ``u`` in ``vertices`` and ``v`` in ``vertices2``.
|
58
|
+
|
59
|
+
- When ``vertices`` is ``None`` and ``vertices2`` is set, consider only
|
60
|
+
edges ``(u, v, l)`` with ``v`` in ``vertices2``.
|
61
|
+
|
62
|
+
- ``labels`` -- boolean (default: ``True``); if ``False``, each edge is
|
63
|
+
simply a pair ``(u, v)`` of vertices
|
64
|
+
|
65
|
+
- ``ignore_direction`` -- boolean (default: ``False``); only applies to
|
66
|
+
directed graphs. If ``True``, searches across edges in either direction.
|
67
|
+
|
68
|
+
- ``sort`` -- boolean (default: ``False``); whether to sort edges according
|
69
|
+
the ordering specified with parameter ``key``. If ``False`` (default),
|
70
|
+
edges are not sorted. This is the fastest and less memory consuming method
|
71
|
+
for iterating over edges.
|
72
|
+
|
73
|
+
- ``key`` -- a function (default: ``None``); a function that takes an edge
|
74
|
+
(a pair or a triple, according to the ``labels`` keyword) as its one
|
75
|
+
argument and returns a value that can be used for comparisons in the
|
76
|
+
sorting algorithm. This parameter is ignored when ``sort = False``.
|
77
|
+
|
78
|
+
- ``sort_vertices`` -- boolean (default: ``True``); whether to sort the
|
79
|
+
ends of the edges; not sorting the ends is faster;
|
80
|
+
only applicable to undirected graphs when ``sort`` is ``False``
|
81
|
+
|
82
|
+
.. WARNING::
|
83
|
+
|
84
|
+
Since any object may be a vertex, there is no guarantee that any two
|
85
|
+
vertices will be comparable, and thus no guarantee how two edges may
|
86
|
+
compare. With default objects for vertices (all integers), or when all
|
87
|
+
the vertices are of the same simple type, then there should not be a
|
88
|
+
problem with how the vertices will be sorted. However, if you need to
|
89
|
+
guarantee a total order for the sorting of the edges, use the ``key``
|
90
|
+
argument, as illustrated in the examples below.
|
91
|
+
|
92
|
+
EXAMPLES::
|
93
|
+
|
94
|
+
sage: from sage.graphs.views import EdgesView
|
95
|
+
sage: G = Graph([(0, 1, 'C'), (0, 2, 'A'), (1, 2, 'B')])
|
96
|
+
sage: E = EdgesView(G, sort=True); E
|
97
|
+
[(0, 1, 'C'), (0, 2, 'A'), (1, 2, 'B')]
|
98
|
+
sage: (1, 2) in E
|
99
|
+
False
|
100
|
+
sage: (1, 2, 'B') in E
|
101
|
+
True
|
102
|
+
sage: E = EdgesView(G, labels=False, sort=True); E
|
103
|
+
[(0, 1), (0, 2), (1, 2)]
|
104
|
+
sage: (1, 2) in E
|
105
|
+
True
|
106
|
+
sage: (1, 2, 'B') in E
|
107
|
+
False
|
108
|
+
sage: [e for e in E]
|
109
|
+
[(0, 1), (0, 2), (1, 2)]
|
110
|
+
|
111
|
+
An :class:`EdgesView` can be iterated multiple times::
|
112
|
+
|
113
|
+
sage: G = graphs.CycleGraph(3)
|
114
|
+
sage: print(E)
|
115
|
+
[(0, 1), (0, 2), (1, 2)]
|
116
|
+
sage: print(E)
|
117
|
+
[(0, 1), (0, 2), (1, 2)]
|
118
|
+
sage: for e in E:
|
119
|
+
....: for ee in E:
|
120
|
+
....: print((e, ee))
|
121
|
+
((0, 1), (0, 1))
|
122
|
+
((0, 1), (0, 2))
|
123
|
+
((0, 1), (1, 2))
|
124
|
+
((0, 2), (0, 1))
|
125
|
+
((0, 2), (0, 2))
|
126
|
+
((0, 2), (1, 2))
|
127
|
+
((1, 2), (0, 1))
|
128
|
+
((1, 2), (0, 2))
|
129
|
+
((1, 2), (1, 2))
|
130
|
+
|
131
|
+
We can check if a view is empty::
|
132
|
+
|
133
|
+
sage: E = EdgesView(graphs.CycleGraph(3), sort=False)
|
134
|
+
sage: if E:
|
135
|
+
....: print('not empty')
|
136
|
+
not empty
|
137
|
+
sage: E = EdgesView(Graph(), sort=False)
|
138
|
+
sage: if not E:
|
139
|
+
....: print('empty')
|
140
|
+
empty
|
141
|
+
|
142
|
+
When ``sort`` is ``True``, edges are sorted by default in the default
|
143
|
+
fashion::
|
144
|
+
|
145
|
+
sage: G = Graph([(0, 1, 'C'), (0, 2, 'A'), (1, 2, 'B')])
|
146
|
+
sage: E = EdgesView(G, sort=True); E
|
147
|
+
[(0, 1, 'C'), (0, 2, 'A'), (1, 2, 'B')]
|
148
|
+
|
149
|
+
This can be overridden by specifying a key function. This first example just
|
150
|
+
ignores the labels in the third component of the triple::
|
151
|
+
|
152
|
+
sage: G = Graph([(0, 1, 'C'), (0, 2, 'A'), (1, 2, 'B')])
|
153
|
+
sage: E = EdgesView(G, sort=True, key=lambda x: (x[1], -x[0])); E
|
154
|
+
[(0, 1, 'C'), (1, 2, 'B'), (0, 2, 'A')]
|
155
|
+
|
156
|
+
We can also sort according to the labels::
|
157
|
+
|
158
|
+
sage: G = Graph([(0, 1, 'C'), (0, 2, 'A'), (1, 2, 'B')])
|
159
|
+
sage: E = EdgesView(G, sort=True, key=lambda x: x[2]); E
|
160
|
+
[(0, 2, 'A'), (1, 2, 'B'), (0, 1, 'C')]
|
161
|
+
|
162
|
+
Not sorting the ends of the vertices::
|
163
|
+
|
164
|
+
sage: G = Graph()
|
165
|
+
sage: G.add_edges([[1,2], [2,3], [0,3]])
|
166
|
+
sage: E = EdgesView(G, sort=False, sort_vertices=False); E
|
167
|
+
[(3, 0, None), (2, 1, None), (3, 2, None)]
|
168
|
+
|
169
|
+
With a directed graph::
|
170
|
+
|
171
|
+
sage: G = digraphs.DeBruijn(2, 2) # needs sage.combinat
|
172
|
+
sage: E = EdgesView(G, labels=False, sort=True); E # needs sage.combinat
|
173
|
+
[('00', '00'), ('00', '01'), ('01', '10'), ('01', '11'),
|
174
|
+
('10', '00'), ('10', '01'), ('11', '10'), ('11', '11')]
|
175
|
+
sage: E = EdgesView(G, labels=False, sort=True, key=lambda e:(e[1], e[0])); E # needs sage.combinat
|
176
|
+
[('00', '00'), ('10', '00'), ('00', '01'), ('10', '01'),
|
177
|
+
('01', '10'), ('11', '10'), ('01', '11'), ('11', '11')]
|
178
|
+
|
179
|
+
We can consider only edges incident to a specified set of vertices::
|
180
|
+
|
181
|
+
sage: G = graphs.CycleGraph(5)
|
182
|
+
sage: E = EdgesView(G, vertices=[0, 1], labels=False, sort=True); E
|
183
|
+
[(0, 1), (0, 4), (1, 2)]
|
184
|
+
sage: E = EdgesView(G, vertices=[0], labels=False, sort=True); E
|
185
|
+
[(0, 1), (0, 4)]
|
186
|
+
sage: E = EdgesView(G, vertices=None, labels=False, sort=True); E
|
187
|
+
[(0, 1), (0, 4), (1, 2), (2, 3), (3, 4)]
|
188
|
+
|
189
|
+
sage: G = digraphs.Circuit(5)
|
190
|
+
sage: E = EdgesView(G, vertices=[0, 1], labels=False, sort=True); E
|
191
|
+
[(0, 1), (1, 2)]
|
192
|
+
|
193
|
+
We can ignore the direction of the edges of a directed graph, in which case
|
194
|
+
we search across edges in either direction::
|
195
|
+
|
196
|
+
sage: G = digraphs.Circuit(5)
|
197
|
+
sage: E = EdgesView(G, vertices=[0, 1], labels=False, sort=True, ignore_direction=False); E
|
198
|
+
[(0, 1), (1, 2)]
|
199
|
+
sage: (1, 0) in E
|
200
|
+
False
|
201
|
+
sage: E = EdgesView(G, vertices=[0, 1], labels=False, sort=True, ignore_direction=True); E
|
202
|
+
[(0, 1), (0, 1), (1, 2), (4, 0)]
|
203
|
+
sage: (1, 0) in E
|
204
|
+
True
|
205
|
+
sage: G.has_edge(1, 0)
|
206
|
+
False
|
207
|
+
|
208
|
+
We can consider only the edges between two specified sets of vertices::
|
209
|
+
|
210
|
+
sage: G = Graph([(0, 1), (1, 2)])
|
211
|
+
sage: E = EdgesView(G, vertices=[0], vertices2=[1], labels=False)
|
212
|
+
sage: (0, 1) in E and (1, 2) not in E
|
213
|
+
True
|
214
|
+
sage: E = EdgesView(G, vertices=[0], labels=False)
|
215
|
+
sage: (0, 1) in E and (1, 2) not in E
|
216
|
+
True
|
217
|
+
sage: E = EdgesView(G, vertices2=[1], labels=False)
|
218
|
+
sage: (0, 1) in E and (1, 2) in E
|
219
|
+
True
|
220
|
+
sage: D = DiGraph([(0, 1), (1, 2)])
|
221
|
+
sage: E = EdgesView(D, vertices=[0], vertices2=[1], labels=False)
|
222
|
+
sage: (0, 1) in E and (1, 2) not in E
|
223
|
+
True
|
224
|
+
sage: EdgesView(D, vertices=[1], vertices2=[0], labels=False)
|
225
|
+
[]
|
226
|
+
sage: E = EdgesView(D, vertices=[1], vertices2=[0], labels=False, ignore_direction=True)
|
227
|
+
sage: (0, 1) in E and (1, 2) not in E
|
228
|
+
True
|
229
|
+
sage: E = EdgesView(D, vertices=[0], labels=False)
|
230
|
+
sage: (0, 1) in E and (1, 2) not in E
|
231
|
+
True
|
232
|
+
sage: E = EdgesView(D, vertices2=[1], labels=False)
|
233
|
+
sage: (0, 1) in E and (1, 2) not in E
|
234
|
+
True
|
235
|
+
sage: E = EdgesView(D, vertices2=[1], labels=False, ignore_direction=True)
|
236
|
+
sage: (0, 1) in E and (1, 2) in E
|
237
|
+
True
|
238
|
+
|
239
|
+
A view is updated as the graph is updated::
|
240
|
+
|
241
|
+
sage: G = Graph()
|
242
|
+
sage: E = EdgesView(G, vertices=[0, 3], labels=False, sort=True); E
|
243
|
+
[]
|
244
|
+
sage: G.add_edges([(0, 1), (1, 2)])
|
245
|
+
sage: E
|
246
|
+
[(0, 1)]
|
247
|
+
sage: G.add_edge(2, 3)
|
248
|
+
sage: E
|
249
|
+
[(0, 1), (2, 3)]
|
250
|
+
|
251
|
+
Hence, the graph should not be updated while iterating through a view::
|
252
|
+
|
253
|
+
sage: G = Graph([('a', 'b'), ('b', 'c')])
|
254
|
+
sage: E = EdgesView(G, labels=False, sort=False); E
|
255
|
+
[('a', 'b'), ('b', 'c')]
|
256
|
+
sage: for u, v in E:
|
257
|
+
....: G.add_edge(u + u, v + v)
|
258
|
+
Traceback (most recent call last):
|
259
|
+
...
|
260
|
+
RuntimeError: dictionary changed size during iteration
|
261
|
+
|
262
|
+
Two :class:`EdgesView` are considered equal if they report either both
|
263
|
+
directed, or both undirected edges, they have the same settings for
|
264
|
+
``ignore_direction``, they have the same settings for ``labels``, and they
|
265
|
+
report the same edges in the same order::
|
266
|
+
|
267
|
+
sage: G = graphs.HouseGraph()
|
268
|
+
sage: EG = EdgesView(G, sort=False)
|
269
|
+
sage: H = Graph(EG)
|
270
|
+
sage: EH = EdgesView(H, sort=False)
|
271
|
+
sage: EG == EH
|
272
|
+
True
|
273
|
+
sage: G.add_edge(0, 10)
|
274
|
+
sage: EG = EdgesView(G, sort=False)
|
275
|
+
sage: EG == EH
|
276
|
+
False
|
277
|
+
sage: H.add_edge(0, 10)
|
278
|
+
sage: EH = EdgesView(H, sort=False)
|
279
|
+
sage: EG == EH
|
280
|
+
True
|
281
|
+
sage: H = G.strong_orientation()
|
282
|
+
sage: EH = EdgesView(H, sort=False)
|
283
|
+
sage: EG == EH
|
284
|
+
False
|
285
|
+
|
286
|
+
The sum of two :class:`EdgesView` is a list containing the edges in both
|
287
|
+
:class:`EdgesView`::
|
288
|
+
|
289
|
+
sage: E1 = EdgesView(Graph([(0, 1)]), labels=False, sort=False)
|
290
|
+
sage: E2 = EdgesView(Graph([(2, 3)]), labels=False, sort=False)
|
291
|
+
sage: E1 + E2
|
292
|
+
[(0, 1), (2, 3)]
|
293
|
+
sage: E2 + E1
|
294
|
+
[(2, 3), (0, 1)]
|
295
|
+
|
296
|
+
Recall that a :class:`EdgesView` is read-only and that this method
|
297
|
+
returns a list::
|
298
|
+
|
299
|
+
sage: E1 += E2
|
300
|
+
sage: type(E1) is list
|
301
|
+
True
|
302
|
+
|
303
|
+
It is also possible to get the sum a :class:`EdgesView` with itself `n`
|
304
|
+
times::
|
305
|
+
|
306
|
+
sage: E = EdgesView(Graph([(0, 1), (2, 3)]), labels=False, sort=True)
|
307
|
+
sage: E * 3
|
308
|
+
[(0, 1), (2, 3), (0, 1), (2, 3), (0, 1), (2, 3)]
|
309
|
+
sage: 3 * E
|
310
|
+
[(0, 1), (2, 3), (0, 1), (2, 3), (0, 1), (2, 3)]
|
311
|
+
|
312
|
+
Recall that a :class:`EdgesView` is read-only and that this method
|
313
|
+
returns a list::
|
314
|
+
|
315
|
+
sage: E *= 2
|
316
|
+
sage: type(E) is list
|
317
|
+
True
|
318
|
+
|
319
|
+
We can ask for the `i`-th edge, or a slice of the edges as a list::
|
320
|
+
|
321
|
+
sage: E = EdgesView(graphs.HouseGraph(), labels=False, sort=True)
|
322
|
+
sage: E[0]
|
323
|
+
(0, 1)
|
324
|
+
sage: E[2]
|
325
|
+
(1, 3)
|
326
|
+
sage: E[-1]
|
327
|
+
(3, 4)
|
328
|
+
sage: E[1:-1]
|
329
|
+
[(0, 2), (1, 3), (2, 3), (2, 4)]
|
330
|
+
sage: E[::-1]
|
331
|
+
[(3, 4), (2, 4), (2, 3), (1, 3), (0, 2), (0, 1)]
|
332
|
+
"""
|
333
|
+
cdef readonly GenericGraph_pyx _graph
|
334
|
+
cdef list _vertices
|
335
|
+
cdef frozenset _vertex_set
|
336
|
+
cdef list _vertices2
|
337
|
+
cdef frozenset _vertex_set2
|
338
|
+
cdef readonly bint _labels
|
339
|
+
cdef readonly bint _ignore_direction
|
340
|
+
cdef bint _sort_vertices
|
341
|
+
cdef bint _sort_edges
|
342
|
+
cdef _sort_edges_key
|
343
|
+
|
344
|
+
def __init__(self, G, vertices=None, vertices2=None, labels=True,
|
345
|
+
ignore_direction=False,
|
346
|
+
sort=False, key=None, sort_vertices=True):
|
347
|
+
"""
|
348
|
+
Construction of this :class:`EdgesView`.
|
349
|
+
|
350
|
+
EXAMPLES::
|
351
|
+
|
352
|
+
sage: from sage.graphs.views import EdgesView
|
353
|
+
sage: G = Graph([(0, 1, 'C'), (0, 2, 'A'), (1, 2, 'B')])
|
354
|
+
sage: E = EdgesView(G, sort=True); E
|
355
|
+
[(0, 1, 'C'), (0, 2, 'A'), (1, 2, 'B')]
|
356
|
+
|
357
|
+
TESTS::
|
358
|
+
|
359
|
+
sage: EdgesView(Graph(), sort=False, key=lambda x:0)
|
360
|
+
Traceback (most recent call last):
|
361
|
+
...
|
362
|
+
ValueError: sort keyword is not True, yet a key function is given
|
363
|
+
"""
|
364
|
+
self._graph = <GenericGraph_pyx?> G
|
365
|
+
|
366
|
+
if vertices is None:
|
367
|
+
self._vertices = None
|
368
|
+
self._vertex_set = None
|
369
|
+
else:
|
370
|
+
self._vertices = list(vertices)
|
371
|
+
self._vertex_set = frozenset(self._vertices)
|
372
|
+
|
373
|
+
if vertices2 is None:
|
374
|
+
self._vertices2 = None
|
375
|
+
self._vertex_set2 = None
|
376
|
+
else:
|
377
|
+
self._vertices2 = list(vertices2)
|
378
|
+
self._vertex_set2 = frozenset(self._vertices2)
|
379
|
+
|
380
|
+
# None and 0 are interpreted as False, 1 as True
|
381
|
+
self._labels = labels
|
382
|
+
self._ignore_direction = ignore_direction
|
383
|
+
self._sort_edges = sort
|
384
|
+
if not sort and key is not None:
|
385
|
+
raise ValueError('sort keyword is not True, yet a key function is given')
|
386
|
+
self._sort_edges_key = key
|
387
|
+
self._sort_vertices = sort_vertices
|
388
|
+
|
389
|
+
def __len__(self):
|
390
|
+
"""
|
391
|
+
Return the number of edges in ``self``.
|
392
|
+
|
393
|
+
EXAMPLES::
|
394
|
+
|
395
|
+
sage: from sage.graphs.views import EdgesView
|
396
|
+
sage: G = graphs.HouseGraph()
|
397
|
+
sage: E = EdgesView(G)
|
398
|
+
sage: len(E)
|
399
|
+
6
|
400
|
+
sage: len(E) == G.size()
|
401
|
+
True
|
402
|
+
sage: E = EdgesView(G, vertices=[0], labels=False, sort=True); E
|
403
|
+
[(0, 1), (0, 2)]
|
404
|
+
sage: len(E)
|
405
|
+
2
|
406
|
+
sage: G = digraphs.Circuit(4)
|
407
|
+
sage: len(EdgesView(G, ignore_direction=False, sort=False))
|
408
|
+
4
|
409
|
+
sage: len(EdgesView(G, ignore_direction=True, sort=False))
|
410
|
+
8
|
411
|
+
"""
|
412
|
+
if self._vertices is None and self._vertices2 is None:
|
413
|
+
if self._graph._directed and self._ignore_direction:
|
414
|
+
return 2 * self._graph.size()
|
415
|
+
return self._graph.size()
|
416
|
+
return sum(1 for _ in self)
|
417
|
+
|
418
|
+
def __repr__(self):
|
419
|
+
"""
|
420
|
+
Return a string representation of ``self``.
|
421
|
+
|
422
|
+
EXAMPLES::
|
423
|
+
|
424
|
+
sage: from sage.graphs.views import EdgesView
|
425
|
+
sage: G = graphs.HouseGraph()
|
426
|
+
sage: E = EdgesView(G, labels=False)
|
427
|
+
sage: repr(E)
|
428
|
+
'[(0, 1), (0, 2), (1, 3), (2, 3), (2, 4), (3, 4)]'
|
429
|
+
sage: E
|
430
|
+
[(0, 1), (0, 2), (1, 3), (2, 3), (2, 4), (3, 4)]
|
431
|
+
"""
|
432
|
+
return "[%s]" % ', '.join(map(repr, self))
|
433
|
+
|
434
|
+
def _iter_unsorted(self):
|
435
|
+
"""
|
436
|
+
Iterator over the unsorted edges in ``self``.
|
437
|
+
|
438
|
+
EXAMPLES::
|
439
|
+
|
440
|
+
sage: from sage.graphs.views import EdgesView
|
441
|
+
sage: G = graphs.HouseGraph()
|
442
|
+
sage: E = EdgesView(G, labels=False, sort=False)
|
443
|
+
sage: list(E)
|
444
|
+
[(0, 1), (0, 2), (1, 3), (2, 3), (2, 4), (3, 4)]
|
445
|
+
"""
|
446
|
+
if self._vertices is None:
|
447
|
+
vertices = self._graph
|
448
|
+
vertex_set = self._graph
|
449
|
+
else:
|
450
|
+
vertices = self._vertices
|
451
|
+
vertex_set = self._vertex_set
|
452
|
+
|
453
|
+
if self._vertices2 is None:
|
454
|
+
if self._graph._directed:
|
455
|
+
yield from self._graph._backend.iterator_out_edges(vertices, self._labels)
|
456
|
+
if self._ignore_direction:
|
457
|
+
yield from self._graph._backend.iterator_in_edges(vertices, self._labels)
|
458
|
+
elif self._sort_vertices:
|
459
|
+
yield from self._graph._backend.iterator_edges(vertices, self._labels)
|
460
|
+
else:
|
461
|
+
yield from self._graph._backend.iterator_unsorted_edges(vertices, self._labels)
|
462
|
+
elif self._graph._directed:
|
463
|
+
for e in self._graph._backend.iterator_out_edges(vertices, self._labels):
|
464
|
+
if e[1] in self._vertex_set2:
|
465
|
+
yield e
|
466
|
+
if self._ignore_direction:
|
467
|
+
for e in self._graph._backend.iterator_in_edges(vertices, self._labels):
|
468
|
+
if e[0] in self._vertex_set2:
|
469
|
+
yield e
|
470
|
+
elif self._sort_vertices:
|
471
|
+
for e in self._graph._backend.iterator_edges(vertices, self._labels):
|
472
|
+
if ((e[0] in vertex_set and e[1] in self._vertex_set2) or
|
473
|
+
(e[1] in vertex_set and e[0] in self._vertex_set2)):
|
474
|
+
yield e
|
475
|
+
else:
|
476
|
+
for e in self._graph._backend.iterator_unsorted_edges(vertices, self._labels):
|
477
|
+
if ((e[0] in vertex_set and e[1] in self._vertex_set2) or
|
478
|
+
(e[1] in vertex_set and e[0] in self._vertex_set2)):
|
479
|
+
yield e
|
480
|
+
|
481
|
+
def __iter__(self):
|
482
|
+
"""
|
483
|
+
Iterator over the edges in ``self``.
|
484
|
+
|
485
|
+
EXAMPLES::
|
486
|
+
|
487
|
+
sage: from sage.graphs.views import EdgesView
|
488
|
+
sage: G = graphs.HouseGraph()
|
489
|
+
sage: E = EdgesView(G, labels=False, sort=True)
|
490
|
+
sage: list(E)
|
491
|
+
[(0, 1), (0, 2), (1, 3), (2, 3), (2, 4), (3, 4)]
|
492
|
+
sage: sum(1 for e in E for ee in E) == len(E) * len(E)
|
493
|
+
True
|
494
|
+
sage: E = EdgesView(G, labels=False)
|
495
|
+
sage: sum(1 for e in E for ee in E) == G.size() * G.size()
|
496
|
+
True
|
497
|
+
"""
|
498
|
+
if self._sort_edges:
|
499
|
+
yield from sorted(self._iter_unsorted(), key=self._sort_edges_key)
|
500
|
+
else:
|
501
|
+
yield from self._iter_unsorted()
|
502
|
+
|
503
|
+
def __bool__(self):
|
504
|
+
"""
|
505
|
+
Check whether ``self`` is not empty.
|
506
|
+
|
507
|
+
EXAMPLES::
|
508
|
+
|
509
|
+
sage: from sage.graphs.views import EdgesView
|
510
|
+
sage: E = EdgesView(Graph())
|
511
|
+
sage: bool(E)
|
512
|
+
False
|
513
|
+
sage: E = EdgesView(graphs.HouseGraph())
|
514
|
+
sage: bool(E)
|
515
|
+
True
|
516
|
+
"""
|
517
|
+
for _ in self._iter_unsorted():
|
518
|
+
return True
|
519
|
+
return False
|
520
|
+
|
521
|
+
def __eq__(self, right):
|
522
|
+
"""
|
523
|
+
Check whether ``self`` and ``right`` are equal.
|
524
|
+
|
525
|
+
Do not call this method directly. That is, for ``E1.__eq__(E2)`` write
|
526
|
+
``E1 == E2``.
|
527
|
+
|
528
|
+
Two :class:`EdgesView` are considered equal if the following hold:
|
529
|
+
- they report either both directed, or both undirected edges;
|
530
|
+
- they have the same settings for ``ignore_direction``;
|
531
|
+
- they have the same settings for ``labels``;
|
532
|
+
- they report the same edges in the same order.
|
533
|
+
|
534
|
+
EXAMPLES::
|
535
|
+
|
536
|
+
sage: from sage.graphs.views import EdgesView
|
537
|
+
sage: G = graphs.HouseGraph()
|
538
|
+
sage: EG = EdgesView(G)
|
539
|
+
sage: H = Graph(EG)
|
540
|
+
sage: EH = EdgesView(H)
|
541
|
+
sage: EG == EH
|
542
|
+
True
|
543
|
+
sage: G.add_edge(0, 10)
|
544
|
+
sage: EG = EdgesView(G)
|
545
|
+
sage: EG == EH
|
546
|
+
False
|
547
|
+
sage: H.add_edge(0, 10)
|
548
|
+
sage: EH = EdgesView(H)
|
549
|
+
sage: EG == EH
|
550
|
+
True
|
551
|
+
sage: H = G.strong_orientation()
|
552
|
+
sage: EH = EdgesView(H)
|
553
|
+
sage: EG == EH
|
554
|
+
False
|
555
|
+
|
556
|
+
TESTS::
|
557
|
+
|
558
|
+
sage: from sage.graphs.views import EdgesView
|
559
|
+
sage: G = graphs.HouseGraph()
|
560
|
+
sage: E = EdgesView(G)
|
561
|
+
sage: E == E
|
562
|
+
True
|
563
|
+
sage: E == G
|
564
|
+
False
|
565
|
+
sage: G == E
|
566
|
+
False
|
567
|
+
|
568
|
+
Check that :issue:`29180` is fixed::
|
569
|
+
|
570
|
+
sage: G = graphs.CycleGraph(4)
|
571
|
+
sage: E = graphs.EmptyGraph()
|
572
|
+
sage: G.edges(sort=True) == E.edges(sort=True)
|
573
|
+
False
|
574
|
+
"""
|
575
|
+
if not isinstance(right, EdgesView):
|
576
|
+
return NotImplemented
|
577
|
+
cdef EdgesView other = <EdgesView> right
|
578
|
+
if self is other:
|
579
|
+
return True
|
580
|
+
# Check parameters
|
581
|
+
if (self._graph._directed != other._graph._directed
|
582
|
+
or self._ignore_direction != other._ignore_direction
|
583
|
+
or self._labels != other._labels):
|
584
|
+
return False
|
585
|
+
# Check that self and other have the same number of edges
|
586
|
+
if len(self) != len(other):
|
587
|
+
return False
|
588
|
+
# Check that the same edges are reported in the same order
|
589
|
+
return all(es == eo for es, eo in zip(self, other))
|
590
|
+
|
591
|
+
def __contains__(self, e):
|
592
|
+
"""
|
593
|
+
Check whether edge ``e`` is part of ``self``.
|
594
|
+
|
595
|
+
INPUT:
|
596
|
+
|
597
|
+
- ``e`` -- tuple; when ``self.labels`` is ``True``, the expected form is
|
598
|
+
``(u, v, label)``, while when ``self.labels`` is ``False``, the
|
599
|
+
expected form is ``(u, v)``
|
600
|
+
|
601
|
+
EXAMPLES::
|
602
|
+
|
603
|
+
sage: from sage.graphs.views import EdgesView
|
604
|
+
sage: G = Graph([(0, 1)])
|
605
|
+
sage: E = EdgesView(G, labels=False)
|
606
|
+
sage: print(E)
|
607
|
+
[(0, 1)]
|
608
|
+
sage: (0, 1) in E
|
609
|
+
True
|
610
|
+
sage: (0, 1, None) in E
|
611
|
+
False
|
612
|
+
sage: E = EdgesView(G, labels=True)
|
613
|
+
sage: print(E)
|
614
|
+
[(0, 1, None)]
|
615
|
+
sage: (0, 1) in E
|
616
|
+
False
|
617
|
+
sage: (0, 1, None) in E
|
618
|
+
True
|
619
|
+
sage: G = Graph([(0, 1), (1, 2)])
|
620
|
+
sage: E = EdgesView(G, vertices=[0], vertices2=[1], labels=False)
|
621
|
+
sage: (0, 1) in E and (1, 2) not in E
|
622
|
+
True
|
623
|
+
sage: E = EdgesView(G, vertices=[0], labels=False)
|
624
|
+
sage: (0, 1) in E and (1, 2) not in E
|
625
|
+
True
|
626
|
+
sage: E = EdgesView(G, vertices2=[1], labels=False)
|
627
|
+
sage: (0, 1) in E and (1, 2) in E
|
628
|
+
True
|
629
|
+
"""
|
630
|
+
if self._labels:
|
631
|
+
try:
|
632
|
+
u, v, label = e
|
633
|
+
except Exception:
|
634
|
+
return False
|
635
|
+
else:
|
636
|
+
try:
|
637
|
+
u, v = e
|
638
|
+
except Exception:
|
639
|
+
return False
|
640
|
+
label = None
|
641
|
+
if self._vertices2 is None:
|
642
|
+
if (self._vertex_set is not None
|
643
|
+
and u not in self._vertex_set and v not in self._vertex_set):
|
644
|
+
return False
|
645
|
+
if self._graph._directed and self._ignore_direction:
|
646
|
+
return (self._graph._backend.has_edge(u, v, label)
|
647
|
+
or self._graph._backend.has_edge(v, u, label))
|
648
|
+
return self._graph._backend.has_edge(u, v, label)
|
649
|
+
|
650
|
+
if u not in self._vertex_set2 and v not in self._vertex_set2:
|
651
|
+
return False
|
652
|
+
if (self._vertex_set is not None
|
653
|
+
and u not in self._vertex_set and v not in self._vertex_set):
|
654
|
+
return False
|
655
|
+
if self._graph._directed:
|
656
|
+
if self._ignore_direction:
|
657
|
+
return (self._graph._backend.has_edge(u, v, label)
|
658
|
+
or self._graph._backend.has_edge(v, u, label))
|
659
|
+
elif ((self._vertex_set is not None and u not in self._vertex_set)
|
660
|
+
or v not in self._vertex_set2):
|
661
|
+
return False
|
662
|
+
return self._graph._backend.has_edge(u, v, label)
|
663
|
+
|
664
|
+
def __getitem__(self, i):
|
665
|
+
r"""
|
666
|
+
Return the `i`-th edge in ``self``.
|
667
|
+
|
668
|
+
This method takes time `O(i)`. When several calls to this method are
|
669
|
+
done, prefer making ``list`` from ``self`` before querying items.
|
670
|
+
|
671
|
+
INPUT:
|
672
|
+
|
673
|
+
- ``i`` -- integer or slice
|
674
|
+
|
675
|
+
EXAMPLES::
|
676
|
+
|
677
|
+
sage: from sage.graphs.views import EdgesView
|
678
|
+
sage: E = EdgesView(graphs.HouseGraph(), labels=False)
|
679
|
+
sage: E[0]
|
680
|
+
(0, 1)
|
681
|
+
sage: E[2]
|
682
|
+
(1, 3)
|
683
|
+
sage: E[1:-1]
|
684
|
+
[(0, 2), (1, 3), (2, 3), (2, 4)]
|
685
|
+
sage: E[-1]
|
686
|
+
(3, 4)
|
687
|
+
|
688
|
+
TESTS::
|
689
|
+
|
690
|
+
sage: from sage.graphs.views import EdgesView
|
691
|
+
sage: E = EdgesView(graphs.HouseGraph(), labels=False)
|
692
|
+
sage: E[10]
|
693
|
+
Traceback (most recent call last):
|
694
|
+
...
|
695
|
+
IndexError: index out of range
|
696
|
+
"""
|
697
|
+
cdef Py_ssize_t start, stop, step
|
698
|
+
if isinstance(i, slice):
|
699
|
+
start, stop, step = i.start or 0, i.stop or sys_maxsize, i.step or 1
|
700
|
+
if start >= 0 and stop >= 0 and step >= 0:
|
701
|
+
return list(islice(self, start, stop, step))
|
702
|
+
else:
|
703
|
+
return list(self)[i]
|
704
|
+
elif i < 0:
|
705
|
+
return list(self)[i]
|
706
|
+
try:
|
707
|
+
return next(islice(self, i, i + 1, 1))
|
708
|
+
except StopIteration:
|
709
|
+
raise IndexError('index out of range')
|
710
|
+
|
711
|
+
def __add__(left, right):
|
712
|
+
"""
|
713
|
+
Return a list containing the edges of ``left`` and ``right``.
|
714
|
+
|
715
|
+
The returned list contains the edges of ``left`` with prescribed order
|
716
|
+
followed by the edges of ``right`` in prescribed order.
|
717
|
+
|
718
|
+
INPUT:
|
719
|
+
|
720
|
+
- ``left``, ``right`` -- :class:`EdgesView` or list of edges
|
721
|
+
|
722
|
+
EXAMPLES::
|
723
|
+
|
724
|
+
sage: from sage.graphs.views import EdgesView
|
725
|
+
sage: E1 = EdgesView(Graph([(0, 1)]), labels=False)
|
726
|
+
sage: E2 = EdgesView(Graph([(2, 3)]), labels=False)
|
727
|
+
sage: E1 + E2
|
728
|
+
[(0, 1), (2, 3)]
|
729
|
+
sage: E2 + E1
|
730
|
+
[(2, 3), (0, 1)]
|
731
|
+
sage: E1 + E2 + E1
|
732
|
+
[(0, 1), (2, 3), (0, 1)]
|
733
|
+
|
734
|
+
Recall that a :class:`EdgesView` is read-only and that this method
|
735
|
+
returns a list::
|
736
|
+
|
737
|
+
sage: E1 += E2
|
738
|
+
sage: type(E1) is list
|
739
|
+
True
|
740
|
+
|
741
|
+
TESTS::
|
742
|
+
|
743
|
+
sage: from sage.graphs.views import EdgesView
|
744
|
+
sage: E = EdgesView(graphs.HouseGraph())
|
745
|
+
sage: E + 'foo'
|
746
|
+
Traceback (most recent call last):
|
747
|
+
...
|
748
|
+
TypeError: unsupported operand type(s) for +: 'sage.graphs.views.EdgesView' and 'str'
|
749
|
+
"""
|
750
|
+
if not isinstance(left, (list, EdgesView)) or not isinstance(right, (list, EdgesView)):
|
751
|
+
return NotImplemented
|
752
|
+
cdef list L = list(left)
|
753
|
+
L.extend(right)
|
754
|
+
return L
|
755
|
+
|
756
|
+
def __mul__(left, right):
|
757
|
+
r"""
|
758
|
+
Return the sum of ``left`` with itself ``right`` times.
|
759
|
+
|
760
|
+
INPUT:
|
761
|
+
|
762
|
+
- ``right`` -- integer
|
763
|
+
|
764
|
+
EXAMPLES::
|
765
|
+
|
766
|
+
sage: from sage.graphs.views import EdgesView
|
767
|
+
sage: E = EdgesView(Graph([(0, 1), (2, 3)]), labels=False, sort=True)
|
768
|
+
sage: E * 3
|
769
|
+
[(0, 1), (2, 3), (0, 1), (2, 3), (0, 1), (2, 3)]
|
770
|
+
sage: 3 * E
|
771
|
+
[(0, 1), (2, 3), (0, 1), (2, 3), (0, 1), (2, 3)]
|
772
|
+
|
773
|
+
Recall that a :class:`EdgesView` is read-only and that this method
|
774
|
+
returns a list::
|
775
|
+
|
776
|
+
sage: E *= 2
|
777
|
+
sage: type(E) is list
|
778
|
+
True
|
779
|
+
|
780
|
+
TESTS::
|
781
|
+
|
782
|
+
sage: from sage.graphs.views import EdgesView
|
783
|
+
sage: E = EdgesView(Graph([(0, 1)]))
|
784
|
+
sage: E * (-1)
|
785
|
+
[]
|
786
|
+
sage: E * 1.5
|
787
|
+
Traceback (most recent call last):
|
788
|
+
...
|
789
|
+
TypeError: can...t multiply sequence by non-int of type 'sage.rings.real_mpfr.RealLiteral'
|
790
|
+
"""
|
791
|
+
if isinstance(left, EdgesView):
|
792
|
+
return list(left) * right
|
793
|
+
# Case __rmul__
|
794
|
+
return list(right) * left
|