Skip to content

Commit 8801f6e

Browse files
author
Release Manager
committed
gh-36574: rename the backtrack algorithm of method `longest_path` with deprecation Fixes #36530. More precisely, we: - Rename algorithm "backtrack" as "heuristic" and add a deprecation warning - Raise an error when some parameters are used in combination with the "backtrack"/"heuristic" algorithm ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. --> <!-- If your change requires a documentation PR, please link it appropriately --> <!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> <!-- Feel free to remove irrelevant items. --> - [x] The title is concise, informative, and self-explanatory. - [x] The description explains in detail what this PR is about. - [x] I have linked a relevant issue or discussion. - [x] I have created tests covering the changes. - [x] I have updated the documentation accordingly. ### ⌛ Dependencies <!-- List all open PRs that this PR logically depends on - #12345: short description why this is a dependency - #34567: ... --> <!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> URL: #36574 Reported by: David Coudert Reviewer(s): David Coudert, Matthias Köppe
2 parents 9014410 + 5e6a0aa commit 8801f6e

File tree

1 file changed

+54
-15
lines changed

1 file changed

+54
-15
lines changed

src/sage/graphs/generic_graph.py

Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7885,25 +7885,34 @@ def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP",
78857885
argument is set to ``None`` by default, which means that no constraint
78867886
is set upon the first vertex in the path.
78877887

7888+
This parameter can only be used when ``algorithm`` is ``"MILP"``.
7889+
78887890
- ``t`` -- a vertex (default: ``None``); forces the destination of the
78897891
path (the method then returns the longest path ending at ``t``). The
78907892
argument is set to ``None`` by default, which means that no constraint
78917893
is set upon the last vertex in the path.
78927894

7895+
This parameter can only be used when ``algorithm`` is ``"MILP"``.
7896+
78937897
- ``use_edge_labels`` -- boolean (default: ``False``); whether to
78947898
compute a path with maximum weight where the weight of an edge is
78957899
defined by its label (a label set to ``None`` or ``{}`` being
78967900
considered as a weight of `1`), or to compute a path with the longest
78977901
possible number of edges (i.e., edge weights are set to 1)
78987902

7903+
This parameter can only be used when ``algorithm`` is ``"MILP"``.
7904+
78997905
- ``algorithm`` -- string (default: ``"MILP"``); the algorithm to use
7900-
among ``"MILP"`` and ``"backtrack"``. Two remarks on this respect:
7906+
among ``"MILP"``, ``"backtrack"`` and ``"heuristic"``:
79017907

7902-
* While the MILP formulation returns an exact answer, the backtrack
7903-
algorithm is a randomized heuristic.
7908+
* ``"MILP"`` returns an exact answer.
79047909

7905-
* As the backtrack algorithm does not support edge weighting, setting
7906-
``use_edge_labels=True`` will force the use of the MILP algorithm.
7910+
* ``"backtrack"`` is renamed ``"heuristic"`` (:issue:`36574`).
7911+
7912+
* ``"heuristic"`` is a randomized heuristic for finding a long path in
7913+
an unweighted (di)graph. This heuristic does not take into account
7914+
parameters ``s``, ``t`` and ``use_edge_labels``. An error is raised
7915+
if these parameters are set.
79077916

79087917
- ``solver`` -- string (default: ``None``); specify a Mixed Integer
79097918
Linear Programming (MILP) solver to be used. If set to ``None``, the
@@ -7948,7 +7957,7 @@ def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP",
79487957
The heuristic totally agrees::
79497958

79507959
sage: g = graphs.PetersenGraph()
7951-
sage: p = g.longest_path(algorithm="backtrack").edges(sort=True, labels=False)
7960+
sage: p = g.longest_path(algorithm="heuristic").edges(sort=True, labels=False)
79527961
sage: len(p)
79537962
9
79547963

@@ -7970,13 +7979,13 @@ def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP",
79707979

79717980
TESTS:
79727981

7973-
The argument ``algorithm`` must be either ``'backtrack'`` or
7974-
``'MILP'``::
7982+
The argument ``algorithm`` must be either ``'backtrack'``,
7983+
``'heuristic'`` or ``'MILP'``::
79757984

79767985
sage: graphs.PetersenGraph().longest_path(algorithm="abc")
79777986
Traceback (most recent call last):
79787987
...
7979-
ValueError: algorithm must be either 'backtrack' or 'MILP'
7988+
ValueError: algorithm must be either 'backtrack', 'heuristic' or 'MILP'
79807989

79817990
Disconnected graphs not weighted::
79827991

@@ -8049,13 +8058,43 @@ def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP",
80498058
sage: H = {(0, 3), (2, 0), (3, 4)}
80508059
sage: H == {x for x in G.longest_path().edge_iterator(labels=False)} # needs sage.numerical.mip
80518060
True
8061+
8062+
:issue:`36574`::
8063+
8064+
sage: G = graphs.PathGraph(3)
8065+
sage: P = G.longest_path(algorithm='backtrack')
8066+
doctest:...: DeprecationWarning: algorithm 'backtrack' is deprecated.
8067+
Use algorithm 'heuristic' instead.
8068+
See https://github.com/sagemath/sage/issues/36574 for details.
8069+
sage: G.longest_path(algorithm='heuristic', s=0)
8070+
Traceback (most recent call last):
8071+
...
8072+
ValueError: parameters s, t, and use_edge_labels can not be used in
8073+
combination with algorithm 'heuristic'
8074+
sage: G.longest_path(algorithm='heuristic', t=2)
8075+
Traceback (most recent call last):
8076+
...
8077+
ValueError: parameters s, t, and use_edge_labels can not be used in
8078+
combination with algorithm 'heuristic'
8079+
sage: G.longest_path(algorithm='heuristic', use_edge_labels=True)
8080+
Traceback (most recent call last):
8081+
...
8082+
ValueError: parameters s, t, and use_edge_labels can not be used in
8083+
combination with algorithm 'heuristic'
80528084
"""
80538085
self._scream_if_not_simple()
80548086

8055-
if use_edge_labels:
8056-
algorithm = "MILP"
8057-
if algorithm not in ("backtrack", "MILP"):
8058-
raise ValueError("algorithm must be either 'backtrack' or 'MILP'")
8087+
if algorithm not in ("backtrack", "heuristic", "MILP"):
8088+
raise ValueError("algorithm must be either 'backtrack', 'heuristic' or 'MILP'")
8089+
if algorithm == "backtrack":
8090+
from sage.misc.superseded import deprecation
8091+
deprecation(36574, "algorithm 'backtrack' is deprecated. "
8092+
"Use algorithm 'heuristic' instead.")
8093+
algorithm = 'heuristic'
8094+
if algorithm == 'heuristic':
8095+
if s is not None or t is not None or use_edge_labels:
8096+
raise ValueError("parameters s, t, and use_edge_labels can not "
8097+
"be used in combination with algorithm 'heuristic'")
80598098

80608099
# Quick improvement
80618100
if not self.is_connected():
@@ -8100,8 +8139,8 @@ def longest_path(self, s=None, t=None, use_edge_labels=False, algorithm="MILP",
81008139
from sage.graphs.graph import Graph
81018140
return [0, Graph()] if use_edge_labels else Graph()
81028141

8103-
# Calling the backtrack heuristic if asked
8104-
if algorithm == "backtrack":
8142+
# Calling the heuristic if asked
8143+
if algorithm == "heuristic":
81058144
from sage.graphs.generic_graph_pyx import find_hamiltonian as fh
81068145
x = fh(self, find_path=True)[1]
81078146
return self.subgraph(vertices=x, edges=list(zip(x[:-1], x[1:])))

0 commit comments

Comments
 (0)