Repository: networkx/networkx

Issue:
Travelling Salesman Problem takes too long for directed graphs
<!-- If you have a general question about NetworkX, please use the discussions tab to create a new discussion -->

<!--- Provide a general summary of the issue in the Title above -->

### Current Behavior

<!--- Tell us what happens instead of the expected behavior -->

Calculating a TSP approximation via `nx.approximation.traveling_salesman_problem` takes too long for directed graphs. Even for directed graphs with 6 nodes, the procedure takes multiple minutes.

### Expected Behavior

The solution should be calculated within a few seconds. For directed graphs, the TSP approximation is really fast.

### Steps to Reproduce

<!--- Provide a minimal example that reproduces the bug -->

```
graph = nx.DiGraph()
graph.add_nodes_from(range(6))
graph.add_weighted_edges_from((s, t, s + t) for s in graph.nodes() for t in graph.nodes() if s != t)
tour = nx.approximation.traveling_salesman_problem(graph)
```

### Environment

<!--- Please provide details about your local environment -->

Python version: 3.10
NetworkX version: 3.1

### Additional context

<!--- Add any other context about the problem here, screenshots, etc. -->



Discussion:
There are multiple different approximation algorithms which you can use for the `traveling_salesman_problem` function. For directed graphs, the default is the Asadpour[^1] method because it actually has an approximation bound, unlike the threshold accepting and simulated annealing methods, and doesn't require extra inputs like an initial solution. 

However, it is slower than the other two and in my experience very inconsistent. Your graph takes around 8 minutes on my computer (nx 3.1, python 3.11.4) but the six vertex graph in the [test suit](https://github.com/networkx/networkx/blob/e4463a4f38bcdce1b6a95b1bdfaf762cbf80ddf7/networkx/algorithms/approximation/tests/test_traveling_salesman.py#L766) only takes about 0.43 seconds. 

According to this script, the other methods are actually many times faster than the default method.

```python
import networkx as nx
import time
from datetime import timedelta

graph = nx.DiGraph()
graph.add_nodes_from(range(6))
graph.add_weighted_edges_from((s, t, s + t) for s in graph.nodes() for t in graph.nodes() if s != t)
for n, m in zip(["Treshold Accepting,", "Simulated Annealing,", "Asadpour,"],
                [lambda G, w: nx.approximation.threshold_accepting_tsp(G, "greedy", w), 
                 lambda G, w : nx.approximation.simulated_annealing_tsp(G, "greedy", w), 
                 nx.approximation.asadpour_atsp]):
    start = time.time()
    tour = nx.approximation.traveling_salesman_problem(graph, method=m)
    end = time.time()
    print(f"Name: {n:20} Duration: {timedelta(seconds=end - start)}, Route: {tour}, Cost: {sum([graph[tour[i]][tour[i+1]]['weight'] for i in range(len(tour) - 1)])}")
```
```
Name: Treshold Accepting,  Duration: 0:00:00.045257, Route: [0, 1, 2, 3, 4, 5, 0], Cost: 30
Name: Simulated Annealing, Duration: 0:00:00.005363, Route: [0, 1, 2, 3, 4, 5, 0], Cost: 30
Name: Asadpour,            Duration: 0:08:34.207166, Route: [1, 2, 3, 5, 0, 4, 1], Cost: 30
```
It is worth noting that for `threshold_accepting_tsp` and `simulated_annealing_tsp` the documentation for `G` states it should be undirected, but the methods work will with directed graphs and even the examples in the documentation use directed graphs. We should at the very least update the documentation to more explicitly states that these methods can be used for directed graphs. 

[^1]: A. Asadpour, M. X. Goemans, A. Madry, S. O. Gharan, and A. Saberi, An O (log n / log log n)-approximation algorithm for the asymmetric traveling salesman problem, SODA ’10, Society for Industrial and Applied Mathematics, 2010, p. 379 - 389 https://dl.acm.org/doi/abs/10.5555/1873601.1873633.

Resolving patch:
diff --git a/networkx/algorithms/approximation/traveling_salesman.py b/networkx/algorithms/approximation/traveling_salesman.py
--- a/networkx/algorithms/approximation/traveling_salesman.py
+++ b/networkx/algorithms/approximation/traveling_salesman.py
@@ -1033,7 +1033,7 @@ def simulated_annealing_tsp(
     Parameters
     ----------
     G : Graph
-        `G` should be a complete weighted undirected graph.
+        `G` should be a complete weighted graph.
         The distance between all pairs of nodes should be included.
 
     init_cycle : list of all nodes or "greedy"
@@ -1249,7 +1249,7 @@ def threshold_accepting_tsp(
     Parameters
     ----------
     G : Graph
-        `G` should be a complete weighted undirected graph.
+        `G` should be a complete weighted graph.
         The distance between all pairs of nodes should be included.
 
     init_cycle : list or "greedy"


Test patch: