You are on page 1of 18

Metaheurstic

a
Prctica 1a: Metaheursticas
basadas en trayectorias
Algoritmos empleados: Greedy, Bsqueda
local y Bsqeuda Tab.
Juan Antonio Prez Cruz 77362120X
japc0010@red.ujaen.es
Juana Mara Rodrguez Garca 77363220Y
jmrg0021@red.ujaen.es
Grupo 2: 12.30-14:30

ndice
Descripcin del
problema
.2
Descripcin de la aplicacin de los
algoritmos..3
Lectura del
fichero.
3
Coste de la funcin
objetivo3

Factorizacin
.4
Solucin
inicial
.4
Estructura del mtodo de
bsqueda
.5
Bsqueda
local
.5
Bsqueda
tab.
...6
Algoritmo de comparacin: bsqueda Greedy..
...9
Breve manual de
usuario
.10
Experimentos y anlisis de
resultados..
.11
Referencias
bibliogrficas
14
1

Descripcin del problema


El problema que debemos resolver se denomina asignacin cuadrtica (QAP). Es uno
de los problemas de optimizacin combinatoria ms conocidos.
Se dispone de n unidades y n localizaciones para situarlas. El problema pues, consiste
en encontrar la asignacin ptima de cada unidad a una localizacin.
La funcin objetivo mide en este caso la bondad de una asignacin y considera el
producto de la distancia entre cada par de localizaciones y el flujo que circula entre
cada par de unidades.
De ah que se hable de funcin cuadrtica, puesto que considera el producto de dos
trminos.
La frmula del QAP quedara:

es una solucin al problema que consiste en una permutacin que representa la

asignacin de la unidad i a la localizacin

(i)

fij
Dkl

es el flujo que circula entre la unidad i y la j.


es la distancia existente entre la localizacin k y la l.

Descripcin de la aplicacin de los algoritmos


Lectura del fichero:
PROCEDIMIENTO lecturaFichero( nombre: cadena, VAR flujo:array(tam,tam) de entero, VAR
distancias: array(tam,tam) de entero, VAR tam:entero)
leerfichero(fp, tam);
//Especifica el tamao de la matriz
Coger_memoria(distancias);
Coger_memoria(flujo);
//Lectura de los datos de las distancias
Para i = 0 hasta tam-1 hacer
Para j = 0 hasta tam-1 hacer
leerfichero (fp, distancias [i][j]);
//Lectura de los flujos
Para i = 0 hasta tam-1 hacer
Para j = 0 hasta tam-1 hacer
leerfichero (fp, flujo [i][j]);
}
Coste de la funcin objetivo:
Se utiliza aqu un vector llamado s de tamao tam que contiene las localizaciones
insertadas en las posiciones del vector que estas indican.
FUNCION coste (s: array de enteros, flujo:array()(tam), localizaciones: array()
(tam), tam:entero)
coste:entero = 0
Para i = 0 Hasta tam Hacer
Para j = 0 Hasta tam Hacer
coste += flujo(i)(j) * localizaciones(s(i),(s(j))
Fin_Para
Fin_Para
Devolver coste

Factorizacin:
Haremos uso de esta funcin, puesto que la funcin del coste tiene mucho costo
computacional. Al hacer cualquier cambio para representar nuestra solucin
empleamos un valor actual r y otro s, cuando generamos nuevas secuencias vecinas
en cada movimiento.
FUNCION factorizacion (solActual:array de enteros, , flujo :array()(tam),
localizaciones:array(tam)(tam), tam:entero, s:entero, r:entero)
costeActual:entero = 0
Para k = 0 Hasta tam Hacer
Si k es distinto de r Y k es distinto de s entonces
costeActual += flujo(r)(k)*(localizaciones(solActual(s))(solActual(k))
localizaciones(solActual(r))(solActual(k))) +
flujo(s)(k)*(localizaciones(solActual(r)(solActual(k)) l localizaciones
(solActual(s))(solActual(k))) +
flujo(k)(r)*(localizaciones(solActual[k))(solActual[s)) - localizaciones
[solActual(k))[solActual[r))) +
flujo(k)(r)*(localizaciones(solActual(k))[solActual[r)) - localizaciones
[solActual[k))(solActual[s)))
Fin_Si
Fin_Para
Devolver costeActual;

Solucin inicial:
Haremos uso de una solucin inicial aleatoria a partir de una semilla:

PROCEDIMIENTO solucionInicial (s:array de enteros, tam:entero, semilla:entero) {


numAleatorio(semilla);
// primero vamos a inicializar todo el vector a -1
Para i = 0 Hasta tam Hacer
s(i) = -1;
Fin_Para
Para i = 0 Hasta tam Hacer
x:entero = numAleatorio entre 0 y tam-1
Si i igual a 0
s(i) = x
Si_no
Para j =0 Hasta i Hacer
Si s(j) es igual a x
i-Salimos del bucle
Si_no
s(i) = x
Fin_Si_no
Fin_Para
Fin_Si_no

Estructura del mtodo de bsqueda


Bsqueda Local
Esta funcin sirve para permutar.
FUNCION swap (solActual : array de enteros, r:entero, s:entero)
aux:entero
aux = solActual[r]
solActual[r] = solActual[s]
solActual[s] = aux

La solucin que obtenemos con la bsqueda local est basada en el pseudocdigo del
seminario: Dont Look Bits:
En la primera iteracin, todos los bits estn a 0, es decir, todas las unidades estn
activadas en un bucle externo y todos sus movimientos pueden ser considerados para
explorar el entorno:
a) Si tras probar todos los movimientos asociados a esa unidad, ninguno provoca
una mejora, se pone su bit a 1 para desactivarla en el futuro

b) b) Si una unidad est implicada en un movimiento que genera una solucin


vecina con mejor coste, se pone su bit a 0 para reactivarla
FUNCION solucionBL(flu:array de enteros, loc:array de enteros, tam:int,
&solucionActual:array de enteros)
dlb(tam):array de enteros
mejora:bool
costeActual : entero = coste(solucionActual, flu, loc, tam)
Para int i = 0 Hasta tam Hacer
Si (dlb(i) es igual a 0)
mejoria = false
Para int j = i + 1 Hasta tam Hacer
c : entero = factorizacion(solucionActual, flu, loc, tam, costeActual, i, j)
Si (c < costeActual)
swap(solucionActual, i, j)
costeActual = c
mejoria = true
dlb(i) = false // 0
dlb(j) = false // 0
i = 0 // para empezar desde el principio la bsqueda
Fin_Si
Fin_Para
Si (mejora es igual a false)
dlb(i) = true //1
Fin_Si
Fin_Para

Bsqueda Tab
Consideramos en este algoritmo una lista de movimientos tab que permitirn o no
seleccionar a unos vecinos generados en cada iteracin. Se coge entonces al mejor de
estos, dejando a un lado la funcin objetivo. Para mejorar las posibles soluciones se
hace una re-inicializacin de la bsqueda, despus de 10 iteraciones sin mejora. Esto lo
haremos de tres formas distintas: desde una nueva solucin aleatoria (mejorando
diversidad), desde una mejor solucin encontrada hasta el momento (mejorando la
intensificacin), o desde la solucin menos frecuente que se ha dado (controlando la
diversidad).

Parmetros de la Bsqueda Tab:


Criterio de parada: 10000 iteraciones
Tamao de la lista tab: ndatos / 2.
Tamao del vecindario: 30.
N de iteraciones necesarias para reinicializar la bsqueda: 10
Tamao de la memoria a largo plazo: ndatos x ndatos (triangular superior).

Criterio
de
aspiracin:
vecino_generado_tabu
<
mejor_encontrada_hasta_ahora

PROCEDIMIENTO BusquedaTabu(): devuelve una solucion {


nuevoTam:entero = tama * (tama - 1) / 2;
solucionesVecinas:array de enteros
solucionesVecinas.reservar(numVecinos, array(tama) de enteros);
mejorValorLocal: entero
mejorSolucionActual:array(tam) de enteros
ListaTabu:array(tam,tam) de enteros
ListaTabu.reservar(tamTabu, array(tama) de enteros)
pi:array(tama) de enteros
solucionInicial(pi,tama,semilla)
mejorSoIucion=pi;
mejorValor = coste(pi,Flujo,Dist,tama);
Para i = 0 Hasta i < numVecinos Hacer
Para j = i + 1 Hasta j < tama Hacer
frec[solucionesVecinas(i)(j))(solucionesVecinas(i)[j))=0
Fin_Para
Fin_Para
contadorReinicio:entero
Para
k
=
0
Hasta
k
<
numPasos
-------------------------------------------------------------------------------todasSolucionesVecinas:array(tam,tam) de enteros
todasSolucionesVecinas.reasignar(nuevoTam, array de enteros)
num:entero
Repetir
Para i = 0 Hasta i <tam Hacer
Para j = i + 1 Hasta j < tama Hacer
TodasSolucionesVecinas(num) = pi
intercambia(todasSoluVecinas(num)(i), todasSoluVecinas(num](j))
num++
Fin_Para
Fin_Para
Mientras (num < nuevoTam)
Elegir:arrray de enteros de tamao numVecinos
Para i = 0 Hasta i < numVecinos Hacer
Elegir(i) = -1 // inicializamos a -1
Fin_para
rnd:entero
8

Hacer

cnt:entero = 0;
Repetir
rnd = aleatorio(0,nuevoTam-1)
Si (find(elegir.begin(), elegir.end(), rnd) == elegir.end())
elegir [cnt] = rnd
cnt++
Mientras (cnt < numVecinos)
Para i = 0 Hasta i < numVecinos Hacer
solucionesVecinas[i] = todasSolucionesVecinas[elegir[i]]
Fin_Para
Para num = 0 Hasta num < numVecinos Hacer
Para i = 0 Hasta i < tama Hacer
Para j = i + 1 Hasta j < tama Hacer
Frec(soluVecinas(num)(i))(soluVecinas(num)(j))++
Fin_Para
Fin_Para
Fin_Para
MejorValorLocal = coste(soluVecinas(0),Flujo,Dist,tama)
mejorSolucionLocal= solucionesVecinas(0)
Para i = 0 Hasta i < numVecinos Hacer
Si (compruebaTabu(soluVecinas(i), ListaTabu) == 0 o mejorValorLocal<mejorValor)
vecinoActual:entero = funcionObjetivo(soluVecinas(i))
Si (vecinoActual < mejorValorLocal)
mejorValorLocal = vecinoActual
mejorSolucionLocal = soluVecinas(i)
Fin_Si
ListaTabu = aadeTabu(mejorSolucionLocal, ListaTabu);
Fin_Si
Fin_Para // fin del para
pi = mejorSolucionLocal
Si (mejorValorLocal< mejorValor)
mejorValor = mejorValorLocal;
mejorSolucion = mejorSolucionLocal
SiNo
contReinicio++
Si (contReinicio !=0 y (contReinicio%numReinicio == 0))
contReinicio=0
tirada:flotante = aleatorio(0, 1)
Si (tirada <= 0.25)
9

solucionInicial(pi,tama,aleatorio(0,100000));
mejorValor = Coste(pi,Flujo,Dist,tama);
SiNo
Si (tirada <= 0.5)
pi=mejorSolucion
mejorValor = coste(pi,Flujo,Dist,tama)
SiNo
pi=generaSolucionFrecuencia(frec)
mejorValor = coste(pi,Flujo,Dist,tama)
Fin_Si
Fin_Si
tirada = aleatorio(0, 1)
Si (tirada <= 0.5)
Si (tamTabu<=1) tamTabu=tama/2
tamTabu *= 0.5
SiNo
Si (tamTabu>=tama) tamTabu=tama/2
tamTabu *= 1.5
Fin_Si
Fin_Si
ListaTabu.borrar ()
ListaTabu.reservar(tamTabu)
Fin_Si //fin de las reinicializaciones
Fin_para//fin
del
general-------------------------------------------------------------------------------------------------

Algoritmo de comparacin
Bsqueda Greedy

10

for

FUNCION solucionGreedy( flu:array(tam,tam) de entero, loc:array(tam,tam) de


entero, tam:entero, s:array de entero){
menord,mayorf:entero;
potflu, potdis:array de enteros;
potdis.reserva(tam);
potflu.reserva(tam);
CalculaPotenciales(potflu, potdis, tam, s, flu, loc);
Para i=0 hasta tam hacer
menord= menorDist(potdis,tam);
mayorf= mayorFluj(potflu,tam);
s[mayorf]=menord;
Fin_Para

El algoritmo Greedy del QAP se basa en la heurstica de asociar unidades de gran flujo
con localizaciones cntricas en la red y viceversa. Para ello, se calculan dos vectores, el
potencial de flujo y el potencial de distancia, que se componen respectivamente de la
sumatoria de flujos de una unidad al resto
localizacin al resto

y de distancias desde una

. Para una unidad concreta, cuanto mayor sea

ms

importante es la unidad en el intercambio de flujos. Por otro lado, cuanto menor sea
ms cntrica es una localizacin concreta. Por tanto, el algoritmo ir seleccionando la
unidad i libre con mayor

y le asignar la localizacin k libre con menor

FUNCION CrearPotenciales(potflu:array de enteros, potdis:array de enteros, tam:entero,


s:array de enteros, flu:array de enteros()(), loc:array de enteros()()) {
Para i = 0; Hasta tam Hacer
potflu(i) = 0
potdis(i) = 0
Para j = 0 Hasta tam Hacer
Potflu(i) = potflu(i) + flu(i)(j)
Potdis(i) = potdis(i) + loc[i)(j)
Fin_Para
Fin_Para

Breve manual de usuario


11

Vamos a probar con los archivos:


Els19,Chr20a,Chr25a,Nug25,Bur26a,Bur26b,Tai30a,Tai30b,Esc32a,Kra32,Tai35a,Tai35b,
Tho40,Tai40a,Sko42,Sko49,Tai50a,Tai50b,Tai60a,Lipa90a con extensin .dat para
comparar resultados.
Para probarlos simplemente tenemos que introducir el nombre del fichero a analizar y
una semilla que puede ser por ejemplo nuestro DNI, sin letra.
Al ejecutar nos aparecern las distintas soluciones de cada algoritmo, mostrndonos
las localizaciones en forma de solucin.
Primero nos mostrar la solucin con el algoritmo Greedy, despus con la bsqueda
local y por ltimo con la bsqueda tab.
En todos ellos aparece el tiempo de ejecucin.

Experimentos y anlisis de resultados:


12

Caso
Els19

Algoritmo GREEDY
Coste obtenido
Desv
38627698
124,42
8632

293,80

0.217238

20820

448,47

0.422075

4462

19,18

0.424213

5968117

9,98

0.302765

4323853

13,25

0.32543

2104696

15,76

0.358785

1387185541

117,73

0.348949

314

141,54

0.582865

116090

30,88

0.374607

2886118

19,16

0.115867

506552163

78,79

0.114889

312578

29,96

0.134444

3730054

18,82

0.1364

19942

26,12

0.145689

27626

18,13

0.189689

5804880

17,54

0.192622

788404422

71,83

0.195067

8373936

16,21

0.271333

367940

2,03

0.464445

Chr20a
Chr25a
Nug25
Bur26a
Bur26b
Tai30a
Tai30b
Esc32a
Kra32
Tai35a
Tai35b
Tho40
Tai40a
Sko42
Sko49
Tai50a
Tai50b
Tai60a
Lipa90a

Tiempo
0.214672

Desviacin media: 75,68


Tiempo medio: 0,28

Caso
Els19

Algoritmo BSQUEDA LOCAL


Coste obtenido
Desv
63148862
266,88
13

Tiempo
0.143685

Chr20a
Chr25a
Nug25
Bur26a
Bur26b
Tai30a
Tai30b
Esc32a
Kra32
Tai35a
Tai35b
Tho40
Tai40a
Sko42
Sko49
Tai50a
Tai50b
Tai60a
Lipa90a

10748

390,33

0.151382

7028

85,14

46.3927

4036

7,80

47.1274

5475745

0,90

77.0502

3844040

0,69

96.8471

1955438

7,55

39.211

773892715

21,47

102.769

192

47,69

50.9753

104930

18,30

67.4926

2677192

10,54

14.8001

374701532

32,26

22.2875

290502

20,78

12.3278

3514614

11,95

13.5857

17874

13,04

21.3068

26204

12,05

16.0825

5528592

11,94

19.8083

629875942

37,28

56.5234

8480430

17,69

1.11271

363968

0,93

571.834

Desviacin
media: 59,76
Tiempo medio:
301,70

Caso
Els19
Chr20a
Chr25a
Nug25

Algoritmo BSQUEDA TAB


Coste obtenido
Desv
21282720
23,65

Tiempo
29096.2

3968

81,02

34849.4

7194

89,52

46889.3

4436

18,48

47588.8

14

Bur26a
Bur26b
Tai30a
Tai30b

5444442

0,52

50883.1

3864205

0,41

47199.9

1924674

5,86

62675.9

864893435

35,75

60164.6

176

35,38

74496.6

127710

43,98

70385.9

2638406

8,93

16645.7

330548906

16,67

17066.9

272132

13,15

22179.6

3354188

6,84

22461.2

17324

9,56

23994.5

27234

16,45

31948.7

5403598

9,41

34479

540781128

17,86

34436.1

7819456

8,51

48830.3

366984

1,76

116204

Esc32a
Kra32
Tai35a
Tai35b
Tho40
Tai40a
Sko42
Sko49
Tai50a
Tai50b
Tai60a
Lipa90a
Desviacin
media: 22,22
Tiempo medio:
44623,79

Resultados globales en el QAP


Algoritm
o
Greedy
BL
BT

Desv

Tiempo

75,68
59,76
22,22

0,28
301,70
44623,79

15

En el Greedy podemos ver que el tiempo de ejecucin nfimo, ya que no genera


aleatorios ni vecinos, sino que simplemente asocia los potenciales de mayor flujo con
los potenciales de menor distancia para generar la solucin. Sin embargo, esto nos
conlleva una gran desventaja, ya que como se ve su desviacin hacia la solucin
ptima es muy elevada debido a que no diversifica ni intensifica.

Como vemos el algoritmo de bsqueda local no parece que sea muy bueno.
Parte de una solucin aleatoria y esto puede penalizar al algoritmo, ya que es
posible que se quede estancado en un mximo local que no sea lo
suficientemente bueno. Aun as, parece lgico que el uso de este algoritmo sea
ms conveniente que el Greedy, ya que se acerca ms a la solucin ptima y su
tiempo de ejecucin no es elevado.
La bsqueda tab, en cambio, nos da casi siempre una mejor solucin, ya que
genera vecinos y se queda con el mejor de ellos. En caso de estancamiento es
capaz de reinicializarse y explorar por otro vecindario diferente. El
inconveniente que este algoritmo nos plantea es un coste muy elevado de
cmputo, ya que tiene que generar muchos aleatorios y realizar 10000
iteraciones, generando en cada una de ellas 30 vecinos distintos.

Referencias bibliogrficas

-Para realizar la bsqueda local nos hemos basado en las trasparencias de


clase.

16

-La bsqueda tab la hemos encontrado en la siguiente pgina y a partir de ese


cdigo hemos modificado de tal forma que realice lo que la prctica pide.
www.geek.com
-Tambin nos hemos servido de algunos archivos pdf que hemos encontrado por
internet adems de lo explicado en clase.
http://link.springer.com/chapter/10.1007/0-306-48056-5_2#page-1
M. Josep Blesa and F. Xhafa. A C++ Implementation of a Skeleton
for Tabu Search Method. Tehnical Report LSI-00-47-R, Dept. de LSI, UPC, 2000
ingenierias.uanl.mx/48/48_Uso_de_busqueda.pdf

17