Source: http://docplayer.es/5723156-Creacion-de-una-plataforma-informatica-de-secuenciacion-de-tareas-para-pymes.html
Timestamp: 2018-02-19 04:21:31+00:00

Document:
CREACIÓN DE UNA PLATAFORMA INFORMÁTICA DE SECUENCIACIÓN DE TAREAS PARA PYMES - PDF
Download "CREACIÓN DE UNA PLATAFORMA INFORMÁTICA DE SECUENCIACIÓN DE TAREAS PARA PYMES"
1 UNIVERSIDAD PONTIFICIA COMILLAS ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA (ICAI) INGENIERO EN INFORMÁTICA PROYECTO FIN DE CARRERA CREACIÓN DE UNA PLATAFORMA INFORMÁTICA DE SECUENCIACIÓN DE TAREAS PARA PYMES AUTOR: Pedro Antonio Campos López MADRID, Septiembre de 2008
2 Autorizada la entrega del proyecto del alumno: Pedro Antonio Campos López DIRECTOR DEL PROYECTO Fdo.: Fecha: / / Vº Bº del Coordinador de Proyectos David Contreras Bárcena Fdo.: Fecha: / /
3 RESUMEN DEL PROYECTO En este proyecto se aborda la creación de un portal informático donde las PYMES puedan obtener una optimización en la secuenciación de tareas que encuadra la programación a corto plazo de estas empresas. La mayoría de las empresas PYMES no acuden a soluciones informáticas para optimizar sus procesos productivos. Existe una idea generalizada que asocia un alto coste a las soluciones informáticas concretas, limitando el uso de los ordenadores a tareas administrativas y gestión económica. Este proyecto pretende conseguir una solución informática a bajo coste, haciendo posible su uso en sectores productivos de forma masiva. El problema del JSSP (Job-Shop Scheduling Problem) plantea el reto de optimizar el procedimiento para distribuir una cantidad de recursos entre un conjunto de tareas en el menor tiempo posible. En el caso más general se trata de optimizar la secuencia a seguir de los productos a elaborar por las distintas máquinas. El problema del JSSP es un problema del tipo NP, por lo que no existe una solución polinomial conocida para hallar el óptimo en un tiempo finito. Este motivo hace necesario el estudio de algoritmos heurísticos como los genéticos o la búsqueda local para obtener soluciones útiles a los problemas planteados. En el Instituto de Investigación Tecnológica (IIT) del ICAI se formó un grupo de trabajo con el objeto de estudiar los distintos algoritmos heurísticos que pudieran abordar el problema y su posterior programación en un lenguaje informático como C++. Como colofón de este trabajo se pretende crear una plataforma informática que haga accesible la herramienta desde Internet y permita al usuario introducir ejemplos de tamaño reducido obteniendo en formato adecuado resultados gráficos y numéricos. I
4 ABSTRACT This project undertakes the creation of a computer gateway where PYMES can obtain optimization in task sequencing that these companies short term schedule requires. Most of PYMES companies do not use computer solutions to optimize their productive process. There is a common belief that links specific computer solutions to high economic costs, limiting computer use to administrative tasks and economic managing. This project pretends to achieve a low cost computer solution that makes possible its use in productive sector. The problem that JSSP (Job-Shop Scheduling Problem) poses is the challenge of optimizing the procedure of distribution of an amount of resources between a set of tasks in the minimum time possible. In the most general case it is about optimizing the sequence to follow in the products that the different machines make. The problem of JSSP is a NP problem, which means it does not exist a known polinomial solution that allows to find the optimum in a finite time. That is the reason that makes the use of heuristic algorithms like genetics or local search to obtain useful solutions to the problems considered. In the Technological Research Institute (IIT in spanish acronyms) of ICAI, a work group was formed with the purpose of studying the different heuristic algorithms that could undertake the problem and its subsequent programming in a a computer language like C++. The ultimate purpose of this work is to build a computer platform that will make the tool accessible from Internet and will allow the user to introduce small sized examples and obtain graphic and numeric results in an appropiate format. II
5 a Padre y Madre a José Manuel a Mº Nieves a Rafael a Juan Ramón a Mº Carmen a Daniel a Gabriel III
6 Agradecimientos En el ámbito de la Ingeniería Informática, el desarrollo de un Proyecto Fin de Carrera tiene suma importancia. Supone el fin del comienzo de la formación especializada. Enfrentarnos a un problema de Ingeniería real, con el rigor y la madurez adquiridos en la disciplina universitaria, será la tónica diaria de los próximos años. Por ello, quiero dedicar estas primera palabras de agradecimiento a mi director y coordinador de proyecto David Contreras por ofrecerme esta oportunidad, por apoyarme y por exigirme hacerlo bien. A Julián Jiménez, administrador informático en el IIT por su inestimable conocimiento de LINUX así como por su velocidad de orden cósmico manejando la consola de comandos, lo que me solucionó más de un problema. Y por último a Diego, Atilano y J. M. Labernia, un aliento impagable para llegar hasta el fin de la carrera. IV
7 Índice de contenido CAPÍTULO 1. INTRODUCCIÓN...1 CAPÍTULO 2. ÁMBITO DEL PROYECTO Introducción Secuenciación de Tareas Introducción Definición y conceptos básicos del problema Suposiciones practicadas Caracterización de la solución Medidas de bondad de la solución Clasificación de los problemas de secuenciación Representación del JSSP Matricial Diagramas de Gantt Programaciones activas y semiactivas Procedimientos de resolución Introducción Formulación en programación lineal Resolución mediante algoritmos genéticos Búsqueda local: búsqueda tabú y recocido simulado Introducción Representación de soluciones y generación del vecindario Resolución mediante recocido simulado Sectores de aplicación...19 CAPÍTULO 3. METODOLOGÍA Metodología PUD...22 CAPÍTULO 4. IDENTIFICACIÓN DE NECESIDADES Objetivos del sistema...26 V
8 4.2 Alcance del sistema Tipología de los usuarios finales...27 CAPÍTULO 5. ANÁLISIS DE REQUISITOS Modelo conceptual de la aplicación web Casos de uso del sistema Diagramas de casos de uso del sistema Descripción de los casos de uso Modelo de dominio Diagrama de modelo de domino Glosario de clases Interfaz de entrada de datos Lista de requisitos Consideraciones...46 CAPÍTULO 6. DISEÑO DEL SISTEMA Arquitectura del sistema Diagramas de secuencia Definir Plan Ejecutar Planificación Subir planificación Subir Resultado Descargar Planificación Descargar Resultado Análisis Funcional Objetivo Definición del plan de trabajos Validación de restricciones Generación de tablas resultado Generación del diagrama de Gantt asociado a la solución Orientación a objetos Java Aplicaciones Web...63 VI
9 6.6.1 Uso empresarial Ventajas y desventajas de las aplicaciones web Servlets y JSP Servlets Java Estructura Básica de un Servlet Servlets de la aplicación web Planificador.java Jchart.java JSP Ventajas de JSP JSPs de la aplicación iniciotenta.jsp nombresmt.jsp definirplan.jsp resultado.jsp Servidor de Aplicaciones Tomcat de Apache...92 CAPÍTULO 7. PLANIFICACIÓN...94 CAPÍTULO 8. PRESUPUESTO...95 CAPÍTULO 9. CONCLUSIONES Y LÍNEAS FUTURAS...96 BIBLIOGRAFÍA...98 ANEXOS...99 VII
11 CAPÍTULO 1. INTRODUCCIÓN Este proyecto nace con la vocación de crear una plataforma informática accesible mediante Internet para que la pequeña y mediana empresaria (PYMES) pueda optimizar su trabajo diario. Para abordar el problema, el Instituto de Investigación Tecnológica (IIT) del ICAI creó un grupo de trabajo con el encargo de estudiar en el ámbito de la programación a corto plazo, cuáles eran los algoritmos más apropiados para optimizar en el mayor grado posible la secuenciación de tareas. En este paso se pretende crear la plataforma informática que recoja los frutos de dichos estudios. El PFC de Beatriz Pacheco y el DEA del doctorado de Santiago López de Haro son el principio en este grupo de trabajo, lo que supone el origen de este proyecto. Cada horizonte de planificación en el mundo laboral tiene su propia metodología de trabajo. Se clasifica según el espectro temporal que abarque. Existe la Planificación de Capacidad de muy largo plazo (3-10 años) donde se toman decisiones que conciernen al tamaño de las instalaciones o a la adquisición de equipo. En la Planificación Agregada de largo plazo (1-2 años) se decide sobre la subcontratación, necesidades de personal o utilización de la instalación. En tercer lugar, la Planificación Maestra de medio plazo (1-3 meses) define el Plan Maestro de Producción que determina el calendario de producción de cada tipo de producto para que se respeten los plazos de entrega. Por último, en la Programación a Corto Plazo (1 día - 3 semanas) las decisiones críticas a tratar son la carga del centro de trabajo y la secuenciación del mismo. Es ésta la Programación que el grupo de trabajo pretende optimizar en la medida de lo posible, ofreciendo a la PYMES una solución informática a bajo coste y unos resultados rentables, obteniendo horas de trabajo mucho más productivas. En la actualidad, las PYMES se encuentran lejos de la aplicación de soluciones informáticas a su trabajo diario, limitándolo a la gestión burocrática. Existe la creencia generalizada de que las aplicaciones especializadas para el trabajo en el 1
12 taller son inalcanzables para la economías de sus presupuestos o excesivamente específicas, lo que las hacen no aplicables a sus problemas de trabajo diario. En este entorno, una de las decisiones más importantes que se deben tomar es la gestión de recursos compartidos por una serie de trabajos a lo largo del tiempo, teniendo un criterio certero para decidir la preferencia en caso de conflicto de más de un trabajo en el mismo recurso en un mismo instante. Esta decisión determina el tiempo total que los trabajos van a utilizar para completar todas las tareas. Las dificultades que desprenden estas decisiones se conocen como el problema de secuenciación de tareas en un taller de trabajo, o sus siglas en inglés JSSP, acrónimo de Job-Shop Scheduling Problem. Desde la perspectiva matemática, el JSSP se encuadra dentro de los problemas de naturaleza combinatorial, es decir, se deben explorar todas las combinaciones posibles para garantizar que se ha obtenido la solución óptima. A medida que el número de variables aumenta, el tiempo necesario para obtener el óptimo crece exponencialmente. Es por ello que el JSSP se encuadra dentro de la tipología NPhard, siendo dentro de éstos uno de los más complicados de resolver. Para intentar abordar una solución satisfactoria y rentable, el IIT realizó un estudio de algoritmos metaheurísticos puesto que reducen los tiempos de ejecución respecto a la Programación Dinámica o Programación Lineal Entera (en el marco de la Investigación Operativa), ya que aquéllos exploran sólo el conjunto de soluciones más prometedoras. Esto los hace mucho más ventajosos en cuanto a coste computacional, con el inconveniente de ser menos generalizables para problemas semejantes. Los algoritmos estudiados para obtener estas soluciones cercanas al óptimo han sido los algoritmos genéticos, el recocido simulado y la búsqueda tabú. Los algoritmos genéticos, desde el punto de vista de la Investigación Operativa, se entienden como procedimientos inteligentes de búsqueda aleatoria. Están basados en la teoría de la selección natural y se obtienen de ellos soluciones cercanas al óptimo. La búsqueda local se basa en la idea de que una 2
13 solución puede ser mejorada realizando pequeños cambios en ella. Dentro de la búsqueda local se encuentran la búsqueda tabú y el recocido simulado. La búsqueda tabú es un procedimiento metaheurístico diseñado para encontrar soluciones subóptimas en problemas de optimización combinacional. El recocido simulado trata de simular la tendencia de las estructuras de algunos materiales a adquirir estructuras regulares a medida que disminuye la temperatura. Ambos son iterativos y recomendados para implementación informática. Posteriormente, en el Capítulo 2 se describen someramente los algoritmos. Para la puesta de largo de los estudios anteriores, este proyecto pretende aplicarlos desde un portal informático accesible desde Internet. Para ello, se desarrolla un proyecto informático completo que obtiene las entradas de los problemas definidos por los usuarios de forma parametrizada y ofrece los resultados mediante tablas y un diagrama de Gantt. Bajo esta óptica es como se trabaja en la inmensa mayoría de las PYMES. Por tanto, se define un objetivo indispensable: desarrollar el portal de manera que al usuario tipo le resulte extremadamente fácil y familiar para su navegabilidad y explotación. La metodología elegida en la especificación, análisis, diseño e implementación del sistema ha sido la del Proceso Unificado de Desarrollo de Software (PUD). En el proceso de análisis se comprobó la viabilidad de usar sevlets y JSP en la definición de planificaciones, posteriormente se llevó a cabo el diseño completo del sistema, desarrollando prototipos, verificando y validando. Se realizaron sucesivas iteraciones hasta conseguir el producto desarrollado, dónde se llevaron a cabo las pruebas finales. Respecto a la organización interna del proyecto, se ha intentado hacer una división en paquetes para que su mantenimiento y ampliación se realice de la mejor manera posible. Se ha desarrollado un cliente ligero, es decir, que tuviese el menor conocimiento de la lógica de negocio posible. Por tanto, todo el peso recae sobre el servidor. 3
14 CAPÍTULO 2. ÁMBITO DEL PROYECTO 2.1 Introducción Este capítulo describe el ámbito donde se enmarca el proyecto. Cómo se menciona en la introducción, el objetivo es estudiar soluciones óptimas aplicables al trabajo diario en las PYMES. El punto de partida está en la Secuenciación de Tareas. 2.2 Secuenciación de Tareas Introducción La secuenciación de tareas constituye un problema importante que se plantea dentro de la Programación a Corto Plazo. El orden en el que un conjunto de tareas serán ejecutadas, no resulta indiferente, sino que determinará algún parámetro de interés cuyos valores conviene optimizar en la medida de lo posible. Puede verse afectado el coste total de ejecución de las tareas o el tiempo necesario para terminarlas. Esto conduce de forma directa al problema de determinar cuál será el orden más adecuado para llevar a cabo las tareas con vistas a optimizar alguno de estos parámetros u otros similares. Es el problema de secuenciación que se presenta de forma habitual en la programación de operaciones a corto plazo en entornos industriales o de manufactura y que puede tomar un varias formas de plantear. La dificultad para resolver el problema determinando una secuencia óptima, o al menos admisible, junto con la importancia de conseguirlo, han hecho proliferar reglas, más o menos complejas, muchas de ellas heurísticas y algunas empíricas, que proporcionan soluciones rápidas y fáciles de calcular destinadas a su uso en situaciones de trabajo reales. 4
15 El desarrollo de los ordenadores y la aparición de nuevas técnicas de simulación y optimización heurística que aprovechan plenamente las disponibilidades de cálculo intensivo que aquéllos proporcionan, han abierto una nueva vía para abordar los problemas de secuenciación, suministrando un creciente repertorio de métodos y algoritmos cuyo uso se extiende paulatinamente sustituyendo a las sencillas reglas heurísticas usadas tradicionalmente. El problema concreto al que aquí se prestará atención es el de determinar la secuencia óptima según la cual deben ser elaborados una serie de trabajos distintos para minimizar los tiempos de ejecución en máquina. En un sistema de producción por lotes (JSSP) cada vez que finaliza la elaboración de uno de dichos lotes, para poder comenzar con la del siguiente se debe proceder a un reajuste o preparación de las máquinas, lo que supondrá una paralización momentánea de la actividad de las máquinas reajustadas. Los tiempos de preparación de dichas máquinas dependerán de los distintos pares de lotes entre los que se produzca la preparación, es decir, del orden en que los lotes sean elaborados. Se plantea entonces el problema de determinar cuál será el orden más adecuado para minimizar el tiempo de preparación total. Aunque una búsqueda exhaustiva puede ser adecuada cuando el número trabajos a considerar es muy reducido, el rápido crecimiento del número de operaciones de búsqueda y comparación a medida que crece el número de lotes la convierte rápidamente en inviable. Se trata el de la secuenciación de un problema muy similar al conocido como el problema del viajante -Travelling Salesman Problem o TSP-, es decir, determinar la secuencia en que deben ser recorridas una serie de ciudades para minimizar el recorrido total. Es éste un problema de complejidad exponencial creciente con el número de ciudades y se encuadra dentro de la categoría de los conocidos como problemas NP-completos. Para 5
16 ellos no se conocen algoritmos que proporcionen soluciones óptimas en tiempos razonables, lo que obliga a recurrir a aproximaciones y métodos heurísticos que con costes computacionales asumibles, proporcionen soluciones si no óptimas, al menos sí aceptables y rentables. Uno de tales algoritmos, de gran sencillez y ampliamente conocido es el de Kaufmann (1964), que consiste en comenzar por un lote cualquiera y elegir como siguiente aquél para el cual sea menor el tiempo de preparación y así sucesivamente. El inconveniente de este método, y de otros similares, es que proporciona un óptimo local que puede estar muy alejado del óptimo global, sin que haya además ninguna manera de estimar la distancia entre ambos. Las máquinas modernas ponen a nuestro alcance otros métodos, más sofisticados, que permiten ir sorteando, al menos en alguna medida, los óptimos locales y aproximarnos cada vez más al óptimo global, sin alcanzarlo salvo por azar. Entre estos métodos destaca por su amplia utilización y los buenos resultados que generalmente consigue el conocido como Recocido Simulado Definición y conceptos básicos del problema Sean n trabajos J 1, J 2,..., J n que deben ser procesados en un conjunto de m máquinas {M j } 1 j m. Procesar el trabajo i en la máquina j se denomina operación y su notación es o i j. Por restricciones técnicas, las operaciones de un trabajo se realizan en un orden determinado que se llama secuencia técnica y es, en el caso general, distinto para cada trabajo. Cada operación o i j tiene una duración o tiempo de procesado (p i j ) donde se incluye el tiempo necesario para ajustar la máquina y el transporte del material que será procesado. 6
17 2.2.3 Suposiciones practicadas 1. Cada trabajo se compone de una serie de operaciones que no pueden ser realizadas simultáneamente. 2. No existen interrupciones. Si una operación comienza a realizarse en una máquina debe completarse antes de que otra operación utilice dicha máquina. 3. En el desarrollo de la teoría se supone que cada trabajo tiene una y sólo una operación en cada máquina y sólo existe una máquina de cada tipo. Las herramientas informáticas desarrolladas superan ésta suposición. 4. No hay cancelación, por lo que cada trabajo ha de completar todas sus tareas. 5. El tiempo de procesado es independiente de la programación. El tiempo de ajuste de la máquina para realizar una operación es independiente de la operación que se realizó anteriormente. 6. Pueden existir trabajos inactivos. Esto crea una cola de procesado para los trabajos en una máquina. 7. Las máquinas pueden estar inactivas. 8. Las máquinas son invulnerables a fallos durante todo el proceso de programación. 9. La secuencia técnica de cada trabajo se conoce a priori. 10. No hay estocasticidad. El número de trabajos, el número de máquinas y los tiempos de procesados están fijados y son conocidos Caracterización de la solución Sea s i j el inicio de procesado de la operación o i j en M j. El conjunto {s i j } caracteriza la solución del problema cumpliendo con las restricciones: No existen tareas que se realicen de forma simultánea en la misma máquina. El orden de las tareas respeta las secuencias técnicas de todos los trabajos. 7
18 2.2.5 Medidas de bondad de la solución Existen numerosas medidas de bondad para evaluar las soluciones. Se exponen dos de ellos por su estrecha relación con la secuenciación de tareas. Los criterios basados en los tiempos de finalización se aplica en los casos donde el coste de programación depende de la cantidad de tiempo total que utilizan los recursos para completar una serie de trabajos. Los criterios basados en las fechas de entrega se aplican en las ocasiones en las que el coste se asocia a los retrasos respecto a los tiempos de entrega. Los parámetros intervienen son el retraso y tardanza medio y máximos. Cuando solamente existe una penalización al retraso de los trabajos se emplea la tardanza y las de retraso si existe algún incentivo asociado a la finalización temprana de éstos Clasificación de los problemas de secuenciación Existe una notación sencilla para la clasificación de tareas mediante cuatro parámetros: n / m / A / B. n : número de trabajos. m : número de máquinas o recursos. A : caso considerado. Puede tomar los siguientes valores: F : Caso donde la secuencia técnica de todos los trabajos es la misma (flowshop). P : Caso donde la secuencia técnica de todos los trabajos es la misma y la secuencia de los trabajos dentro de cada máquina es igual para todas las máquinas (permutation flow-shop). G : Caso donde no todas las máquinas forman parte del procesado de cada trabajo. 8
19 B : Medida de eficiencia por la que ha de medirse la bondad de una programación. Los estudios realizados con anterioridad por el grupo de trabajo al que pertenece este proyecto se centran en el problema de JSSP m / n / G / C max. 2.3 Representación del JSSP Matricial En la representación matricial, cada fila representa un trabajo cuyo identificador es la primera columna y las siguientes representan la secuencia técnica de los trabajos en los recursos o máquinas. Asociado a cada número de secuencia se representa el tiempo de procesado de cada subtrabajo. Así, la interpretación de la primera fila de la siguiente tabla será: El trabajo 1 se procesa en primer lugar en la máquina 2 durante 3 unidades de tiempo, después en la máquina 3 durante 2 unidades de tiempo y luego termina en la máquina 1 durante 3 unidades de tiempos. Las otras dos filas tienen una interpretación análoga. Tr Máquina (tiempo de procesado abajo 1 2 (3) 3 (2) 1 (3) 2 1 (5) 2 (3) 3 (4) 3 2 (4) 1 (2) 3 (5) 9
20 2.3.2 Diagramas de Gantt Los diagrama de Gantt ofrecen una representación gráfica de una solución del problema o programación posible de las tareas. En el diagrama de Gantt, el eje de ordenadas representa las máquinas o recursos mientras que el eje de abscisas representa el espectro temporal. en la siguiente figura se muestra un diagrama de Gantt. Cada bloque representa una operación o i j donde su lado izquierdo indica el inicio de la operación en el tiempo y su lado derecho representa el final. Así, la máquina 2 procesa primero la tarea 3, luego la 1 y por último la 2. M1 o11 o21 o31 M2 o32 o12 o22 M3 o23 o33 o13 Tiempo Programaciones activas y semiactivas Una programación de tareas es semiactiva si no existen tareas que puedan empezar antes sin alterar la secuencia de tareas dentro de una máquina. Dada una ordenación de las operaciones en cada máquina, si no es posible adelantar la posición de una tarea sin retrasar el inicio de la ejecución de las restantes que se ejecutan en la misma máquina entonces la programación es activa. Las programaciones activas son un subconjunto de la semiactivas. Una programación sin retardos es un subconjunto de las programaciones activas son aquellas en las que ninguna máquina está ociosa si existen operaciones esperando para ser procesadas por dicha máquina. Normalmente, las 10
21 soluciones óptimas se encuentran en este conjunto aunque existen excepciones donde no es así. 2.4 Procedimientos de resolución Introducción Santiago López de Haro, realizó el estudio de los diferentes algoritmos de resolución que mejor respuesta podrían dar la resolución de problemas de secuenciación de tareas. Como refleja el DEA de su doctorado hizo un estudio pormenorizado de los procedimientos de resolución utilizados por los algoritmos genéticos y por la búsqueda local. De los resultados de sus estudios se concluyó que para la codificación de la herramienta motor que procesa los problemas se debían utilizar la búsqueda local. En este documento se mencionarán los algoritmos estudiados y se expondrá la taxonomía de los algoritmos que utiliza la herramienta. Para ampliación de conocimientos se recomienda consultar la referencia [referencia]. En la documentación técnica se pueden encontrar diversos procedimientos de resolución del JSSP, clasificados de la siguiente manera: 1. Procedimientos de búsqueda exhaustiva: a. Programación lineal entera. b. Programación de restricciones. 2. Algoritmos heurísticos. 3. Algoritmos metaheurísticos Formulación en programación lineal. Sea s 0 el comienzo de la tarea O. El problema del JSSP formulado según la programación lineal entera sería: 11
22 Minimizar s f s.a. s w s v t v (v, w) A s v 0 v O s w s v t v s v s w t w (v, w) E j, 1 j m La anterior tabla recoge la problemática del JSSP en varias restricciones. La primera condición garantiza que se va a seguir la secuencia técnica de cada trabajo sin solapamiento entre las tareas correspondientes al mismo. La segunda impide que ninguna tarea empiece antes del origen del tiempo. La tercera y última evita el solapamiento de las operaciones v y w si éstas se ejecutan en la misma máquina. La disyunción obliga a que sólo una de las inecuaciones se cumpla según si w precede a v o viceversa. s f es el tiempo de inicio del último nodo por lo que se intenta minimizar es C max Resolución mediante algoritmos genéticos Los algoritmos genéticos (AG) desde el punto de vista de la investigación operativa, se entienden como procedimientos pseudo-inteligentes de búsqueda aleatoria. Se basan en la teoría de la selección natural. Tienen la enorme ventaja que produce el separar genotipo-fenotipo se pueden emplear en la búsqueda de soluciones a problemas diversos tales como el análisis de imágenes, procesamiento de señales, diseño de robots autónomos y programación automática. También están especialmente recomendados para resolver problemas de índole combinatorial como el JSSP y problemas donde pueden haber varias soluciones óptimas o cuasi-óptimas. Proporcionan una gran robustez en su búsqueda de soluciones, ofreciendo soluciones cercanas al óptimo. Los AG fueron desarrollados en un principio por Holland (1975) en su publicación Adaptation in Natural and Artificial System. 12
23 Los AG se basan en un conjunto de individuos o población con dos representaciones llamadas fenotipo y genotipo. El fenotipo es una solución potencial del problema a resolver y el genotipo es una codificación de tal solución en forma de cromosoma. Un cromosoma lo forma una secuencia de genes que representan características del individuo susceptibles de ser hereditarias. A modo de ilustración, se puede tomar un sistema de ecuaciones lineales con varias incógnitas. Un cromosoma o genotipo estaría formado por una secuencia de números y el fenotipo sería la asignación de cada uno a la variable correspondiente. En el caso particular del JSSP, el genotipo sería la secuencia de tareas para cada máquina y el fenotipo sería la programación temporal equivalente, esto es, el diagrama de Gantt. Los cromosomas de una población evolucionan en sucesivas etapas, llamadas generaciones, en las que cada uno de ellos es evaluado según una función objetivo o función de ajuste que cuantifica la bondad de la solución correspondiente. El mecanismo de selección es el encargado de tutelar la búsqueda del algoritmo. Se encarga de seleccionar los individuos que van a ser cruzados basándose en la medida de bondad o ajuste que éstos tienen. En el AG original de Holland, un progenitor es seleccionado basándose en su bondad (mayor valor de ajuste implica mayor probabilidad de ser seleccionado) y el otro se escoge de manera aleatoria. Ambos progenitores son cruzados e introducidos en la población, eliminando otros dos seleccionados aleatoriamente. Los operadores de cruce y mutación son mecanismos de combinación genética que generan nuevos cromosomas. Un operador de cruce intercambia las secuencias que se formarían al cortar ambos cromosomas por uno o más puntos de corte. La eficacia del algoritmo se relaciona de forma directa con la capacidad que este tiene de asumir las características de los progenitores que lo hacen ser buenos y recombinarlas para generar individuos mejores. 13
24 En los AG, como todos los procedimientos iterativos, es necesario definir un criterio de parada que determine en que momento ha de parar el algoritmo. El más sencillo es el número de generaciones que deben ejecutarse aunque también existen otros más complicados que se basan en índices de medida de la convergencia al óptimo global. El encargado de crear individuos espontáneos de forma aleatoria para evitar endogamia, lo que provocaría que en el transcurso de las iteraciones del operador de cruce se generen individuos del mismo entorno convergiendo hacia un mínimo local. Por tanto, el operador mutación es el encargado de explorar nuevos entornos del espacio de búsqueda y el operador cruce es el que estudia o analiza las regiones más prometedoras. La eficacia de un algoritmo como procedimiento de búsqueda inteligente puede medirse comparando sus resultados con los de un algoritmo que genera el mismo número de genotipos de forma completamente aleatoria. 14
25 Sembrado o inicialización de la población Evaluació n individuos (fitness) Indivi duos almacenado Cruce y/o mutación Fin iteraciones? Selección Fin del 15
26 2.5 Búsqueda local: búsqueda tabú y recocido simulado Introducción La búsqueda local está basada en el concepto de que una determinada solución a un problema es susceptible de ser mejorada introduciendo pequeños cambios en ella. Los algoritmos de esta categoría se diseñan para que al introducir un cambio haya una mayor probabilidad de mejora la solución que empeorarla. Sea ℵ un conjunto de soluciones factibles cuya bondad viene dada por una función de coste ℵ R, función que se trata de optimizar minimizando el coste. Para cada solución x ℵ se define un vecindario, N (x) ℵ, donde cada solucón contenida en N (x) se denomina vecino y puede ser alcanzado mediante un movimiento unitario o modificación mínima del cromosoma representante. Entonces, la ejecución de un algoritmo de búsqueda local es una sucesión de movimientos unitarios que define el camino por el que cada solución visitada es vecina de la inmediatamente anterior. Una solución x ℵ se denomina mínimo local respecto a una determinada función de vecindario N si c( x) c( y) para todo y N(x). El algoritmo de mejora iterativa sirve para localizar mínimos locales a partir de una solución inicial dada. Consiste en seleccionar en cada iteración la primera solución perteneciente al vecindario que tenga un coste inferior al actual. Cuando no exista ninguna solución vecina que cumpla con esta última condición, se habrá encontrado un mínimo local. Los mínimos locales suelen encontrarse lejos del óptimo global, por lo que se han desarrollado variantes del algoritmo de mejora iterativa recomendados para la optimización de funciones con varios óptimos locales en el dominio de soluciones: 16
27 Algoritmos de búsqueda iterativa tales que el máximo umbral permitido es 0, es decir, sólo se permiten mejoras. Destaca de entre ellos la búsqueda tabú (taboo search), un caso particular de la búsqueda iterativa de máxima pendiente (steepest descent), que evalúa todas las soluciones del vecindario y selecciona la más prometedora apoyado por una memoria a corto plazo. Dicha memoria contiene las soluciones visitadas recientemente (lista tabú) lo que evita que el algoritmo se estanque en un mínimo local. Algoritmos que permiten la evolución hacia soluciones cuya diferencia de costes se encuentra por debajo de un cierto umbral, aun siendo soluciones peores que la actual. En el recocido simulado (simulated annealing SA) desarrollado por Kirkpatrick (1984), los umbrales son no negativos y estocásticos siguiendo una distribución de probabilidad exponencial de parámetro 1 / T, siendo T un parámetro de control que disminuye a lo largo de la ejecución conforme a un programa de enfriamiento Representación de soluciones y generación del vecindario Un elemento fundamental de los algoritmos de búsqueda local es la representación de soluciones. Los algoritmos explicados a continuación emplean una representación basada en el orden de las operaciones en máquinas, por lo que sólo pueden representarse soluciones activas y semiactivas. No obstante, el elemento determinante en los algoritmos de búsqueda local es la generación de soluciones cercanas o vecinas. Para ahorrar esfuerzo computacional, el vecindario se escoge de forma que sólo las soluciones más prometedoras queden dentro. Para una correcta interpretación de los algoritmos es necesario definir ciertas propiedades del JSSP. Sean dos operaciones v y w que utilizan el mismo recurso. Éstas son adyacentes ( v w) si s ( v) + p( v) = s( w), es decir, si w comienza inmediatamente 17
28 después de terminar v. Un bloque es una secuencia de tareas adyacentes en el mismo recurso. Se dice que una operación es interna si no es ni la primera ni la última del bloque en ejecutarse. Para generar un vecindario han de tenerse en cuenta las siguientes propiedades: 1. Dadas dos tareas adyacentes v y w ( v w) pertenecientes al camino crítico de una solución factible S, la inversión del arco orientado en el grafo disjunto correspondiente ( w v) da lugar a otra solución factible S 2. Si la inversión de cualquier arco entre dos operaciones no pertenecientes al camino crítico diera lugar a otra solución S factible, entonces C max( S ) C max( S). 3. Sean v y w ( v w) dos operaciones internas en un bloque perteneciente al camino crítico, o tales que siendo una de ellas interna, la otra se encuentra situada en cualquiera de los extremos del camino crítico. La inversión del arco que las une ( w v) da lugar a otra solución factible S tal que C max( S ) C max( S). Cada una de esta propiedades puede utilizarse para reducir el tamaño de vecindario con garantía de que ninguna solución prometedora vaya a ser excluida Resolución mediante recocido simulado El recocido simulado es un algoritmo que trata de simular la tendencia de las estructuras de ciertos materiales a adquirir estructuras regulares a medida que disminuye la temperatura. Esto se debe a que el enfriamiento provoca que las disposiciones más regulares se vayan estabilizando (con menos energía), y las 18
29 demás se vayan desestabilizando (con más energía). Por lo tanto, a medida que el algoritmo converge, las estructuras mas estables son las predominantes en el material. Normalmente, el algoritmo comienza con la generación de una solución aleatoria para el problema y el cálculo del coste de tal solución. La evolución se produce realizando desplazamientos unitarios que se aceptan si su coste es inferior a la solución anterior. Si esto no se produce, la solución es aceptada con una probabilidad que decrece exponencialmente con el cociente de la diferencia de costes C y un parámetro T que representa la temperatura. Puesto que la probabilidad de aceptar soluciones peores no es nula, el algoritmo no quedará atrapado en mínimos locales. Si la nueva solución no fuera aceptada, se probaría un nuevo movimiento desde la solución anterior. El algoritmo termina cuando no se ha obtenido ninguna mejora en un número determinado de desplazamientos, aunque existen criterios más complicados. 2.6 Sectores de aplicación empresa: La programación de tareas apoya a las principales áreas funcionales de una El departamento de Producción necesita conocer la secuencia real de productos a fabricar en el día. Por ello, su personal ha de consultar la programación de tareas que resulta tras la planificación maestra de los diferentes productos a fabricar (MRP). El departamento de Contabilidad, a partir de la información de la programación y de las fechas de entrega a los clientes prevé la entrada de 19
30 ingresos, los costes de cada trabajo y realiza un análisis del cash-flow de la empresa. El departamento de Marketing puede establecer medidas de la eficiencia de la programación para determinar si los tiempos de cumplimentación de los pedidos están aportando una ventaja competitiva y si las entregas se están realizando a tiempo. El conocimiento de los tiempos de entrega de cada pedido permite al departamento de Marketing ofrecer tiempos de entrega más ajustados. El departamento de Compras puede realizar el seguimiento de los pedidos a lo largo del proceso productivo para solicitar a los proveedores que adelanten las fechas de entrega de las piezas o por el contrario, que las retrasen. Un sistema de información se puede encargar de mantener en base de datos el tiempo de comienzo de cada tarea así como el enrutamiento de las mismas por cada uno de los recursos disponibles.también se puede encargar de realizar el seguimiento de movimiento del producto a través del proceso. Las empresas diseñadas para satisfacer pedidos de lotes de producto o servicios de gran tamaño poseen unos procesos productivos altamente repetitivos. En estos casos la programación de tareas se suele utilizar para determinar la secuencia productiva de lotes de un mismo producto o servicio que permita cumplir con fechas de entrega de pedido. También en un contexto de fabricación la programación de tareas se puede utilizar para equilibrar la carga de trabajo de los operarios asignando adecuadamente las tareas del proceso. Las empresas diseñadas para proveer al cliente de productos o servicios personalizados llevan a cabo procesos productivos específicos, tal y como ocurre por ejemplo en los servicios técnicos de reparación de equipos. La programación de las tareas en este tipo de empresas ha de tener en cuenta la limitación de capacidad del número de máquinas y operarios disponibles entre otros condicionantes. 20
31 Esta programación de tareas resulta también necesaria en actividades empresariales tales como el transporte de viajeros y mercancías. En estos entornos se necesitan herramientas capaces de programar temporalmente los viajes conforme a las necesidades de la planificación de servicios con las particularidades propias de medios de transporte tan dispares como el transporte por carretera o ferrocarril. 21
32 CAPÍTULO 3. METODOLOGÍA 3.1 Metodología La metodología elegida en la especificación, análisis, diseño e implementación del sistema ha sido la del Proceso Unificado de Desarrollo de Software (PUD), cuya descripción se muestra a continuación PUD Se trata de una metodología para acometer el desarrollo de sistemas informáticos, propuesta por Ivar Jacobson, Grady Booch y James Rumbaugh. Se ha elegido principalmente por tres razones: 1. Se trata de un estándar avalado por OMG (Object Management Group), consorcio de alrededor de 800 miembros (compañías de la industria del software) que buscan el desarrollo de especificaciones que sean técnicamente excelentes, comercialmente viables e independientes del vendedor. OMG define object management como el desarrollo software que modela el mundo real mediante su representación como objetos. Estos objetos no son más que el encapsulamiento de atributos, relaciones y métodos de componentes software identificables. 2. Recoge la experiencia de tres grandes metodologías anteriores: 1. OMT (Object Modeling Technique) de Rumbaugh. 2. OOAD (Object-Oriented Analysis and Design) de Booch. 3. Objectory de Jacobson. 22
33 3. Actualmente, se usa en la mayoría de las empresas para grandes proyectos y se imparte por muchas instituciones. El PUD es un proceso de desarrollo de software, definido como un conjunto de actividades necesarias para transformar los requisitos de un usuario en un sistema software. Sin embargo, el proceso unificado es más que un proceso de trabajo; es un marco de trabajo genérico que puede especializarse para una gran variedad de sistemas software, para diferentes áreas de aplicación, diferentes tipos de organizaciones y diferentes niveles de aptitud. El Proceso Unificado está basado en componentes y utiliza el Lenguaje Unificado de Modelado (Unified Modeling Language, UML). Está dirigido por casos de uso, porque con éstos se especifican las funcionalidades que el sistema proporciona al usuario. Los casos de uso representan los requisitos funcionales y fuerzan a pensar en términos de importancia para el usuario y no sólo en términos de funciones que serían bueno tener. Los casos de uso no sólo son una herramienta para especificar los requisitos del sistema, sino que también guían su diseño, implementación y prueba, es decir, guían el desarrollo software. El PUD está centrado en la arquitectura, pues la manera en que se organiza el sistema depende de los casos de uso clave y debe tener en cuenta la comprensibilidad, la facilidad de adaptación al cambio y la reutilización. Los casos de uso clave son aquéllos que dotan al sistema con la funcionalidad fundamental para los usuarios y, sin los cuales, los demás casos de uso no tienen sentido. Es iterativo e incremental. El trabajo se divide en partes más pequeñas o llamadas iteraciones. En cada iteración se recorren los flujos de trabajo1 y se obtiene una versión interna. 23
34 En síntesis, en cada iteración se amplía el sistema con nuevos casos de uso, se identifican nuevos riesgos y se mitigan los ya conocidos. Las iteraciones se agrupan en fases, que por orden secuencial son las siguientes: inicio, elaboración, construcción y transición. Cada una centra sus esfuerzos más en unos flujos de trabajo que en otros. La etapa de inicio se centra en la captura de requisitos y el análisis. La etapa de elaboración lo hace en el análisis y el diseño. Las etapas de construcción y transición se centran en el diseño, implementación y pruebas. El trabajo de los requisitos se hace fundamentalmente durante la fase de inicio y la de elaboración. Durante la fase de inicio se identifican la mayoría de los casos de uso que delimitan el sistema y el alcance del proyecto, se detallan los más importantes. Durante la fase de elaboración se capturan la mayoría de los requisitos restantes. En la fase de construcción se capturan e implementan los requisitos que restan, mientras que en la fase de transición prácticamente no hay captura a menos que haya requisitos que cambien. Dadas las limitaciones de esta memoria, se van a presentar conjuntamente los requisitos obtenidos en las fases de inicio, elaboración y construcción. De la misma manera, los distintos modelos de casos de uso, modelos de análisis, clases, modelos de despliegue, etcétera, de los flujos de trabajo de requisitos, 24
35 análisis, diseño, implementación y pruebas, se expondrán conjuntamente sin reflejar su evolución a través de las iteraciones. Debido a las dimensiones del proyecto, existen otras actividades de la metodología que no tienen cabida, como por ejemplo la gestión de los recursos humanos, ya que el autor de esta memoria asume todos los roles de un sistema: arquitecto, jefe de proyecto, analista, diseñador, etcétera. De la misma forma no se hará un control de versiones, ya que el desarrollo se corresponde con una primera versión. 25
36 CAPÍTULO 4. IDENTIFICACIÓN DE NECESIDADES En esta fase del desarrollo se ha realizado un análisis de los requerimientos del sistema, sus objetivos, normas a seguir, tecnologías a utilizar, todos estos requerimientos se describen en el documento de conceptos del sistema que figura a continuación. 4.1 Objetivos del sistema En este apartado se relatan los objetivos más generales del sistema en una descripción clara y escueta pero que debe definir claramente la finalidad del sistema, estos objetivos se describen desde una perspectiva empresarial. El sistema consiste en el desarrollo de una aplicación Web en la que permita trabajar con la herramienta de secueciación de tareas pudiendio realizar planificaciones de trabajo de una manera sencilla. Un trabajador de un empresa con producción en serie accederá a la herramienta vía web y desde su navegador podrá definir la planificación y obtener los resultados deseados. 26
37 4.2 Alcance del sistema Desarrollar una interfaz que permita introducir datos en la herramienta mediante definición de formulario o mediante archivos de texto previamente creados para tal fin. La aplicación debe ejecutar satisfactoriamente los datos de entrada y proporcionar un resultado coherente. Para ello ejecutará el algoritmo de recocido simulado. La aplicación debe ser capaz de mostrar los datos de forma tabulada y mediante un gráfico que represente un diagrama de Gantt de la ordenación de los trabajos. 4.3 Tipología de los usuarios finales En este apartado se describe el perfil de los usuarios finales, de tal manera que el interfaz pueda ser lo más apropiado posible para los usuarios. El usuario de la aplicación es un trabajor de una empresa PYME con conocimiento informático a nivel de usuario y familiarizado con la estructura de producción en serie, lo que le permitirá definir planes de trabajo acordes con la planificación a ejecutar. Por tanto, este tipo de usuario será capaz, con un mínimo de formación de introducir una planificación, ejecutarla e interpretar su resultado. 27
38 CAPÍTULO 5. ANÁLISIS DE REQUISITOS El análisis de requisitos consiste en la creación de un modelo conceptual del sistema que satisfaga todos los requisitos, para ello, esta etapa del desarrollo se divide en varias actividades técnicas. Para el desarrollo de la plataforma web, se realizarán las siguientes actividades definidas por la metodología UML: Identificar los casos de Uso del Sistema. Dar detalle de los casos de uso descritos. Dar una interfaz inicial al sistema. Especificar lista de requisitos Esta primera visión técnica del sistema, se encarga de dar una perspectiva de qué funcionalidades debe tener el sistema sin entrar a definir cómo debe realizarlas. El resultado de este análisis es la lista de requisitos de la aplicación web. 5.1 Modelo conceptual de la aplicación web Casos de uso del sistema Los casos de uso permiten recoger y documentar los requerimientos funcionales de un sistema, para su realización se necesita primeramente identificarlos y posteriormente realizar una descripción detallada de cada caso de uso. 28
39 Un caso de uso permite recoger y documentar un requerimiento funcional del sistema y su forma de interactuar con el usuario. Para identificarlos y representarlos se utilizan los diagramas de casos de uso en los que se representa a los actores y sus relaciones con el sistema y otros actores. Un actor puede ser cualquier persona, organización o sistema que sea externo al sistema que se está analizando y que además interactúa de alguna manera con él. Un actor, más que un ente concreto es un rol abstracto que representa la forma de interactuar con el sistema. Un caso de uso responde a un objetivo de un actor con respecto al sistema y es una unidad funcional completa. Un ejemplo puede ser un empleado que quiere comprar planificar el trabajo de una mañana, el caso de uso comprendería todas los pasos que necesitaría el usuario para conseguir su fin Diagramas de casos de uso del sistema Los diagramas de casos de uso son una representación gráfica del caso de uso, representa gráficamente la relación entre el actor principal el sistema. Para nuestro sistema, además nos va a servir para identificar los casos de uso. A continuación figura un gráfico explicativo de las figuras que pueden aparecer en los diagramas de casos de uso. 29
40 Hacer algo Caso de Uso Actor del caso de uso Relación Cadifra Evaluation Definir Plan Subir Resultado Ejecutar Plan Descargar Resultado Usuario Subir Plan Descargar Plan Visualizar Plan Cadifra Evaluation 30
41 5.1.3 Descripción de los casos de uso La descripción de los casos de uso se ha realizado rellenando una plantilla que se explica a continuación, la plantilla tiene diferentes secciones: Título: Da nombre al caso de uso, debe ser claro, conciso y auto explicativo. Actor primario: Es aquel cuyo objetivo da nombre al caso de uso, normalmente es también el que lo inicia aunque no siempre es así. Actor secundario: Cualquier otro actor que intervenga en el caso de uso y que ayude al sistema a conseguir el objetivo del actor primario. Trigger: Es el evento que inicia el caso de uso, a veces precede al primer paso del caso de uso, mientras que otras veces es el primer caso. Precondiciones: Son condiciones que se han de dar para que pueda iniciarse el caso de uso y como se han de cumplir antes, no se vuelven a comprobar una vez iniciado el caso de uso, pueden ser una o varias, pero todas ellas han de cumplirse. Escenario Primario: Se describe mediante una serie de pasos numerados, cada paso consistirá en una frase activa en tiempo presente, cada paso puede ser únicamente de los siguientes tipos: Una interacción entre sistema y actor o actores. Una validación de cierta información recibida o de una regla de negocio. Un cambio de estado lógico del sistema. 31
42 Extensiones: Describen escenarios alternativos al escenario primario, todas las alternativas deben ser activadas por una condición detectable por el sistema. Descripción de datos: En esta sección se desglosan los datos que son referidos en el escenario principal. Reglas de negocio: Son reglas externas al sistema. Caso de Uso Definir Planificación Actor Principal Usuario Actor Secundario **** Trigger Selección de usuario Precondiciones **** Escenario 1. El usuario introduce el número de máquinas y trabajos que actúan. 2. La aplicación valida los datos y muestra el formulario de nombres y tareas por trabajo. 3. El usuario introduce el nombre de las máquinas y trabajos que actúan. 4. El usuario indica el número de tareas por trabajo. 5. La aplicación valida los datos y muestra el formulario tiempos y secuencia. 6. El usuario establece el orden de ejecución de las máquinas 7. El usuario introduce el tiempo de ejecución en máquina 8. La aplicación valida los datos y guarda la planificación. 32
43 Extensiones Descripción de Datos Extensiones 2a. El sistema comprueba los valores mínimo y máximo de los componentes. 1. La aplicación notifica el fallo y vuelve al punto 1. 5a. El sistema comprueba el número de tareas por trabajo. 1. La aplicación notifica el fallo y vuelve al punto 3. 7a. El sistema comprueba que la secuencia de máquinas es correcta. 1. La aplicación notifica el fallo y vuelve al punto 4. 7b. El sistema comprueba que los tiempos son correctos. 1. La aplicación notifica el fallo y vuelve al punto 5. Secuencia de trabajo: Orden de ejecución de los trabajos en las máquinas. Tiempo de ejecución: Entero positivo. Número de máquinas y trabajos: Enteros entre 3 y 10. Número de tareas por trabajo: Enteros entre 2 y
44 Caso de Uso Ejecutar Planificación Actor Principal Usuario Actor Secundario **** Trigger Selección de usuario Precondiciones Existe una planificación definida Escenario 1. El usuario elige ejecutar la planificación. 2. El sistema ejecuta la planificación. 3. El planificador crea las tablas y el gantt. Extensiones Descripción de Datos Extensiones Caso de Uso Subir Planificación Actor Principal Usuario Actor Secundario **** Trigger Selección de usuario Precondiciones Existe una planificación definida en cliente Escenario 1. El usuario selecciona subir la planificación. 2. El sistema comprueba que existe la planificación y muestra el formulario de subida. 3. El sistema sube la planificación al servidor para su ejecución. Extensiones Descripción de Datos Extensiones 34
45 Caso de Uso Subir Resultado Actor Principal Usuario Actor Secundario **** Trigger Existe un resultado ejecutado en cliente Precondiciones Existe una planificación definida Escenario 1. El usuario selecciona el resultado de la planificación. 2. El sistema comprueba que existe el resultado y muestra el formulario de subida. 3. La aplicación sube el resultado al servidor. 4. El sistema muestra el resultado en tablas y gráfica. Extensiones Descripción de Datos Extensiones Caso de Uso Descargar Planificación Actor Principal Usuario Actor Secundario **** Trigger Selección de usuario Precondiciones Existe una planificación ejecutada en servidor Escenario 1. El usuario selecciona la planificación. 2. El sistema comprueba que existe la planificación. 3. El usuario indica la ruta a descargar. 4. El sistema ofrece la planificación. Extensiones Descripción de Datos Extensiones 35
46 Caso de Uso Descargar Resultado Actor Principal Usuario Actor Secundario **** Trigger Selección de usuario Precondiciones Existe un resultado ejecutado en servidor Escenario 1. El usuario selecciona el resultado. 2. El sistema comprueba que existe el resultado. 3. El usuario indica la ruta a descargar. 4. El sistema ofrece el resultado a descargar. Extensiones Descripción de Datos Extensiones 36
47 5.1.4 Modelo de dominio El modelo de dominio es un diagrama de la metodología UML que muestra los conceptos básicos del dominio del problema, sus propiedades más importantes y las relaciones existentes entre ellos. El modelo de dominio obliga a los desarrolladores y usuarios a pensar formalmente sobre el problema para intentar reflejar la realidad sobre un diagrama. Este reflejo de la realidad, permite a los desarrolladores validar su comprensión del problema a tratar. Para realizar el modelo de dominio, se ha utilizado una perspectiva conceptual, que pretende reflejar lo más fielmente posible el problema, sus conceptos, las propiedades de los conceptos y sus relaciones. El modelo de dominio no es una solución, es una perspectiva del problema. En el diagrama del modelo de dominio existen varios conceptos que se explican a continuación para una correcta interpretación del diagrama, estos conceptos son: Clases: Las clases representan conceptos existentes en el dominio del problema, estos conceptos suelen tener información asociada y relaciones entre ellos, por ejemplo cosas físicas como una empresa o conceptos lógicos como son una operación de compra. Su representación suele ser una caja, en la que el nombre de la caja está en la parte superior y los atributos debajo. 37
48 Trabajo +int idtrabajo +String nombre +Collection Tarea Cadifra Evaluation Esta es la clase Trabajo con un int, un String, y una colección de Tareas. Atributos: Los atributos representan información relevante asociado a los conceptos del dominio, es decir, las clases. Suelen ir acompañadas del prototipo del atributo: int, double, Long,... Relaciones: Representan las asociaciones entre las clases del dominio, tienen diversos atributos. Tienen nombre y cardinalidad. El nombre es una referencia explicativa de la relación y la cardinalidad es el número de instancias que participan en la asociación. Planificación contiene 1 n Trabajo Cadifra Evaluation Existen difernetes tipos de relaciones como la composición (una clase esta compuesta por instancias de otra) o la asociación (relación básica de dos clases). 38
49 5.1.5 Diagrama de modelo de domino Maquina m n Trabajo +int idmaquina +String nombre contiene n +int idtrabajo +String nombre +Collection Tarea intervienen 1 Planificación 1 1 sucesión de n Tarea +int idplanificación +String PlanificacionJSSP +String Problema DiagramaGantt n 1 Tabla n +int idtarea +int idmaquina +Long tiempoinicio +Long tiempofin +Long duracion n Resultado Cadifra Evaluation 39
50 5.1.6 Glosario de clases Clase Nombre Atributos Principales Descripción Maquina Maquina IdMaquina, nombre Esta clase representa una máquina como recurso en dónde se ejecutan las tareas. Clase Nombre Atributos Principales Descripción Trabajo Trabajo idtrabajo, nombre, Tareas Esta clase sirve para definir las tareas y las máquinas que componen los trabajos. Clase Nombre Atributos Principales Descripción Tarea Tarea idtarea, idmaquina, tiempoinicio, tiempofin, duracion Trabajo Esta clase representa la ejecución de un subtrabajo en una maquina durante un tiempo. Clase Nombre Atributos Principales Planificación Planificación IdPlanificación, planificacionjssp, problema. Tareas, Trabajo, Maquina 40
51 Descripción Esta clase es la definición de un plan ejecutado por Scheduler TENTA. Clase Nombre Atributos Principales Descripción Tabla Tabla Tarea Interfaz que proporciona a la GUI la tabla de trabajos compuesta de tareas. Clase Nombre Atributos Principales Descripción DiagramaGantt DiagramaGantt Planificacion Interfaz que crea el diagrama de Gantt de la Planificacion. Clase Nombre Atributos Principales Descripción Resultado Resultado DiagramaGantt, Tabla Interfaz que auna una tabla con un diagrama de gantt para mostrar el resultado. 41
52 5.1.7 Interfaz de entrada de datos Para poder definir los datos de la planificación se utilizarám formularios introducidos en páginas JSP que permitirán, de una forma guiada y secuencial, ir definiendo el plan de trabajo. Los diseños se han realizado acorde al uso requerido por el usuario final final, esto es, sencillez en la toma de datos sin recargos visuales. Definición del número de máquinas y trabajos Este formulario se compone de dos campos de texto que recogerán el número de máquinas y trabajos que intervienen en la planificación. Definición de nombres y tareas por trabajo Este formulario recoge los nombres de las máquinas y trabajos, así como el número de tareas que componen cada trabajo. Es un formulario dinámico con tantas filas como trabajos y máquinas se hayan definido. 42
53 Definición de la secuencia del plan y tiempos de ejecución Este formulario dinámico es el más complejo. Cada fila representa un trabajo donde se habrá de definir la secuencia de ejecución de las máquinas mediante una lista de selección y en dónde se fijará el tiempo de ejecución en un textbox. Subir planificación Estos dos formularios multipart recogen los ficheros de planificación y resultado que el usuario desea subir al servidor para ejecutar u obtener su vista. 43
54 5.2 Lista de requisitos Tras el análisis previo, debemos obtener una lista de requisitos que que debe cumplir la aplicación web. Título Código Descripción Objetivo Relacionado Definición de Plan REQ001 La aplicación deberá permitir definir un plan de trabajo mediante formulario. Obtener un plan de trabajo y persistirlo en fichero. Título Código Descripción Objetivo Relacionado Ejecutar Planificación REQ002 La aplicación deberá ejecutar el JSSP en el servidor con los datos obtenidos de la planificación. Obtener el resultado del JSSP. Título Código Descripción Objetivo Relacionado Diagrama de Gantt REQ003 La aplicación debe ser capaz de construir un diagrama de Gantt con los datos de salida de la planificación. Visualizar de forma gráfica la salida. REQ002 44
55 Título Código Descripción Objetivo Relacionado Tablas de Trabajos REQ004 La aplicación deberá construir las tablas necesarias por cada trabajo para su representación matricial. Visualizar el resultado de la planificación. REQ002 Título Código Descripción Objetivo Relacionado Datos previamente definidos REQ005 La aplicación deberá permitir subir datos previamente definidos sin necesidad de rellenar los formularios. Ejecución directa de resultados Título Código Descripción Objetivo Relacionado Persistencia de datos en ficheros REQ006 La aplicación deberá permitir la descargar de planificaciones para su posterior uso o modificación. Persistencia de resultados y planificaciones REQ003, REQ004 45
56 5.2.1 Consideraciones Los elementos que intervienen son los recursos o máquinas, los trabajos y las tareas. Una tarea es la ejecución de un subtrabajo en una máquina por una duración, con un tiempo inicial y final determinado en la conclusión de la ejecución. Un trabajo se compone de al menos dos tareas, pues debe existir algo para optimizar. El número mínimo de máquinas que intervienen en el problema es tres y el máximo diez. Los trabajos tienen la misma restricción. En un trabajo no se pueden ejecutar dos tareas consecutivas en la misma máquina. El tiempo mínimo de ejecución es uno y el máximo diez mil unidades de tiempo. Los nombres de las máquinas y los trabajos son cadena de caracteres parametrizables. 46
57 CAPÍTULO 6. DISEÑO DEL SISTEMA 6.1 Arquitectura del sistema La arquitectura elegida para la realización de la aplicación web es el modelo vista controlador (MVC). El Modelo Vista Controlador (MVC) es un patrón de arquitectura de software que separa los datos de una aplicación, la interfaz de usuario, y la lógica de control en tres componentes distintos. El patrón MVC se ve frecuentemente en aplicaciones web, donde la vista es la página HTML y el código que provee de datos dinámicos a la página, el controlador es el Sistema de Gestión de Base de Datos y el modelo es el modelo de datos. Modelo: Esta es la representación específica de la información con la cual el sistema opera. La lógica de datos asegura la integridad de estos y permite derivar nuevos datos; por ejemplo, no permitiendo comprar un número de unidades negativo, calculando si hoy es el cumpleaños del usuario o los totales, impuestos o portes en un carrito de la compra. Vista: Este presenta el modelo en un formato adecuado para interactuar, usualmente la interfaz de usuario. Controlador: Este responde a eventos, usualmente acciones del usuario e invoca cambios en el modelo y probablemente en la vista. Aunque se pueden encontrar diferentes implementaciones de MVC, el flujo que sigue el control generalmente es el siguiente: 1. El usuario interactúa con la interfaz de usuario de alguna forma (por ejemplo, el usuario pulsa un botón, enlace) 47
58 2. El controlador recibe (por parte de los objetos de la interfaz-vista) la notificación de la acción solicitada por el usuario. El controlador gestiona el evento que llega, frecuentemente a través de un gestor de eventos (handler) o callback. 3. El controlador accede al modelo, actualizándolo, posiblemente modificándolo de forma adecuada a la acción solicitada por el usuario (por ejemplo, el controlador actualiza el carro de la compra del usuario). Los controladores complejos están a menudo estructurados usando un patrón de comando que encapsula las acciones y simplifica su extensión. 4. El controlador delega a los objetos de la vista la tarea de desplegar la interfaz de usuario. La vista obtiene sus datos del modelo para generar la interfaz apropiada para el usuario donde se refleja los cambios en el modelo (por ejemplo, produce un listado del contenido del carro de la compra). El modelo no debe tener conocimiento directo sobre la vista. Sin embargo, el patrón de observador puede ser utilizado para proveer cierta indirección entre el modelo y la vista, permitiendo al modelo notificar a los interesados de cualquier cambio. Un objeto vista puede registrarse con el modelo y esperar a los cambios, pero aun así el modelo en sí mismo sigue sin saber nada de la vista. El controlador no pasa objetos de dominio (el modelo) a la vista aunque puede dar la orden a la vista para que se actualice. Nota: En algunas implementaciones la vista no tiene acceso directo al modelo, dejando que el controlador envíe los datos del modelo a la vista. 5. La interfaz de usuario espera nuevas interacciones del usuario, comenzando el ciclo nuevamente. 48
59 Para el modelo MVC se ha elegido una implementación basada en JavaEE. Modelo: El modelo se controla a través de los DAOs (Data Access Control) para el acceso a los datos, que son clases java que acceden a la base de datos y transmiten al controlador los datos solicitados. Controlador: El controlador lo llevan los Servicios, que controlan todo el flujo de datos y realizan todas las funcionalidades del sistema. Es el encargado de operar con ellos son los servicios. Para la recepción de eventos se utilizan los Servlets que ceden el control a los servicios. Vista: La vista la generan los JSPs (Java Server Pages) generando un código HTML interpretable por cualquier navegador. 6.2 Diagramas de secuencia Una vez elegida la implementación para el sistema, se realizan los diagramas de secuencia para los casos de uso. Los diagramas de secuencia son un tipo de diagramas de interacción. Estos diagramas representan las interacciones, que consisten en el intercambio de mensajes entre un conjunto de objetos con un propósito específico. 49
60 Los diagramas de secuencia hacen énfasis en la secuencia temporal de los mensajes enviados. Mostramos los diagramas de secuencia para los casos de uso descritros en el capítulo anterior: Definir Plan 1. El usuario introduce el número de máquinas y trabajos que actúan. 2. La aplicación valida los datos y muestra el formulario de nombres y tareas por trabajo. 3. El usuario introduce el nombre de las máquinas y trabajos que actúan. 4. El usuario indica el número de tareas por trabajo. 5. La aplicación valida los datos y muestra el formulario tiempos y secuencia. 6. El usuario establece el orden de ejecución de las máquinas 7. El usuario introduce el tiempo de ejecución en máquina 8. La aplicación valida los datos y guarda la planificación. 50
61 Diagrama de secuencia GUI :Maquina :Trabajo :Tarea 1:setMaquina 2: settrabajo ServletPlanificador :Planificación 3: settarea 4: setplanificacion(maquina, trabajo, tarea) <<create>> planificacion 6: SchedulerTENTA Cadifra Evaluation 51
62 6.2.2 Ejecutar Planificación 1. El usuario elige ejecutar la planificación. 2. El sistema ejecuta la planificación. 3. El planificador crea las tablas y el gantt Diagrama de secuencia GUI ServletPlanificador :Planificación ServletJchartGantt :Tabla :Jchart 1: ejecutar(plan) 2: <<create>> planificacion 3: <<exec>> SchedulerTENTA 4: <<create>> Jchart 5: settablas(plan) <<create>> tabla 6: setgantt(plan) Cadifra Evaluation 52
63 6.2.3 Subir planificación 1. El usuario selecciona subir la planificación. 2. El sistema comprueba que existe la planificación y muestra el formulario de subida. 3. El sistema sube la planificación al servidor para su ejecución. Diagrama de secuencia GUI ServletUpload ServletPlanificador 1: upload(planificacion) 2: setplanificacion(planificacion) 3: <<exec>> SchedulerTENTA Cadifra Evaluation 53
64 6.2.4 Subir Resultado 1. El usuario selecciona el resultado de la planificación. 2. El sistema comprueba que existe el resultado y muestra el formulario de subida. 3. La aplicación sube el resultado al servidor. 4. El sistema muestra el resultado en tablas y gráfica. Diagrama de secuencia GUI ServletUpload ServletJchartGantt :Tabla :Jchart 1: upload(resultado) 2: setresultado(resultado) 3: settablas(plan) <<create>> tabla 4: setgantt(plan) Cadifra Evaluation 54
65 6.2.5 Descargar Planificación 1. El usuario selecciona la planificación. 2. El sistema comprueba que existe la planificación. 3. El usuario indica la ruta a descargar. 4. El sistema ofrece la planificación. Diagrama de secuencia GUI ServletDownload 1: download(planificación) Cadifra Evaluation 55
66 6.2.6 Descargar Resultado 1. El usuario selecciona el resultado. 2. El sistema comprueba que existe el resultado. 3. El usuario indica la ruta a descargar. 4. El sistema ofrece el resultado a descargar. Diagrama de secuencia GUI ServletDownload 1: download(resultado) Cadifra Evaluation 56
67 6.3 Análisis Funcional Objetivo El objetivo del apartado es proporcionar un análisis funcional del nuevo sistema Scheduler TENTA; incluyendo los aspectos básicos propios del sistema y, por tanto, comunes a todos los servicios que se implementarían sobre él. Por otra parte, se analizan los servicios que se acometen durante su implantación, desde las operaciones de entrada al sistema hasta las salidas de los resultados esperados Definición del plan de trabajos Desde la GUI del Scheduler TENTA se definirá el plan de trabajo asociado al problema planteado por el cliente. La definición consta de tres pasos: 1. En primer lugar se definirán el número de máquinas y trabajos que interactúan en la planificación. 2. En segundo lugar se nombrarán las máquinas que intervienen, así como los trabajos que la ejecutan. También deberá ser un dato de entrada el número de tareas de los que consta cada trabajo. 3. Por último, se indicará el orden en que cada tarea se ejecuta en un trabajo, el recurso en el que actúa y las unidades de tiempo que requiere para su ejecución. 57
68 6.3.3 Validación de restricciones En cumplimiento con los requisitos exigidos, en cada paso de los anteriormente descritos, se deberá proceder a la validación de las entradas recibidas. 1. El número mínimo de máquinas que actúan es 3 y el máximo 10. El número mínimo de trabajos que actúan es 3 y el máximo es 10. Estos son datos parametrizables, si bien el número de mínimo nunca deberá ser menor de 3 por restricción del JSSP. 2. Los nombres de las máquinas y los trabajos serán cadenas de caracteres de longitud 15. El mínimo número de tareas en un trabajos es 2 y el máximo es 10. Estos son datos parametrizables, si bien el número mínimo de tareas por trabajo debe ser 2 por la misma razón que el punto anterior. 3. En un trabajo deben actuar al menos dos máquinas distintas. Estos se consigue directamente con la restricción de mínimo 2 tareas por trabajo y la nueva que impide que en un mismo trabajo se ejecuten dos tareas conecutivas en la misma máquina. Las unidades de tiempo son enteros positivos, estando previsto su inclusión como de doble precisión en una nueva implementación Generación de tablas resultado Scheduler TENTA deberá mostrar los datos obtenidos por la ejecución del algoritmo de la siguiente manera: 58
69 Máquina de ejecución para la tarea 1 Tiempo de inicio para la tarea 1 Nombre del Trabajo Tiempo de fin para la tarea Máquina de ejecución para la tarea n Tiempo de inicio para la tarea n Tiempo de fin para la tarea n Duración de la tarea 1 Duración de la tarea n Generación del diagrama de Gantt asociado a la solución Scheduler TENTA deberá mostrar los datos obtenidos de la planificación en una imagen cuya representación sea un diagrama de Gantt como el que sigue. Dónde Fresa, Torno y Fresa representan las máquinas en las que se ejecuta la tarea perteneciente al trabajo idicado por su color. Existen tres trabajos (Trabajo A, Trabajo B y Trabajo C). 59
70 PROGRAMACIÓN 6.4 Orientación a objetos La orientación a objetos es el paradigma de programación más utilizado actualmente en el desarrollo de aplicaciones. Esto se debe a la existencia de lenguajes como Java, C# y otros, que aportan otras muchas características que los hacen fáciles de usar, potentes, compatibles con muchas plataformas y, sobre todo, seguros y fáciles de depurar. El paradigma de programación orientada a objetos establece una asociación entre la información y las sentencias encargadas de gestionar dicha información. Desde un punto de vista de la programación procedimental, la orientación a objetos se puede ver como la asociación entre funciones y procedimientos a los tipos de datos que manejan. En programación orientada a objetos una clase es el conjunto formado por la definición de la estructura de la información y las sentencias que la gestionan. A los subprogramas que gestionan los datos, se les denomina métodos. A cada uno de los ítems de información que definen la estructura de la información se les denomina atributos o campos. En esta forma de organizar el código el módulo mínimo de programación es la clase. Cuando ejecutamos un programa orientado a objetos, a la entidad que tiene los valores de los ítems definidos en una clase se le denomina objeto. Además de esta organización del código existen primitivas de encapsulamiento, de forma que los atributos existentes en una clase quedan ocultos a los usuarios de esa clase. Para comunicar esa información se utilizan los métodos. Al conjunto de métodos de una clase que pueden ser usados por otras clases se le denomina interfaz pública. Las principales aportaciones de este paradigma al desarrollo de sistemas software son: 60
71 Herencia: característica que permite construir una clase (conocida como clase hija) basándose o teniendo como plantilla otra clase construida previamente (conocida como clase padre). Al utilizar una clase padre como base para definir una clase hija, los atributos y métodos definidos en la clase padre están disponibles en la clase hija. Es decir, los objetos de la clase hija tendrán valores para los atributos definidos en la clase hija y también tendrán valores para los atributos definidos en la clase padre. Esta característica permite una mayor reutilización del código, ya que si dos clases de un programa tienen ciertas características en común, se puede construir una clase que sea clase padre de las dos clases albergando los atributos y métodos que sean comunes a ambas. Polimorfismo: característica de la programación orientada a objetos, muy relacionada con la herencia, que solventa un conjunto de problemas típicos que aparecían en la programación procedimental. En multitud de aplicaciones es necesario gestionar información con distinta estructura de una forma homogénea. Por ejemplo, en un programa de diseño gráfico hay que gestionar figuras geométricas de distintos tipos como rectángulos, círculos, triángulos,... En algunos casos, estas figuras han de gestionarse de forma homogénea, si se quiere cambiar su color o moverlas por el área de dibujo. En otras ocasiones, cada tipo de figura tendrá que responder de una forma particular. Si se quiere calcular su área, para cada tipo de figura hay que usar una expresión distinta. Para tratarlas de forma homogénea, se crea una clase padre, llamada Figura. En esta clase se definen los métodos comunes a todas las figuras: cambiar el color o cambiar su posición. En cambio, el área no se puede definir de una forma común y, por tanto, cada uno de los tipos de figuras definen su propio método para el cálculo del área. En la clase padre hay que definir un método que no tiene implementación, llamado abstracto. La implementación de este método será establecido en cada una de las clases hijas que representan a cada tipo de figura. Si declaramos una variable de la clase Figura, puede contener objetos de cada una de las clases hijas. Cuando sobre el valor de esta variable se ejecuta el 61
72 método de cálculo del área, se usa el polimorfismo y se ejecuta la implementación del método que corresponde a la clase concreta de la figura. Es decir, el código que se va a ejecutar cuando se llame a un método, depende de la clase del objeto concreto que reciba el mensaje y no de la clase de la variable en que se llame. 6.5 Java El lenguaje de programación utilizado en el desarrollo de este proyecto ha sido Java. A continuación, se presentan algunas de las características que han llevado a la elección de este lenguaje: Orientado a objetos: Java trabaja con sus datos como objetos y con interfaces a esos objetos. Soporta las características propias del paradigma de la orientación a objetos: abstracción, encapsulamiento, herencia y polimorfismo. Encaja perfectamente con el proceso unificado de desarrollo, visto anteriormente. Simple: Posee una curva de aprendizaje muy rápida. Ofrece toda la funcionalidad de un lenguaje potente, pero sin las características menos usadas y más confusas de éstos. Robusto: Java realiza verificaciones en busca de problemas, tanto en tiempo de compilación como en tiempo de ejecución. La comprobación de tipos en Java ayuda a detectar errores lo antes posible, en el ciclo de desarrollo. Java obliga a la declaración explícita de los tipos de los ítems de información, reduciendo así las posibilidades de error. Maneja la memoria para eliminar las preocupaciones por parte del programador de la liberación o corrupción de la misma. Portable: La indiferencia de la arquitectura representa sólo una parte de su portabilidad. Además, Java especifica los tamaños de sus tipos de datos 62
73 básicos y el comportamiento de sus operadores aritméticos, de manera que los programas son iguales en todas las plataformas. Estas dos últimas características se conocen como la Máquina Virtual Java (JVM). Orientado a aplicaciones: Dispone de muchas bibliotecas orientadas al desarrollo de múltiples aplicaciones, por ejemplo, existen librerías para gestionar bases de datos, para XML, gráficos, etcétera. 6.6 Aplicaciones Web En la ingeniería software se denomina aplicación web a aquellas aplicaciones que los usuarios pueden utilizar accediendo a un servidor web a través de Internet o de una intranet mediante un navegador. En otras palabras, es una aplicación software que se codifica en un lenguaje soportado por los navegadores web (HTML, JavaScript, Java, etc.) en la que se confía la ejecución al navegador. Las aplicaciones web son populares debido a lo práctico del navegador web como cliente ligero, así como a la facilidad para actualizar y mantener aplicaciones web sin distribuir e instalar software a miles de usuarios potenciales. Existen aplicaciones como los webmails, wikis, weblogs, tiendas en línea que son ejemplos bien conocidos de aplicaciones web. Es importante mencionar que una página Web puede contener elementos que permiten una comunicación activa entre el usuario y la información. Esto permite que el usuario acceda a los datos de modo interactivo, gracias a que la página responderá a cada una de sus acciones, como por ejemplo rellenar y enviar formularios, participar en juegos diversos y acceder a gestores de base de datos de todo tipo. 63
74 6.6.1 Uso empresarial Una estrategia que está emergiendo para las empresas proveedoras de software consiste en proveer acceso vía web al software. Para aplicaciones previamente distribuidas, como las aplicaciones de escritorio, se puede optar por desarrollar una aplicación totalmente nueva o simplemente por adaptar la aplicación para ser usada con una interfaz web. Estos últimos programas permiten al usuario pagar una cuota mensual o anual para usar la aplicación, sin necesidad de instalarla en el ordenador del usuario. Las compañías que siguen esta estrategia se denominan Proveedores de Aplicaciones de Servicio (ASP por sus siglas en inglés), un modelo de negocio que está atrayendo la atención de la industria del software Ventajas y desventajas de las aplicaciones web Como ventajas proporcionan movilidad, dado que puedes ejecutarlas desde cualquier ordenador con conexion a internet. La información que manejan se accede a través de internet, motivo por el cual son especialmente interesantes para desarrollar aplicaciones multiusuario basadas en la compartición de información. El cliente o usuario que utiliza la aplicación no necesita tener un ordenador de grandes prestaciones para trabajar con ella. Desventajas: la comunicación constante con el servidor que ejecuta la aplicación establece una dependencia con una buena conexión a internet. Además, el servidor debe tener las prestaciones necesarias para ejecutar la aplicación de manera fluida, no sólo para un usuario sino para todos los que la utilicen de forma concurrente. 64
75 6.7 Servlets y JSP Servlets Java Los Servlets son las respuesta de la tecnología Java a la programación CGI. Son programas que se ejecutan en un servidor Web y construyen páginas Web. Construir páginas Web al vuelo es útil (y comunmente usado) por un número de razones: La página Web está basada en datos envíados por el usuario. Por ejemplo, las páginas de resultados de los motores de búsqueda se generan de esta forma, y los programas que procesan pedidos desde sitios web de comercio electrónico también. Los datos cambian frecuentemente. Por ejemplo, un informe sobre el tiempo o páginas de cabeceras de noticias podrían construir la página dinámicamente, quizás devolviendo una página previamente construida y luego actualizándola. Las páginas Web que usan información desde bases de datos corporativas u otras fuentes. Por ejemplo, usaríamos esto para hacer una página Web en una tienda on-line que liste los precios actuales y el número de artículos en stock Estructura Básica de un Servlet Aquí tenemos un servlet básico que maneja peticiones GET. Las peticiones GET son hechas por el navegador cuando el usuario teclea una URL en la línea de direcciones, sigue un enlace desde una página Web, o rellena un formulario que no especifica un METHOD. Los Servlets también pueden manejar peticiones 65
76 POST muy fácilmente, que son generadas cuando alguien crea un formulario HTML que especifica METHOD="POST". import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class SomeServlet extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { submitted) // Use "request" to read incoming HTTP headers (e.g. cookies) // and HTML form data (e.g. data the user entered and headers // Use "response" to specify the HTTP response line and // (e.g. specifying the content type, setting cookies). } } PrintWriter out = response.getwriter(); // Use "out" to send content to browser Para ser un servlet, una clase debería extender HttpServlet y sobreescribir doget o dopost (o ambos), dependiendo de si los datos están siendo enviados mediante GET o POST. Estos métodos toman dos argumentos: un HttpServletRequest y un HttpServletResponse. El HttpServletRequest tiene métodos que nos permiten encontrar información entrante como datos de un FORM, cabeceras de petición HTTP, etc. El HttpServletResponse tiene métodos que nos permiten especificar líneas de respuesta HTTP (200, 404, etc.), cabeceras de respuesta (Content-Type, Set- Cookie, etc.), y, todavía más importante, nos permiten obtener un PrintWriter usado para envíar la salida de vuelta al cliente. Para servlets sencillos, la mayoría del esfuerzo se gasta en sentencias println que generan la página deseada. 66
77 Observamos que doget y dopost lanzan dos excepciones, por eso es necesario incluirlas en la declaración. También observamos que tenemos que importar las clases de los paquetes java.io (para PrintWriter, etc.), javax.servlet (para HttpServlet, etc.), y javax.servlet.http (para HttpServletRequest y HttpServletResponse). Finalmente, observamos que doget y dopost son llamados por el método service, y algunas veces queremos sobreescribir directamente el método service, por ejemplo, para un servlet que maneje tanto peticiones GET como POST Servlets de la aplicación web A continuación mostramos los dos servlets más importantes de la aplicación web, su código y una descripción de su funcionalidad Planificador.java package es.tenta.scheduler.servlets; import java.io.ioexception; import javax.servlet.servletexception; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import es.tenta.scheduler.utils.utils; public class Planificador extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { if (request.getparameter("modo").equals("definicion")){ String nombresmt; 67
78 Utils ut = new Utils(); ut.crearficheroproblema(request); ut.ejecutaficheroproblema(); nombresmt = ut.getnombresmt(request); response.sendredirect("./jsp/resultado.jsp? idficherores=resultado1.txt"+nombresmt); } else if(request.getparameter("modo").equals("upload")) { Utils ut = new Utils(); ut.ejecutaficheroproblema(); idficherores=resultado1.txt"); } response.sendredirect("./jsp/resultado2.jsp? } public void dopost(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { doget(request, response); } } Este servlet es el encargado de ejecutar la planificación definida (modo definición) o subida por fichero (modo upload). El método dopost está sobreescrito para que todas las peticiones al servlet se procesen por el método doget. 68
79 Dentro del método doget, el servlet creará el fichero problema y procederá a la ejecución de la planificación, dejando el resultado en el servidor e indicando este parámetro con respuesta de la petción Jchart.java package es.tenta.scheduler.servlets; import java.awt.color; import java.io.ioexception; import java.io.outputstream; import java.util.arraylist; import java.util.hashmap; import java.util.iterator; import java.util.map; import java.util.set; import java.util.stringtokenizer; import javax.servlet.servletexception; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import org.jfree.chart.chartfactory; import org.jfree.chart.chartutilities; import org.jfree.chart.jfreechart; import org.jfree.chart.axis.symbolaxis; import org.jfree.chart.plot.plotorientation; import org.jfree.chart.plot.xyplot; import org.jfree.chart.renderer.xy.xybarrenderer; import org.jfree.data.time.simpletimeperiod; import org.jfree.data.xy.intervalxydataset; import org.jfree.data.xy.xyintervalseries; import org.jfree.data.xy.xyintervalseriescollection; import es.tenta.scheduler.model.tarea; import es.tenta.scheduler.utils.utils; public class Jchart extends HttpServlet { 69
80 public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { String idproblema = request.getparameter("idficherores").tostring(); System.out.println(idProblema); Utils ut = new Utils(); OutputStream out = response.getoutputstream(); ArrayList<String> nombremaquinas = new ArrayList<String>(); ArrayList<String> nombretrabajos = new ArrayList<String>(); nombremaquinas = ut.getnombremaquinas(request); nombretrabajos = ut.getnombretrabajos(request); HashMap<Integer, ArrayList<Tarea>> resultado = new HashMap<Integer, ArrayList<Tarea>>(); resultado = ut.getproblemaxfichero(idproblema); try { JFreeChart chart = null; nombremaquinas, nombretrabajos); chart = createtimeserieschart(resultado, 400); if (chart!= null) { response.setcontenttype("image/png"); ChartUtilities.writeChartAsPNG(out, chart, 900, } } catch (Exception e) { System.err.println(e.toString()); } finally { out.close(); } } 70
81 private JFreeChart createtimeserieschart(hashmap<integer, ArrayList<Tarea>> resultado, ArrayList<String> nombremaquinas, ArrayList<String> nombretrabajos) { return createchart(nombremaquinas, createdataset(resultado, nombretrabajos)); } token){ public static ArrayList<String> getcampos(string s, String } ArrayList<String> a = new ArrayList<String>(); StringTokenizer st = new StringTokenizer(s, token); while (st.hasmoretokens()) a.add(st.nexttoken()); return a; private static IntervalXYDataset createdataset(hashmap<integer,arraylist<tarea>> resultado, ArrayList<String> nombretrabajos) { XYIntervalSeriesCollection dataset = new XYIntervalSeriesCollection(); SimpleTimePeriod stp1 = null; XYIntervalSeries xyitrabajo; ArrayList<Tarea> artareas; Tarea tarea; Integer idtrabajo = null; //String maquina = null; int idmaquina = 0; long tiempoini = 0; long tiempofin = 0; int i; 71
82 Set set = resultado.entryset(); Iterator iter = set.iterator(); // Recorro el hashmap trabajo a trabajo while(iter.hasnext()){ Map.Entry me = (Map.Entry)iter.next(); idtrabajo = (Integer) me.getkey(); artareas = (ArrayList<Tarea>) me.getvalue(); xyitrabajo = new XYIntervalSeries(nombreTrabajos.get(idTrabajo).toString()); dataset.addseries(xyitrabajo); trabajo:"+artareas.size()); //System.out.println("Numero de tareas para el //Recorro el arraylist tarea a tarea for(i = 0; i < artareas.size(); i++){ tarea = artareas.get(i); idmaquina = tarea.getidmaquina(); tiempoini = (long) tarea.gettiempoini(); tiempofin = (long) tarea.gettiempofin(); tiempofin); stp1 = new SimpleTimePeriod(tiempoINI, } additem(xyitrabajo, stp1, idmaquina); } artareas.clear(); } return dataset; private static void additem(xyintervalseries s, SimpleTimePeriod p0, int index) { 72
83 } s.add( p0.getendmillis(), p0.getstartmillis(), p0.getendmillis(), index, index , index ); private static JFreeChart createchart(arraylist<string> nombremaquinas, IntervalXYDataset dataset) { JFreeChart chart = ChartFactory.createXYBarChart("Planificación de SchedulerTENTA", "Tiempo", false, "Y", dataset, PlotOrientation.VERTICAL, true, false, false); chart.setbackgroundpaint(color.gray); XYPlot plot = (XYPlot) chart.getplot(); //String[] sv = new String[] {"R00", "R01", "R02"}; String[] sv = new String[nombreMaquinas.size()];//{"R00", "R01", "R02"}; nombremaquinas.toarray(sv); SymbolAxis yaxis = new SymbolAxis(null, sv); yaxis.setgridbandsvisible(false); plot.setrangeaxis(yaxis); XYBarRenderer renderer = (XYBarRenderer) plot.getrenderer(); renderer.setuseyinterval(true); plot.setbackgroundpaint(color.lightgray); plot.setdomaingridlinepaint(color.white); plot.setrangegridlinepaint(color.white); } return chart; public void dopost(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { 73
84 doget(request, response); } } Éste servlet es el más interesante, ya que realiza la gráfica con el diagrama de Gantt que contiene el resultado de la planificación. Jchart recibe una petición para realizar un diagráma recibiendo como parámetro el resultado de una planificación. Obtiene los nombres de los trabajos y las máquinas en un ArrayList y carga los datos del resultado de la planificación en un HashMap. Éstos son los datos que utilizará Jchart para realizar el gráfico de series de tiempos. chart=createtimeserieschart(resultado,nombremaquinas,nombretrabajos); Dentro de este método, se recorrerá el HashMap dónde cada fila representa un trabajo y su contenido es la secuencia de tareas a ejecutarse en cada máquina. Una a una, se irán agregando al diagrama de Gantt indicando el trabajo al que pertenece, la máquina en dónde se ejecuta, el tiempo inicial de la tarea y el tiempo final de la tarea JSP Java Server Pages (JSP) es una tecnología que nos permite mezclar HTML estático con HTML generado dinámicamente. Muchas páginas Web que están construidas con programas CGI son casi estáticas, con la parte dinámica limitada a muy pocas localizaciones. Pero muchas variaciones CGI, incluyendo los servlets, hacen que generemos la página completa mediante nuestro programa, incluso aunque la mayoría de ella sea siempre lo mismo. JSP nos permite crear dos partes de forma separada. Aquí tenemos un ejemplo: 74
85 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD><TITLE>Ejemplo de JSP/TITLE></HEAD> <BODY> <H1>Ejemplo de JSP</H1> <SMALL>Welcome, <!-- User name es el nombre de usuario logeado --> <% out.println(utils.getusernamefromcookie(request)); %> Para acceder a su configuración de usuario pulse <A HREF="Account-Settings.html">aquí.</A></SMALL> <P> <!-- Resto de HTM --> </BODY></HTML> Ventajas de JSP 1. Sobre Active Server Pages (ASP). ASP es una tecnología similar de Microsoft. Las ventajas de JSP estan duplicadas. Primero, la parte dinámica está escrita en Java, no en Visual Basic, otro lenguaje específico de MicroSoft, por eso es mucho más poderosa y fácil de usar. Segundo, es portable a otros sistemas operativos y servidores Web. 2. Sobre los Servlets. JSP no nos da nada que no pudierámos en principio hacer con un servlet. Pero es mucho más conveniente escribir y modificar HTML normal que tener que hacer un número muy elevado de sentencias de impresión en pantalla que generen HTML. Además, separando el formato del contenido podemos poner diferentes personas en diferentes tareas: nuestros expertos en diseño de páginas Web pueden construir el HTML, dejando espacio para que nuestros programadores de servlets inserten el contenido dinámico. 3. Sobre Server-Side Includes (SSI). SSI es una tecnología ámpliamente soportada que incluye piezas definidas externamente dentro de una página Web estática. JSP es mejor porque nos permite usar servlets en vez de un 75
86 programa separado para generar las partes dinámicas. Además, SSI, realmente está diseñado para inclusiones sencillas, no para programas reales que usen formularios de datos, hagan conexiones a bases de datos, etc. 4. Sobre JavaScript. JavaScript puede general HTML dinámicamente en el cliente. Este una capacidad útil, pero sólo maneja situaciones donde la información dinámica está basada en el entorno del cliente. Con la excepción de las cookies, el HTTP y el envió de formularios no están disponibles con JavaScript. Y, como se ejecuta en el cliente, JavaScript no puede acceder a los recursos en el lado del servidor, como bases de datos, catálogos, información de precios, etc JSPs de la aplicación Cómo hemos descrito anteriormente, la vista de la aplicación se realiza mediante la tecnología JSP. Aquí mostramos las páginas más importantes del SchedulerTENTA iniciotenta.jsp Esta página JSP se encarga de recoger los datos iniciales de las máquinas y los trabajos. Contiene la primera validación javascript que limita el número de máquinas y trabajos que intervienen en la planificación. page language="java" contenttype="text/html; charset=iso " pageencoding="iso "%> import="es.tenta.scheduler.utils.codigohtml"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/tr/html4/loose.dtd"> <html> <head> 76
87 <meta http-equiv="content-type" content="text/html; charset=iso "> <% CodigoHTML ch = new CodigoHTML(); %> <%=ch.setcss("../css/estilo.css") %> <%=ch.settitle("defina el numero de trabajos y maquinas que intervienen en la planificacion") %> <script language="javascript" type="text/javascript"> function validanmt(formu) { var1 = parseint(formu.nummaq.value, 10) var2 = parseint(formu.numtrab.value, 10) if ( isnan(var1) isnan(var2) ) { alert("debe cumplimentar los dos campos con valores numéricos.") return false } else if (var1 < 3 var2 < 3) { alert("los valores numéricos introducidos deben ser positivos y como mínimo 3.") return false } else if( var1 > 10 var2 > 10 ) { alert("el número máximo de Máquinas y Trabajos es 10.") return false } else { return true } } </script> </head> <body> <%= ch.setcabecera() %> <%= ch.setmenu() %> <%= ch.setcuerpo() %> <table width=70% class='contenedor'> <form name="numeromaqtrab" action="./nombresmt.jsp" onsubmit="return validanmt(this);"> <tr> <td> Indique el número de Máquinas y Trabajos que actúan <br><br> 77
88 </td> </tr> <tr><td> <table align ="center" class="datos"> <tr> <th>número de Máquinas</th><td><input type="text" name="nummaq" maxlength="2" size="2"/></td> <td valign='middle'><font color='red' size='-2'>min 3 </br> Max 10</font></td> </tr> <tr> <th>número de Trabajos</th><td><input type="text" name="numtrab" maxlength="2" size="2"/></td> <td valign='middle'><font color='red' size='-2'>min 3 </br> Max 10</font></td> </tr> </table> <tr align="center"> <td><input type="submit" value="continuar"></td><br> </tr> </td></tr> </form> </table> <%= ch.setfin() %> </body> </html> 78
89 nombresmt.jsp La JSP de nombres simplemente recoge los nombres que identificarán a las máquinas y los trabajos. En ella también se recoge el número de tareas que componen cada trabajo. La validación javascript limita el número de tareas. page language="java" contenttype="text/html; charset=iso " pageencoding="iso "%> import="es.tenta.scheduler.utils.codigohtml"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/tr/html4/loose.dtd"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=iso "> <% CodigoHTML ch = new CodigoHTML(); %> <%=ch.setcss("../css/estilo.css") %> <%=ch.settitle("introduzca los nombres de las maquinas y los trabajos. Tareas por trabajo.") %> <script language="javascript" type="text/javascript"> function validatxt(formu) { numtra = parseint(formu.numtrab.value, 10) error1st = false error1 = "\ndebe cumplimentar los campos de tarea x trabajo con valores numéricos:\n" error2st = false error2 = "\nel mínimo de tareas x trabajo es 2:\n" error3st = false error3 = "\nel número máximo de tareas x trabajo es 10:\n" estado = true for (var i = 0; i < numtra; i++){ TxT = "TxT" + String(i) valortxt = parseint(eval('formu.'+[txt]+'.value')) 79
90 } if (isnan(valortxt)) { error1 += String(eval('formu.T'+ i +'.value'))+ " " error1st = true estado = false } else if (valortxt < 2) { error2 += String(eval('formu.T'+ i +'.value'))+ " " error2st = true estado = false } else if(valortxt > 10) { error3 += String(eval('formu.T'+ i +'.value'))+ " " error3st = true estado = false } if(estado == false){ if (error1st) {alert(error1)} if (error2st) {alert(error2)} if (error3st) {alert(error3)} } return estado } </script> </head> <% String nummaq = request.getparameter("nummaq"); String numtrab = request.getparameter("numtrab"); Integer nm = new Integer(request.getParameter("numMaq")); Integer nt = new Integer(request.getParameter("numTrab")); %> <body> <%= ch.setcabecera() %> <%= ch.setmenu() %> 80
91 <%= ch.setcuerpo() %> <table width=70% class='contenedor'> <form name="nombresmaqtrab" action="./definirplan.jsp" onsubmit="return validatxt(this);"> <table class='contenedor'> <tr> <td> <table class="datos"> <tr><td></td> <th>nombre Maquina</th> </tr> <% for(int i=0; i < nm.intvalue(); i++) { %> <tr> <th>maquina <%=i%></th><td><input type="text" name="r<%=i%>" size="15" maxlength="15" value="maquina<%=i %>"/></td> </tr> <% } %> </table> </td> <td> <table class="datos"> <tr><td></td> <th>nombre Trabajo</th> <th>numero tareas</th> </tr> <% for(int i=0; i < nt.intvalue(); i++) { %> <tr> <th>trabajo <%=i%></th><td><input type="text" name="t<%=i%>" size="15" maxlength="15" value="trabajo<%=i %>"/></td> <td><input type="text" name="txt<%=i%>" maxlength="2" size="2"/></td> </tr> 81
92 <%} %> </table> </td> </tr> <tr align="center"><td colspan=2><input type="submit" value="continuar"></td></tr> </table> <input type="hidden" name="nummaq" value="<%= nm %>"> <input type="hidden" name="numtrab" value="<%= nt %>"> </form> </table> <%= ch.setfin() %> </body> </html> definirplan.jsp Ésta es sin duda la JSP de la aplicación. En ella se recogerán los datos de la planificación. Cada fila del formulario representa un trabajo en el que se define la secuencia de tareas a ejecutar en cada máquina. La validación javascript validará 82
93 los tiempos, así como las restricciones que impone la secuencia de ejecución como por ejemplo no poder ejecutar dos tareas consecutivas en la misma máquina si pertenecen al mismo trabajo. page language="java" contenttype="text/html; charset=iso " pageencoding="iso "%> import="java.util.arraylist"%> import="es.tenta.scheduler.utils.codigohtml"%> import="es.tenta.scheduler.utils.utils"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/tr/html4/loose.dtd"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=iso "> <% CodigoHTML ch = new CodigoHTML(); Utils ut = new Utils(); %> <%=ch.setcss("../css/estilo.css") %> <%=ch.settitle("definicion del Plan de Trabajo.") %> <script language="javascript" type="text/javascript"> function validaplan(formu) { numtra = parseint(formu.numtrab.value, 10) centinela1 = false error1st = false error1 = "Debe cumplimentar los campos de tiempo de tarea con valores numéricos:\n" centinela2 = false error2st = false error2 = "Las unidades de tiempo deben ser entre 1 y 9999:\n" centinela3 = false error3st = false error3 = "No puede haber dos tareas consecutivas que se ejecuten en la misma máquina:\n" estado = true 83
94 for (var i = 0; i < numtra; i++){ TxT = "TxT" + String(i) valortxt = parseint(eval('formu.'+[txt]+'.value')) centinela1 = false centinela2 = false centinela3 = false secuenciatrabajo = " " for(var j = 0; j < valortxt; j++) { +'.value')) +'.value')) tareatiempo = "tareatiempo" + String(i) + String(j) valortareatiempo = parseint(eval('formu.'+[tareatiempo] tareamaquina = "tareamaquina" + String(i) + String(j) valortareamaquina = parseint(eval('formu.'+[tareamaquina] "\n" "\n" if (isnan(valortareatiempo) && centinela1 == false) { error1 += String(eval('formu.T'+ i +'.value'))+ error1st = true estado = false centinela1 = true } else if (valortareatiempo < 1 && centinela2 == false) { error2 += String(eval('formu.T'+ i +'.value'))+ error2st = true estado = false centinela2 = true } } secuenciatrabajo += String(valorTareaMaquina) for (var k = 1; k < secuenciatrabajo.length-1; k++) { if(string(secuenciatrabajo.substring(k,k+1)) == String(secuenciaTrabajo.substring(k+1,k+2)) && centinela3 == false) { error3 += String(eval('formu.T'+ i +'.value'))+ "\n" 84
95 } } } error3st = true estado = false centinela3 = true if(estado == false){ if (error1st) {alert(error1)} if (error2st) {alert(error2)} if (error3st) {alert(error3)} } return estado } </script> </head> <% Integer nm = new Integer(request.getParameter("numMaq")); Integer nt = new Integer(request.getParameter("numTrab")); Integer ntt = new Integer(0); int i; int j; int k; String param1 = null; String param2 = null; String param3 = null; ArrayList nombremaquinas = new ArrayList(); ArrayList nombretrabajos = new ArrayList(); nombremaquinas = ut.getnombremaquinas(request); nombretrabajos = ut.getnombretrabajos(request); %> <body> <%= ch.setcabecera() %> <%= ch.setmenu() %> 85
96 <%= ch.setcuerpo() %> <table width=70% class='contenedor'> <form name="defineplanform" action="../planificador" onsubmit="return validaplan(this);"> <table class='contenedor'> <tr> <td> Introduca el tiempo de ejecución por tarea y la máquina donde se ejecuta.<br> El orden de las tareas es como se muestra.<br> </td> </tr> <tr align='center'> <td align='center'> <table align='center' class="datos"> <% for(i=0; i < nt.intvalue(); i++) { %>"> param2 = "T" + i; param3 = "TxT"+i; ntt = new Integer(request.getParameter(param3)); %> <input type="hidden" name="<%=param3 %>" value="<%= ntt <tr> <th><%= nombretrabajos.get(i).tostring() %></th> <% for(k=0; k < ntt.intvalue(); k++) { %> <td> <select name="tareamaquina<%=(i + "" + k) %>"> <% for(j=0; j < nm.intvalue(); j++) { %> <option value="<%=j %>"><%= nombremaquinas.get(j).tostring() %> <%}//for maquinas %> </select> </td> <td> <input type="text" name="tareatiempo<%=(i + "" + k) %>" size="4" maxlength="4"> 86
97 </td> <%}//for tareas por trabajo %> </tr> <%}//for de trabajos %> </td> </tr> </table> </table> <br><input type="submit" value="continuar"> <% for(i=0; i < nm.intvalue(); i++) { param1 = "R"+i; %> <input type="hidden" name="<%=param1 %>" value="<%= nombremaquinas.get(i) %>"> <% } for(i=0; i < nt.intvalue(); i++) { param2 = "T"+i; %> <input type="hidden" name="<%=param2 %>" value="<%= nombretrabajos.get(i) %>"> <% } %> <input type="hidden" name="nummaq" value="<%= nm %>"> <input type="hidden" name="numtrab" value="<%= nt %>"> <input type="hidden" name="modo" value="definicion"> </form> </table> <%= ch.setfin() %> </body> </html> 87
99 resultado.jsp La última JSP que mostramos es la encargada de imprimir en pantalla la gráfica del diagrama de Gantt y las tablas resultado de la planificación ejecutada. page language="java" contenttype="text/html; charset=iso " pageencoding="iso "%> import="java.util.arraylist"%> import="java.util.hashmap"%> import="es.tenta.scheduler.utils.codigohtml"%> import="es.tenta.scheduler.utils.utils"%> import="es.tenta.scheduler.model.tarea"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/tr/html4/loose.dtd"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=iso "> <% CodigoHTML ch = new CodigoHTML(); Utils ut = new Utils(); %> <%=ch.setcss("../css/estilo.css")%> <%=ch.settitle("planificacion ofrecida por SchedulerTENTA.") %> </head> <% String idproblema = request.getparameter("idficherores"); //String idproblema = "resultado1.txt"; System.out.println(idProblema); String urljchart = ut.geturljchart(request); ArrayList nombremaquinas = new ArrayList(); ArrayList nombretrabajos = new ArrayList(); HashMap<Integer, ArrayList<Tarea>> resultado = new HashMap<Integer, ArrayList<Tarea>>(); nombremaquinas = ut.getnombremaquinas(request); 89
100 nombretrabajos = ut.getnombretrabajos(request); resultado = ut.getproblemaxfichero(idproblema); %> //System.out.println(urlJchart); <body> <%= ch.setcabecera() %> <%= ch.setmenu() %> <%= ch.setcuerpo() %> <table width=100% class='contenedor'> <tr> <td align='center'> <IMG SRC="../jchart?<%=urlJchart %>" BORDER=1/> </td> </tr> <tr> <td><hr></td> </tr> <tr> <td> <table class='datos' WIDTH='65%' align='center'> <tr> <th>fichero Planificación</th> <th>fichero Resultado</th> </tr> <tr> <td><a HREF='../download? idficherores=problema1.txt&folder=entradas'>descarga Planificación</ A></td> <td><a HREF='../download? idficherores=resultado1.txt&folder=salidas'>descarga Resultado</ A></td> </tr> </table> </td> </tr> <tr> <td><hr></td> </tr> <tr> 90
101 <td> <table align='center' class='contenedor'> <%=ch.gettablasresultado(resultado, nombremaquinas, nombretrabajos) %> </table> </td> </tr> </table> <%= ch.setfin() %> </body> </html> 91
102 6.8 Servidor de Aplicaciones Tomcat de Apache Tomcat es un contenedor de Servlets con un entorno JSP. Un contenedor de Servlets es un shell de ejecución que maneja e invoca servlets por cuenta del usuario. Podemos dividir los contenedores de Servlets en: 2. Contenedores de Servlets Stand-alone (Independientes). Estos son una parte integral del servidor web. Este es el caso cuando usando un servidor web basado en Java, por ejemplo, el contenedor de servlets es parte de JavaWebServer (actualmente sustituido por iplanet). Este el modo por defecto usado por Tomcat. Sin embargo, la mayoría de los servidores, no están basados en Java, los que nos lleva los dos siguientes tipos de contenedores. 3. Contenedores de Servlets dentro-de-proceso. El contenedor Servlet es una combinación de un plugin para el servidor web y una implementación de contenedor Java. El plugin del servidor web abre una JVM (Máquina Virtual Java) dentro del espacio de direcciones del servidor web y permite que el contenedor Java se ejecute en él. Si una cierta petición debería ejecutar un servlet, el plugin toma el control sobre la petición y lo pasa al contenedor Java (usando JNI). Un contenedor de este tipo es adecuado para servidores multi-thread de un sólo proceso y proporciona un buen rendimiento pero está limitado en escalabilidad 4. Contenedores de Servlets fuera-de-proceso. El contenedor Servlet es una combinación de un plugin para el servidor web y una implementación de contenedor Java que se ejecuta en una JVM fuera del servidor web. El plugin del servidor web y el JVM del contenedor Java se comunican usando algún mecanismo IPC (normalmente sockets TCP/IP). Si una 92
103 cierta petición debería ejecutar un servlet, el plugin toma el control sobre la petición y lo pasa al contenedor Java (usando IPCs). El tiempo de respuesta en este tipo de contenedores no es tan bueno como el anterior, pero obtiene mejores rendimientos en otras cosas (escalabilidad, estabilidad, etc.). Tomcat puede utilizarse como un contenedor solitario (principalmente para desarrollo y depuración) o como plugin para un servidor web existente (actualmente se soporan los servidores Apache, IIS y Netscape). Esto significa que siempre que despleguemos Tomcat tendremos que decidir cómo usarlo, y, si seleccionamos las opciones 2 ó 3, también necesitaremos instalar un adaptador de servidor web. 93
104 CAPÍTULO 7. PLANIFICACIÓN El anterior diagrama de Gantt muestra la planificación del proyecto. Puesto que es una planificación temporal sin intervención de recursos donde ejecutar las tareas, se ha descartado la utilización de SchedulerTENTA para planificación. La primera fase fue la de Lanzamiento, en el mes de octubre. En noviembre se realizó la identificación de necesidades, tomando el transcurso del proyecto una parada en navidades. En enero y febrero se llevó a cabo el Análisis de Requisitos, empezando este último mes con El Diseño del Sistema. Desde finales de abril hasta setiembre se programó la aplicación web. Durante todo el proceso se llevó a cabo la tarea de documentación. 94
105 CAPÍTULO 8. PRESUPUESTO Antes de proporcionar el presupuesto, se ha de indicar las personas que intervienen, sus cometidos y el salario que percibirán. El Jefe de Proyecto estará muy presente en las fases de lanzamiento, identificación de necesidades y documentación. El coste por hora del Jefe de Proyecto es de 42. El Analista Funcional se encargará del análisis de requisitos y el diseño del sistema. Su tarifa asciende a 36 euros por hora. El Programador Senior realizará las tareas de programación y pruebas. Su tarifa es de 30 euros por hora. El Director y Coodinador del proyecto hará el seguimiento del mismo así como labores de gestión y burocracia. Su tarifa asciende a 52 euros por hora. ACTIVIDAD HORAS COSTE Lanzamiento 6 90 Id. de Necesidades A. de Requisitos Diseño del Sistema Programación Pruebas Documentación Dirección y Coordinación TOTAL
106 CAPÍTULO 9. CONCLUSIONES Y LÍNEAS FUTURAS El desarrollo de SchedulerTENTA hace uso de las tecnologías presentes en el mundo empresarial con un coste muy bajo, debido al uso en su mayoría de estándares abiertos. Una solución a bajo coste es lo que necesitan los pequeños y medianos empresiarios para sacar el mayor provecho posible (dentro de temperatura admisible por el algoritmo del recocido simulado) de sus horas de trabajo en las líneas de producción. Las soluciones de alto coste e interfaces complicados son los proncipales obstáculos que se encuentran a la hora de crecer como empresarios. Salvado el primer escollo, se hace necesaria una herramienta que permita de una forma sencilla definir el plan de trabajo diario o semanal, siempre dentro de la programación a corto plazo. Con SchedulerTENTA se han conseguido eliminar ambos obstáculos. Gracias a la realización de este proyecto, he podido acercarme al estudio de ciertos algoritmos, en especial el del recocido simulado, descubriento su existencia y entendiendo en parte su funcionamiento. También he podido entender como se definen los planes de trabajo en las cadenas de producción en serie, así como lo optimizable de su desarrollo. Este proyecto fin de carrera, me ha permitido crear un proyecto de principio a fin, desarrollando cada una de sus fases, desde el diseño hasta la programación sin olvidar el proceso de documentación que ha acompañado al proyecto durante su desarrollo. Las herramientas adquiridas durante la carrera me han servido de mucha ayuda, ya sean los lenguajes de programación, como la asignatura de ingeniería de software, me han permitido abarcar el proyecto de una forma profesional. La experiencia del aprendizaje en la escuela, me ha permitido 96
107 entender mejor las herramientas que antes no conocía y ponerlas en práctica en un proyecto completo. La principal línea de mejora de este proyecto está en la gestión de usuarios, ya que abarcar el principio de definición del problema no me ha permitido desarrollar esta parte que considero muy interesante en vista de la cotinuidad del mismo. 97
108 BIBLIOGRAFÍA [LDHPS04] López de Haro, S., Sánchez Martín, P. y Conde Collado, J.: Secuenciación de tareas mediante metaheurísticos. VIII Congreso de Ingeniería de Organización, Leganés, 2004 [WEIS00] Gerald Weiss, David M. Arnow Introducción a la programación con Java: Un enfoque orientado a objetos, Addison Wesley, 2000 [LARM04] Craig Larman, UML y Patrones: Una introducción al análisis y diseño orientado a objetos y al proceso unificado, Prectice Hall 2ª Edición, Hill,2002. [SCHI02] Herbert Schildt, Manual de referencia: Java 2, Osborne MCGraw- [JEWE02] Jewell Tyler, Allamaraju Subrahmanyam, Beust Cedric, Davies John, Jonson Rod, Longshaw Andrew, Nagappan Armes, O Connor Daniel, Toussaint Alex, Tyagi Sameer, Watson Gary, Wilcox Mark, Programación Java Server con J2EE Edición 1.3 Profesional, Anaya Multimedia, La enciclopedia libre plurilingüe basada en tecnología wiki. Manual de JavaScript API de JFreeChart API Java Asociación de Java de hispanohablantes 98
109 Manual de usuario ANEXOS Como guía paso a paso vamos a ver un ejemplo práctico donde tres trabajos (A, B y C) tienen que pasar por tres recursos como pueden ser Mesa, Torno y Fresa. El primer paso consiste en definir el número de Máquinas y Trabajos que interactúan. En nuestro caso son 3 Máquinas (mesa, Torno y Fresa) y 3 Trabajos (A, B y C). Hemos de resaltar que para esta primera versión libre existen una limitación máxima de 10 Trabajos y 10 Máquinas para realizar un proceso de optimización. El segundo paso que hemos de dar también es sencillo. Debemos nombrar las Máquinas y Trabajos para facilitar su lectura en las tablas, así como indicar el número de tareas que tiene cada Trabajo. La restricción que debemos tener en cuenta es la de tener al menos dos tareas en cada Trabajo (para tener algo que optimizar.) 99
110 En el siguiente paso debemos definir la posición relativa de cada subtrabajos en cada máquina. De esta forma, imaginemos por un momento que el orden realativo de los subtrabajos es el siguiente: Trabajo A: Mesa(1), Torno(2) y Fresa(3). Trabajo B: Torno(1), Mesa(2) y Fresa(3). Trabajo C: Fresa(1), Mesa(2) y Torno(3). A continuación definimos el tiempo que está cada subtrabajos en cada Máquina. La forma de rellenar esta tabla es sencilla y debemos tener en cuenta que: no se admiten valores negativos, puesto que esta magnitud del tiempo absoluta no existe ni iguales a cero, puesto que si no tiene duración alguna basta con no incluirla en la tabla de posiciones. Debemos utilizar valores enteros ya que trabajamos con unidades de tiempo. 100
111 Una vez terminado y ejecutada la aplicación obtendremos una vista similar a la que muestra el gráfico. En la parte superior observamos el gráfico Gantt con una leyenda para su interpretación visual. Le acompañan las tablas de resultados numéricos para enriquecer el gráfico. Aquí termina el proceso de optimización puediendo volver a repetirlo iniciando de nuevo el proceso. 101

References: resolución 
 Resolución 
 Resolución 
 resolución 
 resolución 
 resolución 
 resolución 
 resolución 
 Resolución 
 Resolución