Sei sulla pagina 1di 4

1

Authors, date, assignment

Authors : C.C. Valkenet s2373092


Date: 31 october 2014
Assignment: Taveling Salesman Problem

Problem description

The Travelling Salesman Problem(TSP) is the following: Given a collection of n cities, find the
shortest route that visits every city exactly once. The real problem with this is the amount of
routes that has to be checked, namely n! routes. This grows to be a very large number very
quickly, and thus its not plausible to check all routes to find the shortest one available.

Problem analysis

As checking all the available routes is not an option, well use an approximation based on a technique for strengthening steel, namely annealing. This technique teaches us that we have to accept
a worse solution at times so we can get to a better one eventually. If we can simulate the settling
of atoms in lower energy positions, we can achieve increasingly better routes.

Design

The program first fills the entire array with NMAX cities, each city consisting out of an x and y
position. These x and y positions are randomly generated variables. Next it will loop through all
the possible pairs of cities and compute the distances between them, which then get stored in the
distance[NMAX][NMAX] array, where NMAX stands for the actual city. This array will late be
useful for calculating the total distance (energy) of the path. The actual path array at this point
is still empty, so it should be filled. The easiest way to do this is to just enter the cities in order, as
such setting path[i] = i; in a loop from 0 to NMAX. We now have a path with every city in it once.
Now the initial setup is complete, we can start the annealing process. This process consists
of computing the total energy from a path, then taking a random permutation from this path and
computing its total energy as well. This random path is generated by taking the current path and
performing one or several permutations on it, namely swapping two random cities, inverting an arbitrarily chosen part of the array and rotating the array one position. The energies of the paths get
compared by subtraction (eDifference = energy - energyTemp), and if the random path has a lower
energy, it will replace the current path. If the random path has a higher energy, theres a chance
it still gets replaced with the current path. This chance is probability P = ee Dif f erence/T .
Since e0 is 1, we know that with a negative eDifference probability will yield a value between 0
and 1. This means we can generate a random number between 0 and 1, and compare this to our
probability. On basis of this we can perform the swap of the paths.
We repeat this process NMAX times for each given temperature. The temperature t is an
arbitrarily chosen number which can be set to any preferred value, increasing or decreasing the
amount of iterations the program makes in the process. After the NMAX routes have been checked
the temperature gets changed, namely t = t * 0.99. The complete program finishes once a certain
(variable) temperature has been reached.

For testing and general purpose, the program outputs the fastest route computed and with it
the energy value attached to that path.

Program code
tsp.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

/*
============================================================================
Name : tsp.c
Author : Cas Valkenet s2373092
Description : Traveling Salesman Problem Approximation
============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define NMAX 50
int
int
int
int
int

city[NMAX][2]; // x and y coordinates for each city


distance[NMAX][NMAX]; // distance between cities
path[NMAX]; // the path
arrRandom[NMAX]; // placeholder for random permutation on path
pathEnergy;

void invert(int arr[], int start, int end){


int i, j;
int invert[NMAX];
j = start;
for (i = end; i >= start; i--){
invert[i] = arr[j];
j++;
}
for (i = start; i <= end; i++){
arr[i] = invert[i];
}
}
void swap(int i, int j, int arr[]){
int h = arr[i];
arr[i] = arr[j];
arr[j] = h;
}
void rotate(int arr[]){ // rotates the entire array downwards
int i;
int h = arr[0];
for(i=0; i<NMAX; i++){
arr[i] = arr[i+1];
}
arr[NMAX-1] = h;
}
void randomArray(int arr[]){ // Creates a permutation of current path[] in
arrRandom[]

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

int i ,r1 = rand() % 100;


int r2 = rand() % 100;
int r3 = rand() % 100;
int rN4 = rand() % NMAX;
int rN3 = rand() % NMAX;
int rN2 = rand() % NMAX;
int rN1 = rand() % NMAX;
for(i=0; i<NMAX; i++){
arrRandom[i] =arr[i];
}
if(r1<80){
rotate(arrRandom);
}
if(r2<60){
if(rN1 < rN2){
invert(arrRandom, rN1, rN2);
} else {
invert(arrRandom, rN2, rN1);
}
}
if(r3>30){
swap(rN3, rN4, arrRandom);
}
}
void eDiff(int arr[], double t){
int city1, city2, i, energy = 0, energyTemp=0;
randomArray(arr);
for(i=0; i<NMAX ; i++){
city1 = arr[i];
city2 = arr[i+1];
energy += distance[city1][city2];
city1 = arrRandom[i];
city2 = arrRandom[i+1];
energyTemp += distance[city1][city2];
}
//printf("%d \n", energy-energyTemp);
if(energy-energyTemp < 0){
float r = ((double) rand() ) / ((double) RAND_MAX);
float p, e = 2.718281828;
p = pow(e, (energy-energyTemp/t));
if(r<p){
for(i=0; i<NMAX ; i++){
arr[i] = arrRandom[i];
}
pathEnergy = energyTemp;
} else {
pathEnergy = energy;
}
} else {
for(i=0; i<NMAX ; i++){
arr[i] = arrRandom[i];
pathEnergy = energyTemp;
}
}
}
int computeDistance(int city1, int city2){

108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

int xDiff, yDiff, difference;


xDiff = city[city1][1]-city[city2][1];
yDiff = city[city1][2]-city[city2][2];
difference = pow(xDiff, 2) + pow(yDiff, 2);
difference = sqrt(difference);
return difference;
}
void annealing(int path[], double t){
int i;
if(t<20){
return NULL;
}
for(i=0; i<NMAX ; i++){
eDiff(path, t);
}
t = t * 0.99;
return annealing(path, t);
}
int main(void) {
int i, j, x, y;
double t = 50;
for(i=0; i<NMAX ;i++){
x= rand() % 100;
y = rand() % 100;
city[i][1] = x;
city[i][2] = y;
}
for(i=0; i<NMAX ;i++){
for(j=0; j<NMAX ;j++){
distance[i][j] = computeDistance(i,j);
}
}
for(i=0; i < NMAX ; i++){
path[i]=i;
}
annealing(path, t);
printf("Program is done!\n");
printf("Fastest route computed was: \n");
for(i=0; i< NMAX; i++){
printf("Destination: %d city: %d \n", i+1 , path[i]);
}
printf("Total energy of path: %d \n", pathEnergy);
return 0;
}

Evaluation and Conclusions

The traveling salesman problem is one that is difficult mainly because of its vast size. This method
of annealing paths will reach a variety of different paths, most of them probably not being the
most optimal one. However this way a pretty close estimate can be made without dedicating too
much computing power to the program.

Potrebbero piacerti anche