Documentos de Académico
Documentos de Profesional
Documentos de Cultura
El Problema Del Viajante de Comercio Inteligencia Articial
El Problema Del Viajante de Comercio Inteligencia Articial
Inteligencia Articial
Vicente J. Ferrer Dalmau (43152879A)
<vicente@jdalmau.es>
1 de abril de 2008
ndice
1. Enunciado
5. Bsqueda A estrella
11
7. Mtodo de escalada
12
8. Comparativa
14
9. Cdigo fuente
9.1.
9.2.
9.3.
9.4.
9.5.
9.6.
9.7.
9.8.
9.9.
AStar . . . . . . .
BranchAndBound .
DepthFirstSearch .
HillClimbing . . .
Main . . . . . . . .
NearestNeighbour .
RoutesMatrix . . .
Town . . . . . . . .
UniformCost . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
17
17
19
22
24
26
36
37
41
42
1. Enunciado
Un seor viajante de comercio debe visitar n ciudades en su trabajo diario c1 , c2 , ...cn de manera
que una de ellas, la ciudad ci , constituye el punto de partida y llegada del camino a seguir en la visita.
Se considera que existen rutas directas entre cada par de ciudades del conjunto considerado, de manera
que cada ruta tiene un costo especco asociado. El problema consiste en determinar, partiendo y llegando a una misma ciudad ci , una ruta ptima que permita visitar las n ciudades consideradas en un
tiempo mnimo. El mencionado problema debe resolverse aplicando cada una de las siguientes tcnicas:
TCNICAS DE BSQUEDA NO INFORMADA
Primero en profundidad.
Primero en profundidad con ramicacin y poda.
Bsqueda de costo uniforme.
TCNICAS DE BSQUEDA INFORMADA
El vecino ms prximo.
Mtodo de escalada.
Bsqueda A*, en la que debe disearse como mnimo- una heurstica haciendo uso de la tcnica
del problema relajado, para calcular la funcin h'.
Debe hacerse un anlisis de cada una de las tcnicas empleadas, determinando los casos en que cada
tcnica funciona mejor/peor; asimismo, deben compararse las diferentes tcnicas, concluyendo sobre
las ventajas de cada una respecto a las dems.
Respecto a la bsqueda A*, debe disearse al menos una heurstica para el clculo de h', utilizando
para ello la tcnica del problema relajado.
Se valorar la capacidad de iniciativa de los estudiantes adems de la presentacin de los resultados
y la calidad del anlisis de cada tcnica.
Tiene un coste temporal exponencial, lo que para problemas grandes lo hace poco recomendable
(en nuestro caso un nmero elevado de ciudades).
En algunos casos el recorrido de ciertas rutas puede conllevar problemas, por ejemplo si tenemos
rutas cclicas o innitas quedaramos estancados, o bien podramos encontrar soluciones no
ptimas despus de grandes recorridos, o incluso llegar a una solucin ptima pero despus de
haber analizado muchas rutas incorrectas. En denitiva y continuando con la conclusin de la
primera desventaja, si la estructura sobre la que realiza la bsqueda es muy grande o innita no
es recomendable usar este algoritmo.
Complejidad temporal:
Complejidad espacial:
Resultados
A continuacin se muestra la evolucin temporal del algoritmo en funcin del nmero de ciudades
del problema. Para cada una de las ejecuciones se atender al nmero de nodos que han sido expandidos
durante la bsqueda (en el caso de este algoritmo siempre se expande el rbol completo):
Nmero de ciudades
4
5
7
8
9
10
11
Nodos expandidos
22
89
2677
18740
149921
1349290
13492901
En el grco puede observarse el claro comportamiento exponencial del algoritmo. Cabe mencionar que slo fue posible ejecutarlo con 11 ciudades cmo mximo.
en rboles de bsqueda muy profundos o incluso innitos. En esos casos se encuentra con un
bucle innito y no devuelve nunca una solucin.
Resultados
En este apartado se muestra la evolucin temporal del algoritmo en funcin del nmero de ciudades
del problema. Para cada una de las ejecuciones se atender al nmero de nodos que han sido expandidos
durante la bsqueda. Hay que decir que para un nmero de ciudades constante, al variar los valores
de su matriz de distancias, el nmero de nodos expandidos variar, es decir, el porcentaje del rbol de
bsqueda que se visita vara.
Nmero de ciudades
4
5
7
8
9
10
11
12
13
14
Nodos expandidos
18
81
259
708
2253
8345
16149
246241
319918
1689825
bd .
Resultados
En este apartado se muestra la evolucin temporal del algoritmo en funcin del nmero de ciudades
del problema. Para cada una de las ejecuciones se atender al nmero de nodos que han sido expandidos
durante la bsqueda. Hay que decir que para un nmero de ciudades constante, al variar los valores
de su matriz de distancias, el nmero de nodos expandidos variar, es decir, el porcentaje del rbol
de bsqueda que se visita vara. Adems al mantenerse una cola de prioridad para los nodos abiertos
es frecuente ver cmo el programa se queda sin memoria, para algunas conguraciones de esa misma
matriz de distancias, y no puede completar la bsqueda; tal efecto se pone de maniesto a partir de
12 ciudades.
Nmero de ciudades
4
5
7
8
9
10
11
12
13
14
Nodos expandidos
13
42
136
641
1703
29221
13595
67942
106030
347424
5. Bsqueda A estrella
El algoritmo A estrella es un algoritmo de bsqueda para grafos que encuentra el camino de menor
coste entre un nodo inicial y un nodo meta.
Usa una funcin heurstica (denotada f'(x), es una aproximacin a f(x), funcin que proporciona
la verdadera evaluacin de un nodo) para determinar el orden en que la bsqueda visita nodos en el
rbol. La mencionada funcin es la suma de otras dos funciones: una funcin que indica el coste del
camino seguido hasta un cierto nodo (denotada g(x)) y una estimacin admisible de la distancia hasta
la meta (h'(x)). La funcin de evaluacin resulta entonces f 0 (x) = g(x) + h0 (x).
Empezando en un nodo inicial dado, el algoritmo expande el nodo con el menor valor de f'(x). A
estrella mantiene un conjunto de soluciones parciales almacenadas en una cola de prioridad, cmo
en el algoritmo del apartado anterior. La prioridad asignada a un camino x viene determinada por la
funcin f'(x). El proceso continua hasta que una meta tiene un valor f'(x) menor que cualquier otro
nodo en la cola (o hasta que el rbol ha sido completamente recorrido).
dnde:
n representa el nmero de ciudades del problema.
l(x) es la profundidad del nodo x.
En el caso considerado el valor h'(x) puede sobreestimar al valor real del coste de la ruta entre
el nodo considerado y un nodo meta, ya que al tener valores de una U(100) bviamente tendremos
rutas con costes mayores a 15 (constante considerada). Lo anterior implica que en este caso el algorimo
no es ptimo. A pesar de lo anterior tras ejecutar el algoritmo se ha comprobado que las soluciones
ofrecidas por el algoritmo son prcticamente siempre las mejores, y en caso de no serlo, son bastante
aproximadas.
Veamos ahora la evolucin temporal del algoritmo en funcin del nmero de ciudades del problema.
Para cada una de las ejecuciones se atender al nmero de nodos que han sido expandidos durante la
9
Nmero de ciudades
5
7
10
13
20
50
75
100
Nodos expandidos
37
422
808
8528
223
232058
14370
5278
Atendiendo al grco no se muestra el carcter exponencial del algoritmo ya que puede ejecutarse
para ms de 100 ciudades. Cmo se dijo en clase el principal problema de este algoritmo es que suele
quedarse sin memoria y as ocurre cundo se ha intentado probar para ms de 100 ciudades. An as
10
no se debe dudar de su coste exponencial en este caso ya que el error de la funcin heurstica crece
ms rpido que el logaritmo del costo real de la ruta.
Este algoritmo permite ejecutarse con un valor mximo de 100 ciudades, si no se presentan
problemas de memoria (tamao de las colas de prioridad).
11
Nmero de ciudades
5
10
20
50
75
100
Nodos expandidos
6
11
21
51
76
101
7. Mtodo de escalada
El algoritmo de escalada consiste en recorrer las distintos nodos explorando en cada momento aquel
cuyo coste f(x)', que incluye el coste real de la ruta g(x), y el coste de h(x)', aproximacin a h(x), sea
menor.
12
Constituye un caso particular de una bsqueda en profundidad sin posibilidad de vuelta atrs.
Es parecido al algoritmo del apartado anterior, pero para el problema de esta prctica no tiene
sentido utilizarlo, ya que no obtiene buenas rutas.
Nmero de ciudades
5
10
20
50
75
100
Nodos expandidos
6
11
21
51
76
101
Queda claro por lo tanto que es muy parecido al anterior algorimo siendo tambin lineal. Aqu es
imposible evaluar lo bueno que es un estado por s mismo (habra que hacerlo en relacin a las dems
rutas), con lo cual es mejor evitar el uso de este algoritmo.
8. Comparativa
Veamos ahora una serie de grcos que dejen constancia del nmero de nodos expandidos para
distinto nmero de ciudades aplicando los seis algoritmos vistos en secciones anteriores. Para cierto
nmero de ciudades no todos los algoritmos podrn ser ejecutados.
14
Algoritmo
Primero en Profundidad (A)
Ramicacin y Poda (B)
Costo Uniforme (C)
A Estrella (D)
Vecino ms Prximo (E)
Escalada (F)
Nodos expandidos
13492901
16149
13595
813
12
12
Nodos expandidos
1689825
347424
699
15
15
15
Nodos expandidos
5278
101
101
Conclusiones
Para el algoritmo de Bsqueda en Profundidad el nmero de nodos visitados crece desorbitadamente en comparacin con los dems algoritmos nicamente para 11 ciudades.
Los algoritmos de Ramicacin y Poda y Costo Uniforme permiten ejecutarse con unas pocas
ciudades ms que el algoritmo anterior, concretamente 14. Adems pese a que el algoritmo de
Costo Uniforme expande menos nodos su ejecucin es ms lenta que el de Ramicacin y poda;
todo se debe a que debe gestionar una cola de prioridad.
A Estrella presenta el mejor comportamiento. Permite obtener en la mayora de casos una solucin
ptima con muy pocos nodos recorridos.
Los algoritmos del Vecino ms Prximo y Escalada recorren un nmero lineal de nodos pero no
garantizan encontrar la mejor solucin, por eso son considerados peores que A Estrella.
Para concluir puede armarse que dada una gran cantidad de ciudades, no debe utilizarse el algoritmo de Bsqueda en Profundidad, la mejor opcin ser aplicar el algoritmo A Estrella
que encontrar la mejor solucin en muy poco tiempo.
16
9. Cdigo fuente
Esta prctica se ha implementado mediante el lenguaje Java (entorno Netbeans 5.5). Para ejecutar
la aplicacin se adjunta un archivo con extensin jar (TravelingSalesMan.jar) en la carpeta dist de
ejecucin directa en sistemas operativos de tipo Windows y Linux.
Consideraciones previas:
Rutas : Las distancias entre las diferentes ciudades del problema se han recogido en forma de
matriz n*n siendo n el nmero de ciudades. As la diagonal de la misma es cero y adems el valor
de la ruta de la ciudad A a la B coincide con el valor de B a A. Dicha matriz aparece en la
clase RoutesMatrix.
A continuacin se muestran las clases en las que se divide la aplicacin.
9.1.
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
AStar
/
AStar . j a v a
I m p l e m e n t a t i o n o f t h e A (A S t a r ) a l g o r i t h m .
/
package t r a v e l i n g s a l e s m a n ;
import
import
import
import
java .
java .
java .
java .
util
util
util
util
. ArrayList ;
. Comparator ;
. PriorityQueue ;
. Vector ;
@author V i c e n t e J . F e r r e r Dalmau
/
RoutesMatrix d i s t a n c e s ;
int s o u r c e C i t y ;
PriorityQueue <Town> opened = new PriorityQueue <Town>(1000 ,
new Comparator<Town>() {
public int compare (Town a , Town b ) {
return a . f b . f ;
}
}
);
S t r i n g r e s u l t = new S t r i n g ( ) ;
A r r a y L i s t optimumRoute ;
17
37
38
39
40
41
42
43
44
45
46
47
48
49
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
int nodes = 0 ;
int optimumCost = I n t e g e r .MAX_VALUE;
// E s t i m a t i o n o f t h e c o s t between two c i t i e s , i t can o v e r e s t i m a t e t h e
real value (h ' > h) ,
// so t h e a l g o r i t h m i t ' s not optimum .
int HEURISTICCONSTANT = 1 5 ;
/
Gets t h e h e u r i s t i c v a l u e f o r a g i v e n d e p t h
The l e v e l 0 has t h e maximum v a l u e .
/
return HEURISTICCONSTANT
( distances . getCitiesCount () l e v e l ) ;
/ C r e a t e s a new i n s t a n c e o f AStar /
this . s o u r c e C i t y = s o u r c e C i t y ;
/
executes the algorithm
/
public S t r i n g e x e c u t e ( ) {
// have we found t h e s o l u t i o n ?
boolean s o l u t i o n = f a l s e ;
// s t a r t t h e t i m e r
// r e b u i l d t h e f o l l o w e d r o u t e f o r t h e s e l e c t e d town
18
i f ( currentTown . l e v e l == d i s t a n c e s . g e t C i t i e s C o u n t ( ) ) {
s o l u t i o n = true ;
88
89
90
91
92
93
94
95
optimumRoute = f o l l o w e d R o u t e ;
optimumCost = currentTown . g ;
} else {
// have we v i s i t e d t h i s c i t y i n t h e c u r r e n t f o l l o w e d
route ?
boolean v i s i t e d = f o l l o w e d R o u t e . c o n t a i n s ( i ) ;
boolean i s S o l u t i o n = ( f o l l o w e d R o u t e . s i z e ( ) ==
96
97
d i s t a n c e s . g e t C i t i e s C o u n t ( ) )&&( i == s o u r c e C i t y ) ;
98
99
100
if (! visited | | isSolution ) {
Town childTown = new Town( i , currentTown . g +
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121 }
9.2.
r e s u l t = "\n" ;
r e s u l t += "A ESTRELLA: \ n" ;
r e s u l t += "\n" ;
r e s u l t += "MEJOR SOLUCIN: \ t "+optimumRoute . t o S t r i n g ( ) + "\nCOSTE
: \ t \ t "+optimumCost+"\n" ;
r e s u l t += "NODOS VISITADOS : \ t "+nodes+"\n" ;
r e s u l t += "TIEMPO TRANSCURRIDO: \ t "+(endTimestartTime )+" ms\n" ;
r e s u l t += "\n" ;
}
return r e s u l t ;
BranchAndBound
1 /
2 BranchAndBound . j a v a
3
4 $LastChangedDate : 2008 03 30 2 2 : 3 5 : 2 4 +0200 (dom , 30 mar 2008) $
5 $LastChangedRevision : 15 $
6 V i c e n t e J . F e r r e r Dalmau
7 < vicente@jdalmau . es >
8
9 I m p l e m e n t a t i o n o f t h e branch and bound s e a r c h a l g o r i t h m .
10 /
19
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
50
51
52
53
54
55
56
57
58
59
60
package t r a v e l i n g s a l e s m a n ;
import j a v a . u t i l . A r r a y L i s t ;
/
@author V i c e n t e J . F e r r e r Dalmau
/
RoutesMatrix d i s t a n c e s ;
int s o u r c e C i t y ;
S t r i n g r e s u l t = new S t r i n g ( ) ;
A r r a y L i s t i n i t i a l R o u t e , optimumRoute ;
int nodes = 0 ;
int ro ut eCo st = 0 ;
int optimumCost = I n t e g e r .MAX_VALUE;
/ C r e a t e s a new i n s t a n c e o f BranchAndBound /
this . s o u r c e C i t y = s o u r c e C i t y ;
/
executes the algorithm
/
public S t r i n g e x e c u t e ( ) {
i n i t i a l R o u t e = new A r r a y L i s t ( ) ;
i n i t i a l R o u t e . add ( s o u r c e C i t y ) ;
optimumRoute = new A r r a y L i s t ( ) ;
nodes++;
r e s u l t = "\n" ;
r e s u l t += "RAMIFICACIN Y PODA: \ n" ;
r e s u l t += "\n" ;
20
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
return r e s u l t ;
/
@param from node where we s t a r t t h e s e a r c h .
@param r o u t e f o l l o w e d r o u t e f o r a r r i v i n g t o node " from " .
/
i f ( f o l l o w e d R o u t e . s i z e ( ) == d i s t a n c e s . g e t C i t i e s C o u n t ( ) ) {
f o l l o w e d R o u t e . add ( s o u r c e C i t y ) ;
nodes++;
// u p d a t e t h e r o u t e ' s c o s t
// DEBUG
// r e s u l t += f o l l o w e d R o u t e . t o S t r i n g ( ) + "// COSTE: "+r o u t e C o s t
+ "\n " ;
// u p d a t e t h e r o u t e ' s c o s t ( back t o t h e p r e v i o u s v a l u e )
rou teC os t = d i s t a n c e s . getCost ( from , s o u r c e C i t y ) ;
else {
for ( int to =0; to<d i s t a n c e s . g e t C i t i e s C o u n t ( ) ; to++){
i f ( ! f o l l o w e d R o u t e . c o n t a i n s ( to ) ) {
// u p d a t e t h e r o u t e ' s c o s t
100
101
102
103
104
105
106
107
108
109
// u p d a t e t h e r o u t e ' s c o s t ( back t o t h e p r e v i o u s
value )
r ou teC ost = d i s t a n c e s . getCost ( from , to ) ;
21
110
111
112 }
9.3.
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
DepthFirstSearch
/
DepthFirstSearch . java
package t r a v e l i n g s a l e s m a n ;
import j a v a . u t i l . A r r a y L i s t ;
/
@author V i c e n t e J . F e r r e r Dalmau
/
RoutesMatrix d i s t a n c e s ;
int s o u r c e C i t y ;
S t r i n g r e s u l t = new S t r i n g ( ) ;
A r r a y L i s t i n i t i a l R o u t e , optimumRoute ;
int nodes = 0 ;
int ro ut eCo st = 0 ;
int optimumCost = I n t e g e r .MAX_VALUE;
/ C r e a t e s a new i n s t a n c e o f D e p t h F i r s t S e a r c h /
this . s o u r c e C i t y = s o u r c e C i t y ;
/
executes the algorithm
/
public S t r i n g e x e c u t e ( ) {
i n i t i a l R o u t e = new A r r a y L i s t ( ) ;
i n i t i a l R o u t e . add ( s o u r c e C i t y ) ;
optimumRoute = new A r r a y L i s t ( ) ;
nodes++;
22
47
48
49
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
r e s u l t = "\n" ;
r e s u l t += "PRIMERO EN PROFUNDIDAD: \ n" ;
r e s u l t += "\n" ;
return r e s u l t ;
/
@param from node where we s t a r t t h e s e a r c h .
@param r o u t e f o l l o w e d r o u t e f o r a r r i v i n g t o node " from " .
/
i f ( f o l l o w e d R o u t e . s i z e ( ) == d i s t a n c e s . g e t C i t i e s C o u n t ( ) ) {
f o l l o w e d R o u t e . add ( s o u r c e C i t y ) ;
nodes++;
// u p d a t e t h e r o u t e ' s c o s t
optimumCost = ro ute Co st ;
optimumRoute = ( A r r a y L i s t ) f o l l o w e d R o u t e . c l o n e ( ) ;
// DEBUG
// r e s u l t += f o l l o w e d R o u t e . t o S t r i n g ( ) + "// COSTE: "+r o u t e C o s t
+ "\n " ;
// u p d a t e t h e r o u t e ' s c o s t ( back t o t h e p r e v i o u s v a l u e )
rou teC os t = d i s t a n c e s . getCost ( from , s o u r c e C i t y ) ;
else {
for ( int to =0; to<d i s t a n c e s . g e t C i t i e s C o u n t ( ) ; to++){
i f ( ! f o l l o w e d R o u t e . c o n t a i n s ( to ) ) {
ArrayList increasedRoute = ( ArrayList ) followedRoute .
clone () ;
i n c r e a s e d R o u t e . add ( to ) ;
23
96
97
98
99
100
101
102
103
nodes++;
// u p d a t e t h e r o u t e ' s c o s t
104
105
106
107
108
109 }
9.4.
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
// u p d a t e t h e r o u t e ' s c o s t ( back t o t h e p r e v i o u s
value )
rou teC os t = d i s t a n c e s . getCost ( from , to ) ;
HillClimbing
/
HillClimbing . java
I m p l e m e n t a t i o n o f t h e H i l l Climbing a l g o r i t h m ( s i m p l e v e r s i o n ) .
/
package t r a v e l i n g s a l e s m a n ;
import j a v a . u t i l . A r r a y L i s t ;
/
@author V i c e n t e J . F e r r e r Dalmau
/
public class H i l l C l i m b i n g {
RoutesMatrix d i s t a n c e s ;
int s o u r c e C i t y ;
S t r i n g r e s u l t = new S t r i n g ( ) ;
ArrayList followedRoute ;
int nodes = 0 ;
int ro ut eCo st = 0 ;
int HEURISTICCONSTANT = 1 5 ;
/
Gets t h e h e u r i s t i c v a l u e f o r a g i v e n d e p t h
24
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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
return HEURISTICCONSTANT
( distances . getCitiesCount () l e v e l ) ;
/ C r e a t e s a new i n s t a n c e o f H i l l C l i m b i n g /
this . s o u r c e C i t y = s o u r c e C i t y ;
/
executes the algorithm
/
public S t r i n g e x e c u t e ( ) {
f o l l o w e d R o u t e = new A r r a y L i s t ( ) ;
f o l l o w e d R o u t e . add ( s o u r c e C i t y ) ;
nodes++;
return r e s u l t ;
/
@param from node where we s t a r t t h e s e a r c h .
/
while ( nodes != d i s t a n c e s . g e t C i t i e s C o u n t ( ) ) {
// c h o o s e t h e c l o s e s t town
int l o w e s t D i s t a n c e = I n t e g e r .MAX_VALUE;
int chosen = 1;
for ( int i =0; i < d i s t a n c e s . g e t C i t i e s C o u n t ( ) ; i ++) {
25
i f ( ! followedRoute . contains ( i ) ) {
int tempDistance = r ou teC ost + g e t H e u r i s t i c V a l u e (
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103 }
9.5.
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
nodes 1) ; // f = g + h
i f ( tempDistance < l o w e s t D i s t a n c e ) {
l o w e s t D i s t a n c e = tempDistance ;
chosen = i ;
}
rou teC os t += d i s t a n c e s . getCost ( currentTown , chosen ) ;
f o l l o w e d R o u t e . add ( chosen ) ;
currentTown = chosen ;
nodes++;
// add t h e l a s t town
Main
/
Main . j a v a
package t r a v e l i n g s a l e s m a n ;
import
import
import
import
import
@author V i c e n t e J . F e r r e r Dalmau
/
public Main ( ) {
26
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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
initComponents ( ) ;
// i n i t t h e r o u t e s m a t r i x
r o u t e s = new RoutesMatrix ( 4 ) ;
// i n i t t h e c i t i e s c h e c k b o x
jComboBox2 . addItem ( i ) ;
jComboBox1 . s e t S e l e c t e d I n d e x ( 2 ) ;
jComboBox2 . s e t S e l e c t e d I n d e x ( 0 ) ;
// c o n f i g u r e t h e JTable t o d i s p l a y de r o u t e s m a t r i x
r o u t e s . drawJTable ( j T ab l e 1 ) ;
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
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
155
156
157
158
159
160
161
162
163
164
165
166
167
29
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
try {
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
int c i t i e s = ( ( I n t e g e r ) jComboBox1 . g e t S e l e c t e d I t e m ( ) ) . i n t V a l u e
() ;
r o u t e s = new RoutesMatrix ( c i t i e s ) ;
r o u t e s . drawJTable ( jT a b le 1 ) ;
// a l t e r t h e 2nd comboBox ( s o u r c e c i t y )
jComboBox2 . removeAllItems ( ) ;
for ( int i =0; i <c i t i e s ; i ++)
jComboBox2 . addItem ( i ) ;
jComboBox2 . s e t S e l e c t e d I n d e x ( 0 ) ;
}
} //GENLAST: event_jComboBox1ItemStateChanged
s o u r c e C i t y = ( ( I n t e g e r ) jComboBox2 . g e t S e l e c t e d I t e m ( ) ) . i n t V a l u e
() ;
}
} //GENLAST: event_jComboBox2ItemStateChanged
try {
H i l l C l i m b i n g s = new H i l l C l i m b i n g ( r o u t e s , s o u r c e C i t y ) ;
jTextArea1 . setText ( s . e x e c u t e ( ) ) ;
} catch ( j a v a . l a n g . OutOfMemoryError e ) {
S t r i n g msg = "La memoria no e s s u f i c i e n t e para e j e c u t a r
e l Mtodo de Escalada con l a s "+
32
295
( ( I n t e g e r ) jComboBox1 . g e t S e l e c t e d I t e m ( ) ) . i n t V a l u e
( )+" c i u d a d e s ge ner ada s . " ;
JOptionPane . showMessageDialog ( new JFrame ( ) , msg , " Error " ,
JOptionPane .ERROR_MESSAGE) ;
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
}
} //GENLAST: e v e n t_ j B u t t o n 8 M o u s e C l i c k e d
try {
} //GENLAST: e v e n t_ j B u t t o n 4 M o u s e C l i c k e d
try {
} //GENLAST: e v e n t _ j Bu t t o n 5 M o u s e C l i c k e d
try {
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
}
} //GENLAST: e v e n t_ j B u t t o n 3 M o u s e C l i c k e d
try {
BranchAndBound s = new BranchAndBound ( r o u t e s , s o u r c e C i t y ) ;
jTextArea1 . setText ( s . e x e c u t e ( ) ) ;
} catch ( j a v a . l a n g . OutOfMemoryError e ) {
S t r i n g msg = "La memoria no e s s u f i c i e n t e para e j e c u t a r
l a bsqueda con R a m i f i c a c i n y Poda con l a s "+
( ( I n t e g e r ) jComboBox1 . g e t S e l e c t e d I t e m ( ) ) . i n t V a l u e
( )+" c i u d a d e s ge ner ada s . " ;
JOptionPane . showMessageDialog ( new JFrame ( ) , msg , " Error " ,
JOptionPane .ERROR_MESSAGE) ;
}
} //GENLAST: e v e n t_ j B u t t o n 2 M o u s e C l i c k e d
// c o n f i g u r e t h e JTable t o d i s p l a y de r o u t e s m a t r i x
// r e g e n e r a t e t h e j T a b l e
r o u t e s . drawJTable ( j T a bl e 1 ) ;
} //GENLAST: e v e n t_ j B u t t o n 7 M o u s e C l i c k e d
r o u t e s = new RoutesMatrix ( c i t i e s ) ;
r o u t e s . drawJTable ( j T a bl e 1 ) ;
} //GENLAST: e v e n t_ j B u t t o n 6 M o u s e C l i c k e d
try {
376
377
378
jTextArea1 . setText ( s . e x e c u t e ( ) ) ;
} catch ( j a v a . l a n g . OutOfMemoryError e ) {
S t r i n g msg = "La memoria no e s s u f i c i e n t e para e j e c u t a r
l a bsqueda Primero en Profundidad con l a s "+
( ( I n t e g e r ) jComboBox1 . g e t S e l e c t e d I t e m ( ) ) . i n t V a l u e
( )+" c i u d a d e s ge ner ada s . " ;
JOptionPane . showMessageDialog ( new JFrame ( ) , msg , " Error " ,
JOptionPane .ERROR_MESSAGE) ;
}
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
} //GENLAST: e v e n t_ j B u t t o n 1 M o u s e C l i c k e d
public void p r i n t R e s u l t s ( S t r i n g r e s u l t s ) {
}
jTextArea1 . setText ( r e s u l t s ) ;
/
@param a r g s t h e command l i n e arguments
/
}) ;
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
// End o f v a r i a b l e s d e c l a r a t i o n //GENEND: v a r i a b l e s
35
425 }
9.6.
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
NearestNeighbour
/
NearestNeighbour . java
I m p l e m e n t a t i o n o f t h e N e a r e s t Neighbour a l g o r i t h m .
/
package t r a v e l i n g s a l e s m a n ;
import j a v a . u t i l . A r r a y L i s t ;
/
@author V i c e n t e J . F e r r e r Dalmau
/
S t r i n g r e s u l t = new S t r i n g ( ) ;
ArrayList followedRoute ;
int nodes = 0 ;
int ro ut eCo st = 0 ;
/ C r e a t e s a new i n s t a n c e o f N e a r e s t N e i g h b o u r /
this . s o u r c e C i t y = s o u r c e C i t y ;
/
executes the algorithm
/
public S t r i n g e x e c u t e ( ) {
f o l l o w e d R o u t e = new A r r a y L i s t ( ) ;
f o l l o w e d R o u t e . add ( s o u r c e C i t y ) ;
nodes++;
36
49
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 }
9.7.
r e s u l t = "\n" ;
r e s u l t += "VECINO MS PRXIMO: \ n" ;
r e s u l t += "\n" ;
r e s u l t += "MEJOR SOLUCIN: \ t "+f o l l o w e d R o u t e . t o S t r i n g ( ) + "\
nCOSTE: \ t \ t "+r out eCo st+"\n" ;
r e s u l t += "NODOS VISITADOS : \ t "+nodes+"\n" ;
r e s u l t += "TIEMPO TRANSCURRIDO: \ t "+(endTimestartTime )+" ms\n" ;
r e s u l t += "\n" ;
}
return r e s u l t ;
/
@param from node where we s t a r t t h e s e a r c h .
/
while ( nodes != d i s t a n c e s . g e t C i t i e s C o u n t ( ) ) {
// c h o o s e t h e c l o s e s t town
int l o w e s t D i s t a n c e = I n t e g e r .MAX_VALUE;
int chosen = 1;
for ( int i =0; i < d i s t a n c e s . g e t C i t i e s C o u n t ( ) ; i ++) {
i f ( ! followedRoute . contains ( i ) ) {
int tempDistance = d i s t a n c e s . getCost ( currentTown , i ) ;
i f ( tempDistance < l o w e s t D i s t a n c e ) {
l o w e s t D i s t a n c e = tempDistance ;
chosen = i ;
}
rou teC os t += d i s t a n c e s . getCost ( currentTown , chosen ) ;
f o l l o w e d R o u t e . add ( chosen ) ;
currentTown = chosen ;
nodes++;
// add t h e l a s t town
RoutesMatrix
1 /
2 RoutesMatrix . j a v a
3
4 $LastChangedDate : 2008 03 30 2 2 : 3 5 : 2 4 +0200 (dom , 30 mar 2008) $
37
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
50
51
52
53
54
$LastChangedRevision : 15 $
V i c e n t e J . F e r r e r Dalmau
< vicente@jdalmau . es >
package t r a v e l i n g s a l e s m a n ;
import
import
import
import
import
import
import
j a v a . awt . Color ;
j a v a . awt . Component ;
j a v a . u t i l . Random ;
javax . swing . JTable ;
javax . swing . JTextField ;
javax . swing . t a b l e . D e f a u l t T a b l e C e l l R e n d e r e r ;
javax . swing . t a b l e . DefaultTableModel ;
@author V i c e n t e J . F e r r e r Dalmau
/
// a l l t h e d i s t a n c e v a l u e s w i l l be i n a Uniform (MAXDISTANCE)
/ C r e a t e s a new i n s t a n c e o f RoutesMatrix
/
else {
theMatrix [ i ] [ j ] = g e n e r a t o r . n e x t I n t (MAXDISTANCE) ;
theMatrix [ j ] [ i ] = theMatrix [ i ] [ j ] ;
38
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
/
r e t u r n s t h e number o f c i t i e s
/
public int g e t C i t i e s C o u n t ( ) {
return c i t i e s ;
/
g e t s t h e c o s t o f g o i n g from c i t y "a" t o c i t y " b "
/
return theMatrix [ a ] [ b ] ;
/
s e t s t h e c o s t o f g o i n g from c i t y "a" t o c i t y " b "
/
theMatrix [ a ] [ b ] = c o s t ;
/
g e t s t h e a r r a y o f c o s t s as an O b j e c t [ ] [ ] a r r a y .
/
public Object [ ] [ ] g e t C o s t s ( ) {
else
}
}
a r r a y [ i ] [ j +1] = theMatrix [ i ] [ j ] ;
return a r r a y ;
/
g e t s t h e c i t i e s i n an O b j e c t [ ] a r r a y .
/
public Object [ ] g e t C i t i e s ( ) {
107
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
155
156
157
else
a r r a y [ i +1] = i ;
return a r r a y ;
/
g e t s t h e maximum d i s t a n c e between two c i t i e s .
/
public S t r i n g t o S t r i n g ( ) {
S t r i n g s t r = new S t r i n g ( ) ;
for ( int i =0; i <c i t i e s ; i ++) {
for ( int j =0; j<c i t i e s ; j++) {
i f ( j == c i t i e s 1)
else
}
s t r += theMatrix [ i ] [ j ] + "\n" ;
s t r += theMatrix [ i ] [ j ] + " , " ;
return s t r ;
// R e d e f i n e t h e b e h a v i o u r o f t h e t a b l e
boolean i s S e l e c t e d ,
boolean hasFocus ,
int row ,
int column )
super . getTableCellRendererComponent ( t a b l e , value , i s S e l e c t e d ,
hasFocus , row , column ) ;
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186 }
else {
9.8.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
return this ;
/
Shows t h e c o n t e n t o f t h e m a t r i x i n a JTable o b j e c t .
/
else
return f a l s e ;
};
dtm . setDataVector ( this . g e t C o s t s ( ) , this . g e t C i t i e s ( ) ) ;
// s e t t h e background o f t h e f i r s t column
j . setModel (dtm) ;
j . s e t D e f a u l t R e n d e r e r ( Object . class , new MyRender ( ) ) ;
Town
/
Town . j a v a
Contains a l l t h e i m p o r t a n t i n f o r m a t i o n a b o u t a Town .
/
package t r a v e l i n g s a l e s m a n ;
/
@author V i c e n t e J . F e r r e r Dalmau
/
41
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 }
9.9.
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
public
public
public
public
int number ;
int f , g , h ;
int l e v e l ;
/ C r e a t e s a new i n s t a n c e o f Town /
UniformCost
/
UniformCost . j a v a
I m p l e m e n t a t i o n o f t h e Uniform Cost a l g o r i t h m .
/
package t r a v e l i n g s a l e s m a n ;
import j a v a . u t i l . A r r a y L i s t ;
import j a v a . u t i l . Comparator ;
import j a v a . u t i l . P r i o r i t y Q u e u e ;
/
@author V i c e n t e J . F e r r e r Dalmau
/
RoutesMatrix d i s t a n c e s ;
int s o u r c e C i t y ;
PriorityQueue <Town> toExpand = new PriorityQueue <Town>(200 ,
new Comparator<Town>() {
public int compare (Town a , Town b ) {
return a . g b . g ;
}
}
);
S t r i n g r e s u l t = new S t r i n g ( ) ;
42
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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
A r r a y L i s t optimumRoute , f o l l o w e d R o u t e ;
int nodes = 0 ;
int ro ut eCo st = 0 ;
int optimumCost = I n t e g e r .MAX_VALUE;
/ C r e a t e s a new i n s t a n c e o f UniformCost /
this . s o u r c e C i t y = s o u r c e C i t y ;
/
executes the algorithm
/
public S t r i n g e x e c u t e ( ) {
// have we found t h e s o l u t i o n ?
boolean s o l u t i o n = f a l s e ;
// s t a r t t h e t i m e r
// r e b u i l d t h e f o l l o w e d r o u t e f o r t h e s e l e c t e d town
i f ( currentTown . l e v e l == d i s t a n c e s . g e t C i t i e s C o u n t ( ) ) {
s o l u t i o n = true ;
optimumRoute = f o l l o w e d R o u t e ;
optimumCost = currentTown . g ;
} else {
// have we v i s i t e d t h i s c i t y i n t h e c u r r e n t f o l l o w e d
route ?
boolean v i s i t e d = f o l l o w e d R o u t e . c o n t a i n s ( i ) ;
boolean i s S o l u t i o n = ( f o l l o w e d R o u t e . s i z e ( ) ==
43
d i s t a n c e s . g e t C i t i e s C o u n t ( ) )&&( i == s o u r c e C i t y ) ;
85
86
87
if (! visited | | isSolution ) {
Town childTown = new Town( i , currentTown . g +
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107 }
return r e s u l t ;
44