Está en la página 1de 44

El problema del viajante de comercio

Inteligencia Articial
Vicente J. Ferrer Dalmau (43152879A)
<vicente@jdalmau.es>
1 de abril de 2008

ndice
1. Enunciado

2. Bsqueda primero en profundidad

3. Bsqueda primero en profundidad con ramicacin y poda

4. Bsqueda de costo uniforme

5. Bsqueda A estrella

6. Bsqueda del vecino ms prximo

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.

2. Bsqueda primero en profundidad


El algoritmo Primero en Profundidad es un algoritmo que nos permite realizar bsquedas en un
rbol o grafo. Formalmente es una bsqueda no informada que progresa expandiendo el primer nodo
hijo en el rbol de bsqueda y continua hasta encontrar un nodo objetivo o hasta encontrar un nodo
sin hijos. En ese momento, la bsqueda realiza una vuelta atrs (backtracking) volviendo al nodo ms
reciente que no haba sido explorado completamente, para elegir el siguiente de sus hijos.

Caractersticas del algoritmo


Aspectos positivos:
La memoria necesaria es relativamente pequea, ya que en cada momento slo hay que guardar
la ruta que se est analizando.
Si hay muchas soluciones posibles, la bsqueda en profundidad es rpida ya que tiene muchas
posibilidades de encontrar una solucin despus de haber explorado nicamente una parte del
rbol. En nuestro caso esta ventaja no se da porque tenemos que recorrer todo el rbol para dar
la mejor solucin.
Aspectos negativos:
3

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.

Evaluacin del algoritmo de bsqueda


Completitud: No, ya que puede quedarse atrapado al descender por el camino equivocado en rboles
de bsqueda muy profundos o incluso innitos. En esos casos se encuentra con un bucle innito
y no devuelve nunca una solucin.

Complejidad temporal:
Complejidad espacial:

bm , lo que supone un coste inaceptable1 .

bm, slo necesita almacenar una rama del rbol de bsqueda.

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):

Figura 1: El valor se dispara entre 10 y 11 ciudades.


b es el factor de ramicacin, en nuestro caso las ciudades aplicables, d es la profundidad de la solucin y m
es la mxima profundidad del rbol de bsqueda.
1 Dnde

Nmero de ciudades
4
5
7
8
9
10
11

Nodos expandidos
22
89
2677
18740
149921
1349290
13492901

Cuadro 1: Valores obtenidos en la ejecucin.

En el grco puede observarse el claro comportamiento exponencial del algoritmo. Cabe mencionar que slo fue posible ejecutarlo con 11 ciudades cmo mximo.

3. Bsqueda primero en profundidad con ramicacin y poda


El algoritmo primero en profundidad con Ramicacin y poda es una variante del algoritmo visto
en el apartado anterior mejorado sustancialmente. El trmino (del ingls, Branch and Bound) se aplica
mayoritariamente para resolver cuestiones o problemas de optimizacin.
La caracterstica de esta tcnica con respecto a la anterior es que el algoritmo se encarga de detectar
en qu ramicacin las soluciones dadas ya no estn siendo ptimas (es decir, mejoran alguna obtenida
prviamente), para podar esa rama del rbol y no continuar malgastando recursos y procesos en
casos que se alejan de la solucin ptima.

Caractersticas del algoritmo


Aspectos positivos:
Bajo consumo de memoria.
Rpido si existen muchas soluciones.
Permite su aplicacin para un mayor nmero de ciudades que en el caso anterior.
Aspectos negativos:
Coste temporal todava exponencial.

Evaluacin del algoritmo de bsqueda


Completitud: No, ya que, de nuevo, puede quedarse atrapado al descender por el camino equivocado

en rboles de bsqueda muy profundos o incluso innitos. En esos casos se encuentra con un
bucle innito y no devuelve nunca una solucin.

Complejidad temporal: exponencial.


Complejidad espacial: lineal.

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.

Figura 2: Nmero de nodos expandidos en funcin del nmero de ciudades.


Aqu el valor se dispara con unas cuantas ciudades ms que
en el caso anterior.

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

Cuadro 2: Valores obtenidos en la ejecucin.


6

De nuevo en la grca observamos el comportamiento exponencial del algoritmo, aunque aqu


el crecimiento importante se produce para un valor ms elevado de ciudades. Este algoritmo permite
ejecutarse con un valor mximo de 14 ciudades.

4. Bsqueda de costo uniforme


Mediante este algoritmo la bsqueda se realiza expandiendo todos los nodos hijo de un nodo padre
y seleccionando aquel cuyo coste sea menor. Se procede de esta forma hasta que se encuentra la mejor
solucin. Observemos que si todos los nodos tienen el mismo coste tenemos un recorrido en anchura.
La bsqueda de coste uniforme encontrar la mejor solucin si se cumple que el coste del camino
nunca decrece a medida que avanzamos, requisito que se cumple para el problema del viajante de
comercio. Para otro tipo de problemas dnde si pudiera producirse nunca sabramos cundo podramos
encontrar un coste negativo. El resultado provocara la necesidad de realizar una bsqueda exhaustiva
en todo el rbol.
Este algoritmo puede implementarse fcilmente con la ayuda de una estructura de datos cola
ordenada por prioridad, dnde aquellos nodos con menor coste (del nodo inicial hasta dicho nodo)
son ms prioritarios.

Caractersticas del algoritmo


Aspectos positivos:
Es un algoritmo de bsqueda completo, si existe una solucin siempre la encuentra.
Es un algoritmo de bsqueda ptimo, siempre encuentra la mejor solucin.
Aspectos negativos:
La complejidad temporal sigue siendo elevada.
Los requerimientos de espacio son elevados en tanto que hay que guardar los nodos de cada nivel,
ya que constituyen posibles soluciones.

Evaluacin del algoritmo de bsqueda


Completitud: S.
Complejidad temporal:
Complejidad espacial:

bd dnde d representa la profundidad de la solucin.

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.

Figura 3: Nmero de nodos expandidos en funcin del nmero de 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

Cuadro 3: Valores obtenidos en la ejecucin.

De nuevo en la grca observamos el comportamiento exponencial del algoritmo, aunque aqu


hay que tener muy en cuenta el tema de memoria (cola de prioridad para los nodos abiertos) cmo
ya se mencion anteriormente. Adems atendiendo al tiempo de ejecucin, pese a visitar menos nodos
resulta por trmino general ms lento que el anterior algoritmo (Ramicacin y Poda) debido de
nuevo a la necesidad de gestionar la cola de prioridad. Este algoritmo permite ejecutarse con un valor
mximo de 14 ciudades.

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).

Caractersticas del algoritmo


Aspectos positivos:
Ningn otro algoritmo ptimo garantiza expandir menos nodos que A estrella.
Aspectos negativos:
Alto consumo de memoria.

Evaluacin del algoritmo de bsqueda


Completitud: S.
Complejidad temporal: exponencial (debido a la heurstica utilizada).
Complejidad espacial: exponencial.
Resultados
En cuanto a la funcin heurstica que se ha utilizado para resolver este problema, para obtener
el valor de la estimacin h'(x) dado un nodo consideramos la profundidad a la que se encuentra dentro
del rbol de bsqueda. Cuanto ms cercano est al nmero de ciudades del problema (por tanto a una
solucin) mejor valoracin tendr. Para calcular dicho valor consideraremos adems de la profundidad
del nodo una estimacin del coste del camino entre dos ciudades cualquiera:
Si por ejemplo, los costes de las rutas entre las ciudades del problema pertenecen a una distribucin
uniforme U(100) y tomamos un coste aproximado de 15 unidades cmo coste entre dos ciudades
cualquiera, tendremos:
h0 (x) = (n l(x)) 15

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

Cuadro 4: Valores obtenidos en la ejecucin.


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.
Pese a utilizar de nuevo colas de prioridad aqu la memoria no supone tanto problema cmo en el
algorimo anterior ya que A estrella converge mucho ms deprisa hacia una solucin.

Figura 4: Nodos expandidos en funcin del nmero de ciudades.

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).

6. Bsqueda del vecino ms prximo


El algoritmo del Vecino ms prximo fu uno de los primeros algoritmos usados para encontrar la
solucin al problema del viajante de comercio. Rpidamente encuentra una solucin pero generalmente
sta no es la ptima.
Este algoritmo es fcil de implementar y se ejecuta rpido pero puede en ocasiones perder rutas
ms cortas. Cmo gua general, si las ltimas etapas de la ruta son comparables en coste a las primeras,
entonces la ruta ser razonable; si son mucho ms grandes la solucin hallada ser muy mejorable.

Caractersticas del algoritmo


Aspectos positivos:
Es un algoritmo muy rpido.
Su consumo de memoria muy bajo.
Aspectos negativos:
No es ptimo.

Evaluacin del algoritmo de bsqueda


Completitud: S.
Complejidad temporal: O(m)
Complejidad espacial: O(m)
Resultados
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
bsqueda.

11

Figura 5: Nodos expandidos en funcin del nmero de ciudades.

Nmero de ciudades
5
10
20
50
75
100

Nodos expandidos
6
11
21
51
76
101

Cuadro 5: Valores obtenidos en la ejecucin.

Observando el grco queda patente el caracter lineal del algoritmo.


Este algoritmo prescinde de la optimalidad en la solucin para lograr un tiempo de ejecucin
mnimo. Se recomienda usar este algoritmo cundo no se dispone de gran poder computacional y/o no
se necesita encontrar la mejor solucin.
En general este algoritmo no suele dar malas soluciones. Es muy improbable que de el peor de los
casos. Puede ejecutarse para cientos de ciudades.

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.

Caractersticas del algoritmo


Aspectos positivos:
Es un algoritmo tan rpido cmo el Vecino ms Prximo.
Tiene un bajo consumo de memoria.
Aspectos negativos:
No es ptimo.
Puede quedar estancado.

Evaluacin del algoritmo de bsqueda


Completitud: No, es irrevocable (no puede volver atrs).
Complejidad temporal: O(m)
Complejidad espacial: O(m)
Resultados
Se muestra a continuacin 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.

Figura 6: Nodos expandidos en funcin del nmero de ciudades.


13

Nmero de ciudades
5
10
20
50
75
100

Nodos expandidos
6
11
21
51
76
101

Cuadro 6: Valores obtenidos en la ejecucin.

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.

Figura 7: Comparativa para 11 ciudades.

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

Cuadro 7: Comparativa para 11 ciudades.

Figura 8: Comparativa para 14 ciudades.


Algoritmo
Ramicacin y Poda (B)
Costo Uniforme (C)
A Estrella (D)
Vecino ms Prximo (E)
Escalada (F)

Nodos expandidos
1689825
347424
699
15
15

Cuadro 8: Comparativa para 14 ciudades.

15

Figura 9: Comparativa para 100 ciudades.


Algoritmo
A Estrella (D)
Vecino ms Prximo (E)
Escalada (F)

Nodos expandidos
5278
101
101

Cuadro 9: Comparativa para 100 ciudades.

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

$LastChangedDate : 2008 03 30 2 2 : 3 5 : 2 4 +0200 (dom , 30 mar 2008) $


$LastChangedRevision : 15 $
V i c e n t e J . F e r r e r Dalmau
< vicente@jdalmau . es >

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
/

public class AStar {

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 .
/

private int g e t H e u r i s t i c V a l u e ( int l e v e l ) {

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 /

public AStar ( RoutesMatrix matrix , int s o u r c e C i t y ) {


d i s t a n c e s = matrix ;

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

long startTime = System . c u r r e n t T i m e M i l l i s ( ) ;


// i n i t i a l town

opened . add ( new Town( s o u r c e C i t y , 0 , g e t H e u r i s t i c V a l u e ( 0 ) , 0) ) ;

while ( ! opened . isEmpty ( ) && ! s o l u t i o n ) {


// g e t s t h e c i t y w i t h l o w e r g v a l u e

Town currentTown = opened . p o l l ( ) ;


nodes++;

// 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

Town aux = currentTown ;


A r r a y L i s t 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 ( aux . number ) ;
while ( aux . l e v e l != 0) {
aux = aux . parent ;
f o l l o w e d R o u t e . add ( 0 , aux . number ) ;
}

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 {

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 ++) {

// 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

d i s t a n c e s . getCost ( currentTown . number , i ) ,


g e t H e u r i s t i c V a l u e ( currentTown . l e v e l + 1) ,
currentTown . l e v e l + 1) ;
childTown . parent = currentTown ;
opened . add ( childTown ) ;

long endTime = System . c u r r e n t T i m e M i l l i s ( ) ;

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
/

public class BranchAndBound {

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 /

public BranchAndBound ( RoutesMatrix matrix , int s o u r c e C i t y ) {


d i s t a n c e s = matrix ;

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" ;

long startTime = System . c u r r e n t T i m e M i l l i s ( ) ;


search ( sourceCity , i n i t i a l R o u t e ) ;

long endTime = System . c u r r e n t T i m e M i l l i s ( ) ;


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" ;

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 " .
/

public void s e a r c h ( int from , A r r a y L i s t f o l l o w e d R o u t e ) {


// we ' ve found a new s o l u t i o n

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

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 ) ;

i f ( ro ute Co st < optimumCost ) {


}

optimumCost = ro ute Cos t ;


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 ) ) {
// u p d a t e t h e r o u t e ' s c o s t

r ou teC ost += d i s t a n c e s . getCost ( from , to ) ;

i f ( ro ute Cos t < optimumCost ) {

100
101
102
103
104
105
106
107
108
109

ArrayList increasedRoute = ( ArrayList )


followedRoute . clone () ;
i n c r e a s e d R o u t e . add ( to ) ;
nodes++;
s e a r c h ( to , i n c r e a s e d R o u t e ) ;

// 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

$LastChangedDate : 2008 03 30 2 2 : 3 5 : 2 4 +0200 (dom , 30 mar 2008) $


$LastChangedRevision : 15 $
V i c e n t e J . F e r r e r Dalmau
< vicente@jdalmau . es >

Implementation of the depth f i r s t search algorithm .


/

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 De pt hF irs tS ear ch {

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 /

public De pt hF irs tS ear ch ( RoutesMatrix matrix , int s o u r c e C i t y ) {


d i s t a n c e s = matrix ;

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" ;

long startTime = System . c u r r e n t T i m e M i l l i s ( ) ;


search ( sourceCity , i n i t i a l R o u t e ) ;

long endTime = System . c u r r e n t T i m e M i l l i s ( ) ;


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 ;

/
@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 " .
/

public void s e a r c h ( int from , A r r a y L i s t f o l l o w e d R o u t e ) {


// we ' ve found a new s o l u t i o n

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

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 ) ;

i f ( ro ute Co st < optimumCost ) {


}

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

r ou teC ost += d i s t a n c e s . getCost ( from , to ) ;


s e a r c h ( to , i n c r e a s e d R o u t e ) ;

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

$LastChangedDate : 2008 03 30 2 0 : 4 1 : 4 1 +0200 (dom , 30 mar 2008) $


$LastChangedRevision : 14 $
V i c e n t e J . F e r r e r Dalmau
< vicente@jdalmau . es >

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

The l e v e l 0 has t h e maximum v a l u e .


/

private int g e t H e u r i s t i c V a l u e ( int l e v e l ) {


}

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 /

public H i l l C l i m b i n g ( RoutesMatrix matrix , int s o u r c e C i t y ) {


d i s t a n c e s = matrix ;

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++;

long startTime = System . c u r r e n t T i m e M i l l i s ( ) ;


search ( sourceCity ) ;

long endTime = System . c u r r e n t T i m e M i l l i s ( ) ;


r e s u l t = "\n" ;
r e s u l t += "MTODO DE ESCALADA: \ 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 .
/

public void s e a r c h ( int from ) {


int currentTown = from ;

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

r out eCo st += d i s t a n c e s . getCost ( currentTown , s o u r c e C i t y ) ;


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++;

Main

/
Main . j a v a

$LastChangedDate : 2008 04 01 0 1 : 2 7 : 5 2 +0200 ( mar , 01 abr 2008) $


$LastChangedRevision : 22 $
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

javax . swing . t a b l e . DefaultTableModel ;


j a v a . awt . ;
j a v a . awt . event . ;
javax . swing . ;
javax . swing . t a b l e . ;

@author V i c e n t e J . F e r r e r Dalmau
/

public class Main extends javax . swing . JFrame {


static RoutesMatrix r o u t e s ;
int s o u r c e C i t y = 0 ;
/ C r e a t e s new form Main /

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

for ( int i = 2 ; i <= 1 0 0 ; i ++)


jComboBox1 . addItem ( i ) ;

for ( int i = 2 ; i <= 1 0 ; i ++)

jComboBox1 . addItem ( i 100) ;

for ( int i = 0 ; i <= 3 ; i ++)

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 ) ;

/ This method i s c a l l e d from w i t h i n t h e c o n s t r u c t o r t o


i n i t i a l i z e t h e form .
WARNING: Do NOT modify t h i s code . The c o n t e n t o f t h i s method i s
a l w a y s r e g e n e r a t e d by t h e Form E d i t o r .
/
// <e d i t o r f o l d d e f a u l t s t a t e =" c o l l a p s e d " d e s c=" Generated Code ">//
GENBEGIN: initComponents

private void initComponents ( ) {


j P a n e l 1 = new javax . swing . JPanel ( ) ;
j S c r o l l P a n e 2 = new javax . swing . J S c r o l l P a n e ( ) ;
jT a b le 1 = new javax . swing . JTable ( ) ;
jButton6 = new javax . swing . JButton ( ) ;
jButton7 = new javax . swing . JButton ( ) ;
jComboBox1 = new javax . swing . JComboBox ( ) ;
j L a b e l 1 = new javax . swing . JLabel ( ) ;
j L a b e l 2 = new javax . swing . JLabel ( ) ;
jComboBox2 = new javax . swing . JComboBox ( ) ;
j P a n e l 2 = new javax . swing . JPanel ( ) ;
jButton1 = new javax . swing . JButton ( ) ;
jButton2 = new javax . swing . JButton ( ) ;
jButton3 = new javax . swing . JButton ( ) ;
j P a n e l 3 = new javax . swing . JPanel ( ) ;
jButton4 = new javax . swing . JButton ( ) ;
jButton5 = new javax . swing . JButton ( ) ;
jButton8 = new javax . swing . JButton ( ) ;
j P a n e l 4 = new javax . swing . JPanel ( ) ;
j S c r o l l P a n e 1 = new javax . swing . J S c r o l l P a n e ( ) ;
jTextArea1 = new javax . swing . JTextArea ( ) ;
j P a n e l 5 = new javax . swing . JPanel ( ) ;
jButton9 = new javax . swing . JButton ( ) ;

getContentPane ( ) . setLayout ( new org . netbeans . l i b . awtextra .


AbsoluteLayout ( ) ) ;
27

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

s e t D e f a u l t C l o s e O p e r a t i o n ( javax . swing . WindowConstants .


EXIT_ON_CLOSE) ;
s e t T i t l e ( "IA El V i a j a n t e de Comercio ( V i c en t e J . F e r r e r Dalmau )
") ;
setBackground ( new j a v a . awt . Color ( 2 5 5 , 255 , 255) ) ;
s e t C u r s o r ( new j a v a . awt . Cursor ( j a v a . awt . Cursor .HAND_CURSOR) ) ;
setResizable ( false ) ;
j P a n e l 1 . setLayout ( new org . netbeans . l i b . awtextra . AbsoluteLayout ( ) )
;
j P a n e l 1 . s e t B o r d e r ( javax . swing . BorderFactory . c r e a t e T i t l e d B o r d e r ( "
C o n f i g u r a r Ciudades " ) ) ;
j S c r o l l P a n e 2 . s e t H o r i z o n t a l S c r o l l B a r P o l i c y ( javax . swing .
S c r o l l P a n e C o n s t a n t s .HORIZONTAL_SCROLLBAR_ALWAYS) ;
j S c r o l l P a n e 2 . s e t A u t o s c r o l l s ( true ) ;
jT a b le 1 . setModel ( new javax . swing . t a b l e . DefaultTableModel (
new Object [ ] [ ] {
{ null , null , null , null } ,
{ null , null , null , null } ,
{ null , null , null , null } ,
{ null , null , null , null }
},
new S t r i n g [ ] {
" T i t l e 1" , " T i t l e 2" , " T i t l e 3" , " T i t l e 4"
}
));
jT a b le 1 . setAutoResizeMode ( javax . swing . JTable .AUTO_RESIZE_OFF) ;
j S c r o l l P a n e 2 . setViewportView ( jT a b l e1 ) ;
j P a n e l 1 . add ( j S c r o l l P a n e 2 , new org . netbeans . l i b . awtextra .
A b s o l u t e C o n s t r a i n t s ( 1 0 , 20 , 870 , 200) ) ;
jButton6 . setTex t ( " Regenerar Matriz " ) ;
jButton6 . addMouseListener ( new j a v a . awt . event . MouseAdapter ( ) {
public void mouseClicked ( j a v a . awt . event . MouseEvent evt ) {
jButton6MouseClicked ( evt ) ;
}
}) ;
j P a n e l 1 . add ( jButton6 , new org . netbeans . l i b . awtextra .
A b s o l u t e C o n s t r a i n t s ( 5 9 0 , 230 , 1, 1) ) ;
jButton7 . setTex t ( " M o d i f i c a r d i s t a n c i a s " ) ;
jButton7 . addMouseListener ( new j a v a . awt . event . MouseAdapter ( ) {
public void mouseClicked ( j a v a . awt . event . MouseEvent evt ) {
jButton7MouseClicked ( evt ) ;
}
}) ;
j P a n e l 1 . add ( jButton7 , new org . netbeans . l i b . awtextra .
A b s o l u t e C o n s t r a i n t s ( 7 3 0 , 230 , 150 , 1) ) ;
28

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

jComboBox1 . a d d I t e m L i s t e n e r ( new j a v a . awt . event . I t e m L i s t e n e r ( ) {


public void itemStateChanged ( j a v a . awt . event . ItemEvent evt ) {
jComboBox1ItemStateChanged ( evt ) ;
}
}) ;
j P a n e l 1 . add ( jComboBox1 , new org . netbeans . l i b . awtextra .
A b s o l u t e C o n s t r a i n t s ( 9 0 , 230 , 1, 1) ) ;
j L a b e l 1 . se tText ( "N\ u00ba Ciudades : " ) ;
j P a n e l 1 . add ( jLabel1 , new org . netbeans . l i b . awtextra .
A b s o l u t e C o n s t r a i n t s ( 1 0 , 230 , 1, 20) ) ;
j L a b e l 2 . se tText ( " Ciudad i n i c i a l : " ) ;
j P a n e l 1 . add ( jLabel2 , new org . netbeans . l i b . awtextra .
A b s o l u t e C o n s t r a i n t s ( 1 6 0 , 230 , 80 , 20) ) ;
jComboBox2 . a d d I t e m L i s t e n e r ( new j a v a . awt . event . I t e m L i s t e n e r ( ) {
public void itemStateChanged ( j a v a . awt . event . ItemEvent evt ) {
jComboBox2ItemStateChanged ( evt ) ;
}
}) ;
j P a n e l 1 . add ( jComboBox2 , new org . netbeans . l i b . awtextra .
A b s o l u t e C o n s t r a i n t s ( 2 5 0 , 230 , 1, 1) ) ;
getContentPane ( ) . add ( jPanel1 , new org . netbeans . l i b . awtextra .
A b s o l u t e C o n s t r a i n t s ( 0 , 0 , 890 , 270) ) ;
j P a n e l 2 . setLayout ( new org . netbeans . l i b . awtextra . AbsoluteLayout ( ) )
;
j P a n e l 2 . s e t B o r d e r ( javax . swing . BorderFactory . c r e a t e T i t l e d B o r d e r ( "B
\ u00fasqueda No Informada " ) ) ;
jButton1 . setTe xt ( " Primero en profundidad " ) ;
jButton1 . addMouseListener ( new j a v a . awt . event . MouseAdapter ( ) {
public void mouseClicked ( j a v a . awt . event . MouseEvent evt ) {
jButton1MouseClicked ( evt ) ;
}
}) ;
j P a n e l 2 . add ( jButton1 , new org . netbeans . l i b . awtextra .
A b s o l u t e C o n s t r a i n t s ( 1 0 , 20 , 170 , 1) ) ;
jButton2 . setTe xt ( " R a m i f i c a c i \ u00f3n y poda" ) ;
jButton2 . addMouseListener ( new j a v a . awt . event . MouseAdapter ( ) {
public void mouseClicked ( j a v a . awt . event . MouseEvent evt ) {
jButton2MouseClicked ( evt ) ;
}
}) ;

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

j P a n e l 2 . add ( jButton2 , new org . netbeans . l i b . awtextra .


A b s o l u t e C o n s t r a i n t s ( 1 9 0 , 20 , 150 , 1) ) ;
jButton3 . setT ext ( " Costo uniforme " ) ;
jButton3 . addMouseListener ( new j a v a . awt . event . MouseAdapter ( ) {
public void mouseClicked ( j a v a . awt . event . MouseEvent evt ) {
jButton3MouseClicked ( evt ) ;
}
}) ;
j P a n e l 2 . add ( jButton3 , new org . netbeans . l i b . awtextra .
A b s o l u t e C o n s t r a i n t s ( 3 5 0 , 20 , 140 , 1) ) ;
getContentPane ( ) . add ( jPanel2 , new org . netbeans . l i b . awtextra .
A b s o l u t e C o n s t r a i n t s ( 0 , 480 , 500 , 60) ) ;
j P a n e l 3 . setLayout ( new org . netbeans . l i b . awtextra . AbsoluteLayout ( ) )
;
j P a n e l 3 . s e t B o r d e r ( javax . swing . BorderFactory . c r e a t e T i t l e d B o r d e r ( "B
\ u00fasqueda Informada " ) ) ;
jButton4 . setTe xt ( " Vecino m\ u00e1s pr \ u00f3ximo " ) ;
jButton4 . addMouseListener ( new j a v a . awt . event . MouseAdapter ( ) {
public void mouseClicked ( j a v a . awt . event . MouseEvent evt ) {
jButton4MouseClicked ( evt ) ;
}
}) ;
j P a n e l 3 . add ( jButton4 , new org . netbeans . l i b . awtextra .
A b s o l u t e C o n s t r a i n t s ( 1 0 0 , 20 , 170 , 1) ) ;
jButton5 . setTe xt ( "A " ) ;
jButton5 . addMouseListener ( new j a v a . awt . event . MouseAdapter ( ) {
public void mouseClicked ( j a v a . awt . event . MouseEvent evt ) {
jButton5MouseClicked ( evt ) ;
}
}) ;
j P a n e l 3 . add ( jButton5 , new org . netbeans . l i b . awtextra .
A b s o l u t e C o n s t r a i n t s ( 1 0 , 20 , 80 , 1) ) ;
jButton8 . setTe xt ( " Escalada " ) ;
jButton8 . addMouseListener ( new j a v a . awt . event . MouseAdapter ( ) {
public void mouseClicked ( j a v a . awt . event . MouseEvent evt ) {
jButton8MouseClicked ( evt ) ;
}
}) ;
j P a n e l 3 . add ( jButton8 , new org . netbeans . l i b . awtextra .
A b s o l u t e C o n s t r a i n t s ( 2 8 0 , 20 , 100 , 1) ) ;
getContentPane ( ) . add ( jPanel3 , new org . netbeans . l i b . awtextra .
30

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

A b s o l u t e C o n s t r a i n t s ( 5 0 0 , 480 , 390 , 60) ) ;


j P a n e l 4 . setLayout ( new org . netbeans . l i b . awtextra . AbsoluteLayout ( ) )
;
j P a n e l 4 . s e t B o r d e r ( javax . swing . BorderFactory . c r e a t e T i t l e d B o r d e r ( "
Resultados " ) ) ;
jTextArea1 . setColumns ( 2 0 ) ;
jTextArea1 . s e t E d i t a b l e ( f a l s e ) ;
jTextArea1 . setRows ( 5 ) ;
j S c r o l l P a n e 1 . setViewportView ( jTextArea1 ) ;
j P a n e l 4 . add ( j S c r o l l P a n e 1 , new org . netbeans . l i b . awtextra .
A b s o l u t e C o n s t r a i n t s ( 1 0 , 20 , 870 , 180) ) ;
getContentPane ( ) . add ( jPanel4 , new org . netbeans . l i b . awtextra .
A b s o l u t e C o n s t r a i n t s ( 0 , 270 , 890 , 210) ) ;
j P a n e l 5 . setLayout ( new org . netbeans . l i b . awtextra . AbsoluteLayout ( ) )
;
j P a n e l 5 . s e t B o r d e r ( javax . swing . BorderFactory . c r e a t e T i t l e d B o r d e r ( "B
\ u00fasqueda No Informada & Informada " ) ) ;
jButton9 . setTe xt ( "Todo" ) ;
jButton9 . addMouseListener ( new j a v a . awt . event . MouseAdapter ( ) {
public void mouseClicked ( j a v a . awt . event . MouseEvent evt ) {
jButton9MouseClicked ( evt ) ;
}
}) ;
j P a n e l 5 . add ( jButton9 , new org . netbeans . l i b . awtextra .
A b s o l u t e C o n s t r a i n t s ( 4 0 0 , 20 , 100 , 1) ) ;
getContentPane ( ) . add ( jPanel5 , new org . netbeans . l i b . awtextra .
A b s o l u t e C o n s t r a i n t s ( 0 , 540 , 890 , 60) ) ;
pack ( ) ;
} // </ e d i t o r f o l d >//GENEND: initComponents

private void jButton9MouseClicked ( j a v a . awt . event . MouseEvent evt ) { //


GENFIRST : e v e n t _ j B u t t o n 9 M o u s e C l i c ke d

try {

Dep th Fi rs tSe ar ch s1 = new De pt hF irs tS ear ch ( r o u t e s , s o u r c e C i t y


);
jTextArea1 . set Text ( s1 . e x e c u t e ( ) ) ;
BranchAndBound s2 = new BranchAndBound ( r o u t e s , s o u r c e C i t y ) ;
jTextArea1 . set Text ( jTextArea1 . getText ( ) + s2 . e x e c u t e ( ) ) ;
UniformCost s3 = new UniformCost ( r o u t e s , s o u r c e C i t y ) ;
jTextArea1 . set Text ( jTextArea1 . getText ( ) + s3 . e x e c u t e ( ) ) ;
AStar s6 = new AStar ( r o u t e s , s o u r c e C i t y ) ;
jTextArea1 . set Text ( jTextArea1 . getText ( ) + s6 . e x e c u t e ( ) ) ;
31

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

NearestNeighbour s4 = new NearestNeighbour ( r o u t e s , s o u r c e C i t y


);
jTextArea1 . set Text ( jTextArea1 . getText ( ) + s4 . e x e c u t e ( ) ) ;
H i l l C l i m b i n g s5 = 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 . set Text ( jTextArea1 . getText ( ) + s5 . 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
alguno de l o s mtodos 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 9 M o u s e C l i c k e d

private void jComboBox1ItemStateChanged ( j a v a . awt . event . ItemEvent evt )


{ //GENFIRST : event_jComboBox1ItemStateChanged

i f ( evt . getStateChange ( ) == evt .SELECTED) {


// new number o f c i t i e s

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

private void jComboBox2ItemStateChanged ( j a v a . awt . event . ItemEvent evt )


{ //GENFIRST : event_jComboBox2ItemStateChanged

i f ( evt . getStateChange ( ) == evt .SELECTED) {


// s e l e c t t h e new s o u r c e c i t y

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

private void jButton8MouseClicked ( j a v a . awt . event . MouseEvent evt ) { //


GENFIRST : e v e n t _ j B u t t o n 8 M o u s e C l i c ke d

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

private void jButton4MouseClicked ( j a v a . awt . event . MouseEvent evt ) { //


GENFIRST : e v e n t _ j B u t t o n 4 M o u s e C l i c ke d

try {

NearestNeighbour s = new NearestNeighbour ( 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 d e l Vecino ms Proximo 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 4 M o u s e C l i c k e d

private void jButton5MouseClicked ( j a v a . awt . event . MouseEvent evt ) { //


GENFIRST : e v e n t _ j B u t t o n 5 M o u s e C l i c ke d

try {

AStar s = new AStar ( 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 A E s t r e l l a 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 Bu t t o n 5 M o u s e C l i c k e d

private void jButton3MouseClicked ( j a v a . awt . event . MouseEvent evt ) { //


GENFIRST : e v e n t _ j B u t t o n 3 M o u s e C l i c ke d

try {

UniformCost s = new UniformCost ( 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 de Costo Uniforme 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) ;
33

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

private void jButton2MouseClicked ( j a v a . awt . event . MouseEvent evt ) { //


GENFIRST : e v e n t _ j B u t t o n 2 M o u s e C l i c ke 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

private void jButton7MouseClicked ( j a v a . awt . event . MouseEvent evt ) { //


GENFIRST : e v e n t _ j B u t t o n 7 M o u s e C l i c ke 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

for ( int i =0; i <r o u t e s . g e t C i t i e s C o u n t ( ) ; i ++) {


for ( int j =0; j<r o u t e s . g e t C i t i e s C o u n t ( ) ; j++) {
int v a l u e = I n t e g e r . p a r s e I n t ( j T ab l e 1 . getValueAt ( i , j +1) .
toString () ) ;

i f ( v a l u e >= 0 && v a l u e <=r o u t e s . getMaxDistance ( ) ) {

routes . setCost ( i , j , value ) ;

// 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

private void jButton6MouseClicked ( j a v a . awt . event . MouseEvent evt ) { //


GENFIRST : e v e n t _ j B u t t o n 6 M o u s e C l i c ke d

int c i t i e s = ( ( I n t e g e r ) jComboBox1 . getItemAt ( jComboBox1 .


getSelectedIndex () ) ) . intValue () ;

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

private void jButton1MouseClicked ( j a v a . awt . event . MouseEvent evt ) { //


GENFIRST : e v e n t _ j B u t t o n 1 M o u s e C l i c ke d

try {

D ept hF ir st Sea rc h s = new De pt hF irs tS ear ch ( r o u t e s , s o u r c e C i t y ) ;


34

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
/

public static void main ( S t r i n g a r g s [ ] ) {


j a v a . awt . EventQueue . i n v o k e L a t e r ( new Runnable ( ) {
public void run ( ) {
new Main ( ) . s e t V i s i b l e ( true ) ;

}) ;

// V a r i a b l e s d e c l a r a t i o n do not modify //GENBEGIN: v a r i a b l e s

private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private

javax . swing . JButton jButton1 ;


javax . swing . JButton jButton2 ;
javax . swing . JButton jButton3 ;
javax . swing . JButton jButton4 ;
javax . swing . JButton jButton5 ;
javax . swing . JButton jButton6 ;
javax . swing . JButton jButton7 ;
javax . swing . JButton jButton8 ;
javax . swing . JButton jButton9 ;
javax . swing . JComboBox jComboBox1 ;
javax . swing . JComboBox jComboBox2 ;
javax . swing . JLabel j L a b e l 1 ;
javax . swing . JLabel j L a b e l 2 ;
javax . swing . JPanel j P a n e l 1 ;
javax . swing . JPanel j P a n e l 2 ;
javax . swing . JPanel j P a n e l 3 ;
javax . swing . JPanel j P a n e l 4 ;
javax . swing . JPanel j P a n e l 5 ;
javax . swing . J S c r o l l P a n e j S c r o l l P a n e 1 ;
javax . swing . J S c r o l l P a n e j S c r o l l P a n e 2 ;
javax . swing . JTable j T ab l e 1 ;
javax . swing . JTextArea jTextArea1 ;

// 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

$LastChangedDate : 2008 03 30 2 0 : 4 1 : 4 1 +0200 (dom , 30 mar 2008) $


$LastChangedRevision : 14 $
V i c e n t e J . F e r r e r Dalmau
< vicente@jdalmau . es >

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
/

public class NearestNeighbour {


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 ;

/ 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 /

public NearestNeighbour ( RoutesMatrix matrix , int s o u r c e C i t y ) {


d i s t a n c e s = matrix ;

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++;

long startTime = System . c u r r e n t T i m e M i l l i s ( ) ;


search ( sourceCity ) ;

36

long endTime = System . c u r r e n t T i m e M i l l i s ( ) ;

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 .
/

public void s e a r c h ( int from ) {


int currentTown = from ;

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

r out eCo st += d i s t a n c e s . getCost ( currentTown , s o u r c e C i t y ) ;


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++;

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 >

This c l a s s d e f i n e s a l l t h e d i s t a n c e s between t h e c i t i e s i n t h e problem


.
For two c i t i e s , x and y , t h e b o t h d i s t a n c e s x t o y and y t o x remain
t h e same .
/

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
/

public class RoutesMatrix {

private int [ ] [ ] theMatrix ;


private int c i t i e s ;

// 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)

private int MAXDISTANCE = 1 0 0 ;

/ C r e a t e s a new i n s t a n c e o f RoutesMatrix
/

public RoutesMatrix ( int c i t i e s ) {

theMatrix = new int [ c i t i e s ] [ c i t i e s ] ;


this . c i t i e s = c i t i e s ;
// f i l l t h e m a t r i x w i t h random v a l u e s
// a new random g e n e r a t o r ( s e e d b a s e d on t h e c u r r e n t time )

Random g e n e r a t o r = new Random ( ) ;

for ( int i =0; i <c i t i e s ; i ++) {


for ( int j=i ; j<c i t i e s ; j++) {
i f ( i == j )
theMatrix [ i ] [ j ] = 0 ;

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 "
/

public int getCost ( int a , int 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 "
/

public void s e t C o s t ( int a , int b , int c o s t ) {

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 ( ) {

Object [ ] [ ] a r r a y = new Object [ c i t i e s ] [ c i t i e s + 1 ] ;


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 == 0) {
array [ i ] [ 0 ] = i ;
a r r a y [ i ] [ j +1] = theMatrix [ i ] [ j ] ;
}

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 ( ) {

Object [ ] a r r a y = new Object [ c i t i e s + 1 ] ;


39

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

for ( int i =0; i <c i t i e s ; i ++) {


i f ( i == 0) {
}

array [ i ] = " " ;


a r r a y [ i +1] = 0 ;

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 int getMaxDistance ( ) {


return MAXDISTANCE;

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

public class MyRender extends D e f a u l t T a b l e C e l l R e n d e r e r {


public Component getTableCellRendererComponent ( JTable t a b l e ,
Object value ,

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 ) ;

this . setOpaque ( true ) ;


this . setToolTipText ( "" ) ;
i f ( column == 0) {
this . setBackground ( Color .LIGHT_GRAY) ;
this . s e t H o r i z o n t a l A l i g n m e n t ( JTextField .CENTER) ;

else i f ( column 1 == row ) {


this . setBackground ( Color .LIGHT_GRAY) ;
40

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

this . setBackground ( Color .WHITE) ;


this . setToolTipText ( "De l a ciudad "+row+" a l a "+(column
1) ) ;

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 .
/

public void drawJTable ( JTable j ) {

DefaultTableModel dtm = new DefaultTableModel ( ) {


public boolean i s C e l l E d i t a b l e ( int row , int column ) {
i f ( column != 0 && ( column 1 != row ) )
return true ;

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

$LastChangedDate : 2008 03 28 2 1 : 3 7 : 2 1 +0100 ( v i e , 28 mar 2008) $


$LastChangedRevision : 9 $
V i c e n t e J . F e r r e r Dalmau
< vicente@jdalmau . es >

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
/

public class Town {

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 ;

Town parent = null ;

/ C r e a t e s a new i n s t a n c e o f Town /

public Town( int number , int g , int h , int l e v e l ) {

this . number = number ;


this . g = g ;
this . h = h ;
this . f = this . g + this . h ;
this . l e v e l = l e v e l ;

UniformCost

/
UniformCost . j a v a

$LastChangedDate : 2008 03 30 2 0 : 4 1 : 4 1 +0200 (dom , 30 mar 2008) $


$LastChangedRevision : 14 $
V i c e n t e J . F e r r e r Dalmau
< vicente@jdalmau . es >

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
/

public class UniformCost {

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 /

public UniformCost ( RoutesMatrix matrix , int s o u r c e C i t y ) {


d i s t a n c e s = matrix ;

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

long startTime = System . c u r r e n t T i m e M i l l i s ( ) ;


// i n i t i a l town

toExpand . add ( new Town( s o u r c e C i t y , 0 , 0 , 0) ) ;

while ( ! toExpand . isEmpty ( ) && ! s o l u t i o n ) {


// g e t s t h e c i t y w i t h l o w e r g v a l u e

Town currentTown = toExpand . p o l l ( ) ;


nodes++;

// 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

Town aux = currentTown ;


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 ( aux . number ) ;
while ( aux . l e v e l != 0) {
aux = aux . parent ;
f o l l o w e d R o u t e . add ( 0 , aux . number ) ;
}

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 {

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 ++) {

// 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 }

d i s t a n c e s . getCost ( currentTown . number , i ) , 0 ,


currentTown . l e v e l + 1) ;
childTown . parent = currentTown ;
toExpand . add ( childTown ) ;

long endTime = System . c u r r e n t T i m e M i l l i s ( ) ;


r e s u l t = "\n" ;
r e s u l t += "BSQUEDA DE COSTO UNIFORME: \ 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 ;

44

También podría gustarte