trabajo de fin de grado - universidad de...
TRANSCRIPT
1 Equation Chapter 1 Section 1
Trabajo de Fin de Grado
Grado en Ingeniería de Tecnologías Industriales
Desarrollo de algoritmos e interfaz gráfica para el
problema de ruteo de vehículos
Autor: D. Alvaro Salinero Martín de la Hinojosa
Tutor: Dr. Alejandro Santana Escudero
Dep. Organización Industrial y gestión de empresas II
Escuela Técnica Superior de Ingeniería
Universidad de Sevilla
Sevilla, 2016
2
3
Trabajo de Fin de Grado
Grado en Ingeniería de Tecnologías Industriales
Desarrollo de algoritmos e interfaz gráfica para el
problema de ruteo de vehículos
Autor:
D. Alvaro Salinero Martín de la Hinojosa
Tutor:
Dr. Alejandro Santana Escudero
Profesor Ayudante Doctor
Dep. Organización Industrial y Gestión de Empresas II
Escuela Técnica Superior de Ingeniería
Universidad de Sevilla
Sevilla, 2016
4
5
Trabajo de Fin de Grado: Desarrollo de algoritmos e interfaz gráfica para el problema de ruteo de vehículos
Autor: D. Alvaro Salinero Martín de la Hinojosa
Tutor: Dr. Alejandro Santana Escudero
El tribunal nombrado para juzgar el Proyecto arriba indicado, compuesto por los siguientes miembros:
Presidente:
Vocales:
Secretario:
Acuerdan otorgarle la calificación de:
Sevilla, 2016
El Secretario del Tribunal
6
7
A mis padres que siempre
creyeron en mí, incluso cuando yo
no podía.
8
9
ÍNDICE
Índice 9
Índice de Tablas 11
Índice de Figuras 13
1 INTRODUCCIÓN 15 1.1 Motivación del proyecto 17 1.2 Objetivo general 17 1.3 Estructura del proyecto 17
2 VRP Y SUS VARIANTES 19 2.1 TSP 21
2.1.1 Presentación TSP 21 2.1.2 Historia 21 2.1.3 Modelo 23
2.2 Otras variantes del TSP 24 2.3 VRP Clásico 25
2.3.1. Presentación del VRP 25 2.3.2. Historia 25 2.3.3. Modelo 25
2.4 VRP+Limitación de capacidad(CVRP) 27 2.4.1 Presentación VRP+Limitación de capacidad(CVRP) 27 2.4.2 Historia 27 2.4.3 Modelo 27
2.5 Otras variantes del VRP 29
3 METODOLOGÍA PROPUESTA 31 3.1 Algoritmo de ahorros 33
3.1.1 Presentación del algoritmo de ahorros 33 3.1.2 Algoritmo de ahorros (version paralela) 33 3.1.3 Algoritmo de ahorros (version secuencial) 34 3.1.4 Ejemplo de utilización 34
3.2 Búsqueda local y estrategias de vecindad 40 3.2.1 Presentación de búsqueda local y estrategias de vecindad 40 3.2.2 Tipos de movimiento 41 3.2.3 Ejemplo de utilización de búsqueda local 42
3.3 Búsqueda tabú 45 3.3.1 Presentación búsqueda tabú 45 3.3.2 Utilidades de la busqueda tabú 45 3.3.3 Uso de memoria 46 3.3.4 Intensificación y diversificación 46 3.3.5 Criterio de aspiración 46 3.3.6 Ejemplo ilustrativo de la búsqueda tabú 47
4 EXPLICACIÓN DEL PROGRAMA 51 4.1 Introducción de datos 53
4.1.1 Vehículos 53 4.1.2 Información de pedidos 54 4.1.3 Información de las ciudades 54
10
4.2 Programa 56 4.2.1 Ejecución del programa 56 4.2.2 Pantalla del programa principal 56
5 RESULTADOS 59 5.1 10 Ciudades 61 5.2 25 Ciudades 62 5.3 50 Ciudades 64 5.4 100 Ciudades 66
6 CONCLUSIONES 69
7 BIBLIOGRAFÍA 73
8 ANEXOS 77 8.1 Código del problema 79
8.1.1 Recolección de datos de excel 79 8.1.2 Algoritmos de ahorros de Clarke and Wright 80 8.1.3 Estrategias de vecindad 84 8.1.4 Lista tabú 91 8.1.5 Heuristica híbrida 101 8.1.6 Cambio de iteraciones 112
11
ÍNDICE DE TABLAS
Tabla 3.1Ejemplo algoritmo de ahorros 35
Tabla 3.2 Ejemplo algoritmo de ahorros 35
Tabla 3.3 Ejemplo algoritmo de ahorros 36
Tabla 3.4 Ejemplo algoritmo de ahorros 36
Tabla 3.5 Ejemplo algoritmo de ahorros 37
Tabla 3.6 Ejemplo algoritmo de ahorros 37
Tabla 3.7 Ejemplo algoritmo de ahorros 37
Tabla 3.8 Ejemplo algoritmo de ahorros 38
Tabla 3.9 Ejemplo algoritmo de ahorros 38
Tabla 3.10 Ejemplo algoritmo de ahorros 39
Tabla 3.11 Ejemplo algoritmo de ahorros 39
12
13
ÍNDICE DE FIGURAS
Figura 2.1 Ejemplo de VRP 21
Figura 2.2 Portada del libro Der Handlungsreisende 22
Figura 2.3 Cartel de la campaña publicitaria de ‘Procter&Gamble’ 22
Figura 3.1 Ejemplo gráfico de funcionamiento del algoritmo de ahorros 33
Figura 3.2 Gráfica diferentes óptimo 40
Figura 3.3 Gráfico representativo de intercambio 41
Figura 3.4 Gráfico representativo de inserción 41
Figura 3.5 Ejemplo de utilización de búsqueda local 42
Figura 3.6 Ejemplo de utilización de búsqueda local 42
Figura 3.7 Ejemplo de utilización de búsqueda local 42
Figura 3.8 Gráfico de ejemplo de intercambio en búsqueda local 43
Figura 3.9 Ejemplo de utilización de búsqueda local 43
Figura 3.10 Ejemplo de utilización de búsqueda local 43
Figura 3.11 Gráfica diferencia entre mínimo global y local 45
Figura 3.12 Ejemplo ilustrativo de búsqueda tabú 46
Figura 3.13 Ejemplo ilustrativo de búsqueda tabú 47
Figura 3.14 Ejemplo ilustrativo de búsqueda tabú 47
Figura 3.15 Ejemplo ilustrativo de búsqueda tabú 48
Figura 3.16 Ejemplo ilustrativo de búsqueda tabú 48
Figura 3.17 Ejemplo ilustrativo de búsqueda tabú 49
Figura 3.18 Ejemplo ilustrativo de búsqueda tabú 49
Figura 3.19 Ejemplo ilustrativo de búsqueda tabú 50
Figura 4.1 Excel Vehículos 53
Figura 4.2 Excel Pedidos 54
Figura 4.3 Central Ciudad 54
Figura 4.4 Excel Localizaciones 55
Figura 4.5 Instrucciones Matlab 56
Figura 4.6 Instrucciones Matlab 56
Figura 4.7 Instrucciones Matlab 57
Figura 5.1 Resultado 10 ciudades 61
Figura 5.2 Gráfica programa 10 ciudades 61
Figura 5.3 Resultado 25 ciudades 62
Figura 5.4 Resultado 25 ciudades (II) 62
Figura 5.5 Gráfica programa 25 ciudades 63
14
Figura 5.6 Resultados 50 ciudades 64
Figura 5.7 Resultados 50 ciudades (II) 64
Figura 5.8 Gráfica programa 50 ciudades 65
Figura 5.9 Resultados 100 ciudades 66
Figura 5.10 Resultado 100 ciudades (II) 66
Figura 5.11 Gráfica programa 100 ciudades 67
15
1 INTRODUCCIÓN
El presente es de ustedes, pero el futuro por el que tanto
he trabajado, me pertence.
- Nikola Tesla-
16
17
1.1 Motivación del proyecto
Los problemas de rutas de vehículos (VRP) siguen siendo a día de hoy uno de los problemas de optimización
en los que más se investiga. Propuesto en 1959 por Dantzig y Ramser, el VRP fue un problema importante en
los campos de transporte, distribución y logística.
VRP es un nombre genérico que se le da a una serie de problemas en los que puede intervenir distintas
restricciones, como la capacidad, tiempo o costes, en todos ellos el objetivo es obtener una ruta óptima entre los
distintos puntos de entrega. El resultado dependerá del objetivo del problema.
El transporte en el reparto de costes asociados a la logística es de un 44%. A su vez el 37% de este coste está
asociado al gasto de combustible, por lo que es un campo en el que minimizar costes es fundamental, sobre todo
en los últimos años en los que se busca reducir mucho los costes en logística, debido a la gran competencia
existente en este campo.
1.2 Objetivo general
En este proyecto se quiere conseguir además de un programa que resuelva un problema particular, que lo muestre
a través de una interfaz gráfica sencilla. Los programas que resuelven estos problemas suelen ser muy técnicos
y a menudo se debe tener un gran conocimiento de ellos para interpretar los resultados, con esta interfaz se quiere
que estos conocimientos se reduzcan sensiblemente y que cualquier persona pueda comprobar si la solución
propuesta por el programa es una solución coherente.
El objetivo general del proyecto es la facilitación de un programa sencillo, con una interfaz gráfica que se pueda
manejar perfectamente. El programa pone a disposición del usuario distintos métodos de resolución y muestra
las distintas soluciones gráficamente y numéricamente.
El usuario podrá introducir en el programa a través de un Excel los datos de su propio problema, el programa
los procesará y le mostrará el resultado obtenido por el mismo, le permitirá elegir entre varias opciones como la
heurística que quiere consultar para resolver el problema o el objetivo a minimizar del problema.
La interfaz gráfica también mostrará al usuario por pantalla la solución dibujada sobre un gráfico para que el
mismo usuario puede comprobar como son las rutas que propone el programa y si tienen sentido.
1.3 Estructura del proyecto
El documento se estructura en 8 capítulos, comienza con una descripción más bien teórica del problema y
continua con los métodos de resolución que se han utilizado y análisis de resultados obtenidos del programa.
1. Introducción:
Se explica el problema de una forma muy general, los detalles del mismo y por qué tiene importancia
el problema, también se definen los objetivos del problema y la estructura del documento.
2. VRP y sus variantes
En este capítulo se describe detalladamente y de forma muy teórica el problema que se resuelve en el
proyecto con sus distintas variantes. También se trata de la historia del programa y de las distintas
variantes del problema.
3. Metodología propuesta
Este capítulo analiza las distintas heurísticas que se proponen para la resolución del problema. Se
resuelven ejemplos ilustrativos con las distintas heurísticas propuestas.
4. Explicación del programa
En este capítulo se describe el programa propuesto al usuario para la resolución del problema, los
distintos pasos que debe seguir el usuario para utilizar el programa y sus características generales.
18
5. Resultados
Con la interfaz gráfica ya resuelta se analiza los distintos resultados que da el programa para las
diferentes heurísticas que se ha propuesto, y proceder a su análisis. Se analizan los resultados con un
número determinado de ciudades.
6. Conclusiones
Se detallan las distintas conclusiones a las que se ha llegado con los resultados que se han obtenido del
programa.
7. Bibliografía
Se cita los distintos medios en los que se ha consultado el autor para hacer el documento del proyecto.
8. Anexos
Se introducen los códigos del programa.
19
2 VRP Y SUS VARIANTES
El orgullo de quienes no pueden edificar es destruir.
- Alexandre Dumas-
20
21
El término VRP se refiere a un grupo bastante amplio de problemas, en este capítulo se va a describir los distintos
VRP que se van a desarrollar en el proyecto y se van a solucionar con el programa.
Figura 2.1 Ejemplo de VRP
Dentro de los problemas de VRP hay dos grandes grupos. El primero de ellos conocidos como TSP (The
travelling Salesman Problem) que cómo característica general tiene que es uno y solo uno el transporte en
realizar todas las entregas. El segundo grupo es el de vehículos múltiple y se utiliza una flota para hacer las
entregas, como se observa en la Figura 2.1, un ejemplo de VRP.
En el TSP la flota de vehículos no existe, es decir que solo es un comerciante viajando entre las ciudades dadas
mientras en el VRP la flota es una de las variables más importantes ya que casi todas las variables con respecto
a este problema vienen desde el VRP
2.1 TSP
2.1.1 Presentación TSP
El TSP es el más básico de estos problemas, su nombre es un acrónimo de Travelling Salesman Problem, o en
español el problema del viajante de comercio y resuelve un problema muy simple, el de la ruta más corta para
pasar por unas series de ciudades dadas y que se conoce la distancia que hay entre ellas. Este problema en
concreto es uno de los más famosos y estudiados dentro de la optimización combinatoria.
2.1.2 Historia
La primera referencia a este problema se encuentra en 1832 en un libro publicado en Alemania y Suiza en una
guía de viajes para vendedores por la zona cuyo título es Der Handlungsreisende—wie er sein soll und was er
zu thun hat, um Auftrag ̈e zu erhalten und eines gluc ̈klichen Erfolgs in seinen Geschaften ̈gewiss zu sein.
(Figura 2.2) En el libro se detalla una ruta optimizada por el interior de Alemania.
22
Todo hace indicar que su introducción a la matemática fue realizada en los años treinta del siglo XX y todo
apunta al profesor universitario de Princeton Hassler Whitney cómo el primero en referirse al problema como
TSP. En 1954 Dantzing, Ray Fulkerson y Selmer Johnson resolvieron un problema de rutas con 49 ciudades,
obteniendo la ruta óptima. En los años 60s el problema se hizo famoso por una campaña publicitaria de
‘Procter&Gamble’ (Figura 2.3) en el que animaban a encontrar la ruta óptima por 33 ciudades de una famosa
serie de televisión norteamericana y con una recompensa de 10.000$.
En 1972 los programadores de IBM M. Held y R.M. Karp prueban que el problema era del tipo NP, e introducen
el uso de heurísticas basadas en programación dinámica para resolver un problema de 64 nodos.
Figura 2.2 Portada del libro Der
Handlungsreisende
Figura 2.3 Cartel de la campaña publicitaria de
‘Procter&Gamble’
23
En 1994 se publica el problema Concorde por Applegate, Bixby, Chvátal, y Cook que se ha utilizado para
solucionar el problema en los últimos años. Se puede observar en la Figura 2.4 la evolución histórica que ha
seguido el TSP, con el año, los autores y cuantas ciudades eran capaces de resolver.
2.1.3 Modelo
En este caso la flota de vehículos se reduce a solo uno por lo que no intervienen en los datos.
2.1.3.1 Datos
Los clientes a servir
La demanda de los clientes a servir
Las distintas distancias entre cliente-almacén y cliente-cliente
2.1.3.2 Restricciones
La ruta debe comenzar y terminar en el almacén.
La ruta debe pasar por todas las ciudades
El objetico a minimizar es el coste de la ruta, en este caso la distancia recorrida ya que es la única y recorrido
por el único vehículo.
El modelo quedaría de la siguiente forma
Min ∑ ∑ 𝑐𝑖𝑗 𝑥𝑖𝑗
∑ ∑ 𝑥𝑖𝑗 ≥ 1
𝑗∈𝑄𝐼∈𝑄
24
2.2 Otras variantes del TSP
La meta del TSP es encontrar una ruta que llegue a cada nodo y que sea óptima, es decir que tenga el menor
coste posible.
Hay diferentes versiones de este problema que se enumeran a continuación:
GTSP (Generalized Travelling Salesman Problem): esta variante del TSP introduce una
variable que son los clusters o grupos de ciudades y en esta ocasión él viajante debe visitar solo
una de las ciudades dentro del cluster, dejando sin visitar el resto de ciudades integrantes en el
cluster, es decir el viajante solo visita una ciudad por cluster.
PTSP (Probabilistic Travelling Salesman Problem): esta variante se da cuando el problema no
tiene una localización de los clientes dada, sino que esa localización depende de una función
con una variable aleatoria.
TSPPD (Travelling Salesman Problem with Pick-up and Delivery) en esta ocasión la variante
nueva del problema es que en todos los nodos del viajante del problema puede recoger
mercancía o entregarla.
DTSP (Dubins Travelling Salesman Problem): en este problema se introduce unas restricciones
con respecto a las trayectorias de curvatura del viajante.
TSPMD (Travelling Salesman Problem with Moving Destinations): en esta ocasión el
problema entra en la variable de la ventana de tiempo donde el vendedor debe visitar al cliente
en unas determinadas horas a las que el cliente está disponible.
25
2.3 VRP Clásico
2.3.1. Presentación del VRP
Este problema definido a mediados del siglo XX es otro de los problemas estrella de la investigación operativa,
el problema consiste en diseñar el conjunto óptimo de rutas para servir a una serie de clientes dados,
minimizando el coste total de las rutas.
2.3.2. Historia
En 1959 Dantig y Ramser en un artículo científico titulado The Truck Dispatching Problem hacen referencia
por primera vez al VRP clásico, en él proponían una solución basada en la programación lineal. En el articuló
se trata este problema como la generalización de un problema ya tratado cómo el TSP, con la multiplicidad de
vehículos asociada a él. En el mismo se define el problema cómo Clover Leaf Problem.
2.3.3. Modelo
En el VRP clásico, que también se conoce cómo MTSP, es decir Multiple Traveling Salesmen Problem, se
estaría en el siguiente escenario:
2.3.1.1 Datos
Vehículos a disposición
Los clientes a servir
La demanda de los clientes a servir
Las distintas distancias entre cliente-almacén y cliente-cliente
2.3.1.2 Restricciones
Cada cliente ha de ser servido por un único vehículo.
Todas las rutas deben comenzar y terminar en el almacén.
Definidos estos términos el VRP Clásico es idéntico al TSP con la única salvedad que en el VRP tiene diferentes
y múltiples viajeros mientras el TSP solo tiene uno.
El objetivo a minimizar es el coste de las rutas, aunque en este proyecto se ampliara a otros objetivos a minimizar
cómo el kilometraje o el tiempo empleado en cubrir las rutas.
El modelo quedaría de la siguiente forma:
Min ∑ ∑ 𝑐𝑖𝑗 𝑥𝑖𝑗
Sujeto a:
∑ 𝑥𝑖𝑗 = 𝑏𝑗
𝑛
𝑖=1
26
∑ 𝑥𝑖𝑗 =
𝑛
𝑗=1
𝑎𝑖
∑ ∑ 𝑥𝑖𝑗 ≥ 1
𝑗∈𝑄𝐼∈𝑄
𝑥𝑖𝑗 = 0,1 𝑖, 𝑗 = 1, …n
27
2.4 VRP+Limitación de capacidad(CVRP)
2.4.1 Presentación VRP+Limitación de capacidad(CVRP)
Este problema introduce la variable de la capacidad en los camiones de la flota por lo que un camión tiene
limitado el peso que puede llevar, otra variable que introduce este problema la demandada de cada cliente o el
peso de cada paquete.
2.4.2 Historia
El problema CVRP también fue introducido conjuntamente con el anterior problema ya que fue la primera
restricción que pusieron los autores Dantiz y Ramser, así que este problema y el VRP sin restricciones están
relacionados desde un principio.
2.4.3 Modelo
Es la primera de las variantes atribuidas al VRP, donde una flota fija de transportes de entrega sirve a un número
conocido de clientes, solo que esta vez la flota de transporte tiene un límite de peso que puede llevar.
2.4.1.1 Datos
Vehículos a disposición
Los clientes a servir
La demanda de los clientes a servir
Las distintas distancias entre cliente-almacén y cliente-cliente
Capacidad de los vehículos
2.4.1.2 Restricciones
Cada cliente ha de ser servido por un único vehículo
Todas las rutas deben comenzar y terminar en el almacén
Los vehículos no pueden transportar por encima de su capacidad
Como en el VRP clásico el objetivo principal es el de minimizar costes, y así es como se va a plantear el modelo.
El modelo quedaría de la siguiente forma:
Min ∑ ∑ 𝑐𝑖𝑗 𝑥𝑖𝑗
Sujeto a:
∑ 𝑥𝑖𝑗 = 𝑏𝑗
𝑛
𝑖=1
28
∑ 𝑥𝑖𝑗 =
𝑛
𝑗=1
𝑎𝑖
∑ ∑ 𝑥𝑖𝑗 ≥ 1
𝑗∈𝑄𝐼∈𝑄
∑ 𝑑𝑖
𝑚
𝑖=1
≤ 𝑄
𝑥𝑖𝑗 = 0,1 𝑖, 𝑗 = 1, …n
29
2.5 Otras variantes del VRP
Además de las variantes del VRP clásicas, ofrece una serie de múltiples problemas que añaden diferentes
variables y restricciones.
TDVRP (Time dependant Vehicle Routing Problem): En este problema las rutas que sigue los vehículos
no se guían por la distancia entre ciudades sino por el tiempo que se tarda entre ellas, por lo que la
función a minimizar de este problema es distinta a la del VRP clásico ya que hay que minimizar el
tiempo empleado en cubrir la ruta ya que el coste estará directamente relacionado.
VRPPD (Vehicle Routing Problem Pick-up and Delivery): Este problema es similar al de TSP, en el
cual los clientes dados pueden entregar o recoger mercancía y a su vez deberá respetar la capacidad de
la flota.
MDVRP (Mutiple Depot Vehicle Routing Problem): La variable que introduce este problema es la de
la multiplicad de almacenes cada uno con una flota de vehículos independiente y con la necesidad de
servir a todos los clientes.
SVRP (Stochastic Vehicle Routing Problem): En este problema la variación que se introduce es la
aleatoriedad del tiempo, demanda o clientes.
PVRP (Periodic Vehicle Routing Problem): Este problema considera un horizonte temporal de M días,
se desarrolló en un principio para su utilización en la recogida de residuos unos ciertos días de la semana
determinados. A partir de esta aplicación se le encontraron muchas más utilidades como la visita a
proveedores, distribución a clientes periódicos, distribución de productos perecederos.
DVRP (Dynamic Routing Problem): Esta variante del problema se creó para satisfacer la variabilidad
que existe en la vida real con respecto a los pedidos. En este problema el flujo de información es
constante para poder actualizarla en el sistema y la asignación de vehículos se hace en tiempo real.
VRPTW (Vehicle Routing Problem with Time-Windows): El problema introduce como variable con
respecto a los anteriores la ventana de tiempos, es decir que solo se puede entregar a un cliente en un
determinado intervalo de tiempos dados.
Dentro de este problema existen dos subproblemas, el primero de ellos con una ventana de tiempo dura,
en la que el cliente solo puede ser atendido dentro del intervalo de tiempo mientras en la otra variable
del problema en la ventana de tiempo blanda, se le puede atender al cliente fuera de la misma, pero con
una penalización.
FSMVRP (Fleet Size and Mix Vehicle Routing Problem): La variante de este problema es que la flota
es heterogénea, es decir que los diferentes vehículos tienen distintas capacidades, costes, velocidades.
Por lo que la estructura de costes cambia con respecto a cada uno de los vehículos.
GVRP (Generalized Vehicle Routing Problem): Esta variante es similar a la del TSP, es decir introduce
clusters o grupos que contienen varios clientes y de ellos solos se debe visitar a uno, dejando los demás
sin atender.
30
31
3 METODOLOGÍA PROPUESTA
La ciencia puede divertirnos y fascinarnos, pero es la
ingeniería la que cambia el mundo
- Isaac Asimov-
32
33
En este capítulo se desarrollarán las distintas formas, o heurística, que el programa utiliza para resolver el
problema en cuestión que el usuario le plantea. Se va a dar una extensa explicación de cada uno de estos métodos
que se proponen, con una descripción de los mismos e incluso un ejemplo ilustrativo de cada uno de ellos. Los
métodos propuestos son los siguiente
Algoritmo de ahorros
Búsqueda local y estrategias de vecindad
Búsqueda tabú
Según la RAE en una de sus acepciones define heurística como ‘en algunas ciencias, manera de buscar la
solución de un problema mediante métodos no rigurosos, como por tanteo, reglas empíricas, etc.’. Estos métodos
son una búsqueda simple en un espacio limitado por las diferentes restricciones que realiza una exploración en
ese mismo espacio mejorando una solución inicial.
3.1 Algoritmo de ahorros
3.1.1 Presentación del algoritmo de ahorros
El primer paso para empezar a resolver el problema es el de generar una solución inicial. En este caso se va a
producir mediante el algoritmo de ahorros de ‘Clarke and Wright’, que es uno de los algoritmos más difundidos
para el VRP, conjuntamente con el del ‘vecino más cercano’.
Para definir este algoritmo primero se va a definir una serie de variables del mismo:
(0, …, i, …,0): ruta generada con 0 como el almacén, satisfaciendo al cliente i y volviendo al
almacén.
(0, …, i, j, …,0): ruta generada con 0 como almacén satisfaciendo al cliente i, al cliente j, y
volviendo al almacén.
Si, j es el ahorro que se obtiene al incluir (i, j) en una sola ruta.
di,0 es la distancia desde el cliente i al almacén
dj,0 es la distancia desde el cliente j al almacén
di, j es la distancia desde el cliente i al cliente j
El algoritmo se inicializa creando una ruta para cada ciudad en la que se parte del almacén, sirve al cliente y
vuelve almacén. Tras la creación de estas rutas se van combinando dependiendo del ahorro de las mismas,
siempre mirando que se respeten las restricciones del sistema.
Para calcular el ahorro se utiliza la siguiente formula:
𝑠𝑖,𝑗 = 𝑐𝑖,0 + 𝑐𝑗,0 − 𝑐𝑖,𝑗
Figura 3.1 Ejemplo gráfico de funcionamiento del algoritmo de ahorros
3.1.2 Algoritmo de ahorros (version paralela)
En esta primera versión del algoritmo las rutas se trabajan todas a la vez, es decir se inicializan tantas rutas como
nodos haya y se van reduciendo conforme el algoritmo avanza. Un ejemplo claro se observa en la Figura 3.1 en
la que el algoritmo inicializa con una ruta hacia cada nodo desde el almacén y en su siguiente paso el algoritmo
34
transforma las dos rutas iniciales en una sola ruta, pasando por los dos nodos. Además este algoritmo también
tiene que cumplir con las restricciones a la hora de ir reduciendo el número de rutas.
Pasos que sigue el algoritmo:
Paso 1 (inicialización): Para cada cliente i construir la ruta (0, i, 0)
Paso 2 (cálculo de ahorros): Calculo de ahorro para cada par de clientes si,j. Con estos datos obtenidos en los
dos primeros pasos, se construye la matriz de ahorros, que es una matriz de dimensión (i,j) y que sus elementos
son los ahorros calculados en este paso.
Paso 3 (mejor unión): Sea si*j*=max sij donde el máximo se escoge entre los ahorros que aún no han sido
considerados . Sea ri* y rj* la ruta que contiene a los clientes i* y j* respectivamente. Si i* es el último de ri* y j*
es el primer cliente de rj, y la combinación de ri* y rj* es factible, combinarlas. Eliminar si*j* de futuras
consideraciones. Si queda algún ahorro por examinar repetir paso 3.
3.1.3 Algoritmo de ahorros (version secuencial)
En esta versión del algoritmo de ahorros las rutas se van tratando de una en una, la ruta termina cuando se topa
con alguna de las restricciones del problema para el nodo con ahorro máximo, a partir el algoritmo desarrolla
una nueva ruta, prosiguiendo así hasta terminar el problema y dar una solución válida.
Pasos que sigue el algoritmo:
Paso 1 (inicialización): Para cada cliente i construir la ruta (0, i, 0)
Paso 2 (cálculo de ahorros): Calculo de ahorro para cada par de clientes si,j. Ídem a su versión paralela se
construye una matriz de ahorros con los datos calculados en este paso.
Paso 3 (selección): Si todas las rutas fueron consideradas, terminar. Si no, seleccionar una ruta que aún no haya
sido considerada.
Paso 4 (extensión): Sea (0, i, . . . , j, 0) la ruta actual. Si no existe ningún ahorro conteniendo a i o a j, ir a 3. Sea
sk*i el máximo ahorro conteniendo a i (o a j). Si k ∗ (o l ∗) es el último (o primer) cliente de su ruta y la
combinación de dicha ruta con la actual es factible, realizar dicha combinación. Eliminar sk*i de futuras
consideraciones. Repetir paso 4.
Además de estas dos versiones algunos autores han propuesto una mejora en la fórmula del cálculo del ahorro
debido a que a veces que se obtienen rutas circulares que no son deseables.
Esto se soluciona con la adición del parámetro λ, llamado parámetro de la forma cuya función es penalizar la
unión entre clientes lejanos. El parámetro puede usarse también para crear un nuevo conjunto de soluciones
cuando se ejecuta varias veces el algoritmo y le da diferentes valores a λ en cada iteración. Quedando la ecuación
de la siguiente forma
𝑠𝑖,𝑗 = 𝑑𝑖,0 + 𝑑𝑗,0 − λ𝑑𝑖,𝑗
3.1.4 Ejemplo de utilización
Se va a dar un ejemplo de utilización del algoritmo de ahorro en su versión secuencial que es la que utiliza el
programa.
El primer paso es construir la matriz de ahorros con respecto a la matriz de distancias de las ciudades entre sí
con la siguiente ecuación:
𝑠𝑖,𝑗 = 𝑑𝑖,0 + 𝑑𝑗,0 − 𝑑𝑖,𝑗
Se toma como ejemplo la siguiente matriz de ahorros:
35
Ciudades 1 2 3 4 5 6 7 8
1 0 10 12 8 9 4 21 15
2 10 0 7 13 9 17 11 14
3 12 7 0 15 22 19 12 8
4 8 13 15 0 6 24 14 10
5 9 9 22 6 0 15 11 20
6 4 17 19 24 15 0 7 17
7 21 11 12 14 11 7 0 12
8 15 14 8 10 20 17 12 0
Tabla 3.1Ejemplo algoritmo de ahorros
Como se observa en la Tabla 3.1 y es lo gico la matriz de ahorros, o en este caso de distancias, es sime trica siendo todos los elementos de la diagonal 0 debido a que las distancias de una ciudad a sí misma es 0.
A esta matriz se debe de an adir tambie n una columna y una fila que represente el almace n, como se le an ade a la Tabla 3.2, representado por la ciudad ‘0’.
Ciudades 1 2 3 4 5 6 7 8 0
1 0 10 12 8 9 4 21 15 0
2 10 0 7 13 9 17 11 14 0
3 12 7 0 15 22 19 12 8 0
4 8 13 15 0 6 24 14 10 0
5 9 9 22 6 0 15 11 20 0
6 4 17 19 24 15 0 7 17 0
7 21 11 12 14 11 7 0 12 0
8 15 14 8 10 20 17 12 0 0
0 0 0 0 0 0 0 0 0 0
Tabla 3.2 Ejemplo algoritmo de ahorros
El siguiente paso es inspeccionar la matriz en busca del elemento más alto de la matriz, lo que quiere decir que
se busca el ahorro más alto.
36
Ciudades 1 2 3 4 5 6 7 8 0
1 0 10 12 8 9 4 21 15 0
2 10 0 7 13 9 17 11 14 0
3 12 7 0 15 22 19 12 8 0
4 8 13 15 0 6 24 14 10 0
5 9 9 22 6 0 15 11 20 0
6 4 17 19 24 15 0 7 17 0
7 21 11 12 14 11 7 0 12 0
8 15 14 8 10 20 17 12 0 0
0 0 0 0 0 0 0 0 0 0
Tabla 3.3 Ejemplo algoritmo de ahorros
Se identifica el mayor ahorro, que se tiene en el traslado de la ciudad 6 a la 4 o al revés de la 4 a la 6 como se
observa en la Tabla 3.3, señalado el ahorro máximo en la tabla.
Se analiza la ruta que se ha escogido y si cumple las restricciones, si no las cumpliese se iría el algoritmo al
siguiente ahorro más alto.
Ruta: 0-6-4
Carga: 7+4=11
Capacidad disponible: 20
Para evitar que el algoritmo vuelva a escoger la primera de las ciudades de las dos que se escogen se debe
penalizar sustituyendo su valor en la matriz de ahorros por un valor nulo (Tabla 3.4).
Ciudades 1 2 3 4 5 6 7 8 0
1 0 10 12 8 9 0 21 15 0
2 10 0 7 13 9 0 11 14 0
3 12 7 0 15 22 0 12 8 0
4 8 13 15 0 6 0 14 10 0
5 9 9 22 6 0 0 11 20 0
6 0 0 0 0 0 0 0 0 0
7 21 11 12 14 11 0 0 12 0
8 15 14 8 10 20 0 12 0 0
0 0 0 0 0 0 0 0 0 0
Tabla 3.4 Ejemplo algoritmo de ahorros
37
El siguiente paso es seleccionar la fila de la última ciudad de las dos que se ha escogido (Tabla 3.5).
Ciudades 1 2 3 4 5 6 7 8 0
4 8 13 15 0 6 0 14 10 0
Tabla 3.5 Ejemplo algoritmo de ahorros
Se puede observar en la Tabla 3.5 que el mayor de los ahorros esta vez es que la ruta pase por la ciudad 3, por
lo que se analiza para comprobar que se cumplen las restricciones.
Ruta: 0-6-4-3
Carga: 7+4+3= 14
Capacidad disponible:20
Como cumple las restricciones también se penaliza la penúltima ciudad escogida como se hizo con anterioridad
(Tabla 3.6).
Ciudades 1 2 3 4 5 6 7 8 0
1 0 10 12 0 9 0 21 15 0
2 10 0 7 0 9 0 11 14 0
3 12 7 0 0 22 0 12 8 0
4 0 0 0 0 0 0 0 0 0
5 9 9 22 0 0 0 11 20 0
6 0 0 0 0 0 0 0 0 0
7 21 11 12 0 11 0 0 12 0
8 15 14 8 0 20 0 12 0 0
0 0 0 0 0 0 0 0 0 0
Tabla 3.6 Ejemplo algoritmo de ahorros
Como el algoritmo ha hecho anteriormente, ahora se escoge la fila de la última ciudad escogida, reflejada en la
Tabla 3.7:
Ciudades 1 2 3 4 5 6 7 8 0
3 12 7 0 0 22 0 12 8 0
Tabla 3.7 Ejemplo algoritmo de ahorros
En este caso el mayor ahorro se tiene en la ciudad 5, como anteriormente se comprueba si cumple las
restricciones:
Ruta: 0-6-4-3-5
38
Carga:7+4+3+5=19
Capacidad disponible= 20
Como sigue dentro de las restricciones repite el proceso:
Ciudades 1 2 3 4 5 6 7 8 0
5 9 9 0 0 0 0 11 20 0
Tabla 3.8 Ejemplo algoritmo de ahorros
En este caso el algoritmo escogería la ciudad 8 ya que se puede observar que tiene el ahorro máximo (Tabla 3.8)
pero se saldría de la restricción de la capacidad, así que iría al siguiente con ahorro más alto, hasta que se termina
por comprobar que no hay ninguno, por lo que se cierra la ruta poniendo el almacén al final de las misma.
Ruta: 0-6-4-3-5-0
Carga: 19
Capacidad disponible= 20
Ahora se volvería al principio y se repetiría el proceso por lo que se escoge la matriz de ahorros, por supuesto
con las actualizaciones que se han ido haciendo.
Ciudades 1 2 3 4 5 6 7 8 0
1 0 10 0 0 0 0 21 15 0
2 10 0 0 0 0 0 11 14 0
3 0 0 0 0 0 0 0 0 0
4 0 0 0 0 0 0 0 0 0
5 0 0 0 0 0 0 0 0 0
6 0 0 0 0 0 0 0 0 0
7 21 11 0 0 0 0 0 12 0
8 15 14 0 0 0 0 12 0 0
0 0 0 0 0 0 0 0 0 0
Tabla 3.9 Ejemplo algoritmo de ahorros
Como en un principio se identifica el ahorro más alto de la matriz por lo que se observa que es el que va desde
la ciudad 7 a la 1 (Tabla 3.9).
Ruta 2: 0-1-7
Carga:5+6=11
Capacidad=20
Como se ha visto anteriormente se anula la fila y columna de la primera de las dos ciudades escogidas, y se coge
la fila de la segunda de ellas (Tabla 3.10).
39
Ciudades 1 2 3 4 5 6 7 8 0
7 0 11 0 0 0 0 0 12 0
Tabla 3.10 Ejemplo algoritmo de ahorros
Se escoge la ciudad número 8 y se comprueba que cumple las restricciones por lo que se escoge la fila
correspondiente a esta ciudad (Tabla 3.11).
Ciudades 1 2 3 4 5 6 7 8 0
8 0 14 0 0 0 0 0 0 0
Tabla 3.11 Ejemplo algoritmo de ahorros
Como se puede observar la única ciudad que queda es la ciudad 2 por lo que ya se tienen las rutas hechas.
Ruta 1: 0-6-4-3-5-0
Ruta 2:0-1-7-8-2-0
40
3.2 Búsqueda local y estrategias de vecindad
3.2.1 Presentación de búsqueda local y estrategias de vecindad
Las soluciones que se encuentran con los algoritmos de construcción de soluciones tienen una calidad media, es
decir que es posible optimizarlas sin mucho esfuerzo dentro de unos algoritmos no muy complejos como los de
búsqueda local, o los que se van a utilizar en este proyecto, que son las estrategias de vecindad de intercambio
y de inserción.
Para afrontar estos algoritmos de búsqueda local el proyecto se guiará por el estudio que hicieron M. Junger, G.
Reinelt y G. Rinaldi para el TSP, aunque con unas pequeñas variantes se van a adaptar al problema VRP que se
trata en este proyecto.
Los procesos de búsqueda local también llamados de mejora son procesos que exploran en un entorno
relativamente cercano una solución que se establece en un mínimo local.
Se define vecindad, como el conjunto de soluciones que se puede encontrar desde una solución inicial con un
movimiento determinado, en este caso estos movimientos serán de intercambio y de inserción.
𝑁(𝑠) = {𝑠′𝜖 𝑆: 𝑠 →𝜎 𝑠′}
N(s) representa el conjunto de soluciones obtenido con búsqueda local con respecto a s
s Representa una solución dentro del espacio S de un problema determinado
s’ Representa la solución generada desde la solución s dentro del espacio S a partir del movimiento 𝜎
𝜎 Es el movimiento específico que se configura para optimizar una solución.
Este mínimo local no se puede mejorar mediante los movimientos que se ha propuestos, también llamado por
los autores ‘greedy’. Este mínimo local como es claro no es la solución global del problema, es más, muchas
veces puede darse una solución que aun siendo mejor que la dada por el algoritmo de construcción de soluciones,
puede no tener toda la calidad que se busca en la solución al verse atascada en el primer mínimo local que
encuentra el algoritmo. Se puede observar en la Figura 3.2 una gráfica los diferentes tipos de óptimos que pueden
existir en el problema tratado y como a veces un óptimo local puede llegar a parecer el óptimo global del
problema.
Figura 3.2 Gráfica óptimo local y global
41
3.2.2 Tipos de movimiento
3.2.2.1 Intercambio
El intercambio dentro de una solución s es el cambio directo de posiciones entre dos o más elementos para dar
una solución mejorada s’. En la figura 3.3 se observa que con un simple intercambio en una ruta se puede mejorar
sustancialmente la misma.
Ruta s: 0-i-j-k-0
Ruta s’:0-i-k-j-0
3.2.2.2 Inserción
La inserción es el segundo movimiento que se encontrará en el algoritmo de búsqueda y se caracteriza por
desplazar un elemento o ciudad de la ruta a una posición determinada, aunque eso implique el desplazar al resto
de elementos de la ruta. En la Figura 3.4 se puede observar una simple inserción que mejoraría la ruta.
Ruta s: 0-i-j-k-0-l-m-0
Ruta s’: 0-i-j-k-l-0-m-0
Figura 3.3 Gráfico representativo de intercambio
Figura 3.4 Gráfico representativo de inserción
42
3.2.3 Ejemplo de utilización de búsqueda local
Para seguir con el ejemplo que se ha utilizado anteriormente en el que la ruta 1 era 0-6-4-3-5-0 y la ruta 2 era
0-1-7-8-2-0. Para este algoritmo se va a juntar las dos rutas como si solo la recorriese un único vehículo, es decir
que la ruta quedaría de la forma representada en la Figura 3.5
Figura 3.5 Ejemplo de utilización de búsqueda local
El primer método que se va a utilizar es el intercambio, para ello el programa evalúa cada cambio que se pueda
hacer en las rutas, por supuesto, siempre comprobando las restricciones y descartando los intercambios que no
cumplan las restricciones, en este caso el programa no intercambia las ciudades con los almacenes ni los
almacenes con las ciudades, en el ejemplo el almacén representado por el número 0 y las ciudades por el numero
1 al 8.
Ahora se representa los intercambios posibles del primer elemento no almacén es decir del 6.
Figura 3.6 Ejemplo de utilización de búsqueda local
Así el programa evalúa que cada uno de los intercambios cumpla las restricciones (Figura 3.6) y obtiene el
cambio que menor valor de la función objetivo consigue. En el caso del ejemplo el coste de la ruta es de 1225,4
y con el cambio 5-6 se pasaría a un coste de 1212,6.
Entonces la nueva ruta quedaría representada en la Figura 3.7.
Figura 3.7 Ejemplo de utilización de búsqueda local
El programa seguiría intercambiando elementos hasta que todos los cambios posibles por intercambio que
pudiera hacer solo empeorarían la función global, o hasta que se encontrase con un criterio de aspiración que el
usuario dé al programa o que el programa tenga por defecto asignado, para no eternizar así la búsqueda. Si este
criterio de aspiración no está bien calibrado, el problema puede quedarse una solución de calidad baja o por el
contrario si se le asigna un criterio de aspiración muy alto el programa puede prolongarse demasiado sin
conseguir mejorar el resultado ya encontrado, por lo que tener un criterio de aspiración acorde al problema
tratado es fundamental para el correcto funcionamiento del programa.
Este movimiento ayuda a encontrar grandes mejores en la ruta como ejemplo la Figura 3.8 optimizada por un
algoritmo de búsqueda local simple.
43
Figura 3.8 Gráfico de ejemplo de intercambio en búsqueda local
El otro proceso que utiliza el programa es la inserción, como se ha explicado teóricamente la inserción es el
desplazamiento de un elemento a una posición fijada pudiendo desplazar los demás elementos de posición. A
continuación, se expone el ejemplo.
Se tiene la misma ruta que en el ejemplo anterior, representada en la Figura 3.9.
Figura 3.9 Ejemplo de utilización de búsqueda local
En este el intercambio no se produce entre ciudades, sino que el cambio es de una ciudad con una posición es
decir que la ciudad pasa a ocupar una posición fijada evaluada por el programa como la mejor que podría ocupar,
así en esta ocasión el programa podría incluso variar las ciudades de cada ruta de vehículos, en el ejemplo las
dos rutas tienen 4 clientes cada una y con este algoritmo esto podría cambiar, con el movimiento de intercambio
esto no sería posible.
En este ejemplo el programa evalúa la ruta y da como la mejor posibilidad de inserción que la ciudad o cliente
6 pasa a ocupar la posición del cliente o ciudad 8 es decir el problema pasaría a quedar de la siguiente forma,
señalando los cambios de posición que se han dado Figura 3.10.
Con este cambio la ruta pasa de tener un coste de 1212,6 a tener un coste 1192,3, como se puede observar en el
ejemplo el cliente 6 no es el único que cambia de posición, sino que arrastra a todos los elementos que hay entre
él y la posición que ha sido evaluada como la mejor opción quedando de la forma representada en la Figura 3.11.
Figura 3.10 Ejemplo de utilización de búsqueda local
44
Figura 3.11 Ejemplo de utilización de búsqueda local
También en la Figura 3.11 se pude observar como ya ha sido comentado anteriormente que podría ocurrir, que
ha variado el número de clientes a los que llega cada ruta. Mientras la primera de las rutas antes de pasar por el
algoritmo (Figura 3.9) llegaba a 4 clientes antes de pasar por el almacén, tras la inserción realizada en la ruta
global, el primer tramo de la ruta ve afectado su número de clientes, llegando en esta ocasión a 3, uno menos
que su antecesora. En el otro lado, el segundo tramo de la ruta, que también ve afectado el número de clientes a
los que llega aumenta en una unidad, pasando de 4 a 5 clientes abastecidos por el mismo.
45
3.3 Búsqueda tabú
3.3.1 Presentación búsqueda tabú
La búsqueda tabú fue introducida por Fred W. Glover profesor en la universidad de Colorado de ciencias
computacionales y matemáticas aplicadas, entre otros logros se le atribuye el acuñamiento del termino
metaheurística. La primera referencia del profesor Glover a la búsqueda tabú fue en 1986 aunque no fue
formalizada hasta 1989.
El termino tabú o taboo en inglés procede de la Polinesia, y era utilizado por los aborígenes para referirse a las
cosas que no pueden ser utilizadas porque son sagradas, en la actualidad la RAE lo define de la siguiente forma:
‘Prohibición de tocar, mencionar o hacer algo por motivos religiosos, supersticiosos o sociales’.
La búsqueda tabú es un proceso iterativo de intercambio de elementos desde una solución inicial hasta una
solución mejorada, este proceso se repite hasta que el algoritmo se topa con un criterio de parada, como un cierto
número de iteraciones.
A diferencia de los algoritmos de ahorro y de búsqueda local, la búsqueda tabú es capaz de salir de un mínimo
local y alcanzar una solución mejor si el criterio de parada está preparado para ello. Esto es un gran avance en
la búsqueda del mínimo global, debido que hasta ahora los métodos utilizados no tenían la posibilidad de salir
de un mínimo local, que como se observó al principio del capítulo de la búsqueda tabú era más probable incidir
en ellos que en el mínimo global del problema.
Para esto el proceso iterativo debe ser capaz de empeorar la función objetivo para escalar hasta encontrar otra
tendencia bajista diferente al camino por el que ha venido, se puede observar un ejemplo gráfico en la Figura
3.13.
3.3.2 Utilidades de la busqueda tabú
Las utilidades de la búsqueda tabú son muy diversas, está relacionada con varios campos que se detallaran a
continuación. El primero de ellos es el campo de la planificación donde la búsqueda tabú se utiliza por ejemplo
para la secuenciación y procesado, planificación de mano de obra, tiempo de flujo en células de trabajo de
procesado, planificación de procesos heterogéneos, planificación de máquinas, planificación de clases.
En otro campo que es interesante aplicar la búsqueda tabú es el del diseño, en distintos apartados como diseño
de ordenadores de apoyo, diseño de redes de transporte, planificación del espacio arquitectónico, diagrama de
coherencia, diseño de redes de carga fija, problemas de corte irregular.
También tiene su utilidad en el campo de la localización y distribución, entre las que destacan los siguientes.
Localización de productos, tareas cuadráticas, tareas generalizadas multinivel, diseño de planificación,
exploración marítima de petróleo.
En la inteligencia y lógica artificial también se ve aplicada este algoritmo, por ejemplo, en lógica probabilística,
agrupación, reconocimiento de patrones, integración de datos, redes neuronales.
En la tecnología también se puede ver aplicada el algoritmo, en la inversión sísmica, distribución de la potencia
Figura 3.11 Gráfica diferencia entre mínimo global y local
46
eléctrica, diseño de ingeniería estructural, construcción de estación espacial.
3.3.3 Uso de memoria
En la búsqueda tabú la memoria se divide en cuatro dimensiones, que son la calidad, la frecuencia, importancia
y la capacidad de ser reciente (Figura 3.14). La frecuencia en la memoria tabú es la cantidad de veces que se
repite una solución como la mejor para el intercambio. La dimensión de capacidad de ser reciente es la cantidad
de movimientos que transcurre desde que un movimiento es seleccionado por el programa hasta que vuelve a
ser seleccionado. La dimensión calidad se refiere básicamente a la capacidad de un movimiento de optimizar
una ruta. La calidad es una opción muy interesante en el uso de memoria ya que constituye un aprendizaje basado
en incentivos, es decir el programa incentiva la búsqueda de soluciones que mayor optimización dan.
Figura 3.12 Ejemplo ilustrativo de búsqueda tabú
En la búsqueda tabú, el uso de memoria se divide en memoria implícita y explicita. En la memoria explicita se
almacenan soluciones enteras y su función es la de expandir los límites de búsqueda, mientras en la otra parte
de la memoria, la implícita, la memoria almacena atributos y su función es restringir movimientos.
3.3.4 Intensificación y diversificación
Dos componentes altamente importantes en la búsqueda tabú son la intensificación y la diversificación. La
intensificación es la capacidad que tiene el programa de modificar las reglas de búsqueda para que el mismo
programa tenga la capacidad de encontrar soluciones de mayor calidad.
La diversificación es la capacidad que tiene el programa de salirse, como se ha visto antes, de un mínimo local
y dirigir la búsqueda en otra dirección para encontrar el mínimo global del problema.
3.3.5 Criterio de aspiración
El criterio de aspiración es otro de los elementos que hace que la búsqueda tabú encuentre unas soluciones de
tan alta calidad. Aunque los criterios de aspiración que se suelen encontrar son muy básicos ya que se ciñen a la
periodicidad de los movimientos que realiza el programa, estos criterios de aspiración pueden afectar a las cuatro
dimensiones de la memoria y ser bastantes complejos.
Entre estos criterios de aspiración hay dos tipos diferenciados, de movimiento y de atributos. Cuando se satisface
un criterio de aspiración de movimiento se borra la memoria explicita del programa, es decir la memoria o lista
tabú que se refiere a movimientos y en el caso contrario cuando se colma el criterio de aspiración de atributo la
memoria borrada es la memoria implícita o lista tabú que se refiere a atributos.
Memoria
Calidad
Ser Reciente
Frecuencia
Influencia
47
Criterios de aspiración ilustrativos según Fred M. Glover:
Aspiración por defecto: Si todos los movimientos están ya clasificados como tabú entonces se escoge el
movimiento “menos tabú”.
Aspiración por objetivos: En este caso el autor hace una distinción entre objetivos regionales y globales, y a su
vez a los objetivos regionales los subdivide en dirección de búsqueda e influencia.
3.3.6 Ejemplo ilustrativo de la búsqueda tabú
Se recoge el ejemplo del mismo ensayo del autor. En este caso se va a empezar una ruta para un problema de
TSP en el que la solución inicial que tiene el problema es la representada en la Figura 3.15.
Figura 3.13 Ejemplo ilustrativo de búsqueda tabú
Para definir todo el problema se necesita un entorno con los intercambios posibles del problema (Tabla 3.12).
Figura 3.14 Ejemplo ilustrativo de búsqueda tabú
En el cuadro de intercambios se puede ver todos los intercambios de dicho problema con un atributo principal
definido como valor del movimiento y que va a ir directamente relacionado con la función objetivo del problema,
que se definirá como F. En el problema inicial el valor de F es de 39 unidades. Se va a proceder a una serie de
iteraciones que ilustrará la búsqueda tabú y su funcionamiento.
El problema crea una estructura de datos en forma de escalera inversa, que es lo que se ha definido como lista
tabú (Figura 3.16) durante la teoría y es la que va a restringir los distintos movimientos que se hagan a lo largo
del problema.
48
Figura 3.15 Ejemplo ilustrativo de búsqueda tabú
Antes de empezar el problema hay que explicar que las restricciones tabúes no son inviolables, es más el profesor
Glover en su ensayo explica que si un movimiento aun estando restringido por la lista tabú y es capaz de
optimizar la función hasta un punto mínimo que no había sido alcanzado anteriormente, esa restricción se debe
saltar.
A continuación se muestran las distintas iteraciones que se hacen en el problema (Figura 3.17).
Figura 3.16 Ejemplo ilustrativo de búsqueda tabú
En este momento el problema está en su fase inicial y por tanto la estructura tabú está totalmente vacía es decir
llena de ceros, por lo que no hay restringido ningún movimiento. Según la tabla de los mejores movimientos se
observa que el movimiento 5-6 resta 7 unidades a la función objetico mientras el siguiente movimiento es el 2-
4 solo resta 2 unidades a la función objetivo, por lo que se escoge el primer movimiento, el problema después
de la primera iteración queda reflejado en la Figura 3.18.
49
Figura 3.17 Ejemplo ilustrativo de búsqueda tabú
El nuevo valor de la función objetivo F es de 32 unidades y hay una restricción en la estructura tabú por un
periodo de 3 iteraciones, es decir que el movimiento 5-6 no se puede volver a hacer hasta dentro de 3 iteraciones.
También se puede comprobar en la Figura 3.18 que la ruta antigua que era 1-2-3-4-5-6 se ha modificado por la
ruta 1-2-3-4-6-5 por lo que se ha hecho efectivo el cambio hecho en la última iteración.
Con respecto a la iteración 2 se observa que en la lista de los candidatos no ésta el valor restringido anteriormente,
así que no hay que preocuparse por la lista tabú y se escoge el primero de los candidatos, el movimiento 2-4 que
resta 2 unidades más a la función objetivo.
Figura 3.18 Ejemplo ilustrativo de búsqueda tabú
Tras la segunda iteración se comprueba que en la lista tabú de la Figura 3.19 que al movimiento 5-6 ya solo le
quedan dos iteraciones para estar disponible. Como nuevo valor de la función objetivo del problema tiene 30
unidades y en la siguiente iteración se le puede restar dos unidades más según la lista de candidatos, donde
aparece un movimiento restringido en la lista como es el 2-4.
50
Figura 3.19 Ejemplo ilustrativo de búsqueda tabú
Tras esta última iteración la función objetivo toma el valor de 28 unidades (Figura 3.20). En esta ocasión para
la siguiente iteración ocurren dos particularidades, la primera es que, entre los candidatos al próximo
movimiento, el primero de la lista es un movimiento restringido en particular el 4-1 y como no da el mínimo
hasta ahora de la función objetivo, es más le suma dos unidades al mismo, el problema no se salta las
restricciones y pasa al siguiente movimiento, es decir el 1-3 que al igual que el 4-1 también le suma dos unidades
a la función objetivo. La segunda de estas particularidades es la de que es la primera iteración en la que la función
objetivo va a verse incrementada por lo que el algoritmo se encuentra en un mínimo local, y a partir de esta
iteración y hasta que no se dé con un máximo local la función objetivo ira incrementando, para luego si llega el
caso bajar y poder alcanzar un valor de la función objetivo más bajo que el alcanzado en el mínimo local de la
Figura 3.20.
51
4 EXPLICACIÓN DEL PROGRAMA
Un hombre con una idea nueva es un loco hasta que la
idea triunfa.
- Mark Twain-
52
53
En este capítulo se explica el manejo para la correcta utilización del programa. En un primer subcapítulo se
expone la manera de introducir datos a través de un documento Excel para que el programa los reconozca
correctamente. La introducción de datos a través de un documento Excel facilita el manejo del programa por
parte del usuario, ya que es un programa de extendido manejo entre los usuarios. El documento Excel a su vez
tiene tres hojas, cada una para una serie de datos determinado. En la primera de ellas se introducen los datos
referidos a vehículos, en la segunda de ellas se introducen datos relacionados con los pedidos y en la tercera los
datos de las localizaciones de los pedidos mencionados.
Tras la explicación de la correcta introducción de datos, también se da instrucciones para arrancar el programa
en Matlab y ejecutarlo, además se explica el manejo del programa y la función de cada botón.
4.1 Introducción de datos
4.1.1 Vehículos
Para la introducción de datos el programa facilita la operación con un Excel que es una plataforma sencilla y
mayoritariamente conocida por el usuario. Matlab da facilidades al usuario con una serie de órdenes para leer y
escribir datos en una hoja Excel.
En la primera hoja del Excel se tiene el formato presentado en la Figura 4.1.
Figura 4.1 Excel Vehículos
En la primera hoja, se introduce básicamente la información de los transportes y de la flota.
Los datos a introducir son los siguientes:
Número de vehículos: Es el número de vehículos que forman la flota, dependiendo del número
de vehículos el problema variará entre el TSP básico y el m-TSP o el VRP.
Capacidad: Este problema al ser CVRP, la capacidad es la restricción más significativa y es el
peso que puede transportar cada camión.
Costes fijos: Es el coste que tiene contratar cada uno de los camiones, si el camión no hace ruta
este coste no se computa, mientras si el camión en cuanto sale del almacén se carga este gasto.
Coste variable: Es el coste que tiene cada camión por cada kilómetro recorrido, este coste refleja
la gasolina, el sueldo del camionero, peajes o mantenimiento del camión.
Se observa que la flota de vehículos es homogénea, es decir que todos los vehículos tienen las mismas
características.
54
4.1.2 Información de pedidos
En la segunda hoja del documento Excel se tiene la información de los pedidos. El ejemplo de la misma lo se
puede observar en la Figura 4.2.
Figura 4.2 Excel Pedidos
Los datos a introducir en esta hoja:
Numero de pedido: Sirve para seguir un orden en los pedidos y tenerlos numerados
Ciudad: Como se verá en la siguiente hoja las ciudades están numeradas, y en esta columna
hay que introducir el número de referencia de la ciudad donde se sitúa el cliente.
Peso: Es lo que pesa cada paquete o la cantidad demanda del cliente.
Figura 4.3 Central Ciudad
Central nº de la ciudad: Es el número de referencia de la ciudad donde se sitúa el almacén, la
referencia se encuentra en la tercera hoja del documento Excel, el ejemplo se puede observar
en la Figura 4.3.
4.1.3 Información de las ciudades
Esta última hoja es la más compleja de todas, ya que requiere hacer una matriz con todas las distancias entre los
distintos nodos del problema. En el ejemplo de la Figura 4.4 los nodos son ciudades, debido a que este ejemplo
se ha tomado como referencias las mismas, pero se podría modificar el documento Excel para el caso que todos
los envíos sean dentro de la misma ciudad, aunque habría que concretar con exactitud las coordenadas en el
mapa.
55
Figura 4.4 Excel Localizaciones
Los datos que se introducen son los siguientes:
Numero ciudad: Es la referencia de la ciudad para tenerlas numeradas y es la referencia que
luego se introducirán en la hoja 2.
Provincia: Es la provincia de la ciudad que se está introduciendo, esta columna no es un
requisito mínimo.
Nombre ciudad: Es el nombre de la ciudad que se está introduciendo y luego se mostrará en el
programa, Matlab no reconoce los acentos ni las ñ.
Latitud y longitud: Son las coordenadas de las ciudades que se introducen.
La hoja Excel para evitar mayores complicaciones calcula mediante una formula la distancia entre las ciudades
con las coordenadas con la siguiente ecuación.
𝐷𝑖𝑠𝑡𝑎𝑛𝑐𝑖𝑎 = 6371 ∗ cos−1( cos(𝑙𝑎𝑡1) ∗ cos(𝑙𝑎𝑡2) ∗ cos(𝑙𝑜𝑛𝑔2 − 𝑙𝑜𝑛𝑔1) + sin(𝑙𝑎𝑡1) ∗ sin(𝑙𝑎𝑡2)
56
4.2 Programa
4.2.1 Ejecución del programa
La plataforma del programa es Matlab 2012, por lo que es necesario tener instalado esta versión o posterior en
el ordenador que se desee ejecutar el programa. El programa está desarrollado en Guide que es una división de
Matlab la que permite desarrollar una interfaz gráfica desde una pantalla de programación. También existe la
posibilidad de crear un ejecutable para que el usuario del programa acceda directamente desde él.
En el presente capítulo se explica cómo se ejecute el programa para que no haya problemas a la hora de abrirlo.
Paso 1. Añadir el Excel llamado Datos.xlsx a la carpeta MATLAB o donde este el Workspace del MATLAB
Paso 2. Ejecutar el programa dentro del subprograma GUIDE dentro de Matlab. (Figura 4.5)
Aquí se puede ver una ‘maqueta’ del programa donde poder cambiarlo y añadir distintos botones.
Paso 3. Ejecutar el programa pulsando la orden RUN.
4.2.2 Pantalla del programa principal
Cuando se ejecuta el programa se tiene la interfaz en blanco entera como se muestra a continuación en la Figura
4.6, en ella se observa varias secciones claras, como la serie de botones en la columna izquierda o la gráfica del
problema, los mismos se detallarán a continuación.
Figura 4.6 Instrucciones Matlab
Figura 4.5 Instrucciones Matlab
57
Para poner el programa en funcionamiento el usuario debe presionar uno de los 4 botones que están situados en
la columna de la izquierda, estos botones tienen como función principal que el usuario escoja la heurística para
resolver el problema. Aun así, el programa permite volver a rehacer el problema si se vuelve a presionar otro
botón. En la Figura 4.7 se ve un problema ya resuelto por el problema, diferenciando por colores las distintas
rutas de los vehículos.
Figura 4.7 Instrucciones Matlab
El programa contiene los siguientes elementos:
4 botones para seleccionar las heurísticas que se quiere aplicar al problema, Clarke and Wright,
estrategias de vecindad, lista tabú y heurística hibrida.
Aviso situado en la esquina inferior izquierda que te indica cuando ha terminado el programa
de resolver el problema. Este aviso se puso debido a la dificultad de algunos equipos de resolver
el problema rápidamente.
Cuadro de texto en el que aparece escrito iteraciones y donde se debe poner el número de
iteraciones que deseas hacer en el problema.
Botón para cambiar las iteraciones, después de cambiar el cuadro de texto se debe pulsar este
botón para hacer efectivo el cambio.
Resultado. El coste total que costarían las rutas trazadas con los costes fijados en la tabla de
datos.
Grafico. La parte más importante de la interfaz gráfica donde aparecen las rutas descritas, tiene
señalado cada ciudad de cada ruta con su nombre escrito dentro del gráfico y una leyenda con
los vehículos.
58
59
5 RESULTADOS
A veces cuando no tienes tiempo, tienes que tomarlo
prestado.
- Steve Jobs-
60
61
En este capítulo se presenta los distintos resultados que se obtienen en el programa, y una comparación entre los
mismos. Para los resultados se ha experimentado con el programa con problemas aleatorios de 10, 25, 50 y 100
ciudades. El número de ciudades ha sido escogido tras observar cambios significativos en los resultados del
problema y así poder analizarlos para este capítulo.
5.1 10 Ciudades
Para empezar el apartado de resultados se propone al programa que resuelva un problema con hasta 10 clientes
y con 2 vehículos. Este problema inicial es un problema fácil de resolver y con tiempo de resolución bajo
Para ver cómo se comportan las heurísticas también se va a cambiar el valor de las iteraciones y así poder
observar cuantas iteraciones le cuesta llegar al mínimo final que obtiene el algoritmo. Se puede ver que en este
problema al ser de fácil resolución se va a llegar muy rápido a un mínimo claro, pero se puede comprobar más
adelante la dificultad para llegar a él.
Figura 5.1 Resultado 10 ciudades
Se observa en la Figura 5.1 que el algoritmo de costes tiene una solución mayor que las demás heurísticas, y es
un algoritmo que no depende de las iteraciones por lo que siempre se va a mantener constante en el tiempo. Las
demás heurísticas mejoran casi un 10% la resolución del algoritmo de costes, siendo la solución del algoritmo
de Clarke and Wright de 887,6637 mientras en las demás heurísticas de 807,153.
También se puede observar en la misma Figura que la heurística de la búsqueda tabú tarda hasta 25 iteraciones
en ajustarse al mínimo alcanzado. El problema resuelto quedaría de la siguiente forma (Figura 5.2).
Figura 5.2 Gráfica programa 10 ciudades
2.500
2.600
2.700
2.800
2.900
1 10 25 50
10 ciudades
Clarke and Wright Vecindad Lista tabu Hibrida
62
5.2 25 Ciudades
Este problema empieza a ser más complejo, el programa maneja 5 vehículos y 25 clientes con lo que las
combinaciones empiezan a ser muy elevadas. Las soluciones del problema están representadas en la figura 5.3.
Figura 5.3 Resultado 25 ciudades
En la Figura 5.3 se observa que el algoritmo de Clarke and Wrigth se queda lejos del mínimo alcanzo por otros
algoritmos, aunque esta vez las demás heurísticas solo han podido mejorar la solución del algoritmo de costes
un 7,6%. El gráfico no es muy claro en las demás heurísticas por lo que se va a eliminar el algoritmo de ahorros
de la siguiente gráfica (Figura 5.4) y así observar con facilidad el comportamiento del resto de heurísticas.
Figura 5.4 Resultado 25 ciudades (II)
Se observa que por las estrategias de vecindad se encuentra un mínimo local enseguida con valor de 1356.1898
y como se explica en la teoría esta heurística no tiene la capacidad de salir de ese mínimo local por lo que no
puede encontrar el mínimo global.
2.500
2.550
2.600
2.650
2.700
2.750
2.800
2.850
1 10 25 50 100
25 ciudades
Clarke and Wright Vecindad Lista tabu Hibrida
1320
1330
1340
1350
1360
1370
1380
1390
1 2 5 10 20
25 ciudades
Vecindad Lista tabu Hibrida
63
Por otro lado, aparece la búsqueda tabú que tras la primera iteración se sitúa en un nivel de 1378,0798, es decir
un 1,6% peor que la solución propuesta por las estrategias de vecindad. Este valor se irá reduciendo hasta que
en la quinta iteración iguala a las estrategias de vecindad. A partir de esa quinta iteración la búsqueda tabú
buscara salir de ese mínimo local, y en la décima iteración ya se encuentra en bajada hasta 1346.0802, ahí
encuentra otro mínimo local y la iteración numero 20 encuentra el valor mínimo encontrado del problema que
es de 1343.9647 por lo que mejora en un 1% el resultado de las estrategias de vecindad.
La tercera heurística, es decir la hibrida que aúna las estrategias de vecindad y la búsqueda tabú tiene una
búsqueda del mínimo mucho más eficiente ya que en la décima iteración ya se ha situado en el valor mínimo
encontrado por la búsqueda tabú.
Para que se tenga una idea de la complejidad que empieza a tomar el problema se deja el gráfico de la Figura
5.6 de rutas propuesto como solución por el programa.
Figura 5.5 Gráfica programa 25 ciudades
64
5.3 50 Ciudades
Como se ha visto en el ejemplo de las 25 ciudades la complejidad del problema se ha hecho bastante notable, en
este ejemplo se sube un escalón más y se sitúa ya ante un problema de complejidad alta, el programa tarda más
en responder y en hacer las operaciones.
Para resolver este problema de 50 ciudades solo se ha añadido un vehículo más por lo que debería haber 6 rutas
en total y así poder observar el gráfico de ruta nítidamente.
Figura 5.6 Resultados 50 ciudades
Se observa en la Figura 5.6 que el algoritmo de ahorro cómo en los dos casos anteriores se descuelga por encima,
aunque se puede observar que cada vez está más cerca, debido a que esta vez su valor es de 2122,5494 y se
queda a un 6,7% del mínimo alcanzado por el problema. Cómo en el caso anterior se elimina el algoritmo de
ahorros del siguiente gráfico para que se pueda ver nítidamente el comportamiento de las otras heurísticas y se
presenta en la Figura 5.7.
Figura 5.7 Resultados 50 ciudades (II)
Se observa que el mínimo que toma las estrategias de vecindad es de 2011,6342 un 5,5% mejor que el algoritmo
2.500
2.550
2.600
2.650
2.700
2.750
2.800
2.850
1 10 25 50 100
50 ciudades
Clarke and Wright Vecindad Lista tabu Hibrida
2500
2550
2600
2650
2700
2750
2800
1 10 25 50 100
Vecindad Lista tabu Hibrida
65
de ahorro. La búsqueda tabú empieza con un 2,8% peor que las estrategias de vecindad, aunque iguala a esta
heurística en la décima iteración, cada vez tarda más en igualarla debido a que cada vez entran más posibilidades
dentro del problema. En la iteración 25 ya se sitúa un 0,83% mejor que la estrategia de vecindad. La búsqueda
tabú sigue mejorando la solución hasta que en la iteración 50 ya ha alcanzado su mínimo de 1987,4915, es decir
mejorando un 4% a través de sus iteraciones.
La heurística hibrida cómo se ve empieza en el mínimo alcanzado por el algoritmo de la vecindad, y aunque en
la iteración 10 ya alcanza el 1994,8957 hasta la iteración 25 no cambia, es decir que se iguala con la búsqueda
tabú simple y a partir de esta iteración sigue su misma evolución.
Figura 5.8 Gráfica programa 50 ciudades
Cómo se puede ver el gráfico de la Figura 5.8 ya presenta una complejidad alta y se puede ver la complejidad
de todas las rutas y los nodos que se eligen.
66
5.4 100 Ciudades
Por último, se va a ver un problema con 100 ciudades o nodos, este problema tendrá una flota de 12 vehículos
con una capacidad de 400 unidades cada uno, en este problema se podrá ver una gran complejidad en las rutas
y al programa le costará encontrar una solución, y cada iteración que se le añada le costará más al programa y
tardará algo más. Se presentan los resultados del problema en la Figura 5.9.
Figura 5.9 Resultados 100 ciudades
En esta ocasión el algoritmo de ahorros empeora con respecto a los anteriores ejemplos y el mínimo hallado por
el problema difiere un 7,6% de la solución del algoritmo de ahorros que según parece ser que se va a mover
entre el 5-10%.
Cómo se hace en los anteriores ejemplos se quita de la gráfica este algoritmo para ver nítidamente el
comportamiento de las otras heurísticas (Figura 5.10).
Figura 5.10 Resultado 100 ciudades (II)
2.500
2.550
2.600
2.650
2.700
2.750
2.800
2.850
1 10 25 50 100
100 ciudades
Clarke and Wright Vecindad Lista tabu Hibrida
2500
2550
2600
2650
2700
2750
2800
1 10 25 50 100
Vecindad Lista tabu Hibrida
67
Cómo en los anteriores ejemplos la búsqueda tabú simple le cuesta unas ciertas iteraciones alcanzar el mínimo
obtenido por las estrategias de vecindad, se puede observar que cada vez le cuesta más iteraciones a la misma
debido a la complejidad del problema, en esta ocasión son 25 iteraciones para alcanzar este mínimo.
En este ejemplo, escogido aleatoriamente sucede una particularidad que no había sucedido antes, y es que la
estrategia de vecindad se sitúa en el mínimo obtenido por el problema, es decir el mínimo local que localiza las
estrategias de vecindad o es el mínimo global y por tanto el mínimo teórico del problema o es un mínimo local
del que nuestra búsqueda tabú no es capaz de salir. Para que pudiese salir necesitaría aumentar la profundidad
de la lista tabú para así diversificar más la búsqueda.
Cómo se hizo en los anteriores ejemplos se muestra en la Figura 5.11 las rutas que da el programa.
Figura 5.11 Gráfica programa 100 ciudades
Se observa que en esta ocasión las rutas son más complejas y que según parece las distribuye por zonas.
68
69
6 CONCLUSIONES
El éxito es un pésimo profesor. Seduce a la gente
inteligente y la lleva a pensar que no puede perder.
- Bill Gates-
70
71
A la vista de los resultados que se han obtenido, es fácil mediante un programa no muy complejo calcular unas
rutas optimizadas que pueden ahorrar una considerable cantidad a una empresa con una flota de vehículos para
repartir sus propios productos.
Con el programa desarrollado por este proyecto se ha optimizado una ruta de hasta 100 nodos, optimizando casi
el 8% un algoritmo de inicialización cómo el algoritmo de Clarke and Wright. Con el desarrollo de las nuevas
tecnologías hace que estos programas de optimización sean fáciles de usar incluso en tiempo real, como sucede
en algunos problemas.
En este proyecto se utilizan coordenadas de las ciudades, pero con los avances de los GPS y las bases de datos,
se puede concretar las rutas hasta un nivel muy alto. Se puede incluso incluir variables cómo tráfico, posibles
cortes de carretera o la máxima velocidad permitida en las carreteras.
Este tipo de programas son de gran interés para las Pymes que tienen unos grandes gastos en logística comparado
con las grandes empresas, que tienen implementado este tipo de programas desde hace tiempo, y que han visto
cómo sus gastos logísticos se han reducido drásticamente con mejoras como esta.
El programa del proyecto permite a una persona sin conocimiento alguno en programación o en MATLAB
acceder al programa y observar de forma visual las rutas elegidas por el programa.
También se puede comprobar las distintas mejoras que hace el programa con las diferentes heurísticas.
Se observa que el programa mejora entre un 5% y un 10% la solución hallado por el algoritmo de
Clarke and Wright.
Las estrategias de vecindad se quedan entre un 1% y un 3% de distancia de la solución hallada por el
programa, aunque en último ejemplo se da la particularidad que la estrategia de vecindad da con la
solución hallada por el algoritmo de la lista tabú.
La búsqueda tabú simple va aumentando su efectividad con respecto a los algoritmos anteriores en el
mismo orden que aumenta la complejidad del problema y las iteraciones que necesita el programa
para alcanzar una solución estable.
72
73
7 BIBLIOGRAFÍA
Experiencia es el nombre que le damos a nuestras
equivocaciones.
-Oscar Wilde-
74
75
[1] Applegate, Bixby, Chvatal y Cook (2006): The travelling Salesman Problem: A computational Study.
Princeston, USA: Princeston Series in Applied Mathematics.
[2] Bellman, R. (1957): Dynamic Programming. Princeton University Press, Princeton, New Jersey, USA.
[3] Beltrami, E. J., y Bodin, L. D. (1974): “Networks and vehicle routing for municipal waste collection”.
Networks, volumen 4, pp. 65–94.
[4] Dantzig y Ramser (1959): “The truck dispatching problem”. Management Science Vol. 6, No. 1 pp. 80-91.
[5] Dantzig, Fulkerson, Johnson (1954) Solution of a large-scale travelling salesman problem. Santa Monica.
California, USA: The Rand Corporation.
[6] Davendra, Donald (2010): Travelling and Salesman Problem, Theory and Applications. Rijeka, Croatia:
InTech.
[7] Diaz, Ghaziri, Glover, Gonzáles, Laguna, Moscato, Tsegn (1996) Optimización Heurística y Redes
Neuronales. Madrid, España: Editorial Paraninfo.
[8] Flood, M.M. (1956). “The traveling-salesman problem”. Operations Research Vol. 4, pp. 61-75.
[9] Garcia de Jalón, Jose Ignacio y Vidal, Jesús (2005) Aprenda Matlab 7.0 cómo si estuviera en primero.
Madrid: Escuela Técnica Superior de Ingenieros Industriales. Universidad Politécnica de Madrid.
[10] Glover, Fred y Laguna, Manuel (1999) Tabu Search. Handbook of Combinatorial Optimization, Volume 3
pp. 621-757
[11] Glover, Fred y Rangaswamy (1998) “Tabu Search Candidate List Strategies in Scheduling” por Kluwer
Academic Publishers. Interfaces in Computer Science and Operation Research pp. 215-233.
[12] Taillard, Eric y Glover, Fred (1993) “A User’s Guide to Tabu Search” Annals of Operations Research Vol.
41 pp. 12-37.
[13] Potters, Curiel, I.J., Tijs, S.H. (1992). “Traveling salesman games”. Mathematical Programming Vol. 53,
pp 199-211.
76
77
8 ANEXOS
Los hombres construimos demasiados muros y no
suficientes puentes.
- Isaac Newton-
78
79
8.1 Código del problema
8.1.1 Recolección de datos de excel
En este apartado el programa saca los datos de una hoja Excel que el usuario utiliza para introducir los datos
concretos del problema que desea resolver. La función principal que se utiliza en este apartado es xlsread, su
utilidad es la de extraer datos desde una hoja Excel.
function proyectoguide1_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to proyectoguide1 (see VARARGIN)
global PED1 PEDTEXT1 VEH1 VEHTEXT1 CIUDNUM1 CIU1 COORD1 COORDTXT1 DIST1 DISTTXT1
MAXCOSTETOTAL CENTRAL1 NUMPED1 NUMVEH1 PRIM COSTETOTAL PESOTOTAL GRAFICA iteracion
CAPVEH1 COSFIJVEH1 COSVARVEH1
[PED1,PEDTEXT1]=xlsread('Datos.xlsx' , 2 , 'B2:E100');%el vector de los pedidos,
primera columna su ciudad de destino y en la segunda el peso%
[VEH1,VEHTEXT1]=xlsread('Datos.xlsx' , 1 , 'A2:D2');%el vector de los vehiculos,
primera columna su capacidad y en la segunda su consumo%
[CIUDNUM1,CIU1]=xlsread('Datos.xlsx' , 3 , 'C4:C700');%el vector con el nombre de
los ciudades%
[COORD1, COORDTXT1]=xlsread('Datos.xlsx', 3, 'D4:E700'); %el vector con las
coordenadas de todas las ciudades%
[DIST1, DISTTXT1]=xlsread('Datos.xlsx', 3, 'F4:YS667');
MAXCOSTETOTAL=10000000000000;
CENTRAL1=xlsread('Datos.xlsx', 2, 'J2'); %La ciudad central%
NUMPED1=length(PED1);
NUMVEH1=VEH1(1);
CAPVEH1=VEH1(2);
COSFIJVEH1=VEH1(3);
COSVARVEH1=VEH1(4);
PRIM=0;
COSTETOTAL=0;
PESOTOTAL=zeros(1,NUMVEH1);
iteracion=10;
% Choose default command line output for proyectoguide1
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
Al ejecutar el programa se mandan esta serie de órdenes y sirven para que lea el excel de datos, por lo que si se
quiere cambiar los datos del problema y que resulte efectivo se debe cerrar el programa y volver a abrirlo.
80
8.1.2 Algoritmos de ahorros de Clarke and Wright
En este apartado lo primero que hace el programa es situar las ciudades sobre el mapa con la función plot. Tras
esta función se pueden observar dos bucles bien diferenciados, el primero para seleccionar los datos dentro de
la matriz y el segundo para borrar los datos de la misma, y a su vez preparar la matriz para la siguiente selección
de datos. Terminados estos bucles, el algoritmo primero actualiza los datos de las trayectorias que se han
obtenido, como el coste total o el tiempo que se tarda. Tras realizar la actualización de datos, el algoritmo se
dispone a representar gráficamente la solución con distintos colores para cada trayectoria.
function Clarke_Callback(hObject, eventdata, handles)
% hObject handle to Clarke (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global PED1 PEDTEXT1 VEH1 VEHTEXT1 CIUDNUM1 CIU1 COORD1 COORDTXT1 DIST1 DISTTXT1
MAXCOSTETOTAL CENTRAL1 NUMPED1 NUMVEH1 PRIM COSTETOTAL PESOTOTAL GRAFICA CAPVEH1
COSFIJVEH1 COSVARVEH1
COSTETOTAL=0;
rep=0;
for i=1:NUMPED1
plot(COORD1(PED1(i,1),2),COORD1(PED1(i,1),1),'d');
text(COORD1(PED1(i,1),2),COORD1(PED1(i,1),1),CIU1(PED1(i,1)));
if i==1
hold on;
end
end
AHORRO=zeros(NUMPED1+1);
TRAYECTORIANUEVA=zeros(1,NUMPED1+NUMVEH1+1);
TRAYECTORIANUEVA(:)=CENTRAL1;
TRAYECTORIA=zeros(NUMVEH1,NUMPED1);
TRAYECTORIA(:,1)=CENTRAL1;
vehiculo=0;
for i=1:NUMPED1
for m=1:NUMPED1
AHORRO(i,m)=DIST1(CENTRAL1,PED1(i,1))+DIST1(CENTRAL1,PED1(m,1))-
DIST1(PED1(i,1),PED1(m,1));
end
end
for t=1:NUMPED1
AHORRO(t,t)=0;
81
end
i=1;
numvehut=0;
tm=0;
for s=1:NUMVEH1
numvehut= numvehut+1;
vehiculo=vehiculo+1;
CARGA=0;
AHORRO1=AHORRO
PRIM=0;
while PRIM==0
[maxi,filamax]=max(AHORRO1);
[maxi2,colmax]=max(maxi);
x=[filamax(colmax),colmax];
if PED1(x(1),2)+PED1(x(2),2)<=CAPVEH1
PRIM=1;
CARGA=PED1(x(1),1)+PED1(x(2),1)+CARGA;
TRAYECTORIANUEVA(s+i)=PED1(x(1),1);
TRAYECTORIANUEVA(s+i+1)=PED1(x(2),1);
TRAYECTORIA(vehiculo,tm+1)=PED1(x(1),1);
TRAYECTORIA(vehiculo,tm+2)=PED1(x(2),1);
i=i+2;
tm=tm+2;
else
AHORRO1(x(1),x(2))=0;
AHORRO1(x(2),x(1))=0;
end
end
82
AHORRO(x(1),:)=0;
AHORRO(:,x(1))=0;
COSTETOTAL=DIST1(CENTRAL1,PED1(x(1),1))+DIST1(PED1(x(1),1),PED1(x(2),1))+COSTETO
TAL;
PESOTOTAL=PED1(x(1),2)+PED1(x(2),2);
POSICIONACTUAL=x(2);
mean=0;
while mean==0
[ahorr,ahorrmax]=max(AHORRO(POSICIONACTUAL,:));
if ahorr==0
break
end
if PESOTOTAL+PED1(ahorrmax,2)<=CAPVEH1
COSTETOTAL=COSTETOTAL+DIST1(POSICIONACTUAL,PED1(ahorrmax,1));
PESOTOTAL=PESOTOTAL+PED1(ahorrmax,2);
AHORRO(POSICIONACTUAL,:)=0;
AHORRO(:,POSICIONACTUAL)=0;
POSICIONACTUAL=ahorrmax;
TRAYECTORIANUEVA(s+i)=PED1(POSICIONACTUAL,1);
i=i+1;
tm=tm+1;
else
mean=1;
rep=rep+1
AHORRO(POSICIONACTUAL,:)=0;
if tm+1==NUMPED1
X=AHORRO;
[sbx,sby]=find(AHORRO>0);
TRAYECTORIANUEVA(s+i+1)=PED1(sbx,1);
end
AHORRO(:,POSICIONACTUAL)=0;
end
end
PESOTOTAL1(s)=PESOTOTAL;
83
TRAYECTORIA(vehiculo,tm)=CENTRAL1;
if AHORRO==zeros(NUMPED1+1)
break
end
end
X=TRAYECTORIANUEVA;
RECOSTETOTAL=numvehut*COSFIJVEH1;
XM=TRAYECTORIANUEVA;
n=length(XM);
for i=1:n-1
RECOSTETOTAL=RECOSTETOTAL+DIST1(XM(i),XM(i+1))*COSVARVEH1;
end
COSTETOTAL1=COSTETOTAL*COSVARVEH1+numvehut*COSFIJVEH1;
COMINSALI=num2str(RECOSTETOTAL);
set(handles.salida,'String',COMINSALI);
CEN=find(X==CENTRAL1);
for j=2:length(CEN)
clear COORDENADAS;
COORDENADAS(:,1)=COORD1(X(CEN(j-1):CEN(j)),2);
COORDENADAS(:,2)=COORD1(X(CEN(j-1):CEN(j)),1);
COLOR1=rand;
COLOR2=rand;
COLOR3=rand;
hold on;
x(j-1)=plot(COORDENADAS(:,1),COORDENADAS(:,2),'LineWidth',2,'Color',[COLOR1
COLOR2 COLOR3])
84
numero=num2str(j-1);
temp(j-1)=strcat({'Vehiculo '},numero);
end
legend(x,temp);
finstr='Finalizado Clarke and Wright';
set(handles.fin,'String', finstr);
hold off;
8.1.3 Estrategias de vecindad
Lo primero que hace el algoritmo es borrar el anterior gráfico y proceder a situar de nuevo los puntos del
problema en la imagen del programa. El algoritmo obtiene la solución inicial del algoritmo anterior, con esta
solución inicial empieza a hacer intercambios entre los elementos comprobando primero si cumplen todas las
restricciones que da el usuario, tras hacer el intercambio actualiza los datos totales de la trayectoria y vuelve a
repetir el proceso hasta un número determinado de veces que es introducido por el usuario. Tras este paso el
algoritmo procede a realizar la inserción entre ciudades de una forma similar a la que hizo anteriormente con los
intercambios. Al final del algoritmo se vuelve a pintar la solución que se ha obtenido para que el usuario la puede
ver.
function Vecindad_Callback(hObject, eventdata, handles)
% hObject handle to Vecindad (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global PED1 PEDTEXT1 VEH1 VEHTEXT1 CIUDNUM1 CIU1 COORD1 COORDTXT1 DIST1 DISTTXT1
MAXCOSTETOTAL CENTRAL1 NUMPED1 NUMVEH1 PRIM COSTETOTAL PESOTOTAL GRAFICA iteracion
CAPVEH1 COSFIJVEH1 COSVARVEH1
for i=1:NUMPED1
plot(COORD1(PED1(i,1),2),COORD1(PED1(i,1),1),'d');
text(COORD1(PED1(i,1),2),COORD1(PED1(i,1),1),CIU1(PED1(i,1)));
if i==1
hold on;
end
end
AHORRO=zeros(NUMPED1+1);
TRAYECTORIANUEVA=zeros(1,NUMPED1+NUMVEH1+1);
TRAYECTORIANUEVA(:)=CENTRAL1;
TRAYECTORIA=zeros(NUMVEH1,NUMPED1);
TRAYECTORIA(:,1)=CENTRAL1;
vehiculo=0;
85
for i=1:NUMPED1
for m=1:NUMPED1
AHORRO(i,m)=DIST1(CENTRAL1,PED1(i,1))+DIST1(CENTRAL1,PED1(m,1))-
DIST1(PED1(i,1),PED1(m,1));
end
end
for t=1:NUMPED1
AHORRO(t,t)=0;
end
i=1;
numvehut=0;
tm=0;
for s=1:NUMVEH1
numvehut= numvehut+1;
vehiculo=vehiculo+1;
CARGA=0;
AHORRO1=AHORRO;
PRIM=0;
while PRIM==0
[maxi,filamax]=max(AHORRO1);
[maxi2,colmax]=max(maxi);
x=[filamax(colmax),colmax];
if PED1(x(1),2)+PED1(x(2),2)<=CAPVEH1
PRIM=1;
CARGA=PED1(x(1),1)+PED1(x(2),1)+CARGA;
TRAYECTORIANUEVA(s+i)=PED1(x(1),1);
TRAYECTORIANUEVA(s+i+1)=PED1(x(2),1);
TRAYECTORIA(vehiculo,tm+1)=PED1(x(1),1);
TRAYECTORIA(vehiculo,tm+2)=PED1(x(2),1);
i=i+2;
tm=tm+2;
86
else
AHORRO1(x(1),x(2))=0;
AHORRO1(x(2),x(1))=0;
end
end
AHORRO(x(1),:)=0;
AHORRO(:,x(1))=0;
COSTETOTAL=DIST1(CENTRAL1,PED1(x(1),1))+DIST1(PED1(x(1),1),PED1(x(2),1))+COSTETO
TAL;
PESOTOTAL=PED1(x(1),2)+PED1(x(2),2);
POSICIONACTUAL=x(2);
mean=0;
while mean==0
[ahorr,ahorrmax]=max(AHORRO(POSICIONACTUAL,:));
if ahorr==0
break
end
if PESOTOTAL+PED1(ahorrmax,2)<=CAPVEH1
COSTETOTAL=COSTETOTAL+DIST1(POSICIONACTUAL,PED1(ahorrmax,1));
PESOTOTAL=PESOTOTAL+PED1(ahorrmax,2);
AHORRO(POSICIONACTUAL,:)=0;
AHORRO(:,POSICIONACTUAL)=0;
POSICIONACTUAL=ahorrmax;
TRAYECTORIANUEVA(s+i)=PED1(POSICIONACTUAL,1);
i=i+1;
tm=tm+1;
else
mean=1;
AHORRO(POSICIONACTUAL,:)=0;
87
if tm+1==NUMPED1
X=AHORRO;
[sbx,sby]=find(AHORRO>0);
TRAYECTORIANUEVA(s+i+1)=PED1(sbx,1);
end
AHORRO(:,POSICIONACTUAL)=0;
end
end
PESOTOTAL1(s)=PESOTOTAL;
TRAYECTORIA(vehiculo,tm)=CENTRAL1;
if AHORRO==zeros(NUMPED1+1)
break
end
end
COSTETT1=numvehut*COSFIJVEH1;
COSTETT=COSTETT1;
for i=1:NUMPED1+NUMVEH1
COSTETT=COSTETT+DIST1(TRAYECTORIANUEVA(i),TRAYECTORIANUEVA(i+1))*COSVARVEH1;
end
COSTENUEV=COSTETT;
TRAYECTORIANUEVA1=TRAYECTORIANUEVA;
TRAYECTORIANUEVA2=TRAYECTORIANUEVA;
PESOTOTAL3=PESOTOTAL;
intento=0;
while intento<=iteracion
for int=1:NUMPED1+NUMVEH1
if TRAYECTORIANUEVA1(int)~=CENTRAL1
NUM=TRAYECTORIANUEVA1(int);
88
for tra=1:NUMPED1+NUMVEH1+1
PESOTOTAL2=zeros(1,NUMVEH1);
TRAYECTORIANUEVA3=TRAYECTORIANUEVA1;
if int~=tra&&TRAYECTORIANUEVA1(tra)~=CENTRAL1
TRAYECTORIANUEVA3(int)=[];
TRAYECTORIANUEVA3=[TRAYECTORIANUEVA3(1:tra-1) NUM
TRAYECTORIANUEVA3(tra:NUMPED1+NUMVEH1)];
vh=1;
COSTETT2=COSTETT1;
for i=2:NUMPED1+NUMVEH1+1
COSTETT2=COSTETT2+DIST1(TRAYECTORIANUEVA3(i-
1),TRAYECTORIANUEVA3(i))*COSVARVEH1;
if TRAYECTORIANUEVA3(i)==CENTRAL1
vh=vh+1;
else
[indf,indc]=find(PED1(:,1)==TRAYECTORIANUEVA3(i));
PESOTOTAL2(vh)=PESOTOTAL2(vh)+PED1(indf,2);
end
end
if all(PESOTOTAL2<=CAPVEH1)&&COSTETT2<COSTENUEV
COSTENUEV=COSTETT2;
TRAYECTORIANUEVA2=TRAYECTORIANUEVA3;
PESOTOTAL3=PESOTOTAL2;
intento=0;
else
end
end
end
end
end
TRAYECTORIANUEVA1=TRAYECTORIANUEVA2;
intento=intento+1;
89
end
COSTENUEV=COSTETT;
TRAYECTORIANUEVA1=TRAYECTORIANUEVA;
TRAYECTORIANUEVA2=TRAYECTORIANUEVA;
PESOTOTAL3=PESOTOTAL;
intento=0;
while intento<=10
for int=1:NUMPED1+NUMVEH1
if TRAYECTORIANUEVA1(int)~=CENTRAL1
NUM=TRAYECTORIANUEVA1(int);
for tra=1:NUMPED1+NUMVEH1+1
PESOTOTAL2=zeros(1,NUMVEH1);
TRAYECTORIANUEVA3=TRAYECTORIANUEVA1;
if int~=tra&&TRAYECTORIANUEVA1(tra)~=CENTRAL1
CAMBIO=TRAYECTORIANUEVA3(int);
TRAYECTORIANUEVA3(int)=TRAYECTORIANUEVA3(tra);
TRAYECTORIANUEVA3(tra)=CAMBIO;
vh=1;
COSTETT2=COSTETT1;
for i=2:NUMPED1+NUMVEH1+1
COSTETT2=COSTETT2+DIST1(TRAYECTORIANUEVA3(i-
1),TRAYECTORIANUEVA3(i))*COSVARVEH1;
if TRAYECTORIANUEVA3(i)==CENTRAL1
vh=vh+1;
else
[indf,indc]=find(PED1(:,1)==TRAYECTORIANUEVA3(i));
PESOTOTAL2(vh)=PESOTOTAL2(vh)+PED1(indf,2);
end
end
90
if all(PESOTOTAL2<=CAPVEH1)&&COSTETT2<COSTENUEV
COSTENUEV=COSTETT2;
TRAYECTORIANUEVA2=TRAYECTORIANUEVA3;
PESOTOTAL3=PESOTOTAL2;
intento=0;
else
end
end
end
end
end
TRAYECTORIANUEVA1=TRAYECTORIANUEVA2;
intento=intento+1;
end
COMINSALI=num2str(COSTENUEV);
set(handles.salida,'String',COMINSALI);
finstr='Finalizado Vecindad';
set(handles.fin,'String', finstr);
X=TRAYECTORIANUEVA1;
CEN=find(X==CENTRAL1);
for j=2:length(CEN)
clear COORDENADAS;
COORDENADAS(:,1)=COORD1(X(CEN(j-1):CEN(j)),2);
COORDENADAS(:,2)=COORD1(X(CEN(j-1):CEN(j)),1);
COLOR1=rand;
COLOR2=rand;
COLOR3=rand;
hold on;
x(j-1)=plot(COORDENADAS(:,1),COORDENADAS(:,2),'LineWidth',2,'Color',[COLOR1
91
COLOR2 COLOR3])
numero=num2str(j-1);
temp(j-1)=strcat({'Vehiculo '},numero);
end
legend(x,temp);
hold off;
8.1.4 Lista tabú
Este algoritmo como el anterior coge la solución inical del algoritmo de ahorros, y desde esa solución procede a
hacer una lista tabú, primero procede a evaluar todos los cambios posibles y recoge en una matriz los 5 más
efectivos, tras comprobar que todas cumplen las restricciones. Cuando evalua los cambios, y comprueba que no
están en la lista tabú, efectua el más efectivo de ellos. Tras una series de iteraciones dadas por el usuario el
algoritmo dibuja la solución obtenida.
function Tabu_Callback(hObject, eventdata, handles)
% hObject handle to Tabu (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global PED1 PEDTEXT1 VEH1 VEHTEXT1 CIUDNUM1 CIU1 COORD1 COORDTXT1 DIST1 DISTTXT1
MAXCOSTETOTAL CENTRAL1 NUMPED1 NUMVEH1 PRIM COSTETOTAL PESOTOTAL GRAFICA
iteracioCAPVEH1 COSFIJVEH1 COSVARVEH1
for i=1:NUMPED1
plot(COORD1(PED1(i,1),2),COORD1(PED1(i,1),1),'d');
text(COORD1(PED1(i,1),2),COORD1(PED1(i,1),1),CIU1(PED1(i,1)));
if i==1
hold on;
end
end
AHORRO=zeros(NUMPED1+1);
TRAYECTORIANUEVA=zeros(1,NUMPED1+NUMVEH1+1);
TRAYECTORIANUEVA(:)=CENTRAL1;
TRAYECTORIA=zeros(NUMVEH1,NUMPED1);
TRAYECTORIA(:,1)=CENTRAL1;
vehiculo=0;
for i=1:NUMPED1
92
for m=1:NUMPED1
AHORRO(i,m)=DIST1(CENTRAL1,PED1(i,1))+DIST1(CENTRAL1,PED1(m,1))-
DIST1(PED1(i,1),PED1(m,1));
end
end
for t=1:NUMPED1
AHORRO(t,t)=0;
end
i=1;
numvehut=0;
tm=0;
for s=1:NUMVEH1
numvehut= numvehut+1;
vehiculo=vehiculo+1;
CARGA=0;
AHORRO1=AHORRO;
PRIM=0;
while PRIM==0
[maxi,filamax]=max(AHORRO1);
[maxi2,colmax]=max(maxi);
x=[filamax(colmax),colmax];
if PED1(x(1),2)+PED1(x(2),2)<=CAPVEH1
PRIM=1;
CARGA=PED1(x(1),1)+PED1(x(2),1)+CARGA;
TRAYECTORIANUEVA(s+i)=PED1(x(1),1);
TRAYECTORIANUEVA(s+i+1)=PED1(x(2),1);
TRAYECTORIA(vehiculo,tm+1)=PED1(x(1),1);
TRAYECTORIA(vehiculo,tm+2)=PED1(x(2),1);
i=i+2;
tm=tm+2;
else
AHORRO1(x(1),x(2))=0;
93
AHORRO1(x(2),x(1))=0;
end
end
AHORRO(x(1),:)=0;
AHORRO(:,x(1))=0;
COSTETOTAL=DIST1(CENTRAL1,PED1(x(1),1))+DIST1(PED1(x(1),1),PED1(x(2),1))+COSTETO
TAL;
PESOTOTAL=PED1(x(1),2)+PED1(x(2),2);
POSICIONACTUAL=x(2);
mean=0;
while mean==0
[ahorr,ahorrmax]=max(AHORRO(POSICIONACTUAL,:));
if ahorr==0
break
end
if PESOTOTAL+PED1(ahorrmax,2)<=CAPVEH1
COSTETOTAL=COSTETOTAL+DIST1(POSICIONACTUAL,PED1(ahorrmax,1));
PESOTOTAL=PESOTOTAL+PED1(ahorrmax,2);
AHORRO(POSICIONACTUAL,:)=0;
AHORRO(:,POSICIONACTUAL)=0;
POSICIONACTUAL=ahorrmax;
TRAYECTORIANUEVA(s+i)=PED1(POSICIONACTUAL,1);
i=i+1;
tm=tm+1;
else
mean=1;
AHORRO(POSICIONACTUAL,:)=0;
if tm+1==NUMPED1
X=AHORRO
94
[sbx,sby]=find(AHORRO>0);
TRAYECTORIANUEVA(s+i+1)=PED1(sbx,1);
end
AHORRO(:,POSICIONACTUAL)=0;
end
end
PESOTOTAL1(s)=PESOTOTAL;
TRAYECTORIA(vehiculo,tm)=CENTRAL1;
if AHORRO==zeros(NUMPED1+1)
break;
end
end
COSTETT1=numvehut*COSFIJVEH1;
COSTETT=COSTETT1;
for i=1:NUMPED1+NUMVEH1
COSTETT=COSTETT+DIST1(TRAYECTORIANUEVA(i),TRAYECTORIANUEVA(i+1))*COSVARVEH1;
end
COSTENUEV=COSTETT;
TRAYECTORIANUEVA1=TRAYECTORIANUEVA;
TRAYECTORIANUEVA2=TRAYECTORIANUEVA;
PESOTOTAL3=PESOTOTAL;
intento=iteracion+1;
while intento<=iteracion
for int=1:NUMPED1+NUMVEH1
if TRAYECTORIANUEVA1(int)~=CENTRAL1
NUM=TRAYECTORIANUEVA1(int);
for tra=1:NUMPED1+NUMVEH1+1
PESOTOTAL2=zeros(1,NUMVEH1);
95
TRAYECTORIANUEVA3=TRAYECTORIANUEVA1;
if int~=tra&&TRAYECTORIANUEVA1(tra)~=CENTRAL1
TRAYECTORIANUEVA3(int)=[];
TRAYECTORIANUEVA3=[TRAYECTORIANUEVA3(1:tra-1) NUM
TRAYECTORIANUEVA3(tra:NUMPED1+NUMVEH1)];
vh=1;
COSTETT2=COSTETT1;
for i=2:NUMPED1+NUMVEH1+1
COSTETT2=COSTETT2+DIST1(TRAYECTORIANUEVA3(i-
1),TRAYECTORIANUEVA3(i))*COSVARVEH1;
if TRAYECTORIANUEVA3(i)==CENTRAL1
vh=vh+1;
else
[indf,indc]=find(PED1(:,1)==TRAYECTORIANUEVA3(i));
PESOTOTAL2(vh)=PESOTOTAL2(vh)+PED1(indf,2);
end
end
if all(PESOTOTAL2<=CAPVEH1)&&COSTETT2<COSTENUEV
COSTENUEV=COSTETT2;
TRAYECTORIANUEVA2=TRAYECTORIANUEVA3;
PESOTOTAL3=PESOTOTAL2;
intento=0;
else
end
end
end
end
end
TRAYECTORIANUEVA1=TRAYECTORIANUEVA2;
intento=intento+1;
end
96
TRAYECTORIANUEVA2=TRAYECTORIANUEVA1;
intento=11;
while intento<=10
for int=1:NUMPED1+NUMVEH1
if TRAYECTORIANUEVA1(int)~=CENTRAL1
NUM=TRAYECTORIANUEVA1(int);
for tra=1:NUMPED1+NUMVEH1+1
PESOTOTAL2=zeros(1,NUMVEH1);
TRAYECTORIANUEVA3=TRAYECTORIANUEVA1;
if int~=tra&&TRAYECTORIANUEVA1(tra)~=CENTRAL1
CAMBIO=TRAYECTORIANUEVA3(int);
TRAYECTORIANUEVA3(int)=TRAYECTORIANUEVA3(tra);
TRAYECTORIANUEVA3(tra)=CAMBIO;
vh=1;
COSTETT2=COSTETT1;
for i=2:NUMPED1+NUMVEH1+1
COSTETT2=COSTETT2+DIST1(TRAYECTORIANUEVA3(i-
1),TRAYECTORIANUEVA3(i))*COSVARVEH1;
if TRAYECTORIANUEVA3(i)==CENTRAL1
vh=vh+1;
else
[indf,indc]=find(PED1(:,1)==TRAYECTORIANUEVA3(i));
PESOTOTAL2(vh)=PESOTOTAL2(vh)+PED1(indf,2);
end
end
if all(PESOTOTAL2<=CAPVEH1)&&COSTETT2<COSTENUEV
COSTENUEV=COSTETT2;
TRAYECTORIANUEVA2=TRAYECTORIANUEVA3;
PESOTOTAL3=PESOTOTAL2;
intento=0;
else
97
end
end
end
end
end
TRAYECTORIANUEVA1=TRAYECTORIANUEVA2;
intento=intento+1;
end
COSTEMIN=COSTENUEV
TRAYECTORIANUEVA2=TRAYECTORIANUEVA1;
TRAYECTORIANUEVAMIN=TRAYECTORIANUEVA1;
TRAYECTORIANUEVAMINIMA=TRAYECTORIANUEVA1;
intento=0;
MATRIZAHORRO=zeros(1,5);
MATRIZAHORRO(:)=-100000;
MATRIZAHORROTRAYORIGEN=zeros(1,5);
MATRIZAHORROTRAYDESTINO=zeros(1,5);
MATRIZAHORROTRAY=zeros(2,5);
NUMMAT=length(MATRIZAHORROTRAY-1);
LISTATABU=zeros(2,NUMMAT);
COSTESTABU=zeros(1,5);
while intento<=iteracion
MATRIZAHORRO(:)=-100000;
for int=1:NUMPED1+NUMVEH1
if TRAYECTORIANUEVA1(int)~=CENTRAL1
NUM=TRAYECTORIANUEVA1(int);
for tra=1:NUMPED1+NUMVEH1+1
TRAYECTO=[int,tra];
PESOTOTAL2=zeros(1,NUMVEH1);
98
TRAYECTORIANUEVA32q=TRAYECTORIANUEVA1;
if int~=tra&&TRAYECTORIANUEVA1(tra)~=CENTRAL1
CAMBIO=TRAYECTORIANUEVA3(int);
TRAYECTORIANUEVA3(int)=TRAYECTORIANUEVA3(tra);
TRAYECTORIANUEVA3(tra)=CAMBIO;
vh=1;
COSTETT2=COSTETT1;
for i=2:NUMPED1+NUMVEH1+1
COSTETT2=COSTETT2+DIST1(TRAYECTORIANUEVA3(i-
1),TRAYECTORIANUEVA3(i))*COSVARVEH1;
if TRAYECTORIANUEVA3(i)==CENTRAL1
vh=vh+1;
else
[indf,indc]=find(PED1(:,1)==TRAYECTORIANUEVA3(i));
PESOTOTAL2(vh)=PESOTOTAL2(vh)+PED1(indf,2);
end
end
AHORRO=COSTENUEV-COSTETT2;
if
all(PESOTOTAL2<=CAPVEH1)&&(AHORRO>MATRIZAHORRO(1)||AHORRO>MATRIZAHORRO(2)||AHORR
O>MATRIZAHORRO(3)||AHORRO>MATRIZAHORRO(4)||AHORRO>MATRIZAHORRO(5))
for i=1:4
if
AHORRO>MATRIZAHORRO(i)&&AHORRO~=MATRIZAHORRO(1)&&AHORRO~=MATRIZAHORRO(2)&&AHORRO
~=MATRIZAHORRO(3)&&AHORRO~=MATRIZAHORRO(4)&&AHORRO~=MATRIZAHORRO(5)
MATRIZAHORRO(5)=[];
COSTESTABU(5)=[];
MATRIZAHORROTRAYORIGEN(5)=[];
MATRIZAHORROTRAYDESTINO(5)=[];
MATRIZAHORRO=[MATRIZAHORRO(1:i-1) AHORRO MATRIZAHORRO(i:4)];
MATRIZAHORROTRAYORIGEN=[MATRIZAHORROTRAYORIGEN(1,1:i-1) TRAYECTO(1)
MATRIZAHORROTRAYORIGEN(1,i:end)];
MATRIZAHORROTRAYDESTINO=[MATRIZAHORROTRAYDESTINO(1,1:i-1) TRAYECTO(2)
MATRIZAHORROTRAYDESTINO(1,i:end)];
COSTESTABU=[COSTESTABU(1,1:i-1) COSTETT2 COSTESTABU(i:end)];
break;
end
99
end
if
AHORRO<MATRIZAHORRO(4)&&AHORRO~=MATRIZAHORRO(1)&&AHORRO~=MATRIZAHORRO(2)&&AHORRO
~=MATRIZAHORRO(3)&&AHORRO~=MATRIZAHORRO(4)&&AHORRO~=MATRIZAHORRO(5)
MATRIZAHORRO(5)=[];
MATRIZAHORROTRAYORIGEN(5)=[];
MATRIZAHORROTRAYDESTINO(5)=[];
COSTESTABU(5)=[];
MATRIZAHORRO=[MATRIZAHORRO AHORRO];
MATRIZAHORROTRAYORIGEN=[MATRIZAHORROTRAYORIGEN TRAYECTO(1)];
MATRIZAHORROTRAYDESTINO=[MATRIZAHORROTRAYDESTINO TRAYECTO(2)];
COSTESTABU=[COSTESTABU COSTETT2];
end
TRAYECTORIANUEVA2=TRAYECTORIANUEVA3;
PESOTOTAL3=PESOTOTAL2;
else
end
end
end
end
end
MATRIZAHORRO
MATRIZAHORROTRAY(1,:)=MATRIZAHORROTRAYORIGEN;
MATRIZAHORROTRAY(2,:)=MATRIZAHORROTRAYDESTINO;
CAMP=0;
SUMA=0;
mp=0;
for mp1=1:length(MATRIZAHORROTRAY)
SUMA=0;
for mt=1:length(LISTATABU)
if
(((MATRIZAHORROTRAY(1,mp1)~=LISTATABU(1,mt))&&(MATRIZAHORROTRAY(1,mp1)~=LISTATAB
U(2,mt)))||((MATRIZAHORROTRAY(2,mp1)~=LISTATABU(1,mt))&&(MATRIZAHORROTRAY(2,mp1)
~=LISTATABU(2,mt))))||(COSTESTABU(mp1)<COSTEMIN)
100
SUMA=SUMA+1;
end
end
if SUMA==length(LISTATABU)
mp=mp1;
break
end
end
if SUMA==length(LISTATABU)
LISTATABU(:,4)=[];
ANADIDO=MATRIZAHORROTRAY(:,mp);
LISTATABU=[ANADIDO LISTATABU];
COSTENUEV=COSTESTABU(mp)
CAMBIOPOS=TRAYECTORIANUEVA1(ANADIDO(1));
TRAYECTORIANUEVA1(ANADIDO(1))=TRAYECTORIANUEVA1(ANADIDO(2));
TRAYECTORIANUEVA1(ANADIDO(2))=CAMBIOPOS;
if COSTESTABU(mp)<COSTEMIN
COSTEMIN=COSTESTABU(mp)
TRAYECTORIANUEVAMINIMA=TRAYECTORIANUEVA1;
end
end
intento=intento+1;
end
COMINSALI=num2str(COSTEMIN);
set(handles.salida,'String',COMINSALI);
X=TRAYECTORIANUEVAMINIMA;
CEN=find(X==CENTRAL1);
for j=2:length(CEN)
clear COORDENADAS;
COORDENADAS(:,1)=COORD1(X(CEN(j-1):CEN(j)),2);
COORDENADAS(:,2)=COORD1(X(CEN(j-1):CEN(j)),1);
101
COLOR1=rand;
COLOR2=rand;
COLOR3=rand;
hold on;
x(j-1)=plot(COORDENADAS(:,1),COORDENADAS(:,2),'LineWidth',2,'Color',[COLOR1
COLOR2 COLOR3])
numero=num2str(j-1);
temp(j-1)=strcat({'Vehiculo '},numero);
end
legend(x,temp);
finstr='Finalizado Lista Tabu';
set(handles.fin,'String', finstr);
hold off;
8.1.5 Heuristica híbrida
Este algoritmo implementa los dos algoritmos encadenados, aplica primero las estrategias de vecindad y tras
ellas la lista tabú.
function hibrida_Callback(hObject, eventdata, handles)
% hObject handle to hibrida (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global PED1 PEDTEXT1 VEH1 VEHTEXT1 CIUDNUM1 CIU1 COORD1 COORDTXT1 DIST1 DISTTXT1
MAXCOSTETOTAL CENTRAL1 NUMPED1 NUMVEH1 PRIM COSTETOTAL PESOTOTAL GRAFICA iteracion
CAPVEH1 COSFIJVEH1 COSVARVEH1
for i=1:NUMPED1
plot(COORD1(PED1(i,1),2),COORD1(PED1(i,1),1),'d');
text(COORD1(PED1(i,1),2),COORD1(PED1(i,1),1),CIU1(PED1(i,1)));
if i==1
hold on;
end
end
AHORRO=zeros(NUMPED1+1);
TRAYECTORIANUEVA=zeros(1,NUMPED1+NUMVEH1+1);
102
TRAYECTORIANUEVA(:)=CENTRAL1;
TRAYECTORIA=zeros(NUMVEH1,NUMPED1);
TRAYECTORIA(:,1)=CENTRAL1;
vehiculo=0;
for i=1:NUMPED1
for m=1:NUMPED1
AHORRO(i,m)=DIST1(CENTRAL1,PED1(i,1))+DIST1(CENTRAL1,PED1(m,1))-
DIST1(PED1(i,1),PED1(m,1));
end
end
for t=1:NUMPED1
AHORRO(t,t)=0;
end
i=1;
numvehut=0;
tm=0;
for s=1:NUMVEH1
numvehut= numvehut+1;
vehiculo=vehiculo+1;
CARGA=0;
AHORRO1=AHORRO;
PRIM=0;
while PRIM==0
[maxi,filamax]=max(AHORRO1);
[maxi2,colmax]=max(maxi);
x=[filamax(colmax),colmax];
if PED1(x(1),2)+PED1(x(2),2)<=CAPVEH1
PRIM=1;
CARGA=PED1(x(1),1)+PED1(x(2),1)+CARGA;
TRAYECTORIANUEVA(s+i)=PED1(x(1),1);
103
TRAYECTORIANUEVA(s+i+1)=PED1(x(2),1);
TRAYECTORIA(vehiculo,tm+1)=PED1(x(1),1);
TRAYECTORIA(vehiculo,tm+2)=PED1(x(2),1);
i=i+2;
tm=tm+2;
else
AHORRO1(x(1),x(2))=0;
AHORRO1(x(2),x(1))=0;
end
end
AHORRO(x(1),:)=0;
AHORRO(:,x(1))=0;
COSTETOTAL=DIST1(CENTRAL1,PED1(x(1),1))+DIST1(PED1(x(1),1),PED1(x(2),1))+COSTETO
TAL;
PESOTOTAL=PED1(x(1),2)+PED1(x(2),2);
POSICIONACTUAL=x(2);
mean=0;
while mean==0
[ahorr,ahorrmax]=max(AHORRO(POSICIONACTUAL,:));
if ahorr==0
break
end
if PESOTOTAL+PED1(ahorrmax,2)<=CAPVEH1
COSTETOTAL=COSTETOTAL+DIST1(POSICIONACTUAL,PED1(ahorrmax,1));
PESOTOTAL=PESOTOTAL+PED1(ahorrmax,2);
AHORRO(POSICIONACTUAL,:)=0;
AHORRO(:,POSICIONACTUAL)=0;
POSICIONACTUAL=ahorrmax;
TRAYECTORIANUEVA(s+i)=PED1(POSICIONACTUAL,1);
104
i=i+1;
tm=tm+1;
else
mean=1;
AHORRO(POSICIONACTUAL,:)=0;
if tm+1==NUMPED1
X=AHORRO;
[sbx,sby]=find(AHORRO>0);
TRAYECTORIANUEVA(s+i+1)=PED1(sbx,1);
end
AHORRO(:,POSICIONACTUAL)=0;
end
end
PESOTOTAL1(s)=PESOTOTAL;
TRAYECTORIA(vehiculo,tm)=CENTRAL1;
if AHORRO==zeros(NUMPED1+1)
break
end
end
COSTETT1=numvehut*COSFIJVEH1;
COSTETT=COSTETT1;
for i=1:NUMPED1+NUMVEH1
COSTETT=COSTETT+DIST1(TRAYECTORIANUEVA(i),TRAYECTORIANUEVA(i+1))*COSVARVEH1;
end
COSTENUEV=COSTETT;
TRAYECTORIANUEVA1=TRAYECTORIANUEVA;
TRAYECTORIANUEVA2=TRAYECTORIANUEVA;
PESOTOTAL3=PESOTOTAL;
intento=0;
105
while intento<=iteracion
for int=1:NUMPED1+NUMVEH1
if TRAYECTORIANUEVA1(int)~=CENTRAL1
NUM=TRAYECTORIANUEVA1(int);
for tra=1:NUMPED1+NUMVEH1+1
PESOTOTAL2=zeros(1,NUMVEH1);
TRAYECTORIANUEVA3=TRAYECTORIANUEVA1;
if int~=tra&&TRAYECTORIANUEVA1(tra)~=CENTRAL1
TRAYECTORIANUEVA3(int)=[];
TRAYECTORIANUEVA3=[TRAYECTORIANUEVA3(1:tra-1) NUM
TRAYECTORIANUEVA3(tra:NUMPED1+NUMVEH1)];
vh=1;
COSTETT2=COSTETT1;
for i=2:NUMPED1+NUMVEH1+1
COSTETT2=COSTETT2+DIST1(TRAYECTORIANUEVA3(i-
1),TRAYECTORIANUEVA3(i))*COSVARVEH1;
if TRAYECTORIANUEVA3(i)==CENTRAL1
vh=vh+1;
else
[indf,indc]=find(PED1(:,1)==TRAYECTORIANUEVA3(i));
PESOTOTAL2(vh)=PESOTOTAL2(vh)+PED1(indf,2);
end
end
if all(PESOTOTAL2<=CAPVEH1)&&COSTETT2<COSTENUEV
COSTENUEV=COSTETT2;
TRAYECTORIANUEVA2=TRAYECTORIANUEVA3;
PESOTOTAL3=PESOTOTAL2;
intento=0;
else
end
end
end
106
end
end
TRAYECTORIANUEVA1=TRAYECTORIANUEVA2;
intento=intento+1;
end
COSTENUEV=COSTETT;
TRAYECTORIANUEVA1=TRAYECTORIANUEVA;
TRAYECTORIANUEVA2=TRAYECTORIANUEVA;
PESOTOTAL3=PESOTOTAL;
intento=0;
while intento<=10
for int=1:NUMPED1+NUMVEH1
if TRAYECTORIANUEVA1(int)~=CENTRAL1
NUM=TRAYECTORIANUEVA1(int);
for tra=1:NUMPED1+NUMVEH1+1
PESOTOTAL2=zeros(1,NUMVEH1);
TRAYECTORIANUEVA3=TRAYECTORIANUEVA1;
if int~=tra&&TRAYECTORIANUEVA1(tra)~=CENTRAL1
CAMBIO=TRAYECTORIANUEVA3(int);
TRAYECTORIANUEVA3(int)=TRAYECTORIANUEVA3(tra);
TRAYECTORIANUEVA3(tra)=CAMBIO;
vh=1;
COSTETT2=COSTETT1;
for i=2:NUMPED1+NUMVEH1+1
COSTETT2=COSTETT2+DIST1(TRAYECTORIANUEVA3(i-
1),TRAYECTORIANUEVA3(i))*COSVARVEH1;
if TRAYECTORIANUEVA3(i)==CENTRAL1
vh=vh+1;
else
[indf,indc]=find(PED1(:,1)==TRAYECTORIANUEVA3(i));
PESOTOTAL2(vh)=PESOTOTAL2(vh)+PED1(indf,2);
107
end
end
if all(PESOTOTAL2<=CAPVEH1)&&COSTETT2<COSTENUEV
COSTENUEV=COSTETT2;
TRAYECTORIANUEVA2=TRAYECTORIANUEVA3;
PESOTOTAL3=PESOTOTAL2;
intento=0;
else
end
end
end
end
end
TRAYECTORIANUEVA1=TRAYECTORIANUEVA2;
intento=intento+1;
end
COSTEMIN=COSTENUEV
TRAYECTORIANUEVA2=TRAYECTORIANUEVA1;
TRAYECTORIANUEVAMIN=TRAYECTORIANUEVA1;
TRAYECTORIANUEVAMINIMA=TRAYECTORIANUEVA1;
intento=0;
MATRIZAHORRO=zeros(1,5);
MATRIZAHORRO(:)=-100000;
MATRIZAHORROTRAYORIGEN=zeros(1,5);
MATRIZAHORROTRAYDESTINO=zeros(1,5);
MATRIZAHORROTRAY=zeros(2,5);
NUMMAT=length(MATRIZAHORROTRAY-1);
LISTATABU=zeros(2,NUMMAT);
108
COSTESTABU=zeros(1,5);
while intento<=iteracion
MATRIZAHORRO(:)=-100000;
for int=1:NUMPED1+NUMVEH1
if TRAYECTORIANUEVA1(int)~=CENTRAL1
NUM=TRAYECTORIANUEVA1(int);
for tra=1:NUMPED1+NUMVEH1+1
TRAYECTO=[int,tra];
PESOTOTAL2=zeros(1,NUMVEH1);
TRAYECTORIANUEVA3=TRAYECTORIANUEVA1;
if int~=tra&&TRAYECTORIANUEVA1(tra)~=CENTRAL1
CAMBIO=TRAYECTORIANUEVA3(int);
TRAYECTORIANUEVA3(int)=TRAYECTORIANUEVA3(tra);
TRAYECTORIANUEVA3(tra)=CAMBIO;
vh=1;
COSTETT2=COSTETT1;
for i=2:NUMPED1+NUMVEH1+1
COSTETT2=COSTETT2+DIST1(TRAYECTORIANUEVA3(i-
1),TRAYECTORIANUEVA3(i))*COSVARVEH1;
if TRAYECTORIANUEVA3(i)==CENTRAL1
vh=vh+1;
else
[indf,indc]=find(PED1(:,1)==TRAYECTORIANUEVA3(i));
PESOTOTAL2(vh)=PESOTOTAL2(vh)+PED1(indf,2);
end
end
AHORRO=COSTENUEV-COSTETT2;
if
all(PESOTOTAL2<=CAPVEH1)&&(AHORRO>MATRIZAHORRO(1)||AHORRO>MATRIZAHORRO(2)||AHORR
O>MATRIZAHORRO(3)||AHORRO>MATRIZAHORRO(4)||AHORRO>MATRIZAHORRO(5))
109
for i=1:4
if
AHORRO>MATRIZAHORRO(i)&&AHORRO~=MATRIZAHORRO(1)&&AHORRO~=MATRIZAHORRO(2)&&AHORRO
~=MATRIZAHORRO(3)&&AHORRO~=MATRIZAHORRO(4)&&AHORRO~=MATRIZAHORRO(5)
MATRIZAHORRO(5)=[];
COSTESTABU(5)=[];
MATRIZAHORROTRAYORIGEN(5)=[];
MATRIZAHORROTRAYDESTINO(5)=[];
MATRIZAHORRO=[MATRIZAHORRO(1:i-1) AHORRO MATRIZAHORRO(i:4)];
MATRIZAHORROTRAYORIGEN=[MATRIZAHORROTRAYORIGEN(1,1:i-1) TRAYECTO(1)
MATRIZAHORROTRAYORIGEN(1,i:end)];
MATRIZAHORROTRAYDESTINO=[MATRIZAHORROTRAYDESTINO(1,1:i-1) TRAYECTO(2)
MATRIZAHORROTRAYDESTINO(1,i:end)];
COSTESTABU=[COSTESTABU(1,1:i-1) COSTETT2 COSTESTABU(i:end)];
break;
end
end
if
AHORRO<MATRIZAHORRO(4)&&AHORRO~=MATRIZAHORRO(1)&&AHORRO~=MATRIZAHORRO(2)&&AHORRO
~=MATRIZAHORRO(3)&&AHORRO~=MATRIZAHORRO(4)&&AHORRO~=MATRIZAHORRO(5)
MATRIZAHORRO(5)=[];
MATRIZAHORROTRAYORIGEN(5)=[];
MATRIZAHORROTRAYDESTINO(5)=[];
COSTESTABU(5)=[];
MATRIZAHORRO=[MATRIZAHORRO AHORRO];
MATRIZAHORROTRAYORIGEN=[MATRIZAHORROTRAYORIGEN TRAYECTO(1)];
MATRIZAHORROTRAYDESTINO=[MATRIZAHORROTRAYDESTINO TRAYECTO(2)];
COSTESTABU=[COSTESTABU COSTETT2];
end
TRAYECTORIANUEVA2=TRAYECTORIANUEVA3;
PESOTOTAL3=PESOTOTAL2;
else
end
end
end
110
end
end
MATRIZAHORRO
MATRIZAHORROTRAY(1,:)=MATRIZAHORROTRAYORIGEN;
MATRIZAHORROTRAY(2,:)=MATRIZAHORROTRAYDESTINO;
CAMP=0;
SUMA=0;
mp=0;
for mp1=1:length(MATRIZAHORROTRAY)
SUMA=0;
for mt=1:length(LISTATABU)
if
(((MATRIZAHORROTRAY(1,mp1)~=LISTATABU(1,mt))&&(MATRIZAHORROTRAY(1,mp1)~=LISTATAB
U(2,mt)))||((MATRIZAHORROTRAY(2,mp1)~=LISTATABU(1,mt))&&(MATRIZAHORROTRAY(2,mp1)
~=LISTATABU(2,mt))))||(COSTESTABU(mp1)<COSTEMIN)
SUMA=SUMA+1;
end
end
if SUMA==length(LISTATABU)
mp=mp1;
break
end
end
if SUMA==length(LISTATABU)
LISTATABU(:,4)=[];
ANADIDO=MATRIZAHORROTRAY(:,mp);
LISTATABU=[ANADIDO LISTATABU];
COSTENUEV=COSTESTABU(mp)
CAMBIOPOS=TRAYECTORIANUEVA1(ANADIDO(1));
TRAYECTORIANUEVA1(ANADIDO(1))=TRAYECTORIANUEVA1(ANADIDO(2));
TRAYECTORIANUEVA1(ANADIDO(2))=CAMBIOPOS;
if COSTESTABU(mp)<COSTEMIN
111
COSTEMIN=COSTESTABU(mp)
TRAYECTORIANUEVAMINIMA=TRAYECTORIANUEVA1;
end
end
intento=intento+1;
end
COSTENUEV
COMINSALI=num2str(COSTEMIN);
set(handles.salida,'String',COMINSALI);
X=TRAYECTORIANUEVAMINIMA;
CEN=find(X==CENTRAL1);
for j=2:length(CEN)
clear COORDENADAS;
COORDENADAS(:,1)=COORD1(X(CEN(j-1):CEN(j)),2);
COORDENADAS(:,2)=COORD1(X(CEN(j-1):CEN(j)),1);
COLOR1=rand;
COLOR2=rand;
COLOR3=rand;
hold on;
x(j-1)=plot(COORDENADAS(:,1),COORDENADAS(:,2),'LineWidth',2,'Color',[COLOR1
COLOR2 COLOR3])
numero=num2str(j-1);
temp(j-1)=strcat({'Vehiculo '},numero);
end
legend(x,temp);
112
finstr='Finalizada Hibrida';
set(handles.fin,'String', finstr);
hold off;
8.1.6 Cambio de iteraciones
Esta es la función por la que el usuario cambia el número de iteraciones y el programa las aplica a los diferentes
algoritmos.
function iteracionescambiar_Callback(hObject, eventdata, handles)
% hObject handle to iteracionescambiar (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global iteracion
iteracion=str2double(get(handles.Iteraciones,'String'));
113