You are on page 1of 18

Travelling Salesperson Problem (TSP)

Algorithm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
procedure SALESMAN(C, N, R, l_path)
begin
INSERT_FIRST_NODES(stack);
for numberOfLinks = 2 to N - 1 do
begin
for node = 2 to N do
CREATE LIST(node, stack, list)
NEW STACK ELEMENT(stack, list)
end;
end;
FINISH_LIST(stack, list);
NEW STACK ELEMENT(stack, list)
FIND_SOLUTION(R, stack, l_path)
RELEASE_STACK(stack)
end


Algorithm ( with Backtracking )
For instance, here's a simple graph (I can't use drawings in these columns, so I write down
the graph's arcs):
A -> B
A -> C
B -> C
B -> D
C -> D
D -> C
E -> F
F -> C

This graph has six nodes (A-F) and eight arcs. It can be represented by the following
Python data structure:
graph = {'A': ['B', 'C'],
'B': ['C', 'D'],
'C': ['D'],
'D': ['C'],
'E': ['F'],
'F': ['C']}

A sample run (using the graph above):
>>> find_path(graph, 'A', 'D')
['A', 'B', 'C', 'D']
>>>












Algorithm ( List of All Paths , without cycles )

A sample run:
>>> find_all_paths(graph, 'A', 'D')
[['A', 'B', 'C', 'D'], ['A', 'B', 'D'], ['A', 'C', 'D']]
>>>














def find_path(graph, start, end, path=[]):
path = path + [start]
if start == end:
return path
if not graph.has_key(start):
return None
for node in graph[start]:
if node not in path:
newpath = find_path(graph,
node, end, path)
if newpath: return newpath
return None

def find_all_paths(graph, start, end,
path=[]):
path = path + [start]
if start == end:
return [path]
if not graph.has_key(start):
return []
paths = []
for node in graph[start]:
if node not in path:
newpaths =
find_all_paths(graph, node, end, path)
for newpath in newpaths:
paths.append(newpath)
return paths

Program 1
#include <stdio.h>
int main(){
int N, K, M, i, distance_motel_start=0, tab_of_total_distance[];
printf("Please type, distance (in km) you want to cover on the route\n");
scanf("%d", N);
printf("Please type, range (in km) of your car per 1 day\n");
scanf("%d", K);
printf("Please type number of motels which are available on the journey\n);
scanf("%d", M);
int i=1;
while (i<M){
++i;
printf("Please type distance between the motel and starting point);
scanf("%d", &distance_motel_start);
tab_of_total_distance[]++;
}


if(tab_of_total_distance[]>N){
printf("WRONG SPECIFICATION");

}
return 0;
}


Program 2
#include<stdio.h>
#include<conio.h>
int main()
{
int cost[20][20],min,l,m,sr[20],sc[20],flag[20][20],i,j,k,rf[20],cf[20],n;
int nrz[20],ncz[20],cn,a,noz,nrz1[20],ncz1[20],counter =0;
printf("\n\nEnter the total number of assignments:");
scanf("%d",&n);

printf("\nEnter the cost matrix\n");
for(i=0;i<n;i++)
{
printf("\n");
for(j=0;j<n;j++)
{
printf("cost[%d][%d] = ",i,j);
scanf("%d",&cost[i][j]);
}
}
printf("\n\n");
printf("Cost matrix:\n");

for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
printf("\t%d\t",cost[i][j]);
printf("\n");
}

for(i=0;i<n;i++)
{
min=cost[i][0];
for(j=0;j<n;j++)
{
if(min>cost[i][j])
min=cost[i][j];
}
for(j=0;j<n;j++)
cost[i][j]=cost[i][j]-min;
}
for(i=0;i<n;i++)
{
min=cost[0][i];
for(j=0;j<n;j++)
{
if(min>cost[j][i])
min=cost[j][i];
}
/
for(j=0;j<n;j++)
cost[j][i]=cost[j][i]-min;
}
printf("\n\n");
printf("Cost matrix after row & column operation:\n");
for(i=0;i<n;i++)
{ for(j=0;j<n;j++)
printf("\t%d\t",cost[i][j]);
printf("\n");
}
repeatx:;
a=0;noz=0,min=1000;
for(i=0;i<n;i++)
{ for(j=0;j<n;j++)
flag[i][j]=0;
}
for(i=0;i<n;i++)
{ cn=0;
for(j=0;j<n;j++)
{ if(cost[i][j]==0)
{ cn++;
flag[i][j]=1;
}
}
nrz[i]=cn;
noz=noz+cn;
}
for(i=0;i<n;i++)
{ cn=0;
for(j=0;j<n;j++)
{ if(cost[j][i]==0)
{ cn++;
flag[j][i]=1;
}
}
ncz[i]=cn;
noz=noz+cn;
}
for(i=0;i<n;i++)
{ nrz1[i]=nrz[i];
ncz1[i]=ncz[i];
}
k=0;
while(nrz[k]!=0||ncz[k]!=0)
{
for(i=0;i<n;i++)
{ cn=0;
for(j=0;j<n;j++)
{ if(flag[i][j]==1)
cn++;
nrz[i]=cn;
}
if(nrz[i]==1)
{ for(j=0;j<n;j++)
{ if(flag[i][j]==1)
{ flag[i][j]=2;
for(k=0;k<n;k++)
{ if(flag[k][j]==1)
flag[k][j]=0;
}
}
}
}
}
for(i=0;i<n;i++)
{ cn=0;
for(j=0;j<n;j++)
{ if(flag[j][i]==1)
cn++;
ncz[i]=cn;
}
if(ncz[i]==1)
{ for(j=0;j<n;j++)
{ if(flag[j][i]==1)
{ flag[j][i]=2;
for(k=0;k<n;k++)
{ if(flag[j][k]==1)
flag[j][k]=0;
}
}
}
}
}
k++;
}
for(i=0;i<n;i++)
{ for(j=0;j<n;j++)
{ if(flag[i][j]==2)
a++;
}
}

/* If minimum number of lines, a is equal to the order of the matrix n then
assignment can be optimally completed.*/
if(a==n)
{
printf("\nAssignments completed in order!!\n");
/* Display the order in which assignments will be completed*/
for(i=0;i<n;i++)
{ for(j=0;j<n;j++)
{ if(flag[i][j]==2)
printf(" %d->%d ",i+1,j+1);
}
printf("\n");
}
getch();
exit(0);
}
/* if order of matrix and number of lines is not same then its difficult to
find the optimal solution.
Now determine the smallest uncovered element i.e. element not covered by lines
and then subtract this minimum element from all uncovered elements and add the
same elements at the intersection of horizontal and vertical lines.*/
else
{ for(i=0;i<n;i++)
{ rf[i]=0,sr[i]=0;
cf[i]=0,sc[i]=0;
}
for(k=n;(k>0&&noz!=0);k--)
{ for(i=0;i<n;i++)
{ m=0;
for(j=0;j<n;j++)
{ if((flag[i][j]==4)&&(cost[i][j]==0))
m++;
}
sr[i]=m;
}
for(i=0;i<n;i++)
{ if(nrz1[i]==k&&nrz1[i]!=sr[i])
{ rf[i]=1;
for(j=0;j<n;j++)
{ if(cost[i][j]==0)
flag[i][j]=4;
}
noz=noz-k;
}
}
for(i=0;i<n;i++)
{
l=0;
for(j=0;j<n;j++)
{ if((flag[j][i]==4)&&(cost[j][i]==0))
l++;
}
sc[i]=l;
}
for(i=0;i<n;i++)
{ if(ncz1[i]==k&&ncz1[i]!=sc[i])
{ cf[i]=1;
for(j=0;j<n;j++)
{ if(cost[j][i]==0)
flag[j][i]=4;
}
noz=noz-k;
}
}
for(i=0;i<n;i++)
{ for(j=0;j<n;j++)
{ if(flag[i][j]!=3)
{ if(rf[i]==1&&cf[j]==1)
{ flag[i][j]=3;
if(cost[i][j]==0)
noz=noz+1;
}
}
}
}
}
for(i=0;i<n;i++)
{ for(j=0;j<n;j++)
{ if(rf[i]!=1&&cf[j]!=1)
{ if(min>cost[i][j])
min=cost[i][j];
}
}
}
for(i=0;i<n;i++)
{ for(j=0;j<n;j++)
{ if(rf[i]!=1&&cf[j]!=1)
cost[i][j]=cost[i][j]-min;
}
}
for(i=0;i<n;i++)
{ for(j=0;j<n;j++)
{ if(flag[i][j]==3)
cost[i][j]=cost[i][j]+min;
}
}
}
printf("\n\n");
if (counter < 10)
{
counter = counter+1;
printf("\n\nIntermediate Matrix: \n");
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
printf("\t%d\t",cost[i][j]);
printf("\n");
}
}
else
{
printf("\n\nOptimal solution to given problem is not possible");
getch();
return 0;
}
goto repeatx;
}

Program 3
#include <iostream>
#include <string>
#include <algorithm>
using namespace::std;

void main(){

int dest[4][5]; //This array is going to hold the number equivalent
of the city inputted. The other value it holds is the distance
string cities[4];
int cityindex[] = {0,1,2,3};
int bestroute[4];
int shortestpath = 99999;
int currentpath = 0;

cout << "Please enter four city prefixes..." << endl;

for(int i=0; i<4; i++){

cout << i+1 << ".";
cin >> cities[i];
}

cout << endl << "Now we need some distances..." <<endl;
cout << "The first distance is from home to the first city."<<endl;
cout << "All other distances are from city A to city B. When asked for
the same city, please input 0 as the distance." << endl;

for(int x=0; x<4; x++){
cout << "Distances for "<< cities[x] << ":"<<endl;

for(int y=0; y<5; y++){
if(y < 1){
cout << "Home:";
}else{
cout << cities[y-1] << ":";
}

cin >> dest[x][y];
}
}

sort(cityindex, cityindex+3);

do {

currentpath = 0;
currentpath = dest[cityindex[0]][0];
for(int z=0; z<3; z++){
int g = z + 1;
currentpath += dest[cityindex[z]][cityindex[g]];
}
if(currentpath < shortestpath){
shortestpath = currentpath;
for(int a=0; a<4; a++){
bestroute[a] = cityindex[a];
}
}

} while ( next_permutation (cityindex,cityindex+3) );

cout << "The Shortest Route is.." << endl;
for(int b=0; b<4; b++){
cout << cities[bestroute[b]] << " ";
}


cin.ignore();
cin.clear();
cin.get();

return;
}





















BREADTH FIRST SEARCH (BFS)

Algorithm
ef paths(graph, start, end):
todo = [[start, [start]]]
while 0 < len(todo):
(node, path) = todo.pop(0)
for next_node in graph[node]:
if next_node in path:
continue
elif next_node == end:
yield path + [next_node]
else:
todo.append([next_node, path + [next_node]])
And an example of how to use it:
graph = {'A': ['B', 'C'],
'B': ['C', 'D'],
'C': ['D'],
'D': ['C'],
'E': ['F'],
'F': ['C']}

for path in paths(graph, 'A', 'D'):
print path


Program 1
# graph is in adjacent list representation
graph = {
'1': ['2', '3', '4'],
'2': ['5', '6'],
'5': ['9', '10'],
'4': ['7', '8'],
'7': ['11', '12']
}

def bfs(graph, start, end):
# maintain a queue of paths
queue = []
# push the first path into the queue
queue.append([start])
while queue:
# get the first path from the queue
path = queue.pop(0)
# get the last node from the path
node = path[-1]
# path found
if node == end:
return path
# enumerate all adjacent nodes, construct a new path and push it into the
queue
for adjacent in graph.get(node, []):
new_path = list(path)
new_path.append(adjacent)
queue.append(new_path)

print bfs(graph, '1', '11')

PROGRAM 2
Another approach would be maintaining a mapping from each node to its parent, and when
inspecting the ajacent node, record its parent. When the search is done, simply backtrace according
the parent mapping.
graph = {
'1': ['2', '3', '4'],
'2': ['5', '6'],
'5': ['9', '10'],
'4': ['7', '8'],
'7': ['11', '12']
}

def backtrace(parent, start, end):
path = [end]
while path[-1] != start:
path.append(parent[path[-1]])
path.reverse()
return path


def bfs(graph, start, end):
parent = {}
queue = []
queue.append(start)
while queue:
node = queue.pop(0)
if node == end:
return backtrace(parent, start, end)
for adjacent in graph.get(node, []):
parent[adjacent] = node # <<<<< record its parent
queue.append(adjacent)

print bfs(graph, '1', '11')

PROGRAM -3
# a sample graph
graph = {'A': ['B', 'C','E'],
'B': ['A','C', 'D'],
'C': ['D'],
'D': ['C'],
'E': ['F','D'],
'F': ['C']}

class MyQUEUE: # just an implementation of a queue

def __init__(self):
self.holder = []

def enqueue(self,val):
self.holder.append(val)

def dequeue(self):
val = None
try:
val = self.holder[0]
if len(self.holder) == 1:
self.holder = []
else:
self.holder = self.holder[1:]
except:
pass

return val

def IsEmpty(self):
result = False
if len(self.holder) == 0:
result = True
return result


path_queue = MyQUEUE() # now we make a queue


def BFS(graph,start,end,q):

temp_path = [start]

q.enqueue(temp_path)

while q.IsEmpty() == False:
tmp_path = q.dequeue()
last_node = tmp_path[len(tmp_path)-1]
print tmp_path
if last_node == end:
print "VALID_PATH : ",tmp_path
for link_node in graph[last_node]:
if link_node not in tmp_path:
new_path = []
new_path = tmp_path + [link_node]
q.enqueue(new_path)

BFS(graph,"A","D",path_queue)

-------------results-------------------
['A']
['A', 'B']
['A', 'C']
['A', 'E']
['A', 'B', 'C']
['A', 'B', 'D']
VALID_PATH : ['A', 'B', 'D']
['A', 'C', 'D']
VALID_PATH : ['A', 'C', 'D']
['A', 'E', 'F']
['A', 'E', 'D']
VALID_PATH : ['A', 'E', 'D']
['A', 'B', 'C', 'D']
VALID_PATH : ['A', 'B', 'C', 'D']
['A', 'E', 'F', 'C']
['A', 'E', 'F', 'C', 'D']
VALID_PATH : ['A', 'E', 'F', 'C', 'D']

PROGRAM -4
// Program to print BFS traversal from a given source vertex. BFS(int s)
// traverses vertices reachable from s.
#include<iostream>
#include <list>

using namespace std;

// This class represents a directed graph using adjacency list
representation
class Graph
{
int V; // No. of vertices
list<int> *adj; // Pointer to an array containing adjacency lists
public:
Graph(int V); // Constructor
void addEdge(int v, int w); // function to add an edge to graph
void BFS(int s); // prints BFS traversal from a given source s
};

Graph::Graph(int V)
{
this->V = V;
adj = new list<int>[V];
}

void Graph::addEdge(int v, int w)
{
adj[v].push_back(w); // Add w to vs list.
}

void Graph::BFS(int s)
{
// Mark all the vertices as not visited
bool *visited = new bool[V];
for(int i = 0; i < V; i++)
visited[i] = false;

// Create a queue for BFS
list<int> queue;

// Mark the current node as visited and enqueue it
visited[s] = true;
queue.push_back(s);

// 'i' will be used to get all adjacent vertices of a vertex
list<int>::iterator i;

while(!queue.empty())
{
// Dequeue a vertex from queue and print it
s = queue.front();
cout << s << " ";
queue.pop_front();

// Get all adjacent vertices of the dequeued vertex s
// If a adjacent has not been visited, then mark it visited
// and enqueue it
for(i = adj[s].begin(); i != adj[s].end(); ++i)
{
if(!visited[*i])
{
visited[*i] = true;
queue.push_back(*i);
}
}
}
}

// Driver program to test methods of graph class
int main()
{
// Create a graph given in the above diagram
Graph g(4);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(2, 0);
g.addEdge(2, 3);
g.addEdge(3, 3);

cout << "Following is Breadth First Traversal (starting from vertex 2)
\n";
g.BFS(2);

return 0;
}


OUTPUT :

Following is Breadth first Traversal (starting from vertex 2)

2 0 3 1








GRAPH = {1 : [2,3], 2:[4,5], 3:[6], 4:None, 5:[7,8], 6:None, 7:None, 8:None}
def BFS(start, target, GRAPH):
'Use a QUEUE to search.'
print "Source:",source,"Target:",target
queue = [start]
visited = []

while len(queue) > 0:
x = queue.pop(0)

if x == target:
visited.append(x)
return visited
elif x not in visited:
visited = visited+[x]
if GRAPH[x] is not None:
'add nodes at the END of the queue'
queue = queue + GRAPH[x]
return visited

def DFS(start, target, GRAPH):
'Use a STACK to search.'
print "Source:",source,"Target:",target
stack = [start]
visited = []

while len(stack) > 0:
x = stack.pop(0)

if x == target:
visited.append(x)
return visited
elif x not in visited:
visited = visited+[x]
if GRAPH[x] is not None:
'add nodes at the top of the stack'
stack = GRAPH[x] + stack
return visited
print "BFS Path",BFS(1,7,GRAPH)
print "DFS Path",DFS(1,7,GRAPH)
print "="*80
print "BFS Path",BFS(1,3,GRAPH)
print "DFS Path",DFS(1,3,GRAPH)

OUTPUT :

1
2
3
4
5
6
7
8
9
10
$ python graph.py
BFS Path Source: 1 Target: 7
[1, 2, 3, 4, 5, 6, 7]
DFS Path Source: 1 Target: 7
[1, 2, 4, 5, 7]
================================================================================
BFS Path Source: 1 Target: 3
[1, 2, 3]
DFS Path Source: 1 Target: 3
[1, 2, 4, 5, 7, 8, 3]


DEPTH FIRST SEARCH (DFS)

PROGRAM -1
#include<iostream>
#include <list>

using namespace std;

// Graph class represents a directed graph using adjacency list
representation
class Graph
{
int V; // No. of vertices
list<int> *adj; // Pointer to an array containing adjacency lists
void DFSUtil(int v, bool visited[]); // A function used by DFS
public:
Graph(int V); // Constructor
void addEdge(int v, int w); // function to add an edge to graph
void DFS(int v); // DFS traversal of the vertices reachable from v
};

Graph::Graph(int V)
{
this->V = V;
adj = new list<int>[V];
}

void Graph::addEdge(int v, int w)
{
adj[v].push_back(w); // Add w to vs list.
}

void Graph::DFSUtil(int v, bool visited[])
{
// Mark the current node as visited and print it
visited[v] = true;
cout << v << " ";

// Recur for all the vertices adjacent to this vertex
list<int>::iterator i;
for(i = adj[v].begin(); i != adj[v].end(); ++i)
if(!visited[*i])
DFSUtil(*i, visited);
}

// DFS traversal of the vertices reachable from v. It uses recursive
DFSUtil()
void Graph::DFS(int v)
{
// Mark all the vertices as not visited
bool *visited = new bool[V];
for(int i = 0; i < V; i++)
visited[i] = false;

// Call the recursive helper function to print DFS traversal
DFSUtil(v, visited);
}

int main()
{
// Create a graph given in the above diagram
Graph g(4);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(2, 0);
g.addEdge(2, 3);
g.addEdge(3, 3);

cout << "Following is Depth First Traversal (starting from vertex 2)
\n";
g.DFS(2);

return 0;
}


OUTPUT:

Following is Depth First Traversal ( starting from vertex 2)

2 0 1 3

You might also like