diff --git a/src/sage/combinat/finite_state_machine_generators.py b/src/sage/combinat/finite_state_machine_generators.py index 0d990ebc551..8be8e4a56e6 100644 --- a/src/sage/combinat/finite_state_machine_generators.py +++ b/src/sage/combinat/finite_state_machine_generators.py @@ -1961,7 +1961,7 @@ def f(n): "Missing initial values for %s." % sorted(missing_initial_values)) - for cycle in recursion_digraph.all_simple_cycles(): + for cycle in recursion_digraph.all_simple_cycles(algorithm="A"): assert cycle[0] is cycle[-1] cycle_set = set(cycle) intersection = cycle_set.intersection(initial_values_set) diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index 1041b4be39b..ed7f3d15de7 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -4895,7 +4895,7 @@ def periodic_points(self, n, minimal=True, formal=False, R=None, algorithm='vari if R in FiniteFields(): g = f.cyclegraph() points = [] - for cycle in g.all_simple_cycles(): + for cycle in g.all_simple_cycles(algorithm="A"): m = len(cycle)-1 if minimal: if m == n: diff --git a/src/sage/graphs/cycle_enumeration.py b/src/sage/graphs/cycle_enumeration.py index dd2b3f350d3..6661c25eaa4 100644 --- a/src/sage/graphs/cycle_enumeration.py +++ b/src/sage/graphs/cycle_enumeration.py @@ -309,10 +309,10 @@ def _all_simple_cycles_iterator_edge(self, edge, max_length=None, sage: g = graphs.Grid2dGraph(2, 5) sage: it = g._all_simple_cycles_iterator_edge(((0, 0), (0, 1), None), report_weight=True) sage: for i in range(4): print(next(it)) - (4, [(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)]) - (6, [(0, 0), (0, 1), (0, 2), (1, 2), (1, 1), (1, 0), (0, 0)]) - (8, [(0, 0), (0, 1), (0, 2), (0, 3), (1, 3), (1, 2), (1, 1), (1, 0), (0, 0)]) - (10, [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1, 4), (1, 3), (1, 2), (1, 1), (1, 0), (0, 0)]) + (4.0, [(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)]) + (6.0, [(0, 0), (0, 1), (0, 2), (1, 2), (1, 1), (1, 0), (0, 0)]) + (8.0, [(0, 0), (0, 1), (0, 2), (0, 3), (1, 3), (1, 2), (1, 1), (1, 0), (0, 0)]) + (10.0, [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1, 4), (1, 3), (1, 2), (1, 1), (1, 0), (0, 0)]) Each edge must have a positive weight:: @@ -379,7 +379,6 @@ def _all_simple_cycles_iterator_edge(self, edge, max_length=None, weight_function=weight_function, by_weight=by_weight, check_weight=check_weight, - algorithm=('Feng' if h.is_directed() else 'Yen'), report_edges=False, report_weight=True) @@ -461,7 +460,8 @@ def all_cycles_iterator(self, starting_vertices=None, simple=False, - The algorithm ``'B'`` holds cycle iterators starting with each edge, and output them in increasing length order. It depends on the k-shortest - simple paths algorithm. Thus, it is not available if ``simple=False``. + simple paths algorithm. Thus, it is not available if ``simple=False`` or + ``rooted=True`` or ``starting_vertices`` is not ``None``. OUTPUT: iterator @@ -573,7 +573,8 @@ def all_cycles_iterator(self, starting_vertices=None, simple=False, [0, 1, 2, 0] [2, 3, 4, 5, 2] - The algorithm ``'B'`` is available only when ``simple=True``:: + The algorithm ``'B'`` is unavailable when ``simple=False`` or ``rooted=True`` + or ``starting_vertices is not None``:: sage: g = DiGraph() sage: g.add_edges([('a', 'b', 1), ('b', 'a', 1)]) @@ -581,7 +582,15 @@ def all_cycles_iterator(self, starting_vertices=None, simple=False, ....: Traceback (most recent call last): ... - ValueError: The algorithm 'B' is available only when simple=True. + ValueError: The algorithm 'B' is unavailable when simple=False. + sage: next(g.all_cycles_iterator(algorithm='B', simple=True, rooted=True)) + Traceback (most recent call last): + ... + ValueError: The algorithm 'B' is unavailable when rooted=True. + sage: next(g.all_cycles_iterator(algorithm='B', simple=True, starting_vertices=['a'])) + Traceback (most recent call last): + ... + ValueError: The algorithm 'B' is unavailable when starting_vertices is not None. The algorithm ``'A'`` works for undirected graphs as well. Specifically, each cycle is enumerated exactly once, meaning a cycle and its reverse are not listed separately:: @@ -591,12 +600,17 @@ def all_cycles_iterator(self, starting_vertices=None, simple=False, ....: print(cycle) [0, 1, 2, 0] """ + if algorithm == 'B': + if not simple: + raise ValueError("The algorithm 'B' is unavailable when simple=False.") + if starting_vertices: + raise ValueError("The algorithm 'B' is unavailable when starting_vertices is not None.") + if rooted: + raise ValueError("The algorithm 'B' is unavailable when rooted=True.") + if starting_vertices is None: starting_vertices = self - if algorithm == 'B' and not simple: - raise ValueError("The algorithm 'B' is available only when simple=True.") - by_weight, weight_function = self._get_weight_function(by_weight=by_weight, weight_function=weight_function, check_weight=check_weight) @@ -700,7 +714,7 @@ def all_simple_cycles(self, starting_vertices=None, rooted=False, max_length=None, trivial=False, weight_function=None, by_weight=False, check_weight=True, report_weight=False, - algorithm='A'): + algorithm='B'): r""" Return a list of all simple cycles of ``self``. The cycles are enumerated in increasing length order. Each edge must have a @@ -741,7 +755,7 @@ def all_simple_cycles(self, starting_vertices=None, rooted=False, a cycle is returned. Otherwise a tuple of cycle length and cycle is returned. - - ``algorithm`` -- string (default: ``'A'``); the algorithm used to + - ``algorithm`` -- string (default: ``'B'``); the algorithm used to enumerate the cycles. - The algorithm ``'A'`` holds cycle iterators starting with each vertex, @@ -773,20 +787,20 @@ def all_simple_cycles(self, starting_vertices=None, rooted=False, sage: g.all_simple_cycles(max_length=6) [[0, 1, 0], [0, 4, 0], [0, 5, 0], [1, 2, 1], [1, 6, 1], [2, 3, 2], [2, 7, 2], [3, 4, 3], [3, 8, 3], [4, 9, 4], [5, 7, 5], [5, 8, 5], - [6, 8, 6], [6, 9, 6], [7, 9, 7], [0, 1, 2, 3, 4, 0], - [0, 1, 2, 7, 5, 0], [0, 1, 6, 8, 5, 0], [0, 1, 6, 9, 4, 0], - [0, 4, 3, 2, 1, 0], [0, 4, 3, 8, 5, 0], [0, 4, 9, 6, 1, 0], - [0, 4, 9, 7, 5, 0], [0, 5, 7, 2, 1, 0], [0, 5, 7, 9, 4, 0], - [0, 5, 8, 3, 4, 0], [0, 5, 8, 6, 1, 0], [1, 2, 3, 8, 6, 1], - [1, 2, 7, 9, 6, 1], [1, 6, 8, 3, 2, 1], [1, 6, 9, 7, 2, 1], - [2, 3, 4, 9, 7, 2], [2, 3, 8, 5, 7, 2], [2, 7, 5, 8, 3, 2], - [2, 7, 9, 4, 3, 2], [3, 4, 9, 6, 8, 3], [3, 8, 6, 9, 4, 3], + [6, 8, 6], [6, 9, 6], [7, 9, 7], [0, 1, 6, 8, 5, 0], + [0, 1, 6, 9, 4, 0], [0, 1, 2, 7, 5, 0], [0, 1, 2, 3, 4, 0], + [0, 4, 9, 7, 5, 0], [0, 4, 9, 6, 1, 0], [0, 4, 3, 8, 5, 0], + [0, 4, 3, 2, 1, 0], [0, 5, 8, 6, 1, 0], [0, 5, 8, 3, 4, 0], + [0, 5, 7, 2, 1, 0], [0, 5, 7, 9, 4, 0], [1, 2, 7, 9, 6, 1], + [1, 2, 3, 8, 6, 1], [1, 6, 9, 7, 2, 1], [1, 6, 8, 3, 2, 1], + [2, 3, 8, 5, 7, 2], [2, 3, 4, 9, 7, 2], [2, 7, 9, 4, 3, 2], + [2, 7, 5, 8, 3, 2], [3, 4, 9, 6, 8, 3], [3, 8, 6, 9, 4, 3], [5, 7, 9, 6, 8, 5], [5, 8, 6, 9, 7, 5], [0, 1, 2, 3, 8, 5, 0], - [0, 1, 2, 7, 9, 4, 0], [0, 1, 6, 8, 3, 4, 0], - [0, 1, 6, 9, 7, 5, 0], [0, 4, 3, 2, 7, 5, 0], + [0, 1, 2, 7, 9, 4, 0], [0, 1, 6, 9, 7, 5, 0], + [0, 1, 6, 8, 3, 4, 0], [0, 4, 3, 2, 7, 5, 0], [0, 4, 3, 8, 6, 1, 0], [0, 4, 9, 6, 8, 5, 0], - [0, 4, 9, 7, 2, 1, 0], [0, 5, 7, 2, 3, 4, 0], - [0, 5, 7, 9, 6, 1, 0], [0, 5, 8, 3, 2, 1, 0], + [0, 4, 9, 7, 2, 1, 0], [0, 5, 7, 9, 6, 1, 0], + [0, 5, 7, 2, 3, 4, 0], [0, 5, 8, 3, 2, 1, 0], [0, 5, 8, 6, 9, 4, 0], [1, 2, 3, 4, 9, 6, 1], [1, 2, 7, 5, 8, 6, 1], [1, 6, 8, 5, 7, 2, 1], [1, 6, 9, 4, 3, 2, 1], [2, 3, 8, 6, 9, 7, 2], @@ -798,8 +812,8 @@ def all_simple_cycles(self, starting_vertices=None, rooted=False, sage: g = graphs.CompleteGraph(4).to_directed() sage: g.all_simple_cycles() [[0, 1, 0], [0, 2, 0], [0, 3, 0], [1, 2, 1], [1, 3, 1], [2, 3, 2], - [0, 1, 2, 0], [0, 1, 3, 0], [0, 2, 1, 0], [0, 2, 3, 0], - [0, 3, 1, 0], [0, 3, 2, 0], [1, 2, 3, 1], [1, 3, 2, 1], + [0, 1, 3, 0], [0, 1, 2, 0], [0, 2, 3, 0], [0, 2, 1, 0], + [0, 3, 2, 0], [0, 3, 1, 0], [1, 2, 3, 1], [1, 3, 2, 1], [0, 1, 2, 3, 0], [0, 1, 3, 2, 0], [0, 2, 1, 3, 0], [0, 2, 3, 1, 0], [0, 3, 1, 2, 0], [0, 3, 2, 1, 0]] @@ -810,41 +824,39 @@ def all_simple_cycles(self, starting_vertices=None, rooted=False, sage: g = graphs.CompleteGraph(20).to_directed() sage: g.all_simple_cycles(max_length=2) [[0, 1, 0], [0, 2, 0], [0, 3, 0], [0, 4, 0], [0, 5, 0], [0, 6, 0], [0, 7, 0], - [0, 8, 0], [0, 9, 0], [0, 10, 0], [0, 11, 0], [0, 12, 0], [0, 13, 0], - [0, 14, 0], [0, 15, 0], [0, 16, 0], [0, 17, 0], [0, 18, 0], [0, 19, 0], - [1, 2, 1], [1, 3, 1], [1, 4, 1], [1, 5, 1], [1, 6, 1], [1, 7, 1], [1, 8, 1], - [1, 9, 1], [1, 10, 1], [1, 11, 1], [1, 12, 1], [1, 13, 1], [1, 14, 1], - [1, 15, 1], [1, 16, 1], [1, 17, 1], [1, 18, 1], [1, 19, 1], [2, 3, 2], - [2, 4, 2], [2, 5, 2], [2, 6, 2], [2, 7, 2], [2, 8, 2], [2, 9, 2], [2, 10, 2], - [2, 11, 2], [2, 12, 2], [2, 13, 2], [2, 14, 2], [2, 15, 2], [2, 16, 2], - [2, 17, 2], [2, 18, 2], [2, 19, 2], [3, 4, 3], [3, 5, 3], [3, 6, 3], - [3, 7, 3], [3, 8, 3], [3, 9, 3], [3, 10, 3], [3, 11, 3], [3, 12, 3], - [3, 13, 3], [3, 14, 3], [3, 15, 3], [3, 16, 3], [3, 17, 3], [3, 18, 3], - [3, 19, 3], [4, 5, 4], [4, 6, 4], [4, 7, 4], [4, 8, 4], [4, 9, 4], [4, 10, 4], - [4, 11, 4], [4, 12, 4], [4, 13, 4], [4, 14, 4], [4, 15, 4], [4, 16, 4], - [4, 17, 4], [4, 18, 4], [4, 19, 4], [5, 6, 5], [5, 7, 5], [5, 8, 5], - [5, 9, 5], [5, 10, 5], [5, 11, 5], [5, 12, 5], [5, 13, 5], [5, 14, 5], - [5, 15, 5], [5, 16, 5], [5, 17, 5], [5, 18, 5], [5, 19, 5], [6, 7, 6], - [6, 8, 6], [6, 9, 6], [6, 10, 6], [6, 11, 6], [6, 12, 6], [6, 13, 6], - [6, 14, 6], [6, 15, 6], [6, 16, 6], [6, 17, 6], [6, 18, 6], [6, 19, 6], - [7, 8, 7], [7, 9, 7], [7, 10, 7], [7, 11, 7], [7, 12, 7], [7, 13, 7], - [7, 14, 7], [7, 15, 7], [7, 16, 7], [7, 17, 7], [7, 18, 7], [7, 19, 7], - [8, 9, 8], [8, 10, 8], [8, 11, 8], [8, 12, 8], [8, 13, 8], [8, 14, 8], - [8, 15, 8], [8, 16, 8], [8, 17, 8], [8, 18, 8], [8, 19, 8], [9, 10, 9], - [9, 11, 9], [9, 12, 9], [9, 13, 9], [9, 14, 9], [9, 15, 9], [9, 16, 9], - [9, 17, 9], [9, 18, 9], [9, 19, 9], [10, 11, 10], [10, 12, 10], [10, 13, 10], - [10, 14, 10], [10, 15, 10], [10, 16, 10], [10, 17, 10], [10, 18, 10], - [10, 19, 10], [11, 12, 11], [11, 13, 11], [11, 14, 11], [11, 15, 11], - [11, 16, 11], [11, 17, 11], [11, 18, 11], [11, 19, 11], [12, 13, 12], - [12, 14, 12], [12, 15, 12], [12, 16, 12], [12, 17, 12], [12, 18, 12], - [12, 19, 12], [13, 14, 13], [13, 15, 13], [13, 16, 13], [13, 17, 13], - [13, 18, 13], [13, 19, 13], [14, 15, 14], [14, 16, 14], [14, 17, 14], - [14, 18, 14], [14, 19, 14], [15, 16, 15], [15, 17, 15], [15, 18, 15], - [15, 19, 15], [16, 17, 16], [16, 18, 16], [16, 19, 16], [17, 18, 17], - [17, 19, 17], [18, 19, 18]] + [0, 8, 0], [0, 9, 0], [0, 10, 0], [0, 11, 0], [0, 12, 0], [0, 13, 0], [0, 14, 0], + [0, 15, 0], [0, 16, 0], [0, 17, 0], [0, 18, 0], [0, 19, 0], [1, 2, 1], [1, 3, 1], + [1, 4, 1], [1, 5, 1], [1, 6, 1], [1, 7, 1], [1, 8, 1], [1, 9, 1], [2, 3, 2], + [2, 4, 2], [2, 5, 2], [2, 6, 2], [2, 7, 2], [2, 8, 2], [2, 9, 2], [3, 4, 3], + [3, 5, 3], [3, 6, 3], [3, 7, 3], [3, 8, 3], [3, 9, 3], [4, 5, 4], [4, 6, 4], + [4, 7, 4], [4, 8, 4], [4, 9, 4], [5, 6, 5], [5, 7, 5], [5, 8, 5], [5, 9, 5], + [6, 7, 6], [6, 8, 6], [6, 9, 6], [7, 8, 7], [7, 9, 7], [8, 9, 8], [10, 1, 10], + [10, 2, 10], [10, 3, 10], [10, 4, 10], [10, 5, 10], [10, 6, 10], [10, 7, 10], + [10, 8, 10], [10, 9, 10], [11, 1, 11], [11, 2, 11], [11, 3, 11], [11, 4, 11], + [11, 5, 11], [11, 6, 11], [11, 7, 11], [11, 8, 11], [11, 9, 11], [11, 10, 11], + [12, 1, 12], [12, 2, 12], [12, 3, 12], [12, 4, 12], [12, 5, 12], [12, 6, 12], + [12, 7, 12], [12, 8, 12], [12, 9, 12], [12, 10, 12], [12, 11, 12], [13, 1, 13], + [13, 2, 13], [13, 3, 13], [13, 4, 13], [13, 5, 13], [13, 6, 13], [13, 7, 13], + [13, 8, 13], [13, 9, 13], [13, 10, 13], [13, 11, 13], [13, 12, 13], [14, 1, 14], + [14, 2, 14], [14, 3, 14], [14, 4, 14], [14, 5, 14], [14, 6, 14], [14, 7, 14], + [14, 8, 14], [14, 9, 14], [14, 10, 14], [14, 11, 14], [14, 12, 14], [14, 13, 14], + [15, 1, 15], [15, 2, 15], [15, 3, 15], [15, 4, 15], [15, 5, 15], [15, 6, 15], + [15, 7, 15], [15, 8, 15], [15, 9, 15], [15, 10, 15], [15, 11, 15], [15, 12, 15], + [15, 13, 15], [15, 14, 15], [16, 1, 16], [16, 2, 16], [16, 3, 16], [16, 4, 16], + [16, 5, 16], [16, 6, 16], [16, 7, 16], [16, 8, 16], [16, 9, 16], [16, 10, 16], + [16, 11, 16], [16, 12, 16], [16, 13, 16], [16, 14, 16], [16, 15, 16], [17, 1, 17], + [17, 2, 17], [17, 3, 17], [17, 4, 17], [17, 5, 17], [17, 6, 17], [17, 7, 17], + [17, 8, 17], [17, 9, 17], [17, 10, 17], [17, 11, 17], [17, 12, 17], [17, 13, 17], + [17, 14, 17], [17, 15, 17], [17, 16, 17], [18, 1, 18], [18, 2, 18], [18, 3, 18], + [18, 4, 18], [18, 5, 18], [18, 6, 18], [18, 7, 18], [18, 8, 18], [18, 9, 18], + [18, 10, 18], [18, 11, 18], [18, 12, 18], [18, 13, 18], [18, 14, 18], [18, 15, 18], + [18, 16, 18], [18, 17, 18], [19, 1, 19], [19, 2, 19], [19, 3, 19], [19, 4, 19], + [19, 5, 19], [19, 6, 19], [19, 7, 19], [19, 8, 19], [19, 9, 19], [19, 10, 19], + [19, 11, 19], [19, 12, 19], [19, 13, 19], [19, 14, 19], [19, 15, 19], [19, 16, 19], + [19, 17, 19], [19, 18, 19]] sage: g = graphs.CompleteGraph(20).to_directed() - sage: g.all_simple_cycles(max_length=2, starting_vertices=[0]) + sage: g.all_simple_cycles(max_length=2, starting_vertices=[0], algorithm='A') [[0, 1, 0], [0, 2, 0], [0, 3, 0], [0, 4, 0], [0, 5, 0], [0, 6, 0], [0, 7, 0], [0, 8, 0], [0, 9, 0], [0, 10, 0], [0, 11, 0], [0, 12, 0], [0, 13, 0], [0, 14, 0], [0, 15, 0], @@ -854,9 +866,9 @@ def all_simple_cycles(self, starting_vertices=None, rooted=False, vertices (compare the following examples):: sage: g = graphs.CompleteGraph(4).to_directed() - sage: g.all_simple_cycles(max_length=2, rooted=False) + sage: g.all_simple_cycles(max_length=2, rooted=False, algorithm='A') [[0, 1, 0], [0, 2, 0], [0, 3, 0], [1, 2, 1], [1, 3, 1], [2, 3, 2]] - sage: g.all_simple_cycles(max_length=2, rooted=True) + sage: g.all_simple_cycles(max_length=2, rooted=True, algorithm='A') [[0, 1, 0], [0, 2, 0], [0, 3, 0], [1, 0, 1], [1, 2, 1], [1, 3, 1], [2, 0, 2], [2, 1, 2], [2, 3, 2], [3, 0, 3], [3, 1, 3], [3, 2, 3]] @@ -865,12 +877,12 @@ def all_simple_cycles(self, starting_vertices=None, rooted=False, sage: cycles = g.all_simple_cycles(weight_function=lambda e:e[0]+e[1], ....: by_weight=True, report_weight=True) sage: cycles - [(2, [0, 1, 0]), (4, [0, 2, 0]), (6, [0, 1, 2, 0]), (6, [0, 2, 1, 0]), - (6, [0, 3, 0]), (6, [1, 2, 1]), (8, [0, 1, 3, 0]), (8, [0, 3, 1, 0]), - (8, [1, 3, 1]), (10, [0, 2, 3, 0]), (10, [0, 3, 2, 0]), (10, [2, 3, 2]), - (12, [0, 1, 2, 3, 0]), (12, [0, 1, 3, 2, 0]), (12, [0, 2, 1, 3, 0]), - (12, [0, 2, 3, 1, 0]), (12, [0, 3, 1, 2, 0]), (12, [0, 3, 2, 1, 0]), - (12, [1, 2, 3, 1]), (12, [1, 3, 2, 1])] + [(2.0, [0, 1, 0]), (4.0, [0, 2, 0]), (6.0, [0, 1, 2, 0]), (6.0, [0, 2, 1, 0]), + (6.0, [0, 3, 0]), (6.0, [1, 2, 1]), (8.0, [0, 1, 3, 0]), (8.0, [0, 3, 1, 0]), + (8.0, [1, 3, 1]), (10.0, [0, 2, 3, 0]), (10.0, [0, 3, 2, 0]), (10.0, [2, 3, 2]), + (12.0, [0, 1, 3, 2, 0]), (12.0, [0, 1, 2, 3, 0]), (12.0, [0, 2, 3, 1, 0]), + (12.0, [0, 2, 1, 3, 0]), (12.0, [0, 3, 2, 1, 0]), (12.0, [0, 3, 1, 2, 0]), + (12.0, [1, 2, 3, 1]), (12.0, [1, 3, 2, 1])] The algorithm ``'B'`` can be used:: diff --git a/src/sage/graphs/path_enumeration.pyx b/src/sage/graphs/path_enumeration.pyx index 92d8e22ecd5..050d89ce1fc 100644 --- a/src/sage/graphs/path_enumeration.pyx +++ b/src/sage/graphs/path_enumeration.pyx @@ -300,8 +300,8 @@ def shortest_simple_paths(self, source, target, weight_function=None, If ``source`` is the same vertex as ``target``, then ``[[source]]`` is returned -- a list containing the 1-vertex, 0-edge path ``source``. - By default ``Yen's`` algorithm [Yen1970]_ is used for undirected graphs and - ``Feng's`` algorithm is used for directed graphs [Feng2014]_. + By default Postponed Node Classification (``algorithm=PNC``) algorithm + [ACN2023]_ is used. The loops and the multiedges if present in the given graph are ignored and only minimum of the edge labels is kept in case of multiedges. @@ -382,16 +382,16 @@ def shortest_simple_paths(self, source, target, weight_function=None, [[1, 6], [1, 2, 5, 6], [1, 3, 5, 6], [1, 4, 5, 6]] sage: list(g.shortest_simple_paths(1, 6, ....: report_edges=True, report_weight=True, labels=True)) - [(1, [(1, 6, 100)]), - (3, [(1, 2, 20), (2, 5, 20), (5, 6, 5)]), - (3, [(1, 3, 10), (3, 5, 10), (5, 6, 5)]), - (3, [(1, 4, 30), (4, 5, 30), (5, 6, 5)])] + [(1.0, [(1, 6, 100)]), + (3.0, [(1, 4, 30), (4, 5, 30), (5, 6, 5)]), + (3.0, [(1, 3, 10), (3, 5, 10), (5, 6, 5)]), + (3.0, [(1, 2, 20), (2, 5, 20), (5, 6, 5)])] sage: list(g.shortest_simple_paths(1, 6, by_weight=True, ....: report_edges=True, report_weight=True, labels=True)) - [(25, [(1, 3, 10), (3, 5, 10), (5, 6, 5)]), - (45, [(1, 2, 20), (2, 5, 20), (5, 6, 5)]), - (65, [(1, 4, 30), (4, 5, 30), (5, 6, 5)]), - (100, [(1, 6, 100)])] + [(25.0, [(1, 3, 10), (3, 5, 10), (5, 6, 5)]), + (45.0, [(1, 2, 20), (2, 5, 20), (5, 6, 5)]), + (65.0, [(1, 4, 30), (4, 5, 30), (5, 6, 5)]), + (100.0, [(1, 6, 100)])] sage: list(g.shortest_simple_paths(1, 6, by_weight=True, ....: report_edges=True, labels=True)) [[(1, 3, 10), (3, 5, 10), (5, 6, 5)], @@ -400,9 +400,9 @@ def shortest_simple_paths(self, source, target, weight_function=None, [(1, 6, 100)]] sage: list(g.shortest_simple_paths(1, 6, report_edges=True, labels=True)) [[(1, 6, 100)], - [(1, 2, 20), (2, 5, 20), (5, 6, 5)], + [(1, 4, 30), (4, 5, 30), (5, 6, 5)], [(1, 3, 10), (3, 5, 10), (5, 6, 5)], - [(1, 4, 30), (4, 5, 30), (5, 6, 5)]] + [(1, 2, 20), (2, 5, 20), (5, 6, 5)]] TESTS:: @@ -423,11 +423,11 @@ def shortest_simple_paths(self, source, target, weight_function=None, [(1, 2, 1), (2, 3, 1), (3, 8, 5), (8, 9, 2), (9, 11, 10), (11, 6, 8)], [(1, 2, 1), (2, 3, 1), (3, 4, 1), (4, 5, 2), (5, 6, 100)]] sage: list(g.shortest_simple_paths(1, 6, report_edges=True, labels=True, by_weight=True, report_weight=True)) - [(10, [(1, 2, 1), (2, 3, 1), (3, 4, 1), (4, 7, 3), (7, 6, 4)]), - (11, [(1, 2, 1), (2, 3, 1), (3, 8, 5), (8, 9, 2), (9, 6, 2)]), - (18, [(1, 2, 1), (2, 3, 1), (3, 8, 5), (8, 9, 2), (9, 10, 7), (10, 6, 2)]), - (27, [(1, 2, 1), (2, 3, 1), (3, 8, 5), (8, 9, 2), (9, 11, 10), (11, 6, 8)]), - (105, [(1, 2, 1), (2, 3, 1), (3, 4, 1), (4, 5, 2), (5, 6, 100)])] + [(10.0, [(1, 2, 1), (2, 3, 1), (3, 4, 1), (4, 7, 3), (7, 6, 4)]), + (11.0, [(1, 2, 1), (2, 3, 1), (3, 8, 5), (8, 9, 2), (9, 6, 2)]), + (18.0, [(1, 2, 1), (2, 3, 1), (3, 8, 5), (8, 9, 2), (9, 10, 7), (10, 6, 2)]), + (27.0, [(1, 2, 1), (2, 3, 1), (3, 8, 5), (8, 9, 2), (9, 11, 10), (11, 6, 8)]), + (105.0, [(1, 2, 1), (2, 3, 1), (3, 4, 1), (4, 5, 2), (5, 6, 100)])] sage: list(g.shortest_simple_paths(1, 6, algorithm='Yen')) [[1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 7, 6], @@ -574,7 +574,7 @@ def shortest_simple_paths(self, source, target, weight_function=None, self = self.to_simple(to_undirected=False, keep_label='min', immutable=False) if algorithm is None: - algorithm = "Feng" if self.is_directed() else "Yen" + algorithm = "PNC" if algorithm in ("Feng", "PNC"): yield from nc_k_shortest_simple_paths(self, source=source, target=target, @@ -897,7 +897,7 @@ def nc_k_shortest_simple_paths(self, source, target, weight_function=None, by_weight=False, check_weight=True, report_edges=False, labels=False, report_weight=False, - postponed=False): + postponed=True): r""" Return an iterator over the simple paths between a pair of vertices in increasing order of weights. @@ -943,7 +943,7 @@ def nc_k_shortest_simple_paths(self, source, target, weight_function=None, the path between ``source`` and ``target`` is returned. Otherwise a tuple of path length and path is returned. - - ``postponed`` -- boolean (default: ``False``); if ``True``, the postponed + - ``postponed`` -- boolean (default: ``True``); if ``True``, the postponed node classification algorithm is used, otherwise the node classification algorithm is used. See below for details. @@ -1616,7 +1616,7 @@ def _all_paths_iterator(self, vertex, ending_vertices=None, sage: list(G._all_paths_iterator(1, ending_vertices=[3], simple=True)) [[1, 3], [1, 0, 3], [1, 2, 3], [1, 0, 2, 3], [1, 2, 0, 3]] sage: list(G.shortest_simple_paths(1, 3)) - [[1, 3], [1, 0, 3], [1, 2, 3], [1, 2, 0, 3], [1, 0, 2, 3]] + [[1, 3], [1, 2, 3], [1, 0, 3], [1, 0, 2, 3], [1, 2, 0, 3]] sage: pi = G._all_paths_iterator(1, ending_vertices=[3]) sage: for _ in range(6): ....: print(next(pi)) @@ -1881,7 +1881,7 @@ def all_paths_iterator(self, starting_vertices=None, ending_vertices=None, sage: list(G.all_paths_iterator(starting_vertices=[1], ending_vertices=[3], simple=True)) [[1, 3], [1, 0, 3], [1, 2, 3], [1, 0, 2, 3], [1, 2, 0, 3]] sage: list(G.shortest_simple_paths(1, 3)) - [[1, 3], [1, 0, 3], [1, 2, 3], [1, 2, 0, 3], [1, 0, 2, 3]] + [[1, 3], [1, 2, 3], [1, 0, 3], [1, 0, 2, 3], [1, 2, 0, 3]] sage: pi = G.all_paths_iterator(starting_vertices=[1], ending_vertices=[3]) sage: for _ in range(6): ....: print(next(pi)) @@ -2117,7 +2117,7 @@ def all_simple_paths(self, starting_vertices=None, ending_vertices=None, sage: G.all_simple_paths([1], [3]) [[1, 3], [1, 0, 3], [1, 2, 3], [1, 0, 2, 3], [1, 2, 0, 3]] sage: list(G.shortest_simple_paths(1, 3)) - [[1, 3], [1, 0, 3], [1, 2, 3], [1, 2, 0, 3], [1, 0, 2, 3]] + [[1, 3], [1, 2, 3], [1, 0, 3], [1, 0, 2, 3], [1, 2, 0, 3]] sage: G.all_simple_paths([0, 1], [2, 3]) [[1, 2], [1, 3], diff --git a/src/sage/knots/link.py b/src/sage/knots/link.py index dbe3f8d2237..81b6c75c49c 100644 --- a/src/sage/knots/link.py +++ b/src/sage/knots/link.py @@ -1522,7 +1522,7 @@ def oriented_gauss_code(self): elif i[1] == -1: cross_number[i[0]] = -i[2] edges_graph = DiGraph(edges) - d = edges_graph.all_simple_cycles() + d = edges_graph.all_simple_cycles(algorithm="A") code = [] for i in d: l = [cross_number[j] for j in i]