mirror of
https://github.com/TheAlgorithms/Python.git
synced 2025-02-22 09:12:08 +00:00
Added graphs/travelling_salesman_problem.py
This commit is contained in:
parent
6c92c5a539
commit
bbacd17034
96
graphs/travelling_salesman_problem.py
Normal file
96
graphs/travelling_salesman_problem.py
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
"""
|
||||||
|
Author:- Sanjay Muthu <https://github.com/XenoBytesX>
|
||||||
|
|
||||||
|
The Problem:
|
||||||
|
In the travelling salesman problem you have to find the path
|
||||||
|
in which a salesman can start from a source node and visit all the other nodes
|
||||||
|
ONCE and return to the source node in the shortest possible way
|
||||||
|
|
||||||
|
Complexity:
|
||||||
|
There are n! permutations of all the nodes in the graph and
|
||||||
|
for each permutation we have to go through all the nodes
|
||||||
|
which will take O(n) time per permutation.
|
||||||
|
So the total time complexity will be O(n * n!).
|
||||||
|
|
||||||
|
Time Complexity:- O(n * n!)
|
||||||
|
|
||||||
|
It takes O(n) space to store the list of nodes.
|
||||||
|
|
||||||
|
Space Complexity:- O(n)
|
||||||
|
|
||||||
|
Wiki page:- <https://en.wikipedia.org/wiki/Travelling_salesman_problem>
|
||||||
|
"""
|
||||||
|
|
||||||
|
from itertools import permutations
|
||||||
|
|
||||||
|
|
||||||
|
def floyd_warshall(graph, v):
|
||||||
|
dist = graph
|
||||||
|
for k in range(v):
|
||||||
|
for i in range(v):
|
||||||
|
for j in range(v):
|
||||||
|
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])
|
||||||
|
return dist
|
||||||
|
|
||||||
|
|
||||||
|
def travelling_salesman_problem(graph, v):
|
||||||
|
"""
|
||||||
|
Returns the shortest path that a salesman can take to visit all the nodes
|
||||||
|
in the graph and return to the source node
|
||||||
|
|
||||||
|
The graph in the below testcase looks something like this:-
|
||||||
|
2
|
||||||
|
_________________________
|
||||||
|
| |
|
||||||
|
2 ^ 6 ^
|
||||||
|
(0) <------------> (1) (2)<------>(3)
|
||||||
|
^ ^
|
||||||
|
| 3 |
|
||||||
|
|_______________________________|
|
||||||
|
|
||||||
|
>>> graph = []
|
||||||
|
>>> graph.append([0, 2, 3, float('inf')])
|
||||||
|
>>> graph.append([2, 0, float('inf'), 2])
|
||||||
|
>>> graph.append([3, float('inf'), 0, 6])
|
||||||
|
>>> graph.append([float('inf'), 2, 6, 0])
|
||||||
|
>>> travelling_salesman_problem(graph, 4)
|
||||||
|
13
|
||||||
|
"""
|
||||||
|
|
||||||
|
# See graphs_floyd_warshall.py for implementation
|
||||||
|
shortest_distance_matrix = floyd_warshall(graph, v)
|
||||||
|
nodes = list(range(v))
|
||||||
|
|
||||||
|
min_distance = float("inf")
|
||||||
|
|
||||||
|
# Go through all the permutations of the nodes to find out
|
||||||
|
# which of the order of nodes lead to the shortest distance
|
||||||
|
# Permutations(nodes) returns a list of all permutations of the list
|
||||||
|
# Permutations are all the possible ways to arrange the elements of the list
|
||||||
|
for permutation in permutations(nodes):
|
||||||
|
current_dist = 0
|
||||||
|
current_node = 0
|
||||||
|
|
||||||
|
# Find the distance of the current permutation by going through all the nodes
|
||||||
|
# in order and add the distance between the nodes to the current_dist
|
||||||
|
for node in permutation:
|
||||||
|
current_dist += shortest_distance_matrix[current_node][node]
|
||||||
|
current_node = node
|
||||||
|
|
||||||
|
# Add the distance to come back to the source node
|
||||||
|
current_dist += shortest_distance_matrix[current_node][0]
|
||||||
|
|
||||||
|
# If the current distance is less than the minimum distance found so far,
|
||||||
|
# update the minimum distance
|
||||||
|
# print(permutation, current_dist)
|
||||||
|
min_distance = min(min_distance, current_dist)
|
||||||
|
|
||||||
|
# NOTE: We are assuming 0 is the source node here.
|
||||||
|
|
||||||
|
return min_distance
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import doctest
|
||||||
|
|
||||||
|
doctest.testmod()
|
Loading…
Reference in New Issue
Block a user