Blog # 05 : Solving Traveling Salesman Problem
Program to solve Traveling Salesman Problem
/*
+-------Program to solve traveling salesman problem-----------------------+
| |
| efficiency: O(n^4) |
| optimality: I think yes!!!!!! |
| but still under test for different graphs |
| so PLEASE:::send me the test cases along with the optimal solution |
| where my algorithm fails to give the optimal solution. |
| Free to use and/or distribute for non-commercial purposes. |
+------------------------------------------------------------------------------------+
*/
/*
example:
2
[0]-------[1]
| \4 /|
| \ / |
3| /\ |3
| 6/ \ |
[3]-------[2]
1
inputs:
infinity:999
no. of cities: 4
no. of paths:6
S D Dist
path0:0 1 2
path0:0 2 4
path0:0 3 3
path0:1 2 3
path0:1 3 6
path0:2 3 1
*/
#include<stdio.h>
#include<conio.h>
#define ALL -1
#define MAXCITIES 10
enum BOOL{FALSE,TRUE};
long*visited;//visited nodes set here
long*min_circuit;//min inner circuit for given node as start node at position indexed 0
long*ham_circuit;//optimal circuit with length stored at position indexed 0
long min_circuit_length;//min circuit length for given start node
int n;//city count
long matrix[MAXCITIES][MAXCITIES];//non directional n*n symmetric matrix
//to store path distances as source*destination
long INFI; // INFINITY value to be defined by user
// function resets minimum circuit for a given start node
//with setting its id at index 0 and setting further node ids to -1
void reset_min_circuit(int s_v_id)
{
min_circuit[0]=s_v_id;
for(int i=1;i<n;i++) min_circuit[i]=-1;
}
// marks given node id with given flag
// if id==ALL it marks all nodes with given flag
void set_visited(int v_id,BOOL flag)
{
if(v_id==ALL) for(int i=0;i<n;i++) visited[i]=flag;
else visited[v_id]=flag;
}
// function sets Hamiltonian circuit for a given path length
//with setting it at index 0 and setting further nodes from current min_circuit
void SET_HAM_CKT(long pl)
{
ham_circuit[0]=pl;
for(int i=0;i<n;i++) ham_circuit[i+1]=min_circuit[i];
ham_circuit[n+1]=min_circuit[0];
}
//function sets a valid circuit by finding min inner path for a given
//combination start vertex and next vertex to start vertex such that
// the 2nd vertex of circuits is always s_n_v and start and dest node is
//always s_v for all possible values of s_n_v, and then returns the
// valid circuit length for this combination
long get_valid_circuit(int s_v,int s_n_v)
{
int next_v,min,v_count=1;
long path_length=0;
min_circuit[0]=s_v;
min_circuit[1]=s_n_v;
set_visited(s_n_v,TRUE);
path_length+=matrix[s_v][s_n_v];
for(int V=s_n_v;v_count<n-1;v_count++)
{ min=INFI;
for(int i=0;i<n;i++)
if( matrix[V][i]<INFI && !visited[i]
&& matrix[V][i]<=min
)
min=matrix[V][next_v=i];
set_visited(next_v,TRUE);
V=min_circuit[v_count+1]=next_v;
path_length+=min;
}
path_length+=matrix[min_circuit[n-1]][s_v];
return(path_length);
}
int main()
{
//clrscr();
printf("Make sure that infinity value < sum of all path distances\n Set Infinity at (signed long):");
scanf("%ld",&INFI);
int pathcount,i,j,source,dest;
long dist=0;
long new_circuit_length=INFI;
printf("Enter no. of cities(MAX:%d):",MAXCITIES);
scanf("%d",&n);
printf("Enter path count:");
scanf("%d",&pathcount);
printf("Enter paths:< source_id destination_id distance >\n ids varying from 0 to %d\n",n-1);
//init all matrix distances to infinity
for(i=0;i<n;i++)
for(j=0;j<n;j++)
matrix[i][j]=INFI;
//populate the matrix
for(i=0;i<pathcount;i++)
{
printf("[path %d]:",i);
scanf("%d %d %ld",&source,&dest,&dist);
if(source!=dest)
matrix[source][dest]=matrix[dest][source]=dist;
}
visited=new long[n];
min_circuit=new long[n];
ham_circuit=new long[n+2];
min_circuit_length=INFI;
// algorithm
//for each vertex, S_V as a staring node
for(int S_V_id=0;S_V_id<n;S_V_id++)
{ //for each and non start vertex as i
for(i=0;i<n;i++)
{ //set all to unvisited
set_visited(ALL,FALSE);
// set staring vertex as visited
set_visited(S_V_id,TRUE);
//reset/init minimum circuit
reset_min_circuit(S_V_id);
// obtain circuit for combination of S_V and i
new_circuit_length=get_valid_circuit(S_V_id,i);
// if newer length is less than the previously
//calculated min then set it as min and set the
//current circuit in hamiltonion circuit
if(new_circuit_length<=min_circuit_length)
SET_HAM_CKT(min_circuit_length=new_circuit_length);
}
}
// if any circuit found
if(min_circuit_length<INFI)
{
printf("\n\nMinimum circuit length is: %ld\nCircuit is:\n",min_circuit_length);
for(i=1;i<n+2;i++) printf("<%ld> ",ham_circuit[i]);
}
else printf("\n\nNo hamiltonian circuit !");
getch();
delete []visited;
delete []min_circuit;
delete []ham_circuit;
}
+-------Program to solve traveling salesman problem-----------------------+
| |
| efficiency: O(n^4) |
| optimality: I think yes!!!!!! |
| but still under test for different graphs |
| so PLEASE:::send me the test cases along with the optimal solution |
| where my algorithm fails to give the optimal solution. |
| Free to use and/or distribute for non-commercial purposes. |
+------------------------------------------------------------------------------------+
*/
/*
example:
2
[0]-------[1]
| \4 /|
| \ / |
3| /\ |3
| 6/ \ |
[3]-------[2]
1
inputs:
infinity:999
no. of cities: 4
no. of paths:6
S D Dist
path0:0 1 2
path0:0 2 4
path0:0 3 3
path0:1 2 3
path0:1 3 6
path0:2 3 1
*/
#include<stdio.h>
#include<conio.h>
#define ALL -1
#define MAXCITIES 10
enum BOOL{FALSE,TRUE};
long*visited;//visited nodes set here
long*min_circuit;//min inner circuit for given node as start node at position indexed 0
long*ham_circuit;//optimal circuit with length stored at position indexed 0
long min_circuit_length;//min circuit length for given start node
int n;//city count
long matrix[MAXCITIES][MAXCITIES];//non directional n*n symmetric matrix
//to store path distances as source*destination
long INFI; // INFINITY value to be defined by user
// function resets minimum circuit for a given start node
//with setting its id at index 0 and setting further node ids to -1
void reset_min_circuit(int s_v_id)
{
min_circuit[0]=s_v_id;
for(int i=1;i<n;i++) min_circuit[i]=-1;
}
// marks given node id with given flag
// if id==ALL it marks all nodes with given flag
void set_visited(int v_id,BOOL flag)
{
if(v_id==ALL) for(int i=0;i<n;i++) visited[i]=flag;
else visited[v_id]=flag;
}
// function sets Hamiltonian circuit for a given path length
//with setting it at index 0 and setting further nodes from current min_circuit
void SET_HAM_CKT(long pl)
{
ham_circuit[0]=pl;
for(int i=0;i<n;i++) ham_circuit[i+1]=min_circuit[i];
ham_circuit[n+1]=min_circuit[0];
}
//function sets a valid circuit by finding min inner path for a given
//combination start vertex and next vertex to start vertex such that
// the 2nd vertex of circuits is always s_n_v and start and dest node is
//always s_v for all possible values of s_n_v, and then returns the
// valid circuit length for this combination
long get_valid_circuit(int s_v,int s_n_v)
{
int next_v,min,v_count=1;
long path_length=0;
min_circuit[0]=s_v;
min_circuit[1]=s_n_v;
set_visited(s_n_v,TRUE);
path_length+=matrix[s_v][s_n_v];
for(int V=s_n_v;v_count<n-1;v_count++)
{ min=INFI;
for(int i=0;i<n;i++)
if( matrix[V][i]<INFI && !visited[i]
&& matrix[V][i]<=min
)
min=matrix[V][next_v=i];
set_visited(next_v,TRUE);
V=min_circuit[v_count+1]=next_v;
path_length+=min;
}
path_length+=matrix[min_circuit[n-1]][s_v];
return(path_length);
}
int main()
{
//clrscr();
printf("Make sure that infinity value < sum of all path distances\n Set Infinity at (signed long):");
scanf("%ld",&INFI);
int pathcount,i,j,source,dest;
long dist=0;
long new_circuit_length=INFI;
printf("Enter no. of cities(MAX:%d):",MAXCITIES);
scanf("%d",&n);
printf("Enter path count:");
scanf("%d",&pathcount);
printf("Enter paths:< source_id destination_id distance >\n ids varying from 0 to %d\n",n-1);
//init all matrix distances to infinity
for(i=0;i<n;i++)
for(j=0;j<n;j++)
matrix[i][j]=INFI;
//populate the matrix
for(i=0;i<pathcount;i++)
{
printf("[path %d]:",i);
scanf("%d %d %ld",&source,&dest,&dist);
if(source!=dest)
matrix[source][dest]=matrix[dest][source]=dist;
}
visited=new long[n];
min_circuit=new long[n];
ham_circuit=new long[n+2];
min_circuit_length=INFI;
// algorithm
//for each vertex, S_V as a staring node
for(int S_V_id=0;S_V_id<n;S_V_id++)
{ //for each and non start vertex as i
for(i=0;i<n;i++)
{ //set all to unvisited
set_visited(ALL,FALSE);
// set staring vertex as visited
set_visited(S_V_id,TRUE);
//reset/init minimum circuit
reset_min_circuit(S_V_id);
// obtain circuit for combination of S_V and i
new_circuit_length=get_valid_circuit(S_V_id,i);
// if newer length is less than the previously
//calculated min then set it as min and set the
//current circuit in hamiltonion circuit
if(new_circuit_length<=min_circuit_length)
SET_HAM_CKT(min_circuit_length=new_circuit_length);
}
}
// if any circuit found
if(min_circuit_length<INFI)
{
printf("\n\nMinimum circuit length is: %ld\nCircuit is:\n",min_circuit_length);
for(i=1;i<n+2;i++) printf("<%ld> ",ham_circuit[i]);
}
else printf("\n\nNo hamiltonian circuit !");
getch();
delete []visited;
delete []min_circuit;
delete []ham_circuit;
}
Your blog is good.