Upload
others
View
3
Download
0
Embed Size (px)
Citation preview
BIBLIOGRAFIA
Universidad Central “Marta Abreu” de Las Villas
Facultad Matemática, Física y Computación
Centro de Estudios de Informática
Departamento de Ciencia de la Computación
Simulaciones para los métodos de Investigación de Operaciones
Trabajo de Diploma
Autor: Daniel Alejandro Pérez Álvarez
Tutores: MSc. Beatriz María Méndez Hernández
Dra. Yailén Martínez Jiménez
Santa Clara, 2014.
1
Dictamen
El que suscribe, Daniel Alejandro Pérez Álvarez, hago constar que el trabajo titulado
Simulaciones para los métodos de Investigación de Operaciones fue realizado en la
Universidad Central “Marta Abreu” de Las Villas como parte de la culminación de los
estudios de la especialidad de Licenciatura en Ciencia de la Computación, autorizando a
que el mismo sea utilizado por la institución, para los fines que estime conveniente, tanto
de forma parcial como total y que además no podrá ser presentado en eventos ni publicado
sin la autorización de la Universidad.
______________________Firma del Autor
Los abajo firmantes, certificamos que el presente trabajo ha sido realizado según acuerdos
de la dirección de nuestro centro y el mismo cumple con los requisitos que debe tener un
trabajo de esta envergadura referido a la temática señalada.
________________________________ ______________________________Firma del Tutor Firma del Jefe del Laboratorio
Estudia para que seas alguien en esta vida…
Frase del habla popular
DEDICATORIA
A mis abuelos maternos Roberto y Meñita
A mi papá y mamá por todo lo que me han dado
A ti, a petición de mi madre
A mi familia por preocuparse tanto por mí
A todos mis amigos
AGRADECIMIENTOS
A mis tutoras, Beatriz y Yailén por ser tan comprensivas conmigo
A Erick por estar siempre ahí cuando lo necesité
A Daynier, Yuney, Rainer, Yairon, Ernest… y toda la gente de la ACM por darme un lugar
entre ellos
A los muchachos de la Cañasanta por tantas cosas compartidas
A mis compañeros de carrera
A todo aquel que me ofreció de una manera u otra su apoyo y aliento.
RESUMEN
La Investigación de Operaciones es uno de los campos de la Matemática Aplicada que mayor
desarrollo ha tenido en los últimos tiempos. Con frecuencia encontramos en empresas y
centros de investigación problemáticas que pueden resolverse haciendo uso de algoritmos
pertenecientes a esta disciplina, evidenciando la gran aplicabilidad de la misma.
Existen diferentes herramientas para resolver problemas de optimización, como el Storm y el
Lingo, los cuales han sido utilizados para la enseñanza de las asignaturas Modelos de
Optimización, de la carrera Licenciatura en Ciencia de la Computación e Investigación de
Operaciones, de la carrera Ingeniería Informática. Una limitante de estos programas es que no
permiten resolver los problemas paso a paso, solo proveen la solución final al modelo
previamente definido. De ahí que ha sido del interés de los profesores de estas asignaturas
realizar una investigación sobre las necesidades actuales de las asignaturas mencionadas, de
cuyo resultado ha surgido la necesidad de contar con un software que resuelva paso a paso los
métodos que se estudian en estas asignaturas con una interfaz agradable al usuario que permita
una mayor comprensión de los métodos por parte de los estudiantes.
Palabras Clave: Optimización, Simulaciones, Investigación de Operaciones, Ejecución paso a
paso.
ABSTRACT
Operations Research is one of the fields of Applied Mathematics which has had the biggest
development in recent times. Several companies and research centers often present problems
that can be solved using algorithms belonging to this discipline, demonstrating its wide
applicability.
There are different tools for solving optimization problems, such as Storm and Lingo, which
have been used for teaching the subjects Optimization Models, in the Computer Science career
and Operations Research in Computer Engineering. One limitation of these programs is that
they do not solve the problems step by step. They just provide the final solution to the
previously defined model. Hence, it has been of interest for the teachers of these subjects to
research on the current needs of the mentioned subjects, which outcome is the need of a
software product to solve, step by step, the methods studied in these subjects with a nice
interface that allows a greater understanding by the students.
Keywords: Optimization, Simulations, Operations Research, Step by step execution.
TABLA DE CONTENIDOS
INTRODUCCIÓN.......................................................................................................................1
CAPÍTULO 1.FUNDAMENTACIÓN TEÓRICA......................................................................1
1.1Enseñanza asistida por computadoras. Simulaciones.........................................................1
1.2Programación lineal. Forma estándar del modelo matemático. Conceptos relevantes.......2
1.2.1 Método Simplex..........................................................................................................2
1.2.2 Árbol de expansión mínimo........................................................................................3
1.2.3 Caminos mínimos desde una fuente............................................................................3
1.2.4 Algoritmo de asignación..............................................................................................4
1.2.5 Flujo máximo...............................................................................................................4
1.2.6 Problema de transporte................................................................................................5
1.2.7 Flujo de costo mínimo.................................................................................................5
1.3 Conclusiones parciales.......................................................................................................6
CAPÍTULO 2. Implementación de SimIO, software educativo para Investigación deOperaciones..................................................................................................................................6
2.1 Detalles de una ejecución paso a paso...............................................................................6
2.2 Biblioteca JGraphX............................................................................................................6
2.3 Diagrama de clases, casos de uso y actividades.................................................................7
2.3.1 Diagrama de casos de uso............................................................................................7
2.3.2 Diagrama de actividades..............................................................................................8
2.3.3 Diagrama de clases......................................................................................................8
2.4 Paquete de métodos............................................................................................................8
2.5 Paquete útil.........................................................................................................................8
2.6 Uso del lenguaje de programación Java.............................................................................9
2.7 Conclusiones parciales.......................................................................................................9
CAPÍTULO 3. Caracterización del software SimIO...................................................................9
3.1 Características del software................................................................................................9
3.2 Trabajo con la aplicación....................................................................................................9
3.3 Conclusiones parciales.....................................................................................................10
CONCLUSIONES.....................................................................................................................10
RECOMENDACIONES............................................................................................................10
BIBLIOGRAFÍA.......................................................................................................................10
INTRODUCCIÓN
La enseñanza del actual siglo ha estado matizada por el uso de los medios técnicos auxiliares,
dentro de los cuales la computadora ha desempeñado una función preponderante por las
ventajas que incorporó, tanto para la explicación de los conceptos como para su apropiación.
En la medida que ha ido avanzando la tecnología se han buscado métodos que resulten
efectivos para el proceso docente-educativo. Se puede afirmar que a cada paradigma de la
informática ha estado asociada una versión didáctica que apoye a la docencia en los
contenidos más diversos (Almeida Campos et al., 1997).
La simulación de sistemas y situaciones existentes en el mundo juega un importante papel en
las investigaciones científicas. En la educación es cada vez más utilizada para la enseñanza de
procesos, procedimientos y en el entrenamiento de situaciones prácticas. Sirven como base de
muchos juegos instructivos y de entretenimiento en general (Chávez and Quesada).
La Investigación de Operaciones es uno de los campos de la Matemática Aplicada que mayor
desarrollo ha tenido en los últimos tiempos. Esto se debe a la gran cantidad de aplicaciones
prácticas que poseen los algoritmos de optimización. En efecto, problemas como el de
transporte, asignación o caminos mínimos se presentan con regularidad en empresas, centros
de investigación y demás instituciones. Con evidente acierto el plan de estudio de la carrera
Licenciatura en Ciencia de la Computación contempla la asignatura Modelos de Optimización
destinando dos semestres en cuarto año al estudio de la misma y la carrera Ingeniería
Informática destina todo un semestre a la asignatura Investigación de Operaciones.
Ha sido del interés de los profesores de la facultad incluir la enseñanza asistida por
computadora como una manera de estimular a los estudiantes al aprendizaje por vías
alternativas. Estas asignaturas no están exentas de este proceder, software como el Lingo o el
Storm han contribuido en su momento con el proceso de enseñanza pero actualmente resultan
ineficientes. Ha sido entonces preciso realizar una investigación sobre las necesidades actuales
de estas asignaturas de cuyo resultado ha surgido la necesidad de contar con un software que
resuelva paso a paso los métodos que se estudian en estas asignaturas con una interfaz
agradable al usuario que permita una mayor comprensión de los métodos por parte de los
estudiantes.
Para dar solución al problema científico se plantea como objetivo general de esta tesis:
Implementar simulaciones que faciliten la comprensión de los algoritmos estudiados en
las asignaturas Modelos de Optimización I y II e Investigación de Operaciones.
Este objetivo se desglosa en los siguientes objetivos específicos:
Analizar la teoría que sustenta los métodos estudiados en las asignaturas Modelos de
Optimización I y II e Investigación de Operaciones.
Implementar simulaciones que ayuden a los profesores a impartir las clases con una
mayor calidad.
Proporcionar una interfaz sencilla pero completa que muestre paso a paso el
funcionamiento de estos métodos permitiendo a los estudiantes una mejor comprensión
de los mismos.
Para dar solución al problema de investigación y a los objetivos específicos de esta tesis se
dará respuesta a las siguientes preguntas de investigación:
¿Cómo agrupar los métodos que serán implementados de acuerdo a las diferentes
temáticas de las asignaturas?
¿Qué herramientas computacionales deben utilizarse en aras de implementar
simulaciones que ayuden a los profesores a impartir las clases con una mayor calidad?
¿Cómo lograr que el funcionamiento de los métodos en cuestión sea mostrado paso a
paso de una manera sencilla y fácil de comprender por los estudiantes?
El software que se utiliza actualmente en la asignatura (Lingo) no muestra las soluciones o
iteraciones intermedias de los algoritmos, solo el resultado final. Además usar este software
precisa de un conocimiento del lenguaje del mismo y también se debe tener en cuenta que es
un software propietario y la política de la universidad es la migración a software libre.
Con el nuevo software que se desea implementar se brindará a los usuarios que aprenden
Investigación de Operaciones un producto sencillo de manejar desde la entrada misma y que
puede convertirse en una herramienta de aprendizaje, consulta y comprobación de
conocimientos. El valor práctico que posee un software de este tipo es innegable, así como su
utilidad metodológica. También ostenta valor social, sobre todo entre los estudiantes y
profesores del área de Investigación de Operaciones. Incluso puede manejarse la idea de
ampliar su uso a otras universidades del país.
La tesis está estructurada en 3 capítulos, en el capítulo uno se realiza un análisis de los
principales aspectos de la enseñanza asistida por computadora. Además se hace una breve
reseña teórica de los principales algoritmos que se estudian en Investigación de Operaciones.
Seguidamente, en el capítulo 2 se hace un acercamiento al funcionamiento del sistema de
ejecución paso a paso, se presentan los principales diagramas de ingeniería de software de la
aplicación propuesta, se describen algunos de los métodos utilizados y se exponen aspectos
fundamentales de la biblioteca JGraphX. Posteriormente, en el capítulo 3 se muestran una
serie de especificaciones sobre el software y se realiza una especie de manual de usuario que
sirve de guía para los futuros usuarios de la aplicación. El documento termina con las
conclusiones y recomendaciones del autor.
CAPÍTULO 1. FUNDAMENTACIÓN TEÓRICA
En el presente capítulo se describe la importancia de la enseñanza asistida por computadora en
el mundo moderno y se hace una breve reseña de los conceptos más importantes relativos a las
simulaciones para la enseñanza, además se hace un acercamiento teórico a los métodos de
optimización a simular.
1.1 Enseñanza asistida por computadoras. Simulaciones.
La televisión por cable, el video, el amplio uso de las computadoras y el acceso a redes de
información constituyen nuevos formatos de información que implican cambio en la
educación y provocan una "crisis". Los estudiosos de la tecnología educacional realizan una
importante función en transformar estas tecnologías modernas en potentes herramientas
educativas (Almeida Campos et al., 1997).
Por enseñanza asistida por computadora (EAC) se puede considerar toda la maquinaria y
programas informáticos diseñados para ayudar al profesor y a los alumnos en el proceso de
enseñanza-aprendizaje. Se incluye también el uso de programas creados para otros usos, pero
aplicados a esta tarea (Cabero et al., 2000).
La idea detrás de la EAC es facilitar el aprendizaje e incentivar en el alumno un impulso para
aprender, despertando su curiosidad natural. Sin embargo debe tenerse en cuenta que la EAC
no sustituye al profesor. Es el profesor quien crea o diseña la aplicación de la EAC y debe
aportar sus habilidades, experiencias, conocimientos y la motivación necesaria para guiar al
alumno(Cabero et al., 2000).
Un programa de EAC debe cumplir ciertos requisitos que resultan indispensables para lograr
un desempeño de calidad consecuente con las necesidades del proceso de enseñanza-
aprendizaje. Un aspecto muy influyente es el diseño de la interfaz visual, o sea, la forma y
contenido de todos aquellos componentes que el usuario observa por pantalla. Es necesario
que la interfaz sea atractiva y organizada propiciando así una mayor motivación en el usuario,
(en este caso el estudiante). Además resulta muy importante que se le añada al programa un
sistema de ayuda que guíe al usuario en aquellos tópicos que puedan resultarle dudosos.
El uso de los sistemas de EAC puede resultar muy ventajoso en los tiempos actuales puesto
que normalmente estos resultan interesantes como medio de enseñanza además de cubrir las
limitaciones de tiempo de los profesores. Como complemento al proceso educativo tradicional
estas herramientas son cada día mas utilizadas. Esto se demuestra en el desarrollo
experimentado por los sistemas de enseñanza-aprendizaje, desde los programas lineales
creados a partir de la segunda mitad del pasado siglo, pasando por los programas ramificados
y los sistemas generativos de los años 60-70, hasta llegar a los sistemas tutores inteligentes de
la actualidad, los cuales combinan técnicas de inteligencia artificial (IA), modelos
psicológicos del estudiante y del experto y teorías de la educación (Almeida Campos et al.,
1997).
Entre los diversos tipos de herramientas de EAC adaptadas a diferentes metodologías de
aprendizaje se abordará solamente el tema de las simulaciones puesto que es el que se
relaciona directamente con el objetivo de este trabajo.
La simulación es el proceso de diseñar un modelo de un sistema real y llevar a término
experiencias con él, con la finalidad de comprender el comportamiento del sistema o evaluar
nuevas estrategias —dentro de los límites impuestos por un cierto criterio, o un conjunto de
ellos— para el funcionamiento del sistema (Chávez and Quesada).
Las simulaciones por computadoras son programas que sostienen modelos de sistemas reales.
El comportamiento de estos sistemas se expresa mediante cambios en las variables que lo
describen. La experimentación con las simulaciones se realiza dando entradas al modelo y
analizando sus salidas. El sistema real puede ser físico, artificial o hipotético. Las
simulaciones por computadora se han convertido en una parte útil del modelado de muchos
sistemas naturales en Física, Química y Biología, y de sistemas humanos como el económico,
entre otros. En la enseñanza, esta posibilidad de ensayar, probar teorías y entrenarse en un
ambiente controlable y sin riesgos es una gran oportunidad (Chávez and Quesada).
Una simulación educativa es una poderosa técnica que enseña algunos aspectos del mundo
mediante su imitación o réplica. Está basada en un modelo de un sistema o fenómeno del
mundo real en el que se han simplificado u omitido algunos elementos para facilitar el
aprendizaje. Las simulaciones educativas son consideradas como el tipo de software que hace
posible la aplicación de las teorías de aprendizaje centradas en el estudiante (Chávez and
Quesada).
La mayoría de los estudiantes encuentran la interacción con simulaciones más motivadora y
cercana a las experiencias con el mundo, el sistema o fenómeno real, que otros tipos de
software educativo. Las simulaciones bien diseñadas pueden contribuir a la eficiencia del
aprendizaje, ya que al estudiante le puede tomar menor tiempo entender una materia cuando
ha visto su contenido a través de la interacción con una simulación (Chávez and Quesada).
1.2 Programación lineal. Forma estándar del modelo matemático. Conceptos relevantes.
La programación lineal (PL) tiene sus raíces en el estudio de las desigualdades lineales, que se
remonta al trabajo de Fourier en 1826. El campo de aplicaciones del tema inició en 1939
cuando el científico soviético L. V. Kantorovich observó la importancia práctica de cierta clase
de problemas de programación lineal y dio un algoritmo para su solución (Vanderbei, 2001a).
Muchas personas clasifican el desarrollo de la programación lineal entre los avances
científicos más importantes de mediados del siglo XX, y es cierto que su impacto desde 1950
ha sido extraordinario. En la actualidad es una herramienta de uso normal que ha ahorrado
millones de dólares a muchas compañías y negocios, incluyendo empresas medianas en los
distintos países industrializados del mundo; su aplicación a otros sectores de la sociedad se
está ampliando con rapidez. Una proporción muy grande de los cálculos científicos en
computadoras está dedicada al uso de la programación lineal (Ayuso, 2007). A menudo, las
situaciones que se modelan son en realidad no lineales pero resulta atrayente aplicar PL debido
al estado avanzado del software en esta rama, la garantía de convergencia a un mínimo global,
y el hecho de que la incertidumbre en los datos puede hacer muy complicados los modelos no
lineales (Nocedal and Wright, 2006).
La programación lineal utiliza un modelo matemático para describir el problema y trata
exclusivamente con funciones objetivos y restricciones. La palabra programación no se refiere
a programación en computadoras; en esencia es un sinónimo de planeación. El adjetivo lineal
significa que todas las funciones matemáticas del modelo deben ser funciones lineales (Ayuso,
2007).
Así, la programación lineal trata la planeación de las actividades para obtener un resultado
óptimo, esto es, el resultado que mejor alcance la meta especificada (según el modelo
matemático) entre todas las alternativas de solución (Ayuso, 2007).
El tipo más común de aplicación abarca el problema general de asignar recursos limitados
entre actividades competitivas de la mejor manera posible (es decir, de forma óptima). La
variedad de situaciones a las que se puede aplicar esta descripción es sin duda muy grande, y
va desde la asignación de instalaciones de producción a los productos, hasta asignación de los
recursos nacionales a las necesidades de un país; desde la selección de una cartera de
inversiones, hasta la selección de los patrones de envío; desde la planeación agrícola, hasta el
diseño de una terapia de radiación, etc. (Ayuso, 2007).
La forma estándar del modelo de programación lineal es la siguiente (Bartels and Golub,
1969):
n...1=j,0≥x
m...1=i,b≤xa+...+xa+xaa sujeto
xc+...+xc=ZMaximizar
j
inn,i22,i11,i
nn11
Los términos clave son recursos y actividades, en donde m denota el número de distintos tipos
de recursos que se pueden usar y n denota el número de actividades bajo consideración.
Identificaremos ahora los principales componentes del modelo (Ayuso, 2007).
Z: valor de la función objetivo o también el valor de la medida global de efectividad.
xj: variables de decisión puesto que deciden el nivel de la actividad j (para j = 1,2,..., n). Son
las incógnitas del problema.
cj: incrementos en Z que resultan al aumentar una unidad en el nivel de la actividad j.
bi: cantidad de recurso i disponible para asignar a las actividades (para i = 1,2,..., m).
aij: cantidad del recurso i consumido por cada unidad de la actividad j.
Todos los problemas que puedan ser modelados de esta forma se consideran problemas de
programación lineal. Un problema de PL que posea restricciones de tipo = ó ≥ puede ser
llevado a un problema equivalente que sólo contenga restricciones de tipo ≤. Además, un
problema de maximización puede ser trasladado a un problema semejante de minimización y
viceversa.
Cualquier problema de programación lineal requiere identificar cuatro componentes básicos
(Castillo et al., 2002):
1. El conjunto de datos.
2. El conjunto de variables involucradas en el problema, junto con sus dominios respectivos de
definición.
3. El conjunto de restricciones lineales del problema que definen el conjunto de soluciones
admisibles.
4. La función lineal que debe ser optimizada (minimizada o maximizada).
Esto lo veremos más claro en el siguiente ejemplo (Dasgupta et al., 2006):
Una boutique de chocolates vende dos productos: un surtido de chocolates triangulares
llamados Pyramide, y los más lujosos, Pyramide Nuit. ¿Cuánto de cada uno debe producirse
para maximizar las ganancias? Digamos que se hacen x1 cajas de Pyramide por día, con una
ganancia de $1 por cada una, y x2 cajas de Nuit, con una ganancia más sustancial de $6 por
pieza; x1 y x2 son valores desconocidos que deseamos determinar. Pero esto no es todo; existen
también algunas restricciones para x1 y x2 que deben ser complacidas (además del obvio x1, x2
≥ 0). Primero, la demanda diaria de estos chocolates exclusivos está limitada a 200 cajas de
Pyramide y 300 cajas de Nuit. Además, la fuerza de trabajo actual no puede producir más de
400 cajas de chocolate por día. ¿Cuáles son los niveles óptimos de la producción?
Las actividades a realizar son dos: fabricar chocolates Pyramide y fabricar Nuit. Las ganancias
por unidad de cada actividad (c1 y c2), son $1 y $6 respectivamente. La cantidad de recursos
disponibles para cada actividad (b1, b2) son 200 y 300 cajas respectivamente y 400 cajas si
ambas actividades se realizan simultáneamente.
Las incógnitas involucradas son x1 y x2 y representan la cantidad de cajas de cada producto
que deben fabricarse. Es imposible que alguna de estas variables tome un valor negativo por lo
tanto: x1, x2 ≥ 0.
Además no tiene sentido fabricar, digamos, 3 cuartos de caja de Nuit. Por lo tanto el dominio
de las variables se reduce a los enteros positivos: x1, x2
Las restricciones del problema son: x1 ≤ 200
x2 ≤ 300
x1 + x2 ≤ 400
Y la función objetivo: Maximizar Z = x1 + 6x2
Una propuesta de valores específicos para las variables de decisión es llamada una solución.
Una solución (x1, x2. . . xn) es llamada factible si satisface todas las restricciones. La solución
factible es óptima si, adicionalmente, consigue el máximo deseado (Vanderbei, 2001a). Por
otra parte, una solución no factible es una solución para la que al menos una restricción se
viola (Ayuso, 2007).
Figura 1.1 Crecimiento paulatino del valor de la función objetivo (Dasgupta et al., 2006).
Para el problema anterior (x1 = 100; x2 = 100) es una solución factible, en cambio (x1 = 400; x2
= 0) es no factible puesto que viola la primera restricción enunciada. La solución óptima la
veremos apoyándonos en el gráfico de la figura 1.1, esto puede hacerse cuando la cantidad de
variables es pequeña (2 o 3 variables). Ya que la actividad que más ganancia produce por
unidad es fabricar Nuit pudiéramos pensar en aumentar la correspondiente variable x2 tanto
como nos sea posible y la producción restante asignarla a x1. Esta idea intuitiva resulta
correcta en este caso: asignamos x2 = 300, esto es, el número máximo de cajas que la segunda
restricción permite y como diariamente pueden producirse 100 cajas más asignamos entonces
este valor a x1. La solución hallada (100, 300) produce una ganancia total (Z) de $1900 al día.
Las líneas discontinuas del gráfico anterior muestran el crecimiento paulatino de Z a medida
que x1 y x2 aumentan.
Es necesario ahora establecer algunos conceptos que serán usados posteriormente.
Una región factible es la colección de todas las soluciones factibles (Ayuso, 2007). La región
factible para este problema se muestra en la figura 1.2 representada por el área sombreada.
Una frontera de restricción es una recta delimitada por el conjunto de restricciones (Ayuso,
2007).
La solución factible en un vértice (FEV) es la solución que está en un vértice de la región
factible (Ayuso, 2007). A, B, C, D y E son soluciones factibles en un vértice.
Existe una fuerte relación entre las soluciones óptimas y las soluciones FEV. Considere
cualquier problema de programación lineal con soluciones factibles y una región factible
acotada. El problema debe poseer soluciones FEV y al menos una solución óptima. Más aún,
la mejor solución FEV debe ser una solución óptima. Así, si un problema tiene exactamente
una solución óptima, ésta debe ser una solución FEV. Si el problema tiene múltiples
soluciones óptimas, al menos dos deben ser soluciones FEV (Ayuso, 2007). Puede
comprobarse que la solución óptima obtenida anteriormente x1 = 100, x2 = 300 es FEV.
Figura 1.2 Región factible del problema.
Para cualquier problema de programación lineal con n variables de decisión, dos soluciones
FEV son adyacentes entre sí si comparten n – 1 fronteras de restricciones. Dos soluciones FEV
adyacentes están conectadas por un segmento de recta que está en estas mismas fronteras de
restricciones compartidas. Este segmento de recta recibe el nombre de orilla o arista de la
región factible (Ayuso, 2007). Por ejemplo, C y D son soluciones FEV adyacentes y el
segmento C-D es una arista de la región factible.
Para saber si una solución es óptima es necesario realizar una prueba de optimalidad. Si una
solución FEV no tiene soluciones FEV adyacentes que sean mejores (según el valor de Z),
entonces esa debe ser una solución óptima (Ayuso, 2007). La solución óptima de nuestro
problema es D con ZD = $1900, las soluciones FEV adyacentes a D son C con ZC = $1400 y E
con ZE = $1800. Se cumple que ZD ≥ ZC, ZE.
Otra acotación importante: cualquier problema que tenga múltiples soluciones óptimas tendrá
un número infinito de ellas, todas con el mismo valor de la función objetivo (Ayuso, 2007).
Por ejemplo, supongamos que deseamos maximizar 3x1 + 3x2, sujeto a x1 + x2 ≤ 1. La región
factible se indica en la figura 1.3 en color gris. Todos los puntos sobre la recta x1 + x2 = 1 son
soluciones óptimas con Z = 3. Dos de las soluciones obtenidas son FEV: (1, 0) y (0,1).
Figura 1.3 Problema con soluciones óptimas múltiples.
Algunos problemas de programación lineal resultan imposibles de resolver ya sea porque su
región factible no está acotada o porque carecen de región factible por completo.
Existen una serie de propiedades que cumplen los problemas de programación lineal (Ayuso,
2007).
La proporcionalidad es una de estas. La contribución de cada actividad al valor de la función
objetivo Z es proporcional al nivel de actividad xi como lo representa el término cjxj en la
función objetivo. De manera similar, la contribución de cada actividad al lado izquierdo de
cada restricción funcional es proporcional al nivel de la actividad x j, en la forma en que lo
representa el término aijxj en la restricción. En consecuencia, esta suposición elimina cualquier
exponente diferente a 1 para las variables en cualquier término de las funciones (ya sea la
función objetivo o la función en el lado izquierdo de las restricciones funcionales) en un
modelo de programación lineal.
Cada función en un modelo de programación lineal (ya sea la función objetivo o el lado
izquierdo de las restricciones funcionales) es la suma de las contribuciones individuales de las
actividades respectivas. Esta propiedad se conoce como aditividad.
Las variables de decisión en un modelo de programación lineal pueden tomar cualquier valor,
incluyendo valores no enteros, que satisfagan las restricciones funcionales y de no
negatividad. Así, estas variables no están restringidas a sólo valores enteros. Como cada
variable de decisión representa el nivel de alguna actividad, se supondrá que las actividades se
pueden realizar a niveles fraccionales; de ahí que las variables cumplan la propiedad de
divisibilidad.
Se supone que los valores asignados a cada parámetro de un modelo de programación lineal
son constantes conocidas, es decir, existe certidumbre.
Todos los problemas de optimización a los que se hará referencia son instancias del modelo
fundamental de la programación lineal. Debido a sus características especiales cada uno de
estos problemas cuenta con algoritmos específicos para su resolución. Se expondrá en primer
término el método simplex, el cual resuelve el problema asociado al modelo general de PL y
luego se expondrán otros problemas señalando en cada caso un algoritmo que permite
solucionarlos.
1.2.1 Método Simplex
El método simplex (MS) es el procedimiento más general y más conocido para resolver
problemas de programación lineal. Fue desarrollado por George Dantzig en 1947 (Vanderbei,
2001a). Desde entonces muchos investigadores han profundizado en sus ideas y han hecho de
la programación lineal la técnica de optimización de uso más frecuente en la ciencia y la
industria (Nocedal and Wright, 2006). Está comprobado que es un método
extraordinariamente eficiente y se usa en forma rutinaria para resolver problemas grandes en
las computadoras de hoy en día (Ayuso, 2007). La mejora ininterrumpida de sus técnicas
algorítmicas y computacionales es probablemente la razón principal del éxito del método
simplex (Nocedal and Wright, 2006). También se usan extensiones y variaciones del método
simplex para realizar análisis pos óptimo, (incluyendo el análisis de sensibilidad), sobre el
modelo (Ayuso, 2007).
El método simplex es un procedimiento algebraico. Sin embargo, sus conceptos fundamentales
son geométricos (Ayuso, 2007):
- El método simplex analiza solo las soluciones FEV.
- Siempre que sea posible, la inicialización de método simplex elige el origen (todas las
variables de decisión iguales a cero) como solución FEV inicial. En otro caso, existen
métodos para hallar la solución FEV inicial.
- Cada vez que el método simplex realiza una iteración para moverse de la solución FEV
actual a una mejor, siempre escoge una solución FEV adyacente a la actual. Toda la
trayectoria que sigue hasta alcanzar, eventualmente, una solución óptima es a lo largo
de las aristas de la región factible.
- Después de identificar la solución FEV actual, el método simplex examina cada una de
las aristas de la región factible que salen de esta solución.
- Entre las aristas con una tasa de mejoramiento en Z positiva, selecciona moverse por
aquella con la tasa de mejoramiento en Z más grande.
- Si ninguna arista posee una tasa de mejoramiento en Z positiva la solución FEV actual
es óptima.
Figura 1.4 Funcionamiento del método simplex visto geométricamente (Dasgupta et al., 2006).
Lo dicho anteriormente se ilustra en la figura 1.4. El gráfico corresponde al problema
enunciado el epígrafe anterior.
Se hace ahora necesario trasladar los conceptos geométricos vistos al lenguaje algebraico. El
primer paso es convertir las restricciones funcionales de desigualdad en restricciones de
igualdad equivalentes. Esto se logra mediante la introducción de variables de holgura (Ayuso,
2007). La forma aumentada del modelo surge cuando se introducen variables de holgura en
todas las restricciones del modelo. La forma aumentada del problema del epígrafe anterior es:
Maximizar Z,
Sujeto a Z - x1 - 6x2 = 0
x1 + x3 = 200
x2 + x4 = 300
x1 + x2 + x5 = 400
Una solución aumentada es una solución para las variables de decisión originales que se ha
aumentado con las variables de holgura (Ayuso, 2007).
Una solución básica es una solución en un vértice aumentada (Ayuso, 2007).
Una solución básica factible es una solución factible en un vértice (FEV) aumentada (Ayuso,
2007). Para el problema aumentado anterior (0, 300, 200, 0, 100) es una solución básica
factible.
Un problema en la forma aumentada posee n variables más que ecuaciones donde n es la
cantidad de variables de decisión en el problema original. Es posible elegir n variables
cualesquiera y otorgarles cualquier valor arbitrario, (el método simplex usa el valor cero) y
resolver el conjunto de ecuaciones en términos de las demás variables eliminando así las
redundancias. Las variables que se igualan a cero son denominadas variables no básicas, el
resto son llamadas variables básicas. La solución simultánea de las ecuaciones en las variables
básicas es una solución básica.
Si al resolver el sistema de ecuaciones todas las variables básicas satisfacen las restricciones
de no negatividad entonces la solución básica es una solución básica factible (Ayuso, 2007).
Ahora es posible hacer un resumen del funcionamiento del método simplex desde el punto de
vista algebraico.
El MS genera una sucesión ordenada de soluciones básicas factibles que progresivamente
mejoran el valor de la función objetivo. El MS opera en dos fases (Castillo et al., 2002):
1. Una etapa de iniciación en la que
(a) El conjunto inicial de restricciones se transforma en otro equivalente asociado a una
solución básica.
(b) Los valores de las variables básicas se transforman en valores no negativos (se obtiene así
una solución básica factible). Este proceso se llamará fase de regulación.
2. Una etapa iterativa estándar, en la que los coeficientes de la función objetivo se transforman
en valores no negativos y el valor de Z se mejora progresivamente hasta que se obtiene la
solución óptima, no se detecta ninguna solución factible, o aparecen soluciones no acotadas.
En este proceso iterativo, se calculan distintas soluciones básicas factibles. Para este fin se usa
una operación que se conoce por pivotación.
Para moverse de una solución básica factible a otra se utiliza el siguiente criterio: Dos
soluciones básicas factibles son adyacentes si todas menos una de sus variables no básicas son
las mismas. En consecuencia, trasladarse de la solución básica factible actual a una adyacente
significa cambiar una variable de no básica a básica y viceversa y después ajustar los valores
de las variables básicas para que sigan satisfaciendo el sistema de ecuaciones (Ayuso, 2007).
Las definiciones geométricas y algebraicas que sustentan al método simplex y que hemos visto
reflejadas en ejemplos de dos dimensiones pueden replantearse para problemas de tres o más
dimensiones. Conceptos como región factible o solución FEV deben ser redefinidos al
aumentar el número de variables de decisión pero la idea geométrica del método simplex de
moverse de una solución FEV a otra hasta alcanzar el óptimo no varía.
1.2.2 Árbol de expansión mínimo
Dado un grafo G(V, A) no dirigido y con pesos positivos en sus aristas queremos hallar un
árbol que conecte todos los vértices de G y que cumpla además que la suma total de pesos en
sus aristas sea mínima, o sea (Nocedal and Wright, 2006):
GdemínimontorecubrimiedeÁrbolelesT
.a.s
AMinimizar ∑T∈x
x
Existen varias aproximaciones para resolver problemas de este tipo como pueden ser el
algoritmo de Prim y el algoritmo de Kruskal. En las asignaturas Modelos de Optimización e
Investigación de Operaciones se estudia este último.
El algoritmo de Kruskal va tomando las aristas del grafo de menor a mayor y en cada paso usa
un criterio de pertenencia para determinar cuáles aristas son agregadas al árbol de expansión y
cuáles no. El algoritmo desarrolla una estrategia voraz para su funcionamiento. Usando un
método de ordenamiento eficiente así como la estructura de datos Conjuntos Disjuntos puede
implementarse en O(A log A) donde A es la cantidad de aristas del grafo (Cormen et al.,
2001a). Si la cantidad de vértices V es mayor que A entonces la complejidad computacional es
O(A log V). Este algoritmo fue creado por Joseph Kruskal en 1956.
Si el grafo es conexo el resultado final es el árbol requerido con n-1 aristas de peso total
mínimo. Si por el contrario el grafo no cumple la conectividad el algoritmo hallará el árbol de
expansión de cada componente aislada del grafo.
Figura 1.3 Ejemplo de ejecución del algoritmo de Kruskal (Cormen et al., 2001a).
De acuerdo al algoritmo en cada paso se analiza la arista marcada por una flecha, las aristas
sombreadas pertenecen al árbol de expansión. Nótese que el método está inconcluso. El
próximo paso sería analizar las aristas a-h y b-c, (debe añadirse la primera de ellas), y luego
añadir también la arista d-e.
El árbol de recubrimiento mínimo (ARM) es único si los pesos de todos los arcos son
distintos. En otro caso, pueden haber varios árboles de recubrimiento (los algoritmos
usualmente devuelven solo uno de ellos).
Un ARM hallado mediante el algoritmo de Kruskal cumple que el producto de los pesos de sus
aristas es mínimo, (esto puede probarse reemplazando los pesos en los arcos por sus
logaritmos), además es una estructura con peso mínimo en su mayor arista. El árbol de
recubrimiento máximo puede hallarse de manera análoga al ARM, solo es necesario cambiar
el signo de los pesos en todas las aristas y ejecutar el algoritmo con los nuevos valores
(Villalobos, 2006).
La formulación del ARM ha sido aplicada para hallar soluciones en diversas áreas (diseño de
redes de transporte, diseño de redes de telecomunicaciones - TV por cable, sistemas
distribuidos, interpretación de datos climatológicos, visión artificial - análisis de imágenes -
extracción de rasgos de parentesco, análisis de clusters y búsqueda de superestructuras de
quasar, plegamiento de proteínas, reconocimiento de células cancerosas) (Villalobos, 2006).
1.2.3 Caminos mínimos desde una fuente
Sea G un grafo con pesos y dirigido con N vértices y M aristas. Los pesos de todas las aristas
son no negativos. Se indica un vértice de inicio S. Se requiere encontrar la longitud de los
caminos más cortos desde S hasta los demás vértices y determinar los propios caminos
mínimos. Este problema es llamado “El problema de las trayectorias mínimas desde una
fuente única” (Stern et al., 2005).
El problema de la ruta más corta se puede resolver utilizando el método general simplex, sin
embargo, debido a que el método simplex es de complejidad exponencial, se prefiere utilizar
algoritmos que aprovechen la estructura en red que se tiene para estos problemas (Dijkstra,
1959). El propio Dijkstra enunció un algoritmo mucho más eficaz que es, en definitiva, el que
se estudia en la carrera.
Para comprender mejor el desenvolvimiento del método Dijkstra es necesario introducir el
concepto de relajación.
“Relajación” a través de un arco:
Sea d[v] la estimación para la distancia más corta desde el nodo fuente hasta el vértice v y
w[u, v] el peso de la arista (u, v). Al estudiar el arco (u, v) podemos mejorar la estimación
dependiendo si la ruta vía u es mejor (Cormen et al., 2001b).
Figura 1.4 Procedimiento de relajación (Cormen et al., 2001b).
El valor estimado de la distancia del camino más corto de cada vértice es mostrado dentro del
vértice. (a) Como d[v] > d[u] + w(u, v), el valor de d[v] se decrementa, (b) Aquí, d[v] <= d[u]
+ w(u, v), por lo tanto d[v] se mantiene igual (Cormen et al., 2001b).
El algoritmo de Dijkstra realiza N iteraciones, una por cada vértice. Para la primera iteración
se escoge el nodo fuente. En cada iteración se toma el vértice con menor distancia hasta la
fuente entre los que no han sido visitados y se calcula la relajación de los vértices adyacentes a
él. Un procedimiento de marcado nos evita visitar dos veces un mismo nodo y permite
controlar el método de manera general.
Figura 1.5 Funcionamiento del algoritmo de Dijkstra paso a paso (Cormen et al., 2001b).
El algoritmo de Dijkstra parte del nodo fuente (etiquetado con la letra S). El valor estimado de
la distancia del camino más corto de cada vértice es mostrado dentro del vértice. Las aristas
sombreadas indican de donde proviene el camino mínimo actual, si la arista (u, v) está
sombreada entonces el vértice que antecede a v en el camino mínimo es u. Los vértices en
negro ya han sido visitados y los demás están por visitar. La figura (a) muestra las
precondiciones necesarias para correr el método. Las figuras de la (b) a la (f) muestran cada
iteración del método, nótese como los valores dentro de los vértices van disminuyendo
(Cormen et al., 2001b).
Las principales aplicaciones de este algoritmo son:
Encaminamiento de paquetes por los routers, para minimizar el costo de llegar desde
un origen a un destino.
Aplicaciones para sistemas de información geográficos, para la extracción de
características curvilíneas de imágenes usando técnicas de minimización del camino.
Reconocimiento de lenguaje hablado, un problema que se presenta es el distinguir
entre palabras que suenan de manera similar.
Otras aplicaciones que se pueden mencionar son el enrutamiento de aviones y tráfico aéreo y
el tratamiento de imágenes médicas.
1.2.4 Algoritmo de asignación
Sea P un conjunto de n personas y A un conjunto de n actividades. Se conoce el costo de
asignación de cada actividad a cada persona, o sea Cij es el costo de asignar la actividad i a la
persona j. Cada persona puede desempeñar cualquier actividad. El problema de asignación
consiste en asignar cada persona a una sola actividad de manera que todas las actividades sean
realizadas y el costo total de asignación sea mínimo (Vanderbei, 2001b).
El problema de asignación se considera un caso especial del problema de transporte y clasifica
entre los temas de estudio de la programación lineal entera binaria. Si consideramos la
solución como una matriz binaria X de tamaño n.
x ij={1, si seasigna laactividad i a la persona j0, en otros casos
La función objetivo puede ser escrita como:
minimizar∑i∈ S
∑j∈D
cij x ij
La restricción de que cada persona es asignada exactamente a una actividad puede ser
expresada por:
∑j∈D
x ij=1, para todoi∈PAsimismo la restricción de que cada actividad es cubierta por alguien se denota:
∑i∈ S
x ij=1, para todo j∈ A
También es posible reformular el problema en términos de Teoría de Grafos. Esto se logra
viendo a las actividades y las personas como un grafo bipartido, donde cada arista entre la i-
ésima persona y la j-ésima actividad tiene peso de Cij. Ahora nuestra tarea es encontrar el
matching de peso mínimo en dicho grafo, (el matching posee n aristas porque nuestro grafo
bipartido es completo).
Un pequeño ejemplo que ilustra lo anterior:
Figura 1.6 Ejemplo de grafo creado mediante una matriz de asignación (Kuhn, 2005).
En general para n personas y n actividades el número posible de asignaciones es igual al
número de permutaciones Pn = n! (Valdés et al., 1978). Para un valor de n elevado se hace
imposible analizar todas las soluciones en aras de encontrar la configuración óptima, es por
eso que se buscan métodos que resuelvan este problema de manera más elegante. Los
problemas de asignación aunque pueden resolverse a través del algoritmo de transporte
también se resuelven aplicando un procedimiento más efectivo llamado algoritmo húngaro
(Valdés et al., 1978), el cual basa su funcionamiento en el siguiente teorema.
Teorema: No se modifica la o las soluciones óptimas de un problema de asignación,
disminuyendo o aumentando una misma cantidad λ a todos los elementos de una misma fila o
columna de la matriz de costos C. Tal operación disminuye o aumenta en λ el valor total, pero
no cambia la solución óptima (Valdés et al., 1978).
La idea principal del método es la siguiente: supóngase que se encuentra el matching de peso
mínimo usando solamente aristas de peso 0. Obviamente, estas aristas serán la solución del
problema de asignación. Si no podemos encontrar el matching en el paso actual, entonces el
algoritmo húngaro modifica los pesos de las aristas disponibles de manera que nuevas aristas
de peso 0 aparecen y estos cambios no influyen en la solución óptima.
1.2.5 Flujo máximo
Una compañía posee una fábrica ubicada en la ciudad S, los productos allí fabricados deben
ser transportados al centro de distribución en la ciudad T. Dados los caminos unidireccionales
que conectan pares de ciudades en el país y el número máximo de camiones que se pueden
conducir a lo largo de cada camino. ¿Cuál es el número máximo de camiones que la compañía
puede enviar al centro de distribución?
Una primera observación es que no tiene sentido enviar un camión a cualquier otra ciudad que
no sea T así que cada camión que entra en una ciudad diferente de T debe salir de esta. Debido
a esto, el número de camiones que dejan S es igual al número de camiones que llegan a T.
Reformulando la declaración anterior en términos de teoría de grafos. Sea G un grafo dirigido
en el cual cada arista tiene cierta capacidad c asociada, S un vértice inicial, (la ciudad que
posee la fábrica) y sea T un vértice final. Debemos asociar un valor f que satisfaga f ≤ c a cada
arista de manera que para cada vértice V distinto de S y T la suma de los valores asociados a
las aristas que entran en V debe ser igual a la suma de los valores de las aristas que salen de V,
esta propiedad se conoce como preservación de flujo. El valor f no es más que el flujo a lo
largo de cada arista. Necesitamos maximizar la suma de los valores asociados a las aristas que
salen de la fuente S (Ahuja et al., 1993).
Figura 1.7 Ejemplo de solución óptima de Flujo Máximo.
La imagen muestra la solución óptima de una instancia de este problema, cada arco está
etiquetado con los valores f/c asociados a él. El valor de flujo máximo en este caso es 3. El
modelo puede formularse matemáticamente como:
maximizar∑i∈V
f Si
Sujeto a:
V∈ ji,∀c≤f≤0 ijij
∑i , j∈V
f ij=0∀ i , j∈V ,i ≠ S , i≠ T
Los investigadores Lester Ford y Delbert Ray Fulkerson fueron pioneros en la investigación
de flujos en grafos. En 1956 publicaron un artículo con un primer acercamiento al problema de
Flujo Máximo. De este se derivó el método básico que todavía se usa para resolver este tipo de
problemas. Para comprender el desenvolvimiento del método es necesario establecer algunas
definiciones.
Definición 1: Dado cualquier nodo i todos los arcos que salen del nodo i se denominan arcos
hacia delante con respecto al nodo i.
Definición 2: Dado cualquier nodo i todos los arcos que entran al nodo i se denominan arcos
hacia atrás para el nodo i.
Definición 3: Un corte que separa el nodo fuente del nodo destino es una partición de los
nodos de la red en dos subconjuntos D y D* tal que el nodo fuente está en D y el nodo destino
está en D*.
Figura 1.8 Ejemplo de un corte.
Definición 4: La capacidad de un corte es la suma de todas las capacidades de los arcos
procedentes de los nodos de D a los nodos en D*. Se denota C(D, D*). La capacidad del corte
anterior es:
C(D, D*) = S1c + +
Definición 5: El corte con la capacidad más pequeña se denomina corte mínimo.
Lema: Para cualquier red dirigida, si f es el flujo desde el nodo fuente al nodo destino, y (S,
S*) es un corte, entonces el valor de f es menor o igual que la capacidad de ese corte C(S, S*).
Cualquier flujo de S a T debe atravesar los arcos en el corte, y por consiguiente, el flujo f
estará limitado por la capacidad de ese corte.
Teorema de flujo máximo-corte mínimo (Ford-Fulkerson): Para cualquier red el flujo máximo
desde el nodo fuente al nodo destino es igual a la capacidad del corte mínimo (Vanderbei,
2001b).
De acuerdo con este teorema la solución del problema de flujo máximo se reduce a encontrar
entre todos los cortes aquel que tenga la mínima capacidad. Sin embargo este método es poco
recomendable ya que la cantidad de cortes crece de manera exponencial respecto al número de
vértices del grafo.
Definición 6: Dada una red G=(V,A) se denomina Red Residual o Incremental R(f), a aquella
red formada a partir de G, con el mismo conjunto de nodos que ésta que cumple lo siguiente:
dado cada arco dirigido (i, j) ∈ A en la red original que no tiene arco en la dirección opuesta
(es decir, (j, i) ∉ A), tal que 0 ≤ fij ≤ cij, se consideran en la Red Incremental dos arcos (i, j) y
(j, i) con capacidades rij = cij – fij y rji = fij, respectivamente. A dichas capacidades se las
denomina capacidades residuales o incrementales.
Definición 7: Se denomina camino incremental o camino de aumento a todo camino dirigido
desde el nodo fuente al nodo destino en la red incremental.
Definición 8: Se denota por δ la menor capacidad residual de los arcos en un camino
incremental.
Figura 1.9 Ejemplo de camino de aumento.
En el ejemplo anterior S-a-b-T es un camino incremental y el valor δ es igual a 2.
El algoritmo de flujo máximo comienza con un flujo viable f=0 y tiene dos partes, las cuales
Ford y Fulkerson llamaron rutina A y rutina B. La primera es un proceso de etiquetado que
busca un camino incremental en la red. Si la rutina A encuentra el camino de aumento la rutina
B envía tanto flujo como sea posible (δ) desde S a T modificando la red residual. Si no existen
caminos de aumento la optimalidad del flujo actual es asegurada por el siguiente teorema:
Teorema: Un flujo f tiene valor máximo si y solo si no existe un camino de aumento de flujo
con respecto a f (Greenberg, 1998).
Existen otras aproximaciones muy usadas a la hora de resolver el problema de flujo máximo,
entre ellas el algoritmo de Dinic y el algoritmo de Edmond-Karp. En nuestra aplicación hemos
optado por este último ya que posee una complejidad temporal y espacial aceptable y es
sencillo de implementar. Su funcionamiento es muy similar al método de Ford-Fulkerson, la
única diferencia es que usa una búsqueda en anchura para hallar el camino de aumento en la
rutina A. Este algoritmo tiene una complejidad computacional O(VE2), donde V es el número
de nodos o vértices, y E el número de arcos del grafo (Villalobos, 2006).
La búsqueda del flujo máximo es fundamental para resolver modelos de: transporte de
mercancías (logística de aprovisionamiento y distribución), flujo de gases y líquidos por
tuberías, componentes o piezas en líneas de montaje, corriente en redes eléctricas, paquetes de
información en redes de comunicaciones, tráfico ferroviario, sistema de regadíos, etc.
(Villalobos, 2006).
1.2.6 Problema de transporte
Consideremos que debemos transportar un único producto homogéneo desde m orígenes o
puntos de embarque hasta n destinos que pueden ser almacenes o fábricas.
Denotemos por a1,…, am las ofertas o cantidades del producto disponible en cada origen y por
b1,…, bn las demandas o necesidades existentes en los n destinos.
Es posible transportar dicho producto desde cualquier origen hasta cualquier destino siendo c ij
el costo de transportación de una unidad del producto desde el origen i hasta el destino j.
Nuestro objetivo será determinar las cantidades del producto que deberán ser enviadas desde
cada origen hasta cada destino, de tal manera que se satisfagan las demandas de los destinos,
respetando las ofertas de los orígenes y que el costo total de transportación sea mínimo
(Valdés et al., 1978).
Figura 1.10 Representación visual del problema de transporte.
El problema de transporte es un caso especial del problema de flujo costo mínimo donde el
grafo es completo y además existen m nodos fuente y n nodos sumidero. El ejemplo anterior
representa una instancia del problema con 3 orígenes y 2 destinos, como puede observarse la
representación del modelo se corresponde con un grafo bipartido ya que las aristas sólo van
del conjunto de nodos oferta al conjunto de nodos demanda. Las cantidades de oferta y
demanda se visualizan sobre los correspondientes vértices. Los costos de transportación se
especifican sobre las aristas. Si por algún motivo no se permite transportar el producto de un
nodo oferta i a un nodo demanda j se considera el costo cij como infinito. Usualmente es más
cómodo representar un problema de transporte mediante una tabla, la figura 3.9 muestra como
luce una tabla de transporte.
Un modelo de transporte se considera balanceado si la suma total de las ofertas coincide con la
suma total de las demandas, o sea:
∑∑n
1=j
m
1=i
= ji ba
Volviendo al ejemplo anterior puede observarse que el sistema está efectivamente balanceado.
Es importante que el criterio de balance se cumpla para poder aplicar los métodos de
resolución conocidos. Se asume que el sistema siempre está balanceado y que los valores ai y
bj son no negativos como ocurre en la mayoría de las aplicaciones. Matemáticamente el
modelo de transporte puede escribirse como (Valdés et al., 1978):
∑∑m
1=i
n
1=jijc ijxMin
Zxx
miax
njbx
as
ijij
iij
jij
∈,0≥
..1=,=
..1=,=
..
∑
∑n
1=j
m
1=i
El modelo anteriormente planeado es de Programación Lineal por las siguientes razones
(Valdés et al., 1978):
- Las restricciones son lineales.- Las variables del problema cumplen con la restricción de no negatividad.- La función objetivo que representa el costo total de transportación es lineal.
El problema de transporte se resuelve mediante el método simplex de transporte, una
adaptación del método general simplex que aprovecha las características especiales del
modelo de transporte. Lo primero que debe hacerse es hallar una solución inicial o solución
básica factible (SBF). El siguiente teorema establece el número de variables básicas ijx > 0
que deberá tener esta SBF.
Teorema: Un problema de transporte siempre tiene solución, pero hay exactamente una
restricción de igualdad redundante. Cuando se elimina cualquier restricción de igualdad, el
sistema restante de n+m-1 restricciones de igualdad es linealmente independiente (Ahuja et al.,
1993).
A continuación se describe un procedimiento general para construir una solución inicial BF
(Ayuso, 2007).
Al iniciar, todos los renglones de los orígenes y las columnas de destinos de la tabla simplex
de transporte se toman en cuenta para proporcionar una variable básica (asignar a esta variable
un valor positivo).
1) Se selecciona la siguiente variable básica (asignación) entre los renglones y columnas
en que todavía se puede hacer una asignación de acuerdo a algún criterio.
2) Se hace una asignación lo suficientemente grande como para que use el resto de los
recursos en ese renglón o la demanda restante en esa columna (cualquiera que sea la
cantidad más pequeña).3) Se elimina ese renglón o columna (la que tenía la cantidad más pequeña en los recursos
o demandas restantes) para las nuevas asignaciones. (Si el renglón y la columna tienen
la misma cantidad de recursos y demanda restantes, entonces arbitrariamente se
elimina el renglón. La columna se usará después para proporcionar una variable básica
degenerada, es decir, una asignación con 0 unidades encerradas en un círculo.)4) Si sólo queda un renglón o un columna dentro de las posibilidades, entonces el
procedimiento termina eligiendo como básicas cada una de las variables restantes (es
decir, aquellas variables que no se han elegido ni se han eliminado al quitar su renglón
o columna) asociadas con ese renglón o columna que tiene la única asignación posible.
De otra manera se regresa al paso 1.
Existen varios métodos para hallar una SBF, el más sencillo de todos se denomina regla de la
esquina noroeste, pues en cada paso se selecciona la celda de la esquina superior izquierda de
la submatriz formada por los requerimientos de fila y columna distintos de cero(Ahuja et al.,
1993).
Al resolver cualquier problema de programación lineal debemos en general esperar que el
número total de iteraciones requeridas dependa de lo próximo que se encuentre el valor de la
función objetivo en la solución posible inicial del mínimo real. Como el método de la
esquina noroeste no considera los coeficientes cij no podemos esperar que el valor de la
función objetivo en una solución inicial por el método de la esquina noroeste se acerque al
mínimo (Valdés et al., 1978).
Los métodos de Russell, Voguel o Mínimo por filas sí toman en cuenta los valores cij para
hallar una solución básica factible. Estos métodos brindan una solución inicial mejor que la
del método de la esquina noroeste aunque son un poco más complejos que este.
Los métodos anteriormente explicados se caracterizan por:
1) La suma de las variables básicas que aparecen en una fila i es igual al valor ai (oferta
correspondiente al origen i)
2) La suma de las variables básicas que aparecen en una columna j es igual al valor bj
(demanda correspondiente al destino j).
3) A lo sumo hay m+n-1 variables básicas ya que cuando colocamos una variable básica en un
escaque (i, j) entonces no es posible colocar simultáneamente más variables básicas en la fila y
columna correspondiente a dicho escaque.
Estas tres propiedades hacen que la solución obtenida sea básica y factible (Valdés et al.,
1978).
Luego de encontrar la SBF es posible aplicar los conceptos válidos para el método simplex al
problema de transporte. Así, la segunda parte del algoritmo modifica la distribución inicial
iterativamente hasta encontrar la distribución óptima que minimiza el costo total.
1.2.7 Flujo de costo mínimo
Sea G un grafo dirigido, en el cual seleccionamos un vértice fuente S y un sumidero T.
Denotamos el conjunto de vértices por V y denotamos el conjunto de aristas por E. Cada arista
(i, j) ∈ E posee una capacidad uij ≥ 0 y un costo por unidad de flujo c ij. Si una arista (i, j) no
existe en el grafo entonces asumimos que uij = cij = 0. El flujo en la red G es una función real F
que asigna a cada par de vértices (i, j) un flujo fij entre ellos y satisface las tres condiciones:
Restricciones de capacidad, (para todo i, j ∈ V): fij ≤ uij
Antisimetría, (para todo i, j ∈ V): fij = -fji
Conservación de flujo, (válido para todo i, j ∈ V excepto i = S e i = T):∑
V∈ jijf
=
0
El flujo es la cantidad:
|f| =∑
V∈ iSif
Se traduce como la sumatoria de los flujos que parten del vértice fuente S. El coste del patrón
de flujo viene dado por (Ahuja et al., 1993):
Z (f) = ∑
V∈ j i,ijijfc
Dado el valor K de flujo requerido se necesita encontrar un flujo |f| de esa magnitud (K = |f|)
que minimice el total de costos Z (f).
Figura 1.11 Ejemplo de red para el problema de flujo de costo mínimo.
Para tener una idea aproximada de cómo luce el modelo fijémonos en la imagen anterior. Se
han resaltado los vértices fuente y destino. Sobre los arcos pueden observarse dos valores, el
primero de ellos es la capacidad de flujo que permite, el segundo es el costo por unidad de
flujo a transportar. El valor de flujo en esta red es cero (|f| = 0).
El caso más simple de este problema ocurre cuando el grafo es orientado, y entre cada par de
vértices hay cuando más una arista, (si existe la arista (i, j), entonces la arista (j, i) no puede
existir).
Sea fij el valor de flujo a través de la arista (i, j), inicialmente igual a cero. Se modifica la red
de la siguiente manera: por cada arista (i, j) adicionamos una arista en reversa (j, i) con
capacidad uij=0 y costo cij = -cij.
Por la suposición, las aristas (j, i) no estaban antes en la red, entonces luego de modificada la
red todavía no será un grafo múltiple. Además, desde el principio hasta el fin el algoritmo
mantendrá la condición verdadera: fij=-fij.
La red residual R(f) correspondiente a un flujo f se define como sigue: la red residual
considera sólo los arcos con capacidad positiva (en los cuales fij < uij), la capacidad residual de
cada una de estas aristas es rij = uij-fij. El tratamiento es muy parecido al problema del flujo
máximo de la sección anterior.
El algoritmo de los caminos mínimos sucesivos busca el flujo máximo y optimiza la función
objetivo Z(f) simultáneamente (Greenberg, 1998). En cada iteración el algoritmo encuentra el
camino de costo mínimo de S a T en la red residual. Si el camino no se encuentra el algoritmo
termina. En otro caso encontramos la capacidad residual mínima δ entre las aristas del camino
e incrementamos el flujo actual sumándole δ. Luego modificamos la red incrementando el
flujo en cada arista del camino en un valor de δ y reduciendo la misma cantidad en las aristas
en reversa.
El algoritmo se detiene cuando el flujo actual alcanza el valor K de flujo requerido cuando los
pesos de todas las aristas son idénticos el modelo es equivalente al problema encontrar el flujo
máximo. Si establecemos K igual a infinito el algoritmo encuentra un flujo máximo de
mínimo costo, o sea, el algoritmo sin modificaciones resuelve ambos problemas (Ahuja et al.,
1993).
El algoritmo de los caminos mínimos sucesivos puede ser usado cuando G no contiene ciclos
de costo negativo (Greenberg, 1998). Debe probarse que un ciclo de este tipo no aparece en el
transcurso del algoritmo. Cuando el flujo actual tiene valor 0 la red G no contiene ciclos de
costo negativo por hipótesis. Supóngase que luego de algunas iteraciones tenemos un flujo
actual de x y Gx aún no contiene ciclos negativos. Se denotan los caminos próximos
encontrados satisfactoriamente en Gx por P.
Figura 1.12 ¿Cómo podría aparecer un ciclo negativo en una red residual?
Supóngase que después de aumentar el flujo actual x a través del camino P aparece un ciclo W
de costo negativo en la red residual. Antes de las modificaciones no había ciclos negativos.
Esto significa que había una arco (i, j) en P (o un subcamino (i,…, j) en P) cuyo arco reverso
(j, i) cerró el ciclo W después del aumento de flujo. Sin embargo se podía escoger otra ruta de
S a T, que fuera de S a i, luego de i a j a través de las aristas de W y por último de j a T. El
costo de este nuevo camino es menor que el costo de P. Surge una contradicción en la
suposición de que P es el mínimo (Greenberg, 1998). En conclusión, se descarta la posibilidad
de que aparezca un ciclo de costo negativo en el grafo.
Existen otras vías para encontrar el flujo de costo mínimo, podemos citar el algoritmo de
cancelación de ciclos y el método simplex de redes (Ayuso, 2007). Por comodidad hemos
escogido para nuestra aplicación el algoritmo expuesto en la página anterior por su similitud
con el método de Edmonds-Karp usado en el problema de flujo máximo. Para la tarea de
encontrar un camino mínimo con pesos negativos usamos el algoritmo de Bellman-Ford
estudiado en la asignatura Estructura de Datos.
El problema de flujo de costo mínimo es muy abarcador. Tareas de optimización como la
asignación, el transporte, el trasbordo y la ruta más corta, se ajustan al formato de este
problema (Ayuso, 2007).
Entre las aplicaciones del flujo máximo de costo mínimo se puede encontrar el
direccionamiento de la acción del ferrocarril y el enrutamiento de aviones de carga vacíos
(Schrijver, 2000).
1.3 Conclusiones parciales
En este capítulo se hizo un estudio de la teoría de los principales métodos que se estudian en
las asignaturas Modelos de Optimización e Investigación de Operaciones. Se hizo un estudio
de cómo sería mejor el agrupamiento de los mismos para el diseño de la interfaz quedando de
la siguiente forma:
- El método Simplex aparece independiente de los demás métodos puesto que resuelve
el problema asociado al modelo estándar de la programación lineal.
- En optimización de redes se agruparon los algoritmos árbol de recubrimiento mínimo,
camino mínimo desde una fuente, y los métodos de flujo; en esta última categoría se
ubican el algoritmo de flujo máximo y el de flujo de costo mínimo.
- En otros métodos se ubicaron el algoritmo de transporte y el de asignación.
CAPÍTULO 2. Implementación de SimIO, software educativo paraInvestigación de Operaciones.
En este capítulo se hace una breve descripción sobre los aspectos a tomar en cuenta para lograr
la correcta visualización de una ejecución paso a paso. Se describen algunos elementos de la
ingeniería de software de la aplicación y se exponen los elementos más interesantes utilizados
para la implementación de la misma.
2.1 Detalles de una ejecución paso a paso
Todos los algoritmos de programación lineal estudiados e implementados son iterativos. A
partir de una configuración inicial factible van optimizando en cada iteración el valor de la
solución actual. El algoritmo de flujo máximo, por ejemplo, parte de un flujo inicial igual a
cero y en cada iteración añade más flujo maximizando la función objetivo. El método de
transporte, por su parte, identifica una solución básica factible y luego, en cada iteración del
paso 2 localiza una variable no básica que entra a formar parte de la solución actual y una
variable básica que sale de esta optimizando también la función objetivo.
Entonces, ¿en qué consiste un paso? Un paso es el equivalente a una iteración. Moverse un
paso atrás o adelante es lo mismo que ir a la iteración anterior o posterior del método
escogido. Lo que cambia para cada método es el conjunto de elementos que se visualizan. Por
ejemplo, la interfaz del Árbol de recubrimiento muestra un grafo con las aristas que se van
añadiendo, la interfaz del simplex, en cambio, muestra una tabla con la función objetivo y
demás componentes que necesita el usuario para comprender lo que va sucediendo en el
transcurso de este método.
Entonces es preciso identificar para cada método los elementos que el usuario necesita
observar por pantalla. Luego, necesitamos encontrar una vía eficiente, desde el punto de vista
de la implementación, de guardar esos elementos y poder acceder a ellos cuando el usuario así
lo pida. Supongamos que el método actual consta de n pasos o iteraciones. Es posible, para
cada iteración, guardar el estado de los elementos a visualizar. Si el elemento a visualizar es,
digamos, una tabla, entonces el estado a guardar es el conjunto de los valores presentes en esa
tabla, si el elemento es un grafo, entonces se guardan los vértices y las aristas que posea el
grafo en la iteración actual. El resultado es que por cada elemento se tiene un arreglo de
tamaño n, donde n es la cantidad de iteraciones del método. En cada posición del arreglo se
guarda el estado del elemento en la iteración actual. A la hora de visualizar el elemento una
variable de control nos indica la iteración actual y funciona como un índice dentro del arreglo
de estados. Cuando el usuario solicita moverse un paso adelante la variable de control aumenta
su valor en uno, entonces se extrae de cada arreglo la configuración actual del elemento y se
muestra por pantalla. Los arreglos de estados se crean y completan cuando el usuario ordena
ejecutar el método al finalizar la entrada de datos.
En el siguiente ejemplo se observa cómo funcionan estos procedimientos desde el punto de
vista del usuario. Se muestra la ejecución paso a paso de una instancia muy sencilla del
problema ARM.
Figura 2.1 Pantalla Inicial de la aplicación.
Se escoge en el menú principal la opción Árbol de recubrimiento mínimo.
Figura 2.2 Pantalla inicial del método ARM.
Se indica la cantidad de vértices del grafo a analizar. La tabla que observamos representa la
matriz de adyacencia del grafo. Los valores en las casillas de la tabla son los pesos de las
aristas que van del vértice fila al vértice columna.
Al presionar el botón “Ejecutar método” se leen los datos de entrada y se ejecuta el algoritmo
de Kruskal. Este algoritmo realiza una iteración por cada arista que posea el grafo, (3 en este
caso). En cada iteración se guarda la información que luego se mostrará en la pantalla.
Figura 2.3 Interfaz inicial del método ARM.
Se nos informa que estamos listos para iniciar el método. La tabla que se observa representa la
matriz de adyacencia del árbol de recubrimiento que vamos construyendo.
Figura 2.4 Representación del método ARM en forma de grafo.
Realmente para comprender el funcionamiento de este método es más que suficiente la
representación visual que se observa en la figura anterior. Se incluye la matriz de adyacencia
del ARM sólo para ser consecuentes con la entrada.
Figura 2.5 Paso uno del método ARM.
Se adiciona una arista de peso 2 uniendo el vértice 1 al vértice 3.
Figura 2.6 Paso uno del método ARM en forma de grafo.
El costo actual del ARM es igual a 2.
Figura 2.7 Paso dos del método ARM.
Ahora se unen el vértice 1 y 2, lo que trae consigo que el costo aumente a 6 unidades.
Figura 2.8 Paso dos del método ARM visto en un grafo.
Figura 2.9 Paso final del método ARM.
No se analiza la arista restante puesto que ya el árbol está completo. El costo total es 6.
2.2 Biblioteca JGraphX
MxGraph es una familia de bibliotecas escrita en una variedad de tecnologías, que suministra
herramientas dirigidas a aplicaciones que exhiben diagramas interactivos y gráficos. JGraphX
es la biblioteca para Java Swing de mxGraph.
JGraphX está principalmente diseñado para ser usado en entornos de escritorio. El núcleo de
JGraphX es una biblioteca compilable escrita en Java 5. Esta biblioteca provee la
funcionalidad requerida para describir, exhibir e interactuar con diagramas como parte de una
aplicación de escritorio manteniendo un alto rendimiento. JGraphX permite visualizar
diagramas de procesos, flujos de trabajo, tráfico, circulación de líquidos, esquemas de bases de
datos, diagramas UML, circuitos electrónicos entre otros.
En la aplicación propuesta esta biblioteca ha sido usada solamente para representar grafos. De
acuerdo con el manual de usuario de JGraphX existen tres operaciones básicas fundamentales
que deben dominarse para poder trabajar con dichos grafos:
1- Insertar un vértice:
mxGraph.insertVertex(padre, id, valor, x, y, ancho, altura, estilo)
padre: El padre inmediato del nuevo componente en la estructura. Se usa el padre por defecto
graph.getDefaultParent()en todas las operaciones.
id: Es un identificador global que referencia al componente, siempre es una cadena. Si se le
pasa null a este parámetro el propio modelo se encarga de manejar los ids asegurando que
estos sean únicos.
valor: Es un objeto que describe lógicamente al componente en cuestión. Se usa siempre una
cadena que se visualiza como una etiqueta dentro del vértice.
x, y, ancho, altura: La posición x, y de la esquina superior izquierda del vértice y el tamaño del
vértice.
estilo: Una cadena con la descripción del estilo que tomará el componente. Permite, entre otras
cosas, otorgar a los vértices formas rectangulares, triangulares o elipsoidales.
2- Insertar una arista
mxGraph.insertEdge(padre, id, valor, fuente, destino, estilo)
fuente, destino: Los vértices a los cuales está conectada la arista
Los demás parámetros son idénticos a los anteriores. Aquí es importante hacer notar que los
vértices fuente y destino deben haberse insertado con anterioridad en el modelo.
3- Eliminar una arista
mxGraph.getModel().remove(arista)
El pequeño ejemplo a continuación ilustra el uso de estas operaciones básicas. Las llamadas
beginUpdate() y endUpdate() notifican el comienzo y el final de un bloque de instrucciones
que modifican el modelo. Al finalizar el bloque se realizan inmediatamente los cambios
requeridos. El uso de esta estructura es una práctica de programación no obligatoria pero sí
recomendada que se siguió al pie de la letra.
graph.getModel().beginUpdate();
try {
Object v=graph.insertVertex(graph.getDefaultParent(),null,"Hola",20,20,80,30);
Object w =graph.insertVertex(graph.getDefaultParent(),null,"Mundo",140,100,80, 30);
Object a=graph.insertEdge(graph.getDefaultParent(),null,"Arista",v1,v2);
}
finally {
graph.getModel().endUpdate();
}
La salida del programa con las declaraciones previas y posteriores debidas es:
Figura 1.10 Ejemplo del uso de la biblioteca.
Si ahora añadiéramos al programa la instrucción graph.getModel().remove(a) justo
después de insertar la arista a se vería algo como:
Figura 1.11 Ejemplo de eliminar la arista.
En el ejemplo anterior definimos estáticamente las coordenadas de los vértices insertados. En
programas más complejos con cantidades de componentes que varían dinámicamente puede
resultar dificultoso para el programador posicionar todos los elementos a visualizar. Es por eso
que JGraphX proporciona layouts que estructuran la información a conveniencia del
programador. Más adelante se abordará esta cuestión.
2.3 Diagrama de clases, casos de uso y actividades
En este epígrafe se describen y exponen una serie de diagramas básicos de la ingeniería de
software que ayudan a la confección de la aplicación.
2.3.1 Diagrama de casos de uso
El diagrama de casos de uso sólo posee un usuario: el estudiante de Investigación de
Operaciones o Modelos de Optimización. Profesores de estas asignaturas o demás personas
interesadas en las mismas también se incluyen en esta categoría.
El caso de uso genérico “Ejecutar algoritmos de optimización paso a paso” engloba a los
demás casos específicos de cada método.
Figura 2.12 Ejemplo de caso de uso.
2.3.2 Diagrama de actividades
El diagrama de actividades que se muestra a continuación se corresponde al hecho de ejecutar
el algoritmo del ARM. La entrada de datos puede hacerse por dos vías. La ejecución del
método no empieza mientras exista algún error en los datos de entrada.
Figura 2.13 Diagrama de actividades del algoritmo ARM.
2.3.3 Diagrama de clases
A continuación se muestra el diagrama de clases de la aplicación. Es importante señalar que no
todas las clases están incluidas en este diagrama, sólo las más importantes. Además, en estas
clases sólo se señalan los métodos y atributos principales.
Figura 2.14 Diagrama de clases.
2.4 Paquete de métodos
Este paquete esta encargado de agrupar las clases que manejan la lógica de todos los métodos
implementados. A continuación se hace una breve descripción de las clases mostradas en la
figura 2.14.
Clase Árbol de recubrimiento
Esta clase implementa la búsqueda del árbol de recubrimiento mínimo. Para ello se apoya en
las clases Arista y Conjuntos_Disjuntos. Se relaciona además con la clase
Pinta_Grafo_Circular a la hora de visualizar paso a paso los resultados de la ejecución del
algoritmo. Sus principales métodos son:
- ARM() {…}: Es el método principal de la clase y se encarga de encontrar el árbol de
recubrimiento mínimo. Además guarda los resultados de cada iteración para que
puedan ser visualizados más tarde.- esConexo(){…}: Permite saber si el grafo que se analiza cumple la propiedad de
conectividad.
Clase Camino Mínimo
La implementación del algoritmo de búsqueda de caminos mínimos (algoritmo de Dijkstra)
puede encontrarse en esta clase. Más exactamente en el método:
- dijkstra(int origen) {…}: Aquí origen se refiere, evidentemente, al nodo desde el cual
se inicia la búsqueda. Otros métodos de esta clase no son relevantes.
Clase Flujo Máximo
Esta clase resuelve la lógica del algoritmo de flujo máximo descrito con anterioridad. Esto se
hace en el método:
- Edmonds_Karp(int s, int t) {…}: Los parámetros s y t referencian al vértice fuente y
sumidero respectivamente.
Clase FCM
Encuentra el flujo de costo mínimo en una red dada. Métodos importantes en esta clase son:
- Bellman_Ford(){…}: En este método se implementa el algoritmo de Bellman y Ford
para hallar los caminos mínimos con aristas de costo negativo. En este caso no es
necesario controlar la aparición de ciclos de costo negativo puesto que ya ha sido
probado que esto no sucede nunca para este tipo de problemas.
- fcm(int flujoRequerido, int s, int t) {…}: El método fcm() llama repetidamente a
bellman_ford() y en cada llamada aumenta el flujo por la trayectoria de s a t que este le
indica. El valor de flujoRequerido es la condición de parada del bucle. Si el
flujoRequerido se fija en infinito el algoritmo se detendrá cuando no pueda encontrarse
un camino de aumento en la red residual.
Clase Asignación
Esta clase resuelve el algoritmo de asignación con un costo computacional igual a O(n 4). Sus
principales métodos son:
- asignar(){…}: Realiza el procedimiento de asignación devolviendo el costo total de la
asignación mínima resultante.- traspuesta(int[][] matriz) {…}:Halla la traspuesta de una matriz dada, esto es necesario
para el desenvolvimiento interno del algoritmo de asignación.
Clase Transporte
- es_solucion_degenerada(){…}: Nos informa si la solución actual es degenerada o no.
- esquinaNoroeste( ) {…}: Encuentra una solución básica factible usando la regla de la
esquina noroeste.
- costoMinimoPorFilas( ) {…}: Encuentra una SBF por la regla del mínimo por filas.
- Voguel( ) {…}: Encuentra una SBF por el método de Voguel.
- Russell ( ) {…}: Encuentra una SBF por el método de Russell.
- hallar_variable_entrante( ){…}: Encuentra la variable no básica que se añadirá a la
nueva solución.
- Balancear( ){…}: Modifica la tabla de transporte sustituyendo una de las variables de
la solución actual (básica) por otra (no básica) con mejor desempeño a la hora de
minimizar (o maximizar) la función objetivo.
Clase Simplex
- hallarVBEntrante(){…}: Encuentra la variable que pasa de no básica a básica.
- hallarVBSaliente(){…}: Encuentra la variable básica que sale de la solución.
- modificarTabla(){…}: Modifica la tabla simplex y por ende la solución actual.
Clase Metodo_Optimizacion
Clase genérica que contiene métodos y atributos comunes a las demás clases lógicas
- contador: Atributo que permite controlar el proceso de visualización proporcionando
un índice que apunta a la iteración actual del método en cuestión.
2.5 Paquete útil.
En este paquete están agrupadas las clases accesorias que facilitan métodos auxiliares a las
clases que desarrollan la lógica del sistema. Además contiene la clase visual del sistema.
Clase Racional
Implementa los métodos necesarios para trabajar con números racionales puesto que Java no
proporciona este tipo de facilidades. Algunos de sus métodos son:
- reducir_racional(Racional r) {…}:Reduce el numerador y el denominador de r a su
mínima expresión.- add() {…}, sub() {…}, mul() {…}, div() {…}, negate(){…}: Implementan
respectivamente la suma, resta, multiplicación, división e inverso de racionales.
Clase Arista
Provee un objeto arista que puede ser utilizado por las clases Arbol_Recubrimiento y
Camino_Minimo.
Clase Conjuntos Disjuntos
Proporciona la implementación de la estructura de datos Conjuntos Disjuntos necesaria para el
algoritmo que busca el Árbol de recubrimiento mínimo. Métodos principales:
- buscar(int x) {…}: Nos informa a que conjunto pertenece x.- unir(int x, int y) {…}: Une el conjunto representado por x con el conjunto representado
por y.
Clase Pinta_grafo_circular
La clase Pinta_grafo_circular se relaciona directamente con la biblioteca JGraphX explicada
con anterioridad. Esta clase asocia un contexto o problema real modelado con conceptos de
teoría de grafos con la representación visual correspondiente usando componentes que pueden
ser vértices o aristas. Luego de posicionar mediante el uso de layouts las aristas y los vértices
del grafo dado esta clase permite observar paso a paso el desenvolvimiento del algoritmo de
búsqueda del árbol de recubrimiento mínimo en dicho grafo.
Un layout en JGraph es una determinada disposición de los componentes del grafo que se
visualiza. JGraph proporciona algoritmos de layouting que distribuyen los componentes de
manera jerárquica, ortogonal, formando árboles o simplemente colocando los componentes
uno al lado del otro. En este caso específico se distribuyen los vértices formando un polígono
regular tamaño n, donde n es la cantidad de vértices, esto se conoce como layout circular.
Figura 2.15 Layout circular para n = 6.
Las ventajas de este tipo de distribución son la sencillez del código por parte del programador
y la uniformidad del modelo a visualizar por parte del usuario.
La clase Pinta_grafo_circular consta de los siguientes métodos:
- adicionar_arista(int v, int w, int peso) {…}: Adiciona una arista.- eliminar_arista(int v, int w) {…}: Elimina una arista.- insertar_aristas(int[][] arm) {…}: Adiciona muchas aristas de una sola vez.
Clase Entrada_Salida
Proporciona en su mayoría métodos que facilitan el trabajo de entrada y salida mediante tablas
en nuestra aplicación además del método
- esNumero(String k) {…}: que nos informa si k es un número válido. Este método se usa
en el tratamiento de excepciones de la aplicación.
Clase Menu principal
Se encarga de manejar los componentes visuales del sistema. Se asocia con las clases del
paquete Métodos.
2.6 Uso del lenguaje de programación Java
Uno de los lenguajes más utilizados en la actualidad por sus amplias potencialidades y su buen
desempeño es Java. En cualquier manual de Introducción a Java pueden encontrarse una serie
de características que explican por qué es una excelente opción escogerlo como lenguaje para
la aplicación propuesta:
- Simple: Java ofrece toda la funcionalidad de un lenguaje potente, pero sin las
características menos usadas y más confusas de éstos.
- Orientado a Objetos: Soporta las características fundamentales del paradigma, todo en
Java es clase u objeto.
- Robusto: Java realiza verificaciones en busca de problemas tanto en tiempo de
compilación como en tiempo de ejecución.
- Arquitectura neutral: El compilador Java compila su código a un fichero objeto de
formato independiente de la arquitectura de la máquina en que se ejecutará. Cualquier
máquina que tenga el sistema de ejecución (run-time) puede ejecutar ese código objeto,
sin importar en modo alguno la máquina en que ha sido generado.
- Portable: Los tipos de datos se implementan siempre de igual forma. El sistema de
ventana sirve en cualquier Sistema Operativo.
- Interpretado: Se necesita la máquina virtual para poder correr los programas.
- Multihilo: Java permite muchas actividades simultáneas en un programa.
- Dinámico: Java se beneficia todo lo posible de la tecnología orientada a objetos. Java
no intenta conectar todos los módulos que comprenden una aplicación hasta el tiempo
de ejecución.
2.7 Conclusiones parciales
En este capítulo se implementó una aplicación que es capaz de mostrar paso a paso la
ejecución de una serie de algoritmos de optimización usando el lenguaje de programación Java
y la biblioteca JGraphX escrita en ese lenguaje. Se expuso también un conjunto de diagramas
relativos a la ingeniería de software de la aplicación creada. Por último se describieron los
principales métodos implementados por cada uno de los algoritmos desarrollados.
CAPÍTULO 3. Caracterización del software SimIO
En este capítulo de realiza una breve caracterización de la aplicación y se explican los
fundamentos y conocimientos básicos necesarios para trabajar con ella.
3.1 Características del software
El software SimIO posee una interfaz visual muy sencilla. Los menús están divididos de
acuerdo a los distintos temas. Se ha tratado de que las entradas de los métodos mantengan un
criterio de uniformidad. Esto se logra mediante el uso de tablas que representan ya sea una
matriz de adyacencia (para grafos), una matriz de costos (para transporte y asignación), o
sencillamente una tabla para el método simplex. Todo esto permite la rápida familiarización
del usuario con la herramienta.
Aunque el software está específicamente diseñado para estudiantes que cursan las asignaturas
de Investigación de Operaciones y Modelos de Optimización no significa que no pueda ser
utilizado por otros usuarios interesados en la materia. Incluso pueden solucionarse en él
problemas de la vida real cuyos modelos se correspondan con los métodos que el software
implementa, siempre tomando en cuenta que éste no es un software de propósito general así
que las instancias de los problemas a solucionar no deben ser muy grandes. Si no es necesario
visualizar paso a paso la construcción de la solución, la aplicación, por la manera en que está
diseñada, nos permite llegar rápidamente al resultado final, (esto se cumple para todos los
métodos implementados).
Este es un software que no necesita instalación. Para ser utilizado es necesario que se cumplan
los siguientes requisitos mínimos:
•Sistema Operativo Windows XP o superior.
• Máquina Virtual de Java instalada.
3.2 Trabajo con la aplicación
Desde la vista principal de la aplicación que fue mostrada en el capítulo anterior puede
accederse a cada uno de los métodos implementados.
Figura 3.1 Pantalla inicial para el método Simplex.
En esta ventana se realiza la entrada de los datos necesaria para ejecutar el método Simplex.
Luego de establecer la cantidad de variables y restricciones el usuario procede a llenar la tabla
simplex. La primera fila de la tabla corresponde a la función objetivo del problema, las demás
representan las restricciones del mismo.
Figura 3.2 Ventana inicial de ejecución paso a paso para el método simplex.
En la imagen anterior se muestra la ventana de ejecución para el método simplex. La tabla que
se observa es muy parecida a la anterior sólo que se han añadido variables de holgura. La
primera columna corresponde a la variable básica de cada ecuación. Mediante el uso de los
botones en la parte inferior de la ventana se realiza el proceso de visualización paso a paso a
través de la solución del ejercicio planteado. En la parte superior de la ventana se explica al
usuario lo que va sucediendo en cada paso y además se muestra alguna información útil como
el valor de la solución actual.
Figura 3.3 Ventana de entrada de datos para el algoritmo Caminos mínimos desde una fuente.
Arriba se muestra la entrada del método de caminos mínimos desde una fuente. Además de la
cantidad de vértices se le pide al usuario que establezca un nodo origen a partir del cual
calcular las distancias mínimas. Cada celda Cij de la tabla representa la distancia del camino
que va desde i a j de existir tal camino. Nótese que en la diagonal principal no se permite la
entrada de valores puesto que en este problema no tienen sentido las aristas que van de un
vértice a él mismo.
Figura 3.4 Ventana intermedia de la ejecución del algoritmo Dijkstra.
Al ejecutar el método se muestra una ventana con tres tablas unidimensionales. La primera de
ellas representa los vértices actualmente marcados; la segunda, la distancia actual del origen a
cada uno de los demás vértices, el signo infinito en el vértice j nos indica que la distancia hasta
j aún no ha sido analizada; la tercera tabla especifica el vértice anterior en el camino actual
hasta cada vértice, el signo “-” en el vértice origen nos indica que este no posee anteriores. Si
al finalizar la ejecución algún vértice en la tabla 2 mantiene el signo “ ” entonces ese
vértice es inalcanzable.
Figura 3.5 Ventana inicial para el algoritmo Flujo Máximo.
La imagen que se muestra arriba es la entrada para el método de flujo máximo. El flujo se
mueve del vértice señalado como fuente al vértice sumidero. Cada celda Cij de la tabla
representa la capacidad de flujo que permite la arista i-j.
Figura 3.6 Paso intermedio del algoritmo Flujo Máximo.
Esta ventana muestra la ejecución paso a paso del método actual. En la parte superior se
muestra el camino de aumento hallado en la iteración actual, así como el flujo que se aumenta
a través de ese camino y el valor total de flujo alcanzado hasta el momento. En cada celda C ij
de la tabla que se observa hay dos valores (f, c) separados por el signo “/”. El valor de la
derecha (c) representa la capacidad de flujo que permite la arista. Este número es el mismo
que el usuario introdujo por parámetros en la ventana anterior y no cambia nunca en el
transcurso del método. El otro valor (f) es el flujo actual que pasa por la arista i-j. Cuando f es
negativo no significa que por la arista i-j está pasando un flujo negativo sino que en el futuro
podemos cancelar o retirar flujo de la arista j-i. Esto es reflejo de la propiedad de conservación
de flujo que debe mantenerse siempre en este tipo de problemas.
Figura 3.7 Ventana principal para el algoritmo Flujo de costo mínimo.
La entrada de los datos para calcular el flujo de costo mínimo es muy similar a la del problema
anterior. En la parte superior se añade un campo de entrada que es la cantidad de flujo que
requerimos pasar de la fuente al sumidero. La tabla de la izquierda coincide con la matriz de
flujo permitido por cada arista del problema anterior. Además se ha adicionado otra tabla que
representa el costo de pasar una unidad de flujo por la arista. Estos costos iniciales deben ser
positivos. Las tablas deben tener aristas equivalentes, o sea, si existe el valor de flujo
permitido en una celda de la primera tabla debe existir el costo en la correspondiente celda de
la segunda tabla.
Figura 3.8 Ventana intermedia para el algoritmo de Flujo Máximo.
La interfaz de ejecución del método FCM es también parecida a la anterior. Ahora la tabla
representa la red residual que va modificándose en el transcurso del método. En cada casilla
puede observarse la capacidad residual de la arista a la izquierda y el costo actual de enviar
una unidad de flujo por esa arista a la derecha. El costo puede ser positivo, negativo o infinito.
Un valor de costo infinito significa que la arista es inexistente y un valor negativo significa
que podemos cancelar flujo en la arista en reversa reduciendo el costo actual. Al igual que para
los demás métodos los botones en la parte inferior permiten controlar la ejecución del
algoritmo. En la parte superior se observa el camino de aumento, flujo y costo mínimo actual.
Figura 3.9 Ventana inicial del método de Transporte.
En la figura anterior se muestra la interfaz para el algoritmo de transporte. Debemos establecer
la cantidad de oferta y demanda, también el método por el cual se hallará la solución básica
factible. Debajo se observa la tabla de transporte. Las demandas se completan en la última fila,
las ofertas en la última columna de la tabla. Los demás valores son los costos Cij de transportar
una unidad de producto del origen i al destino j.
Figura 3.10 Tabla de búsqueda de una SBF para el método simplex de transporte.
Ahora se muestra la interfaz de búsqueda de una solución factible inicial. Las variables que
queden con un signo “-” serán no básicas, las demás pertenecerán a la solución inicial. Los
valores de oferta y demanda se hacen cero a medida que se va construyendo la solución.
Figura 3.12 Ventana de entrada de datos para el método de asignación.
En la imagen anterior observamos la entrada para el método de asignación. Los parámetros
filas y columnas se corresponden con la cantidad de personas y actividades respectivamente.
Cada valor en las casillas de la tabla representa el costo de asignar la persona de la fila a la
actividad de la columna.
Figura 3.13 Ventana final para el método de asignación.
Aquí se visualiza la asignación final para el problema de la figura anterior. La cantidad de
asignaciones que se realizan es igual al mínimo entre la cantidad de personas y actividades. El
costo total de la asignación mínima se observa en la parte superior de la ventana.
El método Árbol de recubrimiento mínimo fue analizado en el capítulo anterior por lo tanto no
lo incluiremos en este.
Figura 3.14 Menús de la aplicación.
En la esquina superior izquierda la ventana de entrada de cada método puede observarse la
barra de menús de la figura anterior. Cada menú proporciona al usuario algunas opciones que
pueden resultarle útiles.
En el menú Archivo el usuario puede cargar un fichero con una configuración de entrada
previamente creada. Esto brinda al usuario la facilidad de no tener que entrar por teclado uno a
uno los valores que requiera el problema. Otra opción del menú Archivo es Exportar Fichero,
la cual nos permite salvar la configuración actual de la entrada para reutilizarla
posteriormente. Con estas dos opciones el profesor de la asignatura puede orientar al
estudiante ejercicios de preparación adjuntando a la descripción del ejercicio el
correspondiente fichero de entrada para así hacer menos tedioso el trabajo con la aplicación.
En el menú Método además de las opciones principales (Ejecutar método etc.) existe la opción
de Limpiar valores que establece la configuración de entrada por defecto del método actual.
El menú Ayuda contiene la opción Ayuda donde se aclaran al usuario cuestiones relativas a
cada método. Además posee la opción Acerca de que muestra datos acerca de los
desarrolladores del software.
3.3 Conclusiones parciales
Se hizo una descripción de las características imprescindibles que debe tener una computadora
para poder ejecutar la aplicación propuesta. También en este capítulo se hace una breve
descripción de cómo deben ser ejecutados todos los algoritmos implementados, como especie
de una guía para ayudar a los usuarios de la aplicación a trabajar con la misma.
CONCLUSIONES
Con este trabajo se logró construir una aplicación que permite visualizar de manera progresiva
la construcción de la solución de algunos algoritmos estudiados en las asignaturas Modelos de
Optimización e Investigación de Operaciones. La aplicación posee una interfaz sencilla y
homogénea que hace agradable su uso y fácil su manejo.
Durante el proceso de desarrollo se realizó un análisis de los métodos estudiados en las
asignaturas antes mencionadas profundizando en cuestiones más apegadas a la teoría que
sustenta a estos métodos para lograr correctas implementaciones de los mismos. Además se
amplió la frontera de conocimientos respecto al lenguaje de programación Java, sobre todo
mediante la utilización de bibliotecas que brindan facilidades al programador para representar
los componentes visuales del software.
RECOMENDACIONES
El conjunto de insatisfacciones percibidas al terminar el trabajo se ven reflejadas en las
siguientes recomendaciones:
- Extender el uso de la biblioteca JGraphX para una mejor visualización de los métodos
de flujo implementados en la aplicación.- Añadir al software algoritmos que resuelvan problemas de programación entera como
pueden ser el método de ramas y cotas, el método de Gomory caso puro o el método de
Gomory mixto.- Ampliar el uso del software a otras instituciones donde se estudien las asignaturas de
Investigación de Operaciones o Modelos de Optimización.- Someter a evaluación los resultados del trabajo.
BIBLIOGRAFÍA
AHUJA, R. K., MAGNANTI, T. L. & ORLIN, J. B. 1993. Network flows: theory, algorithms,
and applications.
ALMEIDA CAMPOS, S., FEBLES RODRÍGUEZ, J. P. & BOLAÑOS RUIZ, O. 1997.
Evolución de la enseñanza asistida por computadoras. Educación Médica Superior, 11,
31-38.
AYUSO, M. D. C. H. 2007. Introducción a la programación lineal, UNAM.
BARTELS, R. H. & GOLUB, G. H. 1969. The simplex method of linear programming using
LU decomposition. Communications of the ACM, 12, 266-268.
CABERO, J., SALINAS, J., DUARTE, A. & DOMINGO, J. 2000. Nuevas tecnologías
aplicadas a la educación. Madrid, Síntesis.
CASTILLO, E., CONEJO, A. J., PEDREGAL, P., GARCıA, R. & ALGUACIL, N. 2002.
Formulación y Resolución de Modelos de Programación Matemática en Ingenierıa y
Ciencia.
CORMEN, T. H., LEISERSON, C. E., RIVEST, R. L. & STEIN, C. 2001a. Introduction to
algorithms, MIT press Cambridge.
CORMEN, T. H., LEISERSON, C. E., RIVEST, R. L. & STEIN, C. 2001b. Introduction to
Algorithms, Cambridge , Massachusetts London, England McGraw-Hill Book
Company
CHÁVEZ, M. S. L. E. R. & QUESADA, C. M. R. La simulación computarizada como
herramienta didáctica de amplias posibilidades.
DASGUPTA, S., PAPADIMITRIOU, C. H. & VAZIRANI, U. 2006. Algorithms, McGraw-
Hill, Inc.
DIJKSTRA, E. 1959. A note on two problems in connexion with graphs. Numerische
Mathematik, 1, 269-271.
GREENBERG, H. J. 1998. Ford-fulkerson max flow labeling algorithm. Tersedia di:
http://glossary. computing. society. informs. org/notes/maxflow-FF. pdf [diakses pada
tanggal 4 april 2012].
KUHN, H. 2005. The Hungarian method for the assignment problem. Naval Research
Logistics (NRL), 52, 7-21.
NOCEDAL, J. & WRIGHT, S. J. 2006. Numerical Optimization 2nd.
SCHRIJVER, A. 2000. A course in combinatorial optimization, TU Delft.
STERN, T., LEISERSON, C., RIVEST, R. & STEIN, C. 2005. Design and Analysis of
Algorithms.
VALDÉS, P. F., PITA, A. M., MÉNDEZ, L. G., AYNAT, B. R., COLLAZO, B. C. & RAMOS,
J. 1978. Introducción a la Programación Lineal III, Cuba.
VANDERBEI, R. J. 2001a. Linear programming. Foundations and extensions, International
Series in Operations Research & Management Science, 37.
VANDERBEI, R. J. 2001b. Linear Programming: Foundations and Extensions, USA.
VILLALOBOS, A. R. Grafos: herramienta informática para el aprendizaje y resolución de
problemas reales de teoría de grafos. X Congreso de Ingeniería de Organización,
2006.