@@ -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