3

I want to list all TSP route combinations.

There are 5 vertices and thus 10 edges: enter image description here

All the edges are as follows:

edges = [('A', 'B'), ('A', 'C'), ('A', 'D'), ('A', 'E'), ('B', 'C'), ('B', 'D'), ('B', 'E'), ('C', 'D'), ('C', 'E'), ('D', 'E')]

Note: ('A', 'B') is the same as ('B', 'A'), same goes for the other edges. I want to list all route combinations where you start at A and visit each other number and end at A.

This is what I got so far:

edges = [('A', 'B'), ('A', 'C'), ('A', 'D'), ('A', 'E'), ('B', 'C'), ('B', 'D'), ('B', 'E'), ('C', 'D'), ('C', 'E'), ('D', 'E')]
x = list(itertools.permutations(['A','B','C','D','E', 'A'], 6))

b = 1
for i in x:
    if i[-1] == 'A' and i[0] == 'A':
        print(i, b)
        b += 1

However, I don't want duplicate routes. How do I sort those out? Eg. A->B->C->A is the same as A->C->B->A, and should not be counted/listed twice.

purrp son
  • 51
  • 5

1 Answers1

0

You can use recursion with a generator:

edges = [('A', 'B'), ('A', 'C'), ('A', 'D'), ('A', 'E'), ('B', 'C'), ('B', 'D'), ('B', 'E'), ('C', 'D'), ('C', 'E'), ('D', 'E')]
def all_paths(graph, start, end=None, _flag = None, _pool = [], _seen= []):
   if start == end:
      yield _pool
   else:
      for a, b in graph:
        if a == start and a not in _seen:
          yield from all_paths(graph, b, end=_flag, _flag=_flag, _pool = _pool+[b], _seen =_seen+[a])


results = list(all_paths(edges+[(b, a) for a, b in edges], 'A', _flag = 'A'))
filtered = [a for i, a in enumerate(results) if not any(len(c) == len(a) and all(h in c for h in a) for c in results[:i])]

Output:

[['B', 'C', 'D', 'E', 'A'], ['B', 'C', 'D', 'A'], ['B', 'C', 'E', 'A'], ['B', 'C', 'A'], ['B', 'D', 'E', 'A'], ['B', 'D', 'A'], ['B', 'E', 'A'], ['B', 'A'], ['C', 'D', 'E', 'A'], ['C', 'D', 'A'], ['C', 'E', 'A'], ['C', 'A'], ['D', 'E', 'A'], ['D', 'A'], ['E', 'A']]
Ajax1234
  • 69,937
  • 8
  • 61
  • 102