Unidad Azcapotzalco División de Ciencias Básicas e Ingeniería “Métodos heurísticos aplicados al despacho económico con funciones de costo no convexas y zonas muertas de unidades térmicas” Tesis que para obtener el grado de Maestro en Ciencias de la Computación Presenta: Benjamín Carpio Flores Asesor: Dr. Javier Ramírez Rodríguez Departamento de Sistemas UAM Azcapotzalco México, Octubre-2007 Dedicatorias A mi niña Alma Teresa, tus sonrisas son mi mayor felicidad. A mi esposa Alma, gracias por tu amor y consejos. A mis padres, Justino, Epi y Tomasa , por sus sacrificios, amor y enseñanzas. A mis hermanos Tino, Hugo, Jaz, David y Tomi, ya no me quieran tanto☺. A Dios, por los regalos que me ha dado. Agradecimientos: A mi asesor, Ing. Javier Ramírez Rodríguez. Gracias por su amistad y dedicación. A todos mis profesores de la UAM, por el tiempo y conocimiento brindados. Al MC Anselmo Sánchez Sánchez, por la disposición y atención a mis dudas. INDICE Pág. Lista de tablas y figuras ………………………………………………………… i Nomenclatura …………………………………………………………………… iv Resumen …………………………………………………………………………. v Abstract…………………………………………………………………………... vii Introducción …………………………………………………………………….. viii Antecedentes …………………………………………………………………….. xiii Justificación ……………………………………………………………………... xvii Objetivos ………………………………………………………………………… xix Contenido de la tesis…………………………………………………………….. xx CAPÍTULO 1. DESPACHO ECONÓMICO. 1.1 Introducción…………………………………………………………. 1 1.2 Despacho Económico Sin Pérdidas…………………………………. 1 1.3 Otros problemas de Despacho Económico…………………………. 4 1.4 Técnicas clásicas de solución………………………………………... 5 1.5 Casos de Estudio……………………………………………………... 6 1.5.1 Caso de estudio 1, 7 Us (función de costo no convexa de un PIE y zona muerta) ………………………………………………………………... 1.5.2 Caso de estudio 2, 36 Us (problema de mayor tamaño) …………………. 6 10 1.5.3 Caso de estudio 3, 3 Us (funciones no convexas en las tres unidades que consideran puntos de válvula) ……………………………………….. 12 CAPÍTULO 2. MÉTODOS HEURÍSTICOS. 2.1 Introducción ………………………………………………………… 14 2.2 Algoritmos Genéticos ……………………………………………….. 14 2.3 Búsqueda local ………………………………………………………. 16 2.4 Algoritmo de Recocido Simulado ………………………………….. 18 2.5 GRASP ………………………………………………………………. 19 2.6 Satisfacción de Restricciones ……………………………………….. 22 2.7 Algoritmos Híbridos ………………………………………………… 23 CAPÍTULO 3. IMPLEMENTACIÓN DEL ALGORTIMO GENÉTICO. 3.1 Introducción ………………………………………………………… 24 3.2 Descripción del programa ………………………………………….. 25 3.3 Población inicial y codificación …………………………………….. 26 3.3.1 Codificación ………………………………………………………………… 3.3.2 Representación de los límites de potencia del generador ………………... 3.3.3 Decodificación ………………………………………………………………. 3.3.4 Codificación de la zona muerta …………………………………………… 26 27 27 27 3.4 Evaluación …………………………………………………………… 29 3.4.1 Aptitud de los individuos …………………………………………………... 3.4.2 Funciones de costo ………………………………………………………….. 29 29 3.5 Selección ……………………………………………………………... 31 3.5.1 Selección por torneo ………………………………………………………... 31 3.6 Nuevas Generaciones ……………………………………………….. 31 3.6.1 Mutación y Cruza …………………………………………………………... 3.6.1.1 Zona muerta ………………………………………………………... 31 34 3.7 Ajuste de parámetros particulares del AG al problema de DE ….. 34 3.7.1 Tamaño de la población ……………………………………………………. 3.7.2 Elitismo ……………………………………………………………………... 3.7.3 Factor de penalización por incumplimiento del balance de potencia …... 35 37 38 3.8 Resumen de resultados del AG (DE con funciones convexas) …… 42 3.9 Algoritmo Genético Híbrido ………………………………………. 43 3.9.1 Población inicial a partir de algoritmo de SR …………………………….. 3.9.2 Población inicial a partir de fc_GRASP ………………………………….. 3.9.3 Adición de búsqueda local al AG ………………………………………….. 43 45 46 3.10 Resumen de resultados del AGH (DE con funciones convexas) ... 51 CAPÍTULO 4. IMPLEMENTACIÓN DEL ALGORITMO DE RECOCIDO SIMULADO. 4.1 Introducción ………………………………………………………… 52 4.2 Descripción del programa ………………………………………….. 53 4.3 Solución inicial ………………………………………………………. 53 4.3.1 Zona muerta ………………………………………………………………... 53 4.4 Vecindades …………………………………………………………... 54 4.4.1 Zona muerta ………………………………………………………………... 55 4.5 Ajuste de los parámetros de ARS ………………………………….. 55 4.5.1 Temperatura ………………………………………………………………... 4.5.2 Ajuste de k0 en la búsqueda local …………………………………………. 56 59 4.6 Resumen de resultados del ARS (DE con funciones convexas) ...... 60 CAPÍTULO 5. IMPLEMENTACIÓN DEL GRASP. 5.1 Introducción ………………………………………………………... 61 5.2 Descripción del programa …………………………………………. 62 5.3 Fase Constructora ………………………………………………….. 62 5.4 Fase de Búsqueda Local ……………………………………………. 68 5.5 Zona muerta ………………………………………………………... 68 5.6 Ajuste de parámetros, Nitr, α ……………………………………... 68 5.7 Resumen de resultados del GRASP (DE con funciones convexas) 74 CAPÍTULO 6. RESULTADOS FINALES. 6.1 Introducción ………………………………………………………… 75 6.2 Resultados para el caso de estudio 1, 7 unidades ………………… 76 6.3 Resultados para el caso de estudio 2, 36 unidades ……………….. 86 6.4 Resultados para el caso de estudio 3, 3 unidades ………………… 87 CONCLUSIONES ………………………………………………………………. 89 REFERENCIAS ………………………………………………………………… 91 APENDICE I Solución analítica al caso de estudio 1 (7 Us) por el método del lagrangiano. APENDICE II Código fuente de los programas en lenguaje C Lista de tablas y figuras Tablas Tabla 1.1 Limites de potencia y coeficientes abc de las unidades del caso 1. Tabla 1.2 Solución óptima del caso 1 con funciones de costo de segundo grado convexas. Tabla 1.3 Datos de las 36 unidades del caso 2. Tabla 1.4 Solución óptima del caso 2 con funciones de costo de segundo grado convexas Tabla 1.5 Datos de las 3 unidades del caso 3. Tabla 1.6 Solución óptima del caso 3. Tabla 2.1 Algoritmo Genético simple. Tabla 2.2 Algoritmo de búsqueda local. Tabla 2.3 Algoritmo de Recocido Simulado. Tabla 2.4 Algoritmo GRASP simple. Tabla 2.5 Algoritmo de fase de construcción del GRASP basado en valor. Tabla 2.6 Algoritmo de fase de construcción del GRASP basado en cardinalidad. Tabla 2.7 Algoritmo de búsqueda local del GRASP. Tabla 3.1 Estructura de datos generador. Tabla 3.2 Límites de potencia usados en la decodificación del valor entero Pcod según el valor de bit_zm. Tabla 3.3 Factores de escalamiento de aptitud para cada caso de estudio. Tabla 3.4 Tipos de funciones de costo de los casos de estudio. Tabla 3.5 Unidades de los coeficientes abcef de la función general de costo. Tabla 3.6 Tabla de costos del PIE CC Mexicali. Tabla 3.7 Parámetros utilizados por defecto para el AG. Tabla 3.8 Parámetros a determinar para el AG. Tabla 3.9 Resultados del AG para distintos valores del FP_IBP y solución óptima del caso 1. Tabla 3.10 Ajustes del FP_IBP y número de generaciones para cada caso de estudio. Tabla 3.11Resultados del AG para los casos de estudio 1, 2 y 3 (con funciones de costo convexas). Tabla 3.12 Datos para el ejemplo de SR. Tabla 3.13 Algoritmo para crear una solución factible por SR. Tabla 3.14 Soluciones creadas con a) SR b) fc_GRASP. Tabla 3.15 Comparativo del costo de las soluciones creadas por SR y fc_GRASP. Tabla 3.16 Algoritmo Genético Híbrido (AGH). Tabla 3.17 Generaciones iniciales n del AGH para cada caso de estudio. Tabla 3.18 Comparativo de aptitudes después de 75 y 150 generaciones, para el AG con diferentes tipos de población inicial, caso 1. Tabla 3.19 Ajuste del parámetro k0 para el caso 1 (7 U’s). Tabla 3.20 Ajuste del parámetro k0 para el caso 2 (36 U’s). Tabla 3.21 Ajuste del parámetro k0 para el caso 3 (3 U’s). Tabla 3.22Resultados del AGH para los casos de estudio 1, 2 y 3 (con funciones de costo convexas). Tabla 4.1 Datos del ejemplo para el cálculo de una solución vecina. Tabla 4.2 Rangos permisibles de movimiento a partir de la solución inicial del ejemplo 4.1. Tabla 4.3 Parámetros utilizados por defecto para el ARS. Tabla 4.4 Criterio de Metrópolis para aceptación de una solución. Tabla 4.5 Máxima diferencia en costo mdc para el caso 1 con funciones convexas. Tabla 4.6 Valores de mdc y criterios de paro para los casos de estudio 1,2 y 3. Tabla 4.7 Resultados para diferentes valores de T. Resaltados los valores de referencia para el cálculo de los porcentajes. El valor mínimo y el valor promedio son de diez pruebas. Tabla 4.8 Parámetros del ARS para cada caso de estudio. i Tabla 4.9 Ajuste de la búsqueda local a través del parámetro k0 para caso 1 (7 U’s). Tabla 4.10 Ajuste de la búsqueda local a través del parámetro k0 para caso 2 (36 U’s). Tabla 4.11 Ajuste de la búsqueda local a través de parámetro k0 para caso 3 (3 U’s). Tabla 4.12 Resultados del ARS para los casos de estudio 1, 2 y 3 (con funciones de costo convexas). Tabla 5.1 Algoritmo general GRASP para el DE. Tabla 5.2 Algoritmo GRASP (fase constructora) para el DE. Tabla 5.3 Datos del ejemplo 5.1. Aplicación del GRASP. Tabla 5.4 Resultados del GRASP al caso 1, con k0 = 100 y distintos valores de alfa (0.0, 1.0 y 0.5). Tabla 5.5 Resultados del GRASP al caso 1, con diferentes combinaciones de N_itr y k0. Tabla 5.6 Ajuste de k0 para el caso 1 (7 U’s). Tabla 5.7 Resultados del GRASP para el DE del caso 2, con diferentes combinaciones de N_itr y k0. Tabla 5.8 Ajuste de k0 para el caso 2 (36 U’s). Tabla 5.9 Resultados del GRASP para el DE del caso 3, con diferentes combinaciones de N_itr y k0. Tabla 5.10 Ajuste de k0 para el caso 3 (3 U’s). Tabla 5.11 Parámetros del GRASP determinados para cada caso de estudio. Tabla 5.12 Resultados del GRASP para los casos de estudio 1, 2 y 3 (con funciones de costo convexas). Tabla 6.1 Ajustes de los parámetros de las heurísticas, caso 1 (7 U’s). Tabla 6.2 Caso 1. Aplicación del AG. Número de generaciones = 300, FP_IBP = 2500, probabilidad de cruza = 0.8, probabilidad de mutación = 0.01. a) todas las unidades con funciones de costo convexas, b) unidad 7 con función de costo no convexa y zona muerta. Tabla 6.3 Caso 1. Aplicación del AGH. Número de generaciones = 75, K0 = 500, FP_IBP = 2500, probabilidad de cruza = 0.8, probabilidad de mutación = 0.01. a) todas las unidades con funciones de costo convexas, b) unidad 7 con función de costo no convexa y zona muerta. Tabla 6.4 Caso 1. Aplicación del Algoritmo de Recocido Simulado. T= 500 000, k0 = 50, a) todas las unidades con funciones de costo convexas, b) unidad 7 con función de costo no convexa y zona muerta. Tabla 6.5 Caso 1. Aplicación del GRASP. Nitr = 300, k0 = 400, a) todas las unidades con funciones de costo convexas, b) unidad 7 con función de costo no convexa y zona muerta. Tabla 6.6 Resumen de la aplicación de los métodos heurísticos al caso 1 con funciones de costo convexas. Tabla 6.7 Resumen de la aplicación de los métodos heurísticos al caso 1, con zona muerta y función de costo no convexa para unidad 7. Tabla 6.8 Resultados del ARS con zona muerta y función no convexa en U7, k0 = 100. Tabla 6.9 Evaluación de funciones de costo, caso 1 (7Us) sin zona muerta. Demanda = 870 MW Tabla 6.10 Resultados de las heurísticas para el caso 1. U7 con función de costo real. Demanda = 870 MW. Tabla 6.11 Evaluación de funciones de costo, caso 1 (7Us). Demanda = 700 MW. Tabla 6.12 Resultados de las heurísticas para el caso 1. U7 con función de costo real. Demanda = 700 MW. Tabla 6.13 Evaluación de funciones de costo, caso 1 (7 Us). Demanda = 1 050 MW. Tabla 6.14 Resultados de las heurísticas para el caso 1. U7 con función de costo real. Demanda = 1 050 MW. Tabla 6.15 Ajustes de los parámetros de las heurísticas, caso 2 (36 U’s). Tabla 6.16 Resumen de la aplicación de los métodos heurísticos al caso 2 con funciones de costo convexas. Tabla 6.17 Resumen de la aplicación de los métodos heurísticos al caso 2, con zona muerta y función no convexa para la unidad 36. Tabla 6.18 Ajustes de los parámetros de las heurísticas, caso 3 (3 U’s). Tabla 6.19 Resumen de la aplicación de los métodos heurísticos al caso 3 (3 Us). Tabla 6.20 Resultados del DE para el caso 3 (3 Us). ii Figuras Figura a) Semana típica de verano del Sistema Interconectado Nacional en México. Figura b) Curva de entrada-salida de la U3 de la central Mérida II. Figura c) Curva de consumo específico o régimen térmico de U3 Mérida tg. Figura d) Modelado del punto de válvula en unidades térmicas. Figura e) Planta de ciclo combinado. Figura f) Curva de entrada-salida de un ciclo combinado. Figura g) Curva de consumo específico basada en tres puntos del PIE CC Mexicali. Figura 2.1 Funciones de costo o curvas de entrada-salida de las unidades del caso 1. Figura 2.2 Régimen térmico en $/MWh del CC Mexicali (U7). Figura 2.3 Costos incrementales de las unidades del caso 1. Figura 2.4 Costos incrementales de los dos modelos utilizados para la unidad 7. Figura 2.5 Costos incrementales de las unidades del caso 2. Figura 2.6 Funciones de a) costo y b) costos incrementales de las unidades del caso 3. Figura 3.1 Cadena, individuo o cromosoma. Figura 3.2 Subcadena de 11 bits. Figura 3.3 Representación de diferentes valores de potencia a través del bit_zm para una unidad con zona muerta. Figura 3.4 Cruza de 2 individuos a nivel de bits, con pcruza = 14. Figura 3.5 Modificación del valor de potencia por operador de cruza, pcruza = 16. Figura 3.6 Operador de cruza a nivel de unidades con dos puntos de cruza, pcruza1 = 2, pcruza2=5. Figura 3.7 Operador de mutación modificó bit 23 en una cadena de longitud 33. Figura 3.8 a) aptitud mejor individuo b) aptitud promedio de cada generación c) balance de potencia BP, para poblaciones de 40 y 100 individuos, caso 1. Figura 3.9 a) aptitud mejor individuo b) aptitud promedio de cada generación c) balance de potencia BP, para poblaciones de 40 y 100 individuos, caso 2. Figura 3.10 Comparación de la convergencia del AG con y sin elitismo, a) aptitud del mejor individuo, b) BP, caso 1. Figura 3.11 Comparación de la convergencia del AG con y sin elitismo, caso 2. Figura 3.12 Curvas de las unidades con mayor costo incremental del caso1. Figura 3.13 Convergencia en aptitud y en BP del AG, con valores de FP_IBP de 2000, 2500 y 3000, caso 1. Figura 3.14 Curvas de las unidades con mayor costo incremental del caso 2. Figura 3.15. Convergencia en aptitud y en BP del AG aplicado al caso 2, con distintos valores de FP_IBP. Figura 3.16. Convergencia en aptitud y en BP del AG aplicado al caso 3, con distintos valores de FP_IBP. Figura 3.17 Convergencia del AGH con diferentes poblaciones iniciales, caso 1. Figura 3.18 Desempeño del AG con población inicial de soluciones factibles y no factibles para el caso 3 (DEPV de 3 unidades). Fig. 4.1 Evaluación de la función de Boltzman con valores de T referidos a la mdc del caso 1. Fig. 4.2 Desempeño del ARS para diferentes valores de T, caso 1 (7 U’s). Fig. 4.3 Desempeño del ARS para diferentes valores de T, caso 2 (36 U’s). Fig. 4.4 Desempeño del ARS para diferentes valores de T, caso 3 (3 U’s). Figura 5.1 Costo de las soluciones mejoradas de cada iteración, fase de construcción con α=0.5, caso 1 (7 U’s). Figura 5.2 Costo de las soluciones mejoradas de cada iteración, fase de construcción con α=1, caso 1 (7 U’s). Figura 5.3 Costo de las soluciones mejoradas de cada iteración, fase de construcción con α=0, caso 1 (7 U’s). Figura 6.1 Punto de operación de la unidad 7 (306 MW), caso 1 con 870 MW de demanda. Figura 6.2 Funciones de costo del caso 3 (3 Us). iii Nomenclatura AG AGH ARS ASR BP CC CENACE DE DEPV F FP_IBP GRASP K0 kcal kWh MWh Nitr PDE PIE Pmin Pmax T tam_pob Us V tg Algoritmo Genético Algoritmo Genético Híbrido Algoritmo de Recocido Simulado Algoritmo de Satisfacción de Restricciones Balance de Potencia Ciclo Combinado Centro Nacional de Control de Energía Despacho Económico DE con Punto de Válvula Función de costo Factor de Penalización por Incumplimiento de Balance de Potencia “Greedy Randomized Adaptive Search Procedure” Parámetro de ajuste de la intensidad de la búsqueda local kilocaloría Kilowatt-hora Megawatt-hora Número de iteraciones del GRASP Problema de despacho económico Productor Independiente de Energía Potencia mínima Potencia máxima Temperatura Tamaño de la población Unidades Vapor Turbogás iv Resumen En México, el Centro Nacional de Control de Energía (CENACE) de la Comisión Federal de Electricidad (CFE) realiza diariamente el despacho económico de generación. El problema de despacho económico (PDE) consiste en determinar la potencia que cada unidad generadora debe suministrar para cubrir la demanda pronosticada de un Sistema Eléctrico de Potencia al menor costo posible. La función de costo que se utiliza para la optimización del PDE es la curva de entrada-salida de las unidades térmicas y representa la cantidad o costo de combustible que la unidad consume por hora para la potencia generada. Para simplificar el problema, esta relación se representa por una función de segundo grado, convexa y continua, y entonces se utilizan técnicas de programación lineal para optimizar el problema. En realidad, las funciones de costo de las unidades térmicas son discontinuas y no convexas debido al cierre y apertura de válvulas en el sistema de la caldera para el control de la potencia del generador eléctrico. Por otra parte, funciones no convexas son derivadas de los modelos contractuales de algunos Productores Independientes de Energía, quienes adicionalmente declaran zonas muertas o prohibidas en las transiciones por las diferentes configuraciones del ciclo combinado. En este trabajo se muestra la aplicación de cuatro métodos heurísticos al PDE, donde se consideran funciones de costo no convexas y zonas muertas de unidades térmicas, para evaluar los costos de las simplificaciones que se realizan por las restricciones que impone el método clásico de solución. Los métodos heurísticos utilizados son el Algoritmo Genético (AG), Algoritmo Genético Hibrido (AGH), Algoritmo de Recocido Simulado (ARS) y el GRASP (greedy randomized adaptive search procedure). Se describen los ajustes de parámetros y procedimientos particulares al PDE, como son el factor de penalización por incumplimiento del balance de potencia FP_IBP (AG), parámetro de temperatura T (ARS), función miope (GRASP), el algoritmo de generación de vecindades para la búsqueda local (ARS, AGH, GRASP) y el algoritmo de satisfacción de restricciones para generar soluciones factibles (ARS, AGH). Para los algoritmos genéticos, la zona muerta zm es restringida desde la propia codificación, agregando un bit adicional bit_zm a la subcadena que representa a cada unidad. Para el GRASP y ARS, la zm se evita desde la generación aleatoria de la solución inicial. Los resultados muestran que con la evaluación de las funciones no convexas, a través de métodos heurísticos, se obtiene un mejor despacho de generación, con excepción del AG que requirió ser mejorado (AGH). En la comparación de los desempeños, el GRASP presentó la mejor calidad en las soluciones referidas a v costo y a variabilidad. Cualquier mejora en el despacho de generación resulta en ahorros importantes si consideramos los costos de producción por combustibles y costos variables que se tienen en el Sistema Interconectado Nacional que, por ejemplo, en el año 2006 totalizaron 86 mil millones de pesos. Palabras clave: Despacho Económico, Métodos Heurísticos, Algoritmo Genético, Algoritmo de Recocido Simulado, GRASP. vi Abstract In Mexico, the National Energy Control Center (CENACE) accomplishes the diary Economic Dispatch of generation (ED). The ED problem consists in determining the electric power outputs of thermal units to supply the forecast load on the system at minimum operating cost. In the traditional ED problem, convex quadratic functions are used to approximately represent the variable operation costs, which mostly depend on fuel. Then, the DE problem can be optimized using mathematical programming such as linear programming techniques. In fact, fuel cost functions of thermal units are discontinuous and non-convex due to the closing and opening of valves in the steam boiler system. Besides, nonconvex functions are derived from the contractual models of some Independent Energy Generators, which additionally declare dead or prohibited zones in the transitions by the different configurations from the combined cycle technology. In this work, the application of four heuristic methods to the ED problem is presented, where non-convex cost functions and dead zones of thermal units are considered to evaluate the costs of the simplifications that are made by the restrictions that the classic method of solution imposes. The used heuristic methods are Genetic Algorithm (AG), Hybrid Genetic Algorithm (AGH), Simulated Annealing Algorithm (ARS) and the GRASP (greedy randomized adaptive search procedure). Adjustments of parameters and procedures particular to the PDE are described, such as power misbalance penalty factor (AG), temperature parameter T (ARS), myopic function (GRASP), the neighborhood algorithm for local search (ARS, AGH, GRASP) and the constraint satisfaction algorithm to generate feasible solutions (ARS, AGH). For the genetic algorithms, the dead zone zm is restricted from the own codification, having added an additional bit bit_zm to the sub-chain that represents each unit. For GRASP and ARS, the dead zone is avoided from the random generation of the initial solution. The results show that the fact of evaluating the non-convex functions with the heuristic methods approaches a better generation dispatch, with exception of the AG that required to be improved (AGH). In the comparison of the performances, the GRASP presented the best quality in the solutions referred to cost and variability. Any improvement in the generation dispatch is in important savings, if we considered the operating variable costs in the Interconnected National System of México that totalized, for example in year 2006, 86 billion pesos,. Keywords: Economic Dispatch, GRASP, Simulated Annealing, Genetic Algorithm, Heuristic methods. vii Introducción El patrón de demanda de energía eléctrica de los consumidores es completamente irregular, con tendencias de mayor demanda por las tardes y noches que por las madrugadas. También los patrones son diferentes para los días de descanso y para días festivos. En la figura a) se muestra la demanda de energía de una semana típica del Sistema Interconectado Nacional de México, normalizada respecto a la demanda máxima anual. 1.0 Demanda en pu 0.9 0.8 0.7 0.6 0.5 1 5 9 13 17 horas Sábado Domingo 21 Lun-Vie Figura a) Semana típica de verano del Sistema Interconectado Nacional en México. Con estos comportamientos irregulares de las demandas, algunas unidades de generación deben entrar y salir del sistema, mientras que otras sólo necesitan cambiar su aportación en potencia siguiendo el perfil de la demanda. Al problema de decidir qué unidades deben participar para cubrir la demanda se llama Asignación de Unidades y al problema de asignar el nivel de potencia de cada generador en cada hora, se le conoce como Despacho de Generación. El Despacho Económico de generación (DE) consiste en determinar la potencia eléctrica que debe suministrar cada generador térmico para satisfacer la demanda de energía pronosticada al menor costo posible. Para ello se consideran principalmente los costos de generación termoeléctrica, que son variables debido a que las unidades generadoras convierten combustible en energía eléctrica con diferentes eficiencias. La función de costo que se utiliza para la optimización del problema de DE (PDE) es la curva de entrada-salida de cada unidad térmica. Esta curva representa la cantidad o el costo de combustible que una unidad consume por hora para la potencia a la que la unidad está generando. Esta relación se representa generalmente por un polinomio de segundo grado. Los datos de esta curva se viii obtienen de pruebas de consumo específico de las unidades o por cálculos de diseño. La figura b) muestra una curva de entrada-salida de una unidad turbogas de la central termoeléctrica Mérida II en México. 100,000 90,000 $/ h 80,000 70,000 60,000 50,000 40,000 30,000 5 10 15 20 25 30 35 40 MW Figura b) Curva de entrada-salida de la U3 de la central Mérida II. La curva de consumo específico o de régimen térmico representa el costo por megawatt-hora (MWh) que tiene la unidad para una determinada potencia de salida. Este tipo de curva muestra la eficiencia de la unidad térmica. Obsérvese en la figura c que para valores mínimos de generación los costos por MWh son altos y la máxima eficiencia se presenta aproximadamente al 85% de la potencia máxima. La eficiencia máxima de esta unidad se alcanza cuando opera a 31 MW. La curva de régimen térmico se determina durante el periodo de pruebas de un generador nuevo o después de un mantenimiento mayor y se construye generalmente a partir de por lo menos tres puntos de operación, que corresponden al 50%, 75% y 100% de la potencia máxima. 6,500 6,000 5,500 $/MWh 5,000 4,500 4,000 3,500 3,000 2,500 2,000 5 10 15 20 25 30 35 40 MW Figura c) Curva de consumo específico o régimen térmico de U3 Mérida tg. En realidad las funciones de costo de las unidades térmicas son discontinuas, debido a que presentan brincos por el cierre y apertura de válvulas que se ix realizan en el sistema de la caldera para el control de la potencia del generador [12]. A este efecto se le conoce como punto de válvula y las curvas representativas son no convexas, como se aprecia en la figura d. 8,000 7,000 $/h 6,000 5,000 U1 4,000 U2 3,000 U3 2,000 1,000 0 50 150 250 350 450 550 650 MW Figura d) Modelado del punto de válvula en unidades térmicas. Otro tipo de discontinuidades los presentan las unidades tipo ciclo combinado. Este tipo de centrales están formadas por varias unidades turbogás donde los vapores a la salida de sus turbinas son reutilizados a través de un recuperador de calor que alimenta a la caldera de una unidad de vapor, ver figura e. Figura e) Planta de ciclo combinado. Las curvas de entrada-salida y consumo específico de la unidad de ciclo combinado se obtienen para cada combinación de turbinas de gas con la unidad de vapor, lo cuál es útil cuando una o más unidades turbogás no están disponibles por falla o mantenimiento. En la figura f se muestran curvas características de entrada-salida de un ciclo combinado. x Figura f) Curva de entrada-salida de un ciclo combinado En el caso de las plantas de ciclo combinado de CFE, para el DE sólo se utiliza la curva correspondiente a la configuración disponible y generalmente corresponde al ciclo completo. Esto no sucede para algunos Productores Independientes de Energía (PIE´s), quienes son empresas particulares a quienes se les permite la generación de energía eléctrica para venta exclusiva a CFE. Estos permisionarios declararon un rango de operación que incluye el paso por todas las configuraciones posibles. Las funciones de costo que se derivan de su régimen térmico contractual corresponden a una curva no convexa en el primer rango de operación y a una curva convexa en el rango complementario. Además, estos PIE´s han declarado zonas prohibidas de operación conocidas como “zonas muertas” por las dificultades técnicas y altos costos de parar o arrancar una unidad turbogás en las transiciones de cada configuración. Una de las metodologías más utilizadas en la solución del PDE es conocida como la técnica del Lagrangiano, que lo reduce a un problema de programación lineal donde las restricciones son incorporadas a la función objetivo a través de multiplicadores de Lagrange, uno por cada restricción; luego se aplica el método simplex para minimizar la función objetivo. Sin embargo, esta técnica requiere de estricta convexidad de la función objetivo y no se puede aplicar para evaluar funciones de costo no convexas ni discontinuidades. Por lo tanto, se deben buscar otras metodologías que permitan considerar estas situaciones operativas especiales y así poder evaluar el impacto de las simplificaciones que se realizan. Los métodos heurísticos son herramientas eficientes de búsqueda de soluciones a problemas complejos para los cuales no existe un algoritmo que los resuelva, o a problemas con dominios tan grandes que no existe un algoritmo eficiente de solución. Las reglas y operaciones matemáticas que definen el funcionamiento de los métodos heurísticos son fáciles de entender e implementar. Entre los métodos heurísticos más populares utilizados para problemas de optimización se xi encuentran el Algoritmo Genético (AG) y el Algoritmo de Recocido Simulado (ARS). El AG toma los conceptos de la teoría de la evolución de Darwin para crear nuevos individuos (soluciones) a través de operadores de cruza y mutación, que van sobreviviendo de generación en generación por su mejor aptitud. La base teórica de estos algoritmos fue introducida por su creador John Holland en 1975 y es conocida como teoría de los esquemas [3]. El ARS imita un proceso de recocido en metalurgia, una técnica que incluye calentar y luego enfriar controladamente un material para aumentar el tamaño de sus cristales y reducir sus defectos. El calor causa que los átomos se salgan de sus posiciones iniciales (un mínimo local de energía) y se muevan de forma aleatoria. El enfriamiento lento les da mayores probabilidades de encontrar configuraciones con menor energía que la inicial. En la analogía con el método de optimización, las soluciones corresponden a estados del sistema físico. El costo de la solución corresponde a la energía del estado. Se introduce un parámetro de control que corresponde a la temperatura. Si se baja la temperatura lo suficientemente lento se puede alcanzar el equilibrio térmico en cada nivel de temperatura. Esto se hace mediante la generación de varias transiciones en cada temperatura. xii Antecedentes En el problema del despacho económico, las restricciones impuestas por los métodos matemáticos clásicos en las curvas de costo de las unidades generadoras han impedido la utilización de mejores modelos de las funciones de costo de las unidades térmicas que permitan reducciones adicionales en los costos de generación. Si se considera el costo total de generación de un sistema de potencia real, resulta evidente que evitar cualquier restricción en el modelado de las funciones de costo se traducirá en un ahorro significativo. Los métodos heurísticos son utilizados como herramientas de optimización que, a diferencia de los métodos matemáticos clásicos, no imponen restricciones en el modelado de los elementos implícitos en el problema, ya que tienen la habilidad de adaptarse a las no-linealidades y discontinuidades comúnmente encontradas en los sistemas físicos, además muestran buenas características de funcionamiento en problemas con espacio de solución multimodal. El AG ha mostrado buenos resultados en problemas de DE donde los métodos clásicos de solución no tienen aplicación. Un problema típico es el DE con punto de válvula, en donde se utiliza una mejor aproximación de las curvas de entradasalida de las unidades térmicas al considerar curvas no convexas. Los resultados de los métodos heurísticos se han comparado con los de las técnicas de solución clásicas en los casos donde estas últimas tienen aplicación, para revisar la proximidad de sus soluciones. F. Li [5], por ejemplo, prueba la robustez del AG sobre cuatro problemas de DE y compara su desempeño contra tres técnicas clásicas de solución, que son la tabla de mérito, la lambda iterativa y la técnica del gradiente. El sistema es de sólo tres unidades y aumenta la complejidad de cada problema con la consideración de pérdidas de transmisión y puntos de válvula. • • • • Para el problema más sencillo, que es el caso sin pérdidas y funciones convexas de segundo grado, todas las técnicas ofrecen solución y la del AG es superior en 0.006% respecto a la del método exacto de la lambda iterativa. Para el segundo caso, donde se consideran pérdidas de transmisión, el costo de la solución del AG es superior en 0.6%. El tercer caso considera puntos de válvula y la solución del AG es superior en 3.7% sobre el método de la tabla de mérito (los otros métodos no tienen aplicación en este caso). Finalmente, para el caso más complejo donde se consideran puntos de válvula y pérdidas de transmisión, el AG es el único que ofrece solución. xiii El AG también ha sido utilizado para problemas de despacho con restricciones de tipo no lineal, por ejemplo, restricciones ambientales [11]. Las emisiones de dióxido de azufre y óxidos de nitrógeno son representadas por funciones de segundo grado en función de la potencia de salida de cada generador. Estas restricciones son incorporadas a la función objetivo mediante un factor de penalización. El AG tiene muchos parámetros de control que deben ser ajustados, uno de ellos es el tamaño de la población. David Goldberg, un estudiante de John Holland, determinó que el tamaño óptimo para una codificación binaria de longitud n estaba en función exponencial de n, aunque posteriormente sugirió que un valor adecuado era de 100 individuos. Otros resultados empíricos sugieren poblaciones de 30 individuos [9]. Olachea A. [7] analiza la aplicación del AG al PDE con diferentes restricciones (sin pérdidas, con punto de válvula y con restricción de flujo máximo en líneas) en un sistema de tres máquinas y para uno de gran escala (17 unidades), que era un sistema aislado del Sistema Eléctrico Nacional. Olachea reporta una gran variedad de pruebas para diferentes parámetros del AG, coincidiendo sus ajustes con algunos ya ampliamente recomendados en la literatura. Estos son algunos resultados que obtuvo: • • • • • • • utilizar poblaciones iniciales lo más grande posible para obtener una rápida convergencia debido a que se explota con mayor eficacia el recurso de búsqueda en paralelo. Obtiene sus mejores resultados con poblaciones de 100 individuos menores desviaciones de potencia utilizando puntos de cruza uniforme, respecto al punto de cruza en un solo punto probabilidades de cruza alta (0.8) y de mutación bajas (0.1) uso de elitismo (conservar al mejor individuo de cada generación) las funciones de evaluación estructuradas en forma de sumatorias facilitan el proceso de sintonización del algoritmo conveniencia del uso de factores de prioridad y penalización en la función de evaluación cuando se incluyen restricciones adicionales utilizar una función de evaluación de tipo exponencial para el caso del DE con punto de válvula. También compara los resultados codificando por una parte, las potencias de los generadores y por otra, valores de costo incremental λ, siguiendo el criterio de que el óptimo se logra cuando todas las unidades operan a un mismo valor de λ. En ambos casos logra convergencia con un número similar de iteraciones y desviaciones de costo del mismo orden. xiv El desempeño de las heurísticas también ha sido mejorado mediante la hibridación para tratar de compensar algunas deficiencias. Por ejemplo, se sabe que los AG’s son imperfectos en cuanto a la exactitud de la solución encontrada, y las mejoras siguen en general dos líneas: • • La primera es mejorar los procedimientos genéticos: la representación o codificación de los individuos, el tamaño y calidad de la población inicial, diferentes funciones de evaluación, operadores genéticos avanzados y auto-adaptables, y selección óptima de los parámetros del algoritmo. La segunda línea va en el sentido de usar híbridos, combinando el AG con técnicas de búsqueda local para acelerar el proceso y mejorar la calidad de la solución. Como ejemplo de esta segunda línea de mejora, F. Li et al [6] proponen un algoritmo genético híbrido (AGH) usando el AG combinado con la técnica del gradiente para el PDE. Comentan que el AG balancea la exploración y explotación del espacio de búsqueda, lo que significa que un incremento en la exactitud de la solución sólo se logra sacrificando la rapidez de convergencia y viceversa. No es posible que ambas cosas se mejoren al mismo tiempo. El AGH propuesto consta de un AG encargado de dirigir la búsqueda hacia regiones prometedoras, y de la técnica del gradiente de primer orden para hacer el trabajo fino. La efectividad de su algoritmo fue probada en un sistema real de 25 unidades generadoras. En sus resultados, el AGH presenta una mejora en costo del 0.36% respecto al AG para tiempos iguales de ejecución; y una mejora en tiempo de ejecución del 52.9% para costos iguales de generación. Ongsakul W. [8] utilizó métodos basados en tablas de mérito para el despacho de unidades tipo ciclo combinado, para resolver una limitación del programa de despacho económico en tiempo real de la compañía Electricity Generating Authority of Thailand. Esta aplicación sólo consideraba funciones de costo incremental monótonas crecientes y los modelos que se querían utilizar eran funciones lineales decrecientes y de tipo escalón (correspondientes a curvas de entrada-salida de segundo y primer orden, respectivamente). El autor utilizó los costos incrementales de las unidades generando a su máxima potencia como criterio para despachar los ciclos combinados y obtuvo mejores resultados que los obtenidos con el método de Newton. Las desviaciones promedio fueron del 0.43 % respecto de la solución óptima. El caso de estudio referido estaba formado por 4 ciclos combinados con curvas de costos incrementales lineales decrecientes y 1 ciclo combinado con curva de costo incremental de tipo escalera decreciente. Sin embargo, el autor no comenta nada acerca de las variaciones derivadas de utilizar modelos aproximados (curvas de costo incremental lineales y de escalera decrecientes). xv El AG es el método heurístico más popular aplicado al PDE. Los últimos trabajos se han enfocado más a resolver el problema de asignación de unidades, en donde el PDE implícito se resuelve con las técnicas clásicas de solución que consideran funciones de costo convexas de segundo grado. xvi Justificación Con la reciente modificación en México a la Ley del Servicio Público de Energía Eléctrica1, se ha permitido la generación de energía eléctrica por particulares. Uno de los permisos es el de producción independiente de energía eléctrica, que autoriza a los Productores Independientes de Energía (PIE) la generación para venta exclusiva a la Comisión Federal de Electricidad (CFE). A la fecha, operan 21 PIE’s en distintas zonas del país y utilizan la tecnología de ciclo combinado. Los PIE’s actualizan periódicamente al CENACE el régimen térmico para su participación en el despacho de generación, y es referido a los consumos específicos en kcal/kWh de al menos tres puntos de operación. En algunos permisionarios, como es el caso del PIE CC Mexicali, los primeros dos puntos dan origen a una curva de entrada-salida no convexa, (ver figura g). Adicionalmente, este permisionario tiene una zona muerta de 260 a 320 MW, que es un rango de operación donde no se desea operar debido a las dificultades técnicas y altos costos que implica desplazarse en ese rango de operación, pues se debe arrancar o parar una unidad turbogás. . zona muerta 1,880 kcal / kWh 1,860 1,840 1,820 1,800 1,780 25 50 100 % Capacidad Figura g) Curva de consumo específico basada en tres puntos del PIE CC Mexicali. Las funciones de costo de las plantas térmicas de CFE, incluyendo los ciclos combinados, son representadas con curvas convexas de segundo grado, como lo exige la aplicación que se utiliza para ejecutar el Despacho de Económico de Generación. Los modelos con regiones no convexas que proporcionan algunos PIE’s, son ajustados a una curva convexa de segundo orden y cuando los 1 Diario Oficial de la Federación, 27 diciembre de 1993 xvii resultados del despacho indican una operación del PIE en una zona muerta, éstos trasladan su punto de operación al límite más cercano de la zona muerta. Es necesario contar con una herramienta que permita la evaluación de las regiones no convexas y las zonas muertas que se presentan en las unidades térmicas, ya que no es posible hacerlo con los métodos clásicos de solución. Se utiliza el problema de DE sin pérdidas de transmisión con la única finalidad de poder comparar los resultados de las heurísticas con la solución de un método clásico. En este trabajo de tesis, se muestra la aplicación de heurísticas aplicadas a la solución del problema de DE sin pérdidas, considerando las funciones de costo no convexas y las zonas muertas de unidades térmicas para evaluar el costo de las consideraciones que se realizan por las restricciones que impone el método clásico de solución. xviii Objetivos Objetivo General: Aplicar métodos heurísticos al problema de despacho económico sin pérdidas, considerando las funciones de costo no convexas y zonas muertas de unidades térmicas. Objetivos particulares: - Resolver el problema planteado con los métodos heurísticos siguientes: Algoritmo Genético, Algoritmo Genético Hibrido, Algoritmo de Recocido Simulado y GRASP. - Determinar los mejores ajustes de los parámetros de cada heurística. - Comparar el desempeño de los cuatro métodos heurísticos utilizados - Evaluar el efecto en los costos de operación del despacho económico al considerar las zonas muertas y las curvas no convexas de las unidades térmicas. xix Contenido de la tesis En el capítulo primero se describen los métodos heurísticos que se aplican al PDE. Se explican de forma general los algoritmos utilizados para resolver el problema: el AG, AGH, ARS y GRASP. Se describen también la técnica de satisfacción de restricciones (SR) para generar soluciones iniciales factibles y la creación de vecindades para la búsqueda local utilizadas en los algoritmos. Se mencionan los valores típicos recomendados en la literatura de los parámetros de cada heurística. En el capítulo segundo se describe el problema de DE, su formulación matemática, y la técnica de solución clásica. Se describen también otros problemas de DE según el tipo de restricción. Al final del capítulo se muestran los casos de estudio con los que se probarán los métodos heurísticos. En los capítulos 3, 4 y 5 se presenta la implementación de los métodos heurísticos al problema de DE. Los valores típicos de los parámetros generales de cada método heurístico son utilizados, como son las probabilidades de cruza y de mutación para el AG, o el coeficiente de enfriamiento alfa del ARS y el coeficiente de miopía alfa del GRASP. Se ajustan solamente aquellos parámetros que son particulares del PDE. Los ajustes de estos parámetros se hacen sobre problemas para los cuáles se puede obtener la solución analítica, para utilizarlos posteriormente en los problemas con funciones de costo no convexas y zonas muertas. En el capítulo 6 se muestran los resultados comparativos de cada heurística, referidos a tiempos de ejecución, mejores soluciones obtenidas, variabilidad de resultados y porcentajes de error respecto a la mejor solución encontrada. De acuerdo con estos resultados, se comentan las conclusiones sobre la aplicación de las heurísticas utilizadas. Finalmente se muestran las conclusiones de este trabajo y dos apéndices. El primer apéndice muestra paso a paso obtención de la solución al caso de estudio 1 con funciones de costo convexas de segundo grado mediante la técnica del lagrangiano. El segundo apéndice contiene el código fuente de los programas elaborados para cada método heurístico. xx Capítulo 1. Despacho Económico 1.1 Introducción El problema de DE se puede hacer tan sencillo o complicado como se quiera. Pero en general, el problema tiene que ser dividido para el análisis de restricciones que dan origen a diferentes problemas de DE. Las diferentes soluciones son iteradas hasta que no se viola ninguna restricción. En este capítulo se describe el problema de DE sin pérdidas, que es ampliamente utilizado para mostrar la naturaleza y un buen entendimiento del problema. Este problema es relativamente fácil de resolver, cuando se hacen consideraciones adicionales como utilizar funciones de costo convexas de segundo orden, que lo convierte en un problema de programación lineal. La única dificultad mayor, viéndolo de esta forma, sería con el número de unidades del sistema a tratar, pero aún así, con los recursos de cómputo y programas de software actuales, no representan más dificultades que el de tener que esperar unos minutos para su solución. En el capítulo se describen brevemente algunos otros problemas de DE con el único fin de mostrar las restricciones más estudiadas y al final se presentan los sistemas utilizados como casos de estudio. 1.2 Despacho Económico sin pérdidas El problema más sencillo de despacho es que se plantea para un sólo intervalo de tiempo donde la demanda es constante y generalmente se asume que las curvas de entrada-salida son suaves y convexas, las cuales pueden ser representadas por funciones lineales o cuadráticas. Un caso simple es el DE sin pérdidas de 1 transmisión, en donde las únicas restricciones son el balance de potencia (BP) y los límites de potencia de cada generador. La formulación [1] es la siguiente : minimizar : n ∑ F (Pi) i =1 i sujeto a: n ∑ P = demanda i =1 i Pmini ≤ Pi ≤ Pmaxi Donde: n: número de unidades generadoras Fi : Función de costo del generador i Pi : Potencia del generador i Pmini : Potencia mínima que puede suministrar el generador i Pmaxi : Potencia máxima que puede suministrar el generador i Se utilizan multiplicadores de Lagrange para incorporar a la función objetivo las restricciones de igualdad (balance generación-demanda). Función lagrangeana: n ⎛ n ⎞ L( P, λ ) = ∑ Fi ( Pi ) + λ ⎜ ∑ Pi − demanda ⎟ i =1 ⎝ i =1 ⎠ Luego, la condición necesaria para el mínimo es cuando el gradiente de la función lagrangeana es cero: ∂L dFi = + λ = 0; i = 1,..., n ∂Pi dPi n ∂L = ∑ Pi − demanda = 0; ∂λ i =1 dFi , se le conoce como costo incremental del generador i, y dPi representa el incremento de costo debido a un incremento en la potencia generada. Se observa de las condiciones de optimalidad, que para lograr el óptimo, todas las unidades deben operar a un mismo costo incremental λ. Al término λ = - 2 El problema consiste en la solución de un sistema de ecuaciones simultáneas, el cual se puede resolver por el método simplex o con el método de Newton, según sea el grado de las funciones de costo de los generadores. Si al resolver el sistema de ecuaciones se encuentran valores de potencia que violan los límites de los generadores, es necesario aplicar algún criterio para decidir cuál generador se fija en su límite máximo, o cuál en su límite mínimo. Para esto se aplican las condiciones de optimalidad de Kuhn-Tucker: dFi =λ dPi para P min i < Pi < P maxi dFi ≤λ dPi para Pi = P maxi dFi ≥λ dPi para Pi = P min i donde es el costo incremental del sistema, obtenido de la solución del sistema de ecuaciones. Se sigue entonces el siguiente procedimiento: 1.- Fijar a los generadores fuera de límites en su límite alcanzado. 2.- Solucionar nuevamente el sistema de ecuaciones. 3.- Calcular los costos incrementales λi para los generadores del paso 1. 4.- Verificar las condiciones de optimalidad 5.- Para los generadores que cumplen con las condiciones de optimalidad, fijar sus generaciones en el límite; mientras que los que no cumplen deben integrarse en un nuevo conjunto de generadores para realizar un nuevo despacho. 6.- Ejecutar un nuevo despacho (solucionar nuevamente el sistema de ecuaciones). 7.- Verificar límites. Si todos los generadores cumplen con los límites, entonces termina el problema; de lo contrario, regresar al paso 1. Otra forma de considerar los límites de generación es agregando nuevos multiplicadores de Lagrange a la función objetivo, dos por cada unidad. La función Lagrangeana es ahora: n n ⎛ n ⎞ n L( P, λ ) = ∑ Fi ( Pi ) + λ ⎜ ∑ Pi − demanda ⎟ + ∑ µimax ( Pi − Pi max ) + ∑ µimin ( Pi − Pi min ) i =1 i =1 ⎝ i =1 ⎠ i =1 3 ∂L dFi = + λ + µimax + µimin = 0; i = 1,..., n ∂Pi dPi n ∂L = ∑ Pi − demanda = 0; ∂λ i =1 Como se observa, la cantidad de términos es considerable al incorporar los límites operativos de las unidades, lo cuál requiere de más recursos de cómputo. 1.3 Otros problemas de Despacho Económico Respecto a la exactitud deseada y relevancia del problema considerado se han derivado otros problemas de DE, como por ejemplo: 1.- DE con punto de válvula.- el cual considera la no linealidad de las funciones de costo, con el fin de tener mayores ahorros en el costo. En unidades térmicas grandes, los niveles de potencia se van escalando a través de la apertura de válvulas, en forma escalonada, lo cual origina que la función de costo pueda ser no convexa y con discontinuidades. 2.- DE dinámico.- su objetivo es satisfacer la demanda de energía entre las unidades asignadas, pero tomando en cuenta la demanda actual y futura pronosticada, minimizando costos dentro de un periodo corto de tiempo, y tomando en consideración restricciones como rampas de carga y reserva rodante. 3.- DE con consideraciones Ambientales.- su objetivo es satisfacer la demanda de energía entre las unidades asignadas minimizando costos por uso de combustibles y las emisiones de contaminantes que generan las unidades de generación. 4.- Flujos óptimos.- el objetivo es minimizar el costo sujeto a restricciones de seguridad, y las potencias activa y reactiva de cada generador se sujetan a los niveles seguros de voltaje y ángulos de fase en los buses del sistema. 4 1.4 Técnicas clásicas de solución Convencionalmente, se aplican diferentes técnicas para atacar los diferentes tipos de problemas del despacho. Sin embargo, cualquier cambio en la formulación del problema, puede requerir una alteración parcial o el reemplazo total de la técnica utilizada. El tiempo y esfuerzo que se requiere para adecuar la técnica son inadecuados para muchas aplicaciones prácticas. Algunas de las técnicas utilizadas para solucionar los problemas de DE son la tabla de mérito, el método de la lambda iterativa, la programación dinámica y el método de gradiente. Todas ellas utilizan reglas deterministas transitorias para obtener estrategias de solución. 1.- Tabla de mérito. La idea es que la unidad más eficiente opere a su máxima capacidad, luego la segunda más eficiente, y así sucesivamente hasta satisfacer la demanda de energía. Este método es muy simple y eficiente, pero no permite considerar un gran número de restricciones y da resultados costosos. 2.- Método de la lambda iterativa. Está basado en el principio de costos incrementales iguales. Se empieza por un valor de λ inicial y se termina hasta que las potencias de las unidades se ajustan a la demanda. Este método requiere estricta convexidad y continuidad de las funciones objetivo. 3.- Programación Dinámica. Es una técnica matemática útil en la toma de una serie de decisiones interrelacionadas. Proporciona un procedimiento sistemático para determinar la combinación óptima de decisiones. Sin embargo, en la práctica el espacio de búsqueda es tan grande que simplemente no es posible completarla. 4.- Técnica del gradiente. Es un método iterativo muy eficiente cuando se parte de una buena solución inicial, ya que busca óptimos locales. En contraste a las técnicas convencionales, los Algoritmos Genéticos han exhibido robustez en la habilidad para encontrar óptimos globales en la solución de los problemas de DE de diferente complejidad. La mayor atracción de estos algoritmos es que son computacionalmente simples, pero bastante poderosos en la búsqueda de óptimos globales. En el caso del problema de DE, estos algoritmos permiten utilizar de igual manera funciones de costo lineal o no lineales, de ahí que sean una buena opción para resolver el DEPV. 5 1.5 Casos de Estudio. Se utilizaron tres casos de estudio para evaluar el desempeño de los métodos heurísticos aplicados al DE. El primer caso está formado por 7 unidades y se analiza la función de costo no convexa del CC Mexicali y la zona muerta. El caso 3 está formado por 3 unidades y se utilizó para analizar funciones de costo no convexas que consideran los puntos de válvula de las unidades. El caso 2 consta de 36 unidades y se utilizó para probar el desempeño de los métodos heurísticas con un problema de mayor dimensión. 1.5.1 Caso de estudio 1, 7 Us (función de costo no convexa de un PIE y zona muerta). Estas unidades fueron tomadas del sistema aislado de Baja California. En este sistema la unidad 7 corresponde a un PIE y se modela de dos formas. La primera corresponde al modelo actual que se utiliza en CENACE y que es un ajuste a una función de costo de segundo orden a partir de los tres puntos del régimen térmico que proporciona el PIE (ver figura 1.2). El segundo modelo utiliza una función de costo no convexa para el primer rango (122 a 245 MW) y una curva convexa para el rango complementario (245 a 489 MW). Además, se considera la zona muerta donde no opera el PIE (de 160 a 320 MW). La tabla 1.1 muestra las potencias máximas y mínimas de cada unidad, el tipo de tecnología y los coeficientes abc de las curvas de entrada-salida que, como ya se ha explicado, son de segundo orden convexas. Tabla 1.1 Límites de potencia y coeficientes abc de la unidades del caso 1. Coeficientes de la function de costo F Pmin central tipo [MW] Pmax [MW] a 2 [$/MWh ] b c [$/MWh] [$] Presidente Juárez U1 vapor 40 160 1.2800 368.0 22770 Presidente Juárez U2 ciclo combinado 62 248 0.5635 158.5 33830 Presidente Juárez U3 ciclo combinado 62 248 0.5635 158.5 33830 Ciprés U4 turbogás 7 27 24.9200 1154.0 13330 Mexicali U5 turbogás turbogás U6 7 26 19.4500 1204.0 16680 8 30 21.1600 1190.0 16660 122 489 0.0291 467.7 6957 Tijuana CC Mexicali 1) U7 ciclo combinado Total 308 1,228 1) Coeficientes abc de la curva ajustada a los tres puntos del régimen térmico 6 La figura 1.1 muestra las curvas de entrada-salida o funciones de costo F de las 7 unidades. La curva F7a es la función ajustada de segundo orden convexa del PIE CC Mexicali. La curva F7b es la función de costo no convexa. 250,000 200,000 $/h 150,000 100,000 50,000 0 0 50 100 150 200 250 300 350 400 450 MW F1 F2 F3 F4 F5 F6 F7 a F7 b Figura 1.1 Funciones de costo o curvas de entrada-salida de las unidades del caso 1. Curva de regimen termico (Heat Rate) CC Mexicali [$/MWh] 122 494.5 245 500.1 489 480.9 505 500 495 $ / MWh MW 490 485 480 475 50 75 100 % Capacidad Figura 1.2 Régimen térmico en $/MWh del CC Mexicali (U7). 7 500 La función de costo incremental es la derivada de la función de costo y cada punto representa el costo de generar el siguiente megawatt. El criterio de optimalidad del PDE establece el óptimo cuando todas las unidades operan a un mismo costo incremental. Algunas unidades no son coordinables porque su rango de potencia tiene costos incrementales que están por encima (son más caras) o por debajo (son más baratas) de las demás unidades. La figura 1.3 muestra los CI’s de las 7 unidades. Las unidades 4, 5 y 6 no son coordinables con las demás unidades. 2,500 2,000 $/MWh 1,500 1,000 500 0 0 100 200 300 400 500 MW CI 1 CI 2 CI 3 CI 4 CI 5 CI 6 CI 7a Figura 1.3 Costos incrementales de las unidades del caso 1. En la figura 1.4 se observa la diferencia entre los costos incrementales de los dos modelos utilizados para la unidad 7. La curva CI 7a es la misma de la figura 1.3, sólo que la pendiente se ve más grande por la escala utilizada. La zona muerta de la unidad 7 es de 160 a 320 MW. 8 zona muerta 505 500 $/MWh 495 490 CI 7a 485 CI 7b 480 475 470 0 100 200 300 400 500 MW Figura 1.4 Costos incrementales de los dos modelos utilizados para la unidad 7. Demanda: 870 MW Solución analítica con funciones de segundo grado convexas y sin zona muerta. La solución óptima se muestra en la tabla 1.2. Las funciones de costo de todas las unidades son curvas de segundo grado convexas, sin zona muerta para la unidad 7. Tabla 1.2 Solución óptima del caso 1 con funciones de costo de segundo grado convexas. Solución analítica P1 P2 P3 P4 P5 P6 P7 demanda [MW]: 870.0 45.9 248.0 248.0 7.0 7.0 8.0 306.1 costo óptimo [$]: 487,018 42,358 107,796 107,796 22,629 26,061 27,534 152,845 La solución analítica se obtuvo con la técnica del lagrangiano. El desarrollo completo se explica en el ANEXO 1. 9 1.5.2 Caso de estudio 2, 36 Us (problema de mayor tamaño). Estas unidades fueron tomadas del Sistema Interconectado Nacional. Se omiten los nombres por brevedad simplemente. La tabla 1.3 contiene los datos de las 36 unidades. Todas son unidades de vapor con funciones de costo de segundo grado convexas. U1 U2 U3 U4 U5 U6 U7 U8 U9 U10 U11 U12 U13 U14 U15 U16 U17 U18 U19 U20 U21 U22 U23 U24 U25 U26 U27 U28 U29 U30 U31 U32 U33 U34 U35 U36 Tabla 1.3 Datos de las 36 unidades del caso 2. Pmin Pmax a b c [$/MWh] [$/h] [MW] [MW] [$/MW2h] 220 300 0.037132 201.24 3550.7 220 300 0.041288 199.26 3948.2 260 350 0.026299 224.54 3423.0 260 350 0.027610 226.70 3593.7 225 350 0.105430 188.96 13722.0 225 350 0.106470 196.73 13857.0 225 350 0.101950 202.09 13270.0 225 350 0.069689 225.86 9070.4 225 350 0.079484 219.15 10345.0 225 350 0.077196 221.33 10048.0 140 227 0.162280 348.18 9483.9 180 240 0.504030 186.40 33471.0 122 184 0.676600 233.93 25139.0 150 225 0.248010 381.11 13352.0 225 350 0.156080 408.54 20314.0 225 350 0.155620 411.79 20254.0 55 70 1.438000 127.75 23277.0 90 122 0.427510 347.77 13513.0 90 129 0.335730 367.52 13534.0 50 62 1.608000 131.94 22128.0 64 138 0.880550 115.52 44688.0 50 63 2.061700 45.90 27971.0 249 498 0.272490 291.24 44357.0 518 1036 0.118610 261.78 135260.0 125 250 0.341910 341.77 22705.0 291.3 500 0.000096 522.55 25.7 470 580 0.032259 485.21 11531.0 124 247.5 0.540800 226.62 35198.0 600 983 0.019976 464.50 20509.0 162 489 0.025944 480.16 6591.4 160 258 0.543030 173.30 38405.0 280 449 0.025059 446.95 2881.2 242 484 0.264990 203.06 65955.0 350 495 0.007721 465.96 2010.1 248 495 0.005007 476.31 1303.3 120 252.4 0.384100 283.63 25998.0 10 En la fig. 1.5 se muestran las curvas de costo incremental de las 36 unidades. 600 CI23 550 500 CI30 CI14 CI19 $/MWh 450 CI18 CI13 400 350 CI20 CI26 CI25 CI16 CI27 CI15 CI36 CI35 CI34 CI32 CI33 CI11 CI12 CI29 CI24 CI28 CI31 CI17 300 CI22 CI8 CI7 250 CI21 CI1 200 50 150 CI10 CI9 CI6 CI5 CI4 CI3 CI2 250 350 450 550 650 750 850 950 MW CI1 CI2 CI3 CI4 CI5 CI6 CI7 CI8 CI9 CI10 CI11 CI12 CI13 CI14 CI15 CI16 CI17 CI18 CI19 CI20 CI27 CI28 CI29 CI30 CI21 CI22 CI23 CI24 CI25 CI26 CI31 CI32 CI33 CI34 CI35 CI36 Figura 1.5 Costos incrementales de las unidades del caso 2. Demanda: 10 500 MW Zona muerta: no Solución analítica para funciones de segundo grado convexas y sin zona muerta. Esta solución se encontró usando la función “solver” de Excel 2003 de Microsoft. 11 Tabla 1.4 Solución óptima del caso 2 con funciones de costo de segundo grado convexas. Potencia Costo Potencia Costo Unidad Unidad [MW] [$] [MW] [$] 1 300 67,265 19 129 66,531 2 300 67,442 20 62 36,489 3 350 85,234 21 138 77,399 4 350 86,321 22 63 39,046 5 350 92,773 23 332 170,993 6 350 95,755 24 886 460,539 7 350 96,490 25 191 100,270 8 350 96,658 26 291 152,253 9 350 96,784 27 470 246,706 10 350 96,970 28 227 114,482 11 227 96,883 29 600 306,400 12 240 107,239 30 162 85,058 13 176 87,265 31 258 119,263 14 183 91,570 32 449 208,614 15 225 120,137 33 484 226,312 16 225 120,785 34 396 187,822 17 70 39,266 35 248 119,736 18 122 62,304 36 245 118,696 demanda 10,500 MW costo 4,443,749 $ Funciones de costo no convexas, zonas muertas y punto de válvula. Para observar el desempeño con diferentes tipos de funciones de costo y zona muerta. Incluye 33 unidades del caso 2, una de las cuáles se modela con una función de costo no convexa y zona muerta; 3 unidades del caso 3, que modelan los puntos de válvula. 1.5.3 Caso de estudio 3, 3 Us (evaluación de puntos de válvula). Este caso se tomó de Walters [13] y consta de 3 unidades con funciones de costo que modelan los puntos de válvula. La tabla 2.5 contiene los datos de las 3 unidades. La función de costo de cada unidad térmica es de la forma: F = aP2 + bP + c + e sen(f * (Pmin-P)) Tabla 1.5 Datos de las 3 unidades del caso 3. Pmin Pmax [MW] a 2 [MW] [$/MW h] b c e f [$/MWh] [$/h] [$/h] U1 100 700 0.001570 7.92 571.0 300 0.0315 U2 100 400 0.001940 7.85 310.0 200 0.042 U3 50 200 0.004820 7.97 78.0 150 0.073 12 En la figura 1.6 se grafican las funciones de costo y las curvas de costo incremental. 8,000 24 7,000 20 5,000 U1 4,000 U2 3,000 U3 $/ M W h $/h 6,000 2,000 U1 16 U2 12 U3 8 1,000 4 0 50 150 250 350 450 550 50 100 150 200 250 300 350 400 450 500 550 600 650 700 650 MW MW a) b) Figura 1.6 Funciones de a) costo y b) costos incrementales de las unidades del caso 3. Demanda: 850 MW La tabla 1.6 presenta la mejor solución encontrada por Walters y según reporta, coincide con la solución óptima obtenida por el método de programación dinámica. Tabla 1.6 Solución óptima del caso 3. P1 P2 P3 demanda Costo [MW] [MW] [MW] [MW] [$] 300.0 400.0 150.0 850.0 8,237.6 13 Capítulo 2. Métodos Heurísticos 2.1 Introducción El término heurística proviene del griego heuriskein que significa encontrar o descubrir. De acuerdo con ANSI/IEEE Std 100-1984 (Standard Dictionary of Electrical and Electronics Terms), una heurística se refiere a aquellos métodos o algoritmos exploratorios para la resolución de problemas en los que las soluciones se descubren por la evaluación del progreso logrado en la búsqueda de un resultado final. Se trata de métodos en los que, aunque la exploración se realiza de manera algorítmica, el progreso se logra por la evaluación puramente empírica del resultado. Se gana eficacia, sobre todo en términos de eficiencia computacional, a costa de la precisión. Las técnicas heurísticas son usadas en problemas en los que la complejidad de la solución algorítmica disponible es función exponencial de algún parámetro; cuando el valor de éste crece, el problema se vuelve rápidamente inabordable. Las técnicas heurísticas no aseguran soluciones óptimas sino solamente soluciones válidas, aproximadas, y frecuentemente no es posible justificar en términos estrictamente lógicos la validez del resultado. En este capítulo se hace una breve descripción de los métodos heurísticos que se implementaron para el PDE (AG, AGH, ARS, GRASP) , y de métodos heurísticos que sirvieron de soporte para la implementación del AGH, como son la búsqueda en vecindades y un algoritmo de satisfacción de restricciones. 2.2 Algoritmo Genético Un AG puede considerarse un algoritmo de búsqueda probabilística inteligente que puede aplicarse a varios problemas de optimización combinatoria. Las bases 14 teóricas de los algoritmos genéticos fueron desarrolladas por John Holland en los años setenta; la idea está basada en el proceso evolutivo de los organismos biológicos en la naturaleza, donde las poblaciones evolucionan de acuerdo a los principios de la selección natural en que sobreviven y se reproducen los más aptos. Los algoritmos genéticos intentan imitar matemáticamente algunos procesos adaptativos del fenómeno biológico, considerando una población inicial de individuos y aplicando operadores genéticos en cada reproducción. Con dichos operadores se define un mecanismo de búsqueda sin necesidad de imponer restricciones matemáticas adicionales. En términos de optimización, cada individuo de una población es codificado en una cadena o cromosoma que representa una posible solución de un problema dado. La aptitud de un individuo es evaluado con respecto a una función objetivo propuesta. A los individuos mejor adaptados, o mejores soluciones, se les permite reproducirse intercambiando algunos elementos de su información genética en un proceso de cruce con otros individuos también muy aptos, lo cuál produce nuevas soluciones que comparten algunas características tomadas de sus padres. Frecuentemente se aplica la mutación después del cruce, alterando algunos genes en las cadenas con el fin dar mayor variedad en las soluciones. Los descendientes pueden reemplazar a la población total (enfoque generacional), o reemplazar a los individuos menos aptos (enfoque de estado uniforme). Este ciclo de evaluación-selección-reproducción se repite hasta encontrar una solución satisfactoria. Un AG simple se puede resumir en la siguiente tabla: Tabla 2.1 Algoritmo Genético simple. inicio Representar adecuadamente las soluciones del Problema Generar población inicial con individuos o soluciones del Problema Definir una función de aptitud de los individuos de la población do while (NO se haya satisfecho el criterio de parada) Elegir pares de individuos como padres Cruzar con probabilidad Pc a los padres elegidos para obtener dos hijos Reemplazar los padres elegidos, por sus hijos Mutar con probabilidad Pm algunas características de cada individuo Evaluar la aptitud de los individuos de la población Seleccionar individuos que sobreviven en la siguiente generación enddo fin 15 Los algoritmos genéticos manejan simultáneamente un conjunto de soluciones (individuos) en cada etapa (la generación). Las características de cada solución deben ser codificadas adecuadamente (el cromosoma) de forma que al combinar dos soluciones para producir una nueva solución, parte de estas características (los genes) se transmitan a ésta. Los parámetros del AG han sido ampliamente estudiados y se recomiendan valores altos para la probabilidad de cruza Pc, siendo un valor típico 0.8. La probabilidad de mutación Pm se recomienda sea de valor muy bajo y un valor típico es de 0.001. En otros trabajos se reportan algoritmos genéticos modificados o refinados con operadores especiales de cruza [2] y probabilidades de cruza y mutación que se van adaptando al nivel de progreso en la solución. Respecto al tamaño de la población, resultados empíricos de varios autores sugieren poblaciones tan pequeñas como 30 individuos. Un trabajo experimental de J.T. Alander sugiere valores entre n y 2n [9], siendo n el tamaño de la cadena o string que representa a un individuo. A. Olachea [7] trabajó con poblaciones de 40 y 100 individuos y sugirió este último valor para los problemas de DE que estudió. Para un mayor análisis de los parámetros generales del AG se puede consultar [3]. 2.3 Búsqueda local La búsqueda local se basa en el método de optimización más antiguo, que es el de prueba y error. La idea es tan simple y natural que sorprende como puede ofrecer tan buenos resultados para problemas difíciles de optimización combinatoria. El algoritmo general se puede describir como sigue: dada una instancia (F,c) de un problema de optimización, dónde F es un conjunto de soluciones factibles y c es la función de costo, se escoge una vecindad N: F 2F , donde se busca un punto t ∈ F de mejora a través de la subrutina: ⎧a lg ún s ∈ N (t ) con c( s ) < c(t ) si tal s existe mejorar (t ) = ⎨ " no" si no ⎩ Tabla 2.2 Algoritmo de búsqueda local. procedure búsqueda local begin t:= un punto de inicio en F; while mejorar(t) ≠ ‘no’ do t:= mejorar(t); return t end 16 El seudocódigo se muestra en la tabla 2.2, se inicia a partir de una solución inicial factible t∈ F y usa la subrutina mejorar para buscar una mejor solución en su vecindad. Mientras ésta exista, se adopta como la mejor solución y se repite la búsqueda en la vecindad de la nueva solución. El algoritmo termina cuando se haya encontrado el óptimo local [9]. Para aplicarlo a un problema en particular se deben hacer algunas selecciones. Primero que nada, se debe obtener una solución inicial factible. Es recomendable, en muchas ocasiones, correr el algoritmo a partir de distintos puntos de inicio y entonces escoger el mejor resultado. En tales casos, se debe decidir cuántas soluciones iniciales utilizar y cómo deben estar distribuidas. Luego, se debe definir una buena vecindad y tener un método de búsqueda dentro de esa vecindad para el problema en particular. Esta selección se tiene que hacer prácticamente de manera intuitiva, ya que existe poco respaldo teórico para obtener una guía general. Respecto al tamaño de la vecindad, se debe evaluar la conveniencia de utilizar una de gran tamaño que podría proporcionar un mejor óptimo local, pero que requeriría de más tiempo de búsqueda. La otra alternativa es la de tener una vecindad pequeña, pero con la posibilidad de obtener más soluciones en un tiempo similar. Vecindades Dado un punto o solución factible f∈ F en un problema particular, es útil en muchos casos definir un conjunto de vecindades N(f) de puntos que son “cercanos” en alguna forma a f. Definición. Dado un problema de optimización con instancias (F,c), una vecindad es un mapeo N : F 2F, definido para cada instancia. Si F = Rn, el conjunto de puntos dentro de una distancia euclidiana x, define una vecindad de forma muy natural. En muchos problemas de optimización combinatoria, la selección de N puede depender críticamente de la estructura de F [9]. 17 2.4 Algoritmo de Recocido Simulado El concepto de recocido simulado en optimización combinatoria fue introducido por Kirkpatrick, Gellat y Vecchi en 1983 y en forma independiente por C erný en 1985. Usando una analogía entre estos problemas y el recocido de sólidos que es un proceso físico en el cual un sólido se funde y después se enfría lentamente con el fin de obtener estructuras de cristal perfectas las cuales pueden modelarse como un estado de mínima energía. La idea es resolver problemas de optimización combinatoria por un proceso análogo. Sea s la solución actual y N(s) una vecindad de s que contiene soluciones alternativas. Se selecciona de forma aleatoria s’ ∈ N(s) y se calcula la diferencia D = f(s’) – f(s), donde f(s) es el valor de la función objetivo en s. Si D < 0, entonces s’ se selecciona como la nueva solución, lo que quiere decir que soluciones mejores se aceptan siempre. Si D > 0 y e-D/cT > r, donde r es un número aleatorio generado de una distribución uniforme, entonces s’ se acepta como nueva solución, lo que significa que también pueden aceptarse soluciones peores que la actual. T es un parámetro de control llamado temperatura y c es la constante de Boltzman (1.38054x10-3). Como ya se dijo, la temperatura se hace descender lentamente, mediante una constante de enfriamientoα, durante el proceso de búsqueda de tal manera que la probabilidad de aceptar peores soluciones decrece constantemente. En cada temperatura el proceso continúa hasta que se cumple el criterio de parada. Tabla 2.3 Algoritmo de Recocido Simulado. Inicio inicializa (sini, T, K0) k 0 s sini do while (T> temperatura mínima (criterio de paro) for k=1 to K0 do genera s’ ∈ N(s)) if f(s’) < f(s) then s s’ else genera_aleatorio n en [0,1] if (exp((f(s) – f(s’))/ c T) > n) then s s’ end if end for T α T , α∈ (0,1) end do fin 18 2.5 GRASP (greedy randomized adaptive search procedures) GRASP es un método iterativo multi-arranque diseñado para resolver problemas difíciles de optimización combinatoria. Una característica importante de GRASP es la facilidad para implementarse. En su forma más simple sólo hay que determinar el número de iteraciones y el tamaño de la lista de candidatos. Cada iteración consiste de dos fases: una de construcción, en la cuál se produce una solución factible buena, y una de mejora, que es una búsqueda local en la que se examinan vecindades de la solución producida en la fase anterior. La mejor solución encontrada en cada fase se va almacenando hasta concluir el proceso con un criterio de terminación. Se muestra a continuación el seudocódigo de un GRASP básico [9]. Tabla 2.4 Algoritmo GRASP simple. procedure GRASP (f(.), g(.), imax) Require: imáx f* ← ∞ for i ≤ imáx do construct(g(.), α,x) x ← GreedyRandomized() x ← local_search(x) if f(x) < f* then f* ← f(x) x* ← x end if end for return x* Fase de construcción En esta fase se construye en forma iterativa una solución factible, se incorpora un elemento a la vez. En cada iteración, la elección del siguiente elemento se determina ordenando a todos los candidatos de una lista C con respecto a una función glotona o miope g:C ⇒ R. Esta función mide el beneficio local de seleccionar cada elemento. La heurística es adaptativa porque los beneficios asociados con cada elemento son actualizados en cada iteración de la fase de construcción para reflejar los cambios resultantes por la selección del elemento previo. La componente probabilística del GRASP es caracterizado por elegir de 19 forma aleatoria uno de los mejores candidatos en la lista, y no necesariamente al mejor de ellos. La lista de los mejores candidatos es llamada lista restringida de candidatos (RCL, restricted candidate list). Esta técnica de selección permite obtener diferentes soluciones en cada iteración del GRASP. La tabla 2.5 muestra un algoritmo para la fase de construcción. Tabla 2.5 Algoritmo de fase de construcción del GRASP basado en valor. procedure construct(g(.), α, x) x = 0; Inicializar lista de candidatos C; while C ≠ 0 do s = mín{ g(t) | t ∈ C }; f- = máx{ g(t) | t ∈ C }; RCL = { s ∈ C | g(s) ≤ s + α( f- – s) }; Selección aleatoria de s de la RCL; x = x ∪ {s}; actualizar la lista de candidatos C; end while end construct; El parámetro alfa controla el grado de miopía y aleatoriedad en el algoritmo. Un valor de α = 0 corresponde a un procedimiento de construcción puramente miope, mientras que con α = 1, uno aleatorio. Aunque los algoritmos miopes pueden producir buenas soluciones razonables, su principal desventaja como generador de soluciones iniciales para búsquedas locales es su falta de diversidad. Aplicando repetidamente un algoritmo miope, una sola o muy pocas soluciones pueden generarse. Un algoritmo totalmente aleatorio produce una gran cantidad de soluciones diversas, pero la calidad de éstas es generalmente muy pobre, y al usarlas como soluciones iniciales para búsquedas locales, generalmente conducen a una convergencia muy lenta. Así entonces, para beneficiarse de la convergencia rápida del algoritmo miope y la gran diversidad de soluciones del algoritmo aleatorio, se recomienda usar valores de α estrictamente contenido dentro del rango [0,1] El algoritmo de construcción de la tabla 2.5 utiliza una RCL basada en el valor, donde los elementos que la forman cumplen con un valor de la función miope dentro de un rango dado. En la tabla 2.6 se muestra un algoritmo de construcción con RCL basada en cardinalidad [10], donde la lista está formada por un número fijo de elementos con las mejores evaluaciones de la función miope. 20 Tabla 2.6 Algoritmo de fase de construcción del GRASP basado en cardinalidad. Procedure Construcción-C Require: k, E, c(.) x←0 C←E Calcular costo miope c(e), ∀ e ∈ C while C ≠ 0 do RCL ← { k elementos e ∈ C con el menor c(e) } Seleccionar un elemento s de RCL al azar x ← x ∪ {s} Actualizar el conjunto candidato C Calcular el costo miope c(e), ∀ e ∈ C end while return x Existen diferentes variantes del algoritmo de construcción (construcción aleatoria después miope, construcción con perturbaciones, RCL basada en valores con sesgo) que pueden ser revisadas en [10]. Fase de búsqueda Local Las soluciones generadas en la fase de construcción del GRASP no garantizan ser localmente óptimas respecto a definiciones simples de vecindades. Por lo cuál es benéfico aplicar una búsqueda local para intentar mejorar cada solución construida. Un algoritmo de búsqueda local explora repetidamente la vecindad de una solución en busca de una mejor solución. Cuando no se encuentra una solución que mejora la actual, se dice que la solución es localmente óptima. La clave de éxito de los algoritmos de búsqueda local depende de una elección apropiada de la estructura de vecindades, de técnicas eficientes de búsqueda en vecindades y de la solución inicial. En la tabla 2.7 se muestra un algoritmo sencillo de búsqueda local para el GRASP [10]. Tabla 2.7 Algoritmo de búsqueda local del GRASP. Procedure BúsquedaLocal Require : x0, N(.), f(.) x ← x0 while x no es localmente óptimo con respecto a N(x) do Sea y ∈ N(x) | f(y) < f(x) x←y end while return x 21 2.6 Satisfacción de Restricciones La programación de restricciones puede dividirse en dos ramas claramente diferenciadas: la satisfacción de restricciones y la resolución de restricciones. Ambas comparten la misma terminología pero sus orígenes y técnicas de resolución son diferentes. Un problema de satisfacción de restricciones (PSR) está definido por un conjunto de variables X1, X2,…, Xn, y un conjunto de restricciones r1, r2,…,rm. Cada variable Xi tiene un dominio Di de posibles valores. Cada restricción ri comprende algún subconjunto de variables y especifica las combinaciones de valores permisibles para cada subconjunto. Dependiendo si los dominios de las variables son discretos o continuos, finitos o infinitos, se pueden distinguir distintos tipos de PSRs. Un estado del problema está definido por una asignación de valores a algunas o a todas las variables, {Xi=vi, Xj = vj,…}. Una asignación que no viola ninguna restricción se llama consistente o asignación válida. Una asignación completa es una en la que cada variable es mencionada; una solución a un PSR es una asignación completa que satisface a todas las restricciones. La resolución de un PSR consta de dos fases: i. Modelar el problema como uno de satisfacción de restricciones. La modelación expresa el problema mediante un conjunto de variables, dominios y restricciones del PSR. ii. Procesar el problema de satisfacción de restricciones resultante, para lo que hay dos formas. 1. Técnicas de consistencia. Son técnicas de resolución de PSR basadas en la eliminación de valores inconsistentes de los dominios de las variables. 2. Algoritmos de búsqueda. Se basan en la exploración sistemática del espacio de soluciones hasta encontrar una solución, o probar que no existe alguna. Las técnicas de consistencia o inferenciales permite deducir información del problema, niveles de consistencia, valores posibles de variables, dominios mínimos, etc., aunque en general se combinan con las técnicas de búsqueda, ya que reducen el espacio de soluciones y los algoritmos de búsqueda exploran dicho espacio resultante. Una forma de hacer mejor uso de las restricciones durante la búsqueda se llama inspección hacia delante. Siempre que una variable X es asignada, el proceso de inspección hacia delante mira a cada variable Y no asignada que está conectada a X por una restricción y borra del dominio de Y cualquier valor que es inconsistente para el valor escogido para X. 22 El conjunto formado por todas las posibles asignaciones de un PSR, también conocido como espacio de estados, se representa mediante un árbol de búsqueda. En cada nivel se asigna un valor a una variable, y los sucesores de un nodo son todos los valores de la variable asociada a este nivel. Cada camino del nodo raíz a un nodo terminal representa una asignación completa. Los algoritmos se diferencian en cómo recorren el árbol de búsqueda a la hora de encontrar soluciones: búsqueda hacia atrás, salta hacia atrás, salta hacia atrás directo a conflicto, etc. 2.7 Algoritmos Híbridos En algunos casos, la efectividad de un algoritmo puede ser mejorada al combinarlo con otro algoritmo, a lo que se le conoce como hibridación y se puede aplicar de diferentes maneras. Por ejemplo, para el AG se puede aplicar una heurística específica para crear la población inicial de tal manera que cada individuo sea una solución factible. El AG se puede combinar con algoritmos de búsqueda local para mejorar la calidad de la solución. Los algoritmos híbridos consisten en la combinación de algoritmos, ya sea que formen parte de otro algoritmo o que sirvan para mejorar la entrada o salida de un algoritmo principal. Esto con el fin de mejorar el desempeño del algoritmo y la calidad de la solución. Sin embargo, esto requiere de un conocimiento más específico del problema. A veces estas modificaciones rompen con los paradigmas de cada algoritmo. Por ejemplo, Reeves [10 ] comenta que el incorporar heurísticas específicas al AG rompe con una de sus principales ventajas, que es la de encontrar soluciones para cualquier tipo de problema, sin tener un conocimiento detallado de éste y su funcionamiento depende de una adecuada codificación del problema. Sin embargo, concluye que esto es preferible si se desea una buena solución para un problema en específico, más que la evaluación del desempeño del AG para diferentes problemas. En el caso de recocido simulado, las combinaciones son en el sentido de mejorar la solución a la entrada o a la salida del algoritmo. Cuando se proporciona una buena solución al ARS en lugar de una solución generada de forma aleatoria, se recomienda empezar el algoritmo a temperaturas bajas, para no correr el riesgo de destruir la solución en las primeras etapas. El problema pudiera ser que la solución encontrada sea un mínimo local. 23 Capítulo 3. IMPLEMENTACIÓN DEL ALGORITMO GENÉTICO 3.1 Introducción El AG es quizá el método heurístico más utilizado para el PDE debido a su fácil representación en código binario. Para resolver el PDE, algunos autores hacen uso de un algoritmo de reparación de soluciones que se aplica a cada nueva generación. Esto debido a que aún cuando la población inicial esté conformada por soluciones factibles, los operadores de cruza y mutación se encargan de que las nuevas combinaciones de potencias resultantes no cumplan con el balance de potencia BP. Sin embargo, el AG no requiere más que una apropiada codificación y el establecimiento adecuado de la función objetivo. No se requiere conocer más del problema en cuestión. Basta con generar números aleatorios para conformar los individuos de la población inicial y poner en marcha el AG para encontrar una solución. En el desarrollo del capítulo se muestra la implementación de un AG al problema de DE. Se utiliza una codificación binaria para representar el nivel de potencia de cada generador. Un cromosoma está formado por las potencias codificadas de las unidades. 24 3.2 Descripción del programa El programa principal Despacho_AG que implementa el AG tiene 4 módulos: - Pob_ini: Crea la población inicial de forma aleatoria. - Evaluación: Evalúa la función objetivo. - Selección: Selecciona por "torneo" a los mejores individuos de acuerdo a su evaluación - Hijos. Implementa los operadores de cruza y mutación y que aplicados a los individuos seleccionados por el módulo de selección, dan paso a una nueva población. La estructura de datos utilizada en el programa para representar una unidad generadora es la siguiente: Tabla 3.1 Estructura de datos generador. struct generador { float coef_a; float coef_b; float coef_c; float coef_e; float coef_f; float Pmin; float Pmax; int L; bool hay_zm; float ini_zm; float fin_zm; } Las primeras 5 variables de la estructura de datos generador corresponden a los coeficientes abcef de la función general de costo F, que es de la forma: F = aP2 + bP + c + e sen(f * (Pmin-P)) Esta es la función general que modela los puntos de válvula. Si los coeficientes e y f son cero, entonces la función de costo no modela el punto de válvula y se transforma en una función de segundo grado. Pmín y Pmáx son variables de punto flotante que almacenan los límites de potencia de la unidad. L es una variable de tipo entero que almacena el tamaño de la subcadena que representa a una unidad. hay_zm es una variable de tipo booleana que toma el valor 1 si está definida una zona muerta o 0 sino lo está. 25 ini_zm y fin_zm son variables de punto flotante que almacenan las potencias de inicio y fin de la zona muerta. Si hay_zm = 0, entonces estas variables deben ser iguales al valor de Pmín. 3.3 Población inicial y codificación La población inicial se crea a través del módulo Pob_ini. Módulo Pob_ini. Crea la población inicial de forma aleatoria. Entrada: número de unidades: Us tamaño de la población: tam_pob límites de potencia de generadores: Pmini, Pmaxi 1 ≤ i ≤ Us longitud de subcadena: Li Salida: población de tam_pob individuos. Cada individuo tiene Us enteros generados de forma aleatoria. Las soluciones no son factibles. 3.3.1 Codificación. Los individuos o cromosomas se representaron por una cadena binaria. Cada cadena binaria está formada por subcadenas de 2 bytes (fig. 3.1) que representan la potencia de una unidad. El problema del DE no requiere mucha precisión en el nivel de generación asignado, normalmente se utilizan cifras enteras tanto para las potencias como para la demanda pronosticada. Sin embargo, si se quiere usar una precisión de 1 decimal, con 2 bytes se puede disponer de un rango de 216/10 = 6553.6, suficiente para representar la potencia de una unidad generadora (en México las unidades de la CN Laguna Verde son las de mayor potencia: 682.4 MW c/u) 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 U1 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 U2 7 6 5 4 3 2 1 0 . . . s u b c 2 b y t e s 7 6 4 2 1 5 3 a d e n a 0 UUs Figura 3.1 Cadena, individuo o cromosoma. 26 3.3.2 Representación de los límites de potencia del generador. La representación de los límites de potencia está en función del rango de operación de la unidad y la precisión que se desea utilizar. Por ejemplo, si el rango de operación de la unidad es de 35 a 210 MW y se desea una precisión de un decimal, entonces se requiere de al menos (210-35)*10 = 1750 números diferentes, lo cuál se logra con 11 bits: 210 < 1750 < 211 211=2048 210=1024 Para esta unidad sólo se utilizarían 11 de los 16 bits, y la longitud L de la subcadena es 11: entero de 2 bytes 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 sin uso Figura 3.2 Subcadena de 11 bits. 3.3.3 Decodificación. Para convertir una subcadena binaria (bL-1,..., b3, b2, b1, b0) al valor entero correspondiente, se utiliza la siguiente ecuación: ⎛ L −1 ⎞ (bt −1 ...b1b0 ) 2 = ⎜ ∑ bk ⋅10 k ⎟ = valor entero; ⎝ k =0 ⎠10 k = 0,..., L − 1 El valor entero representa un valor de potencia entre los límites de generación especificados, que se decodifica con la siguiente ecuación: Pi = P min i + valor entero ( P max i − P min i ) 2 Li − 1 3.3.4 Codificación de la zona muerta. La zona muerta es un rango de operación donde no se puede operar una unidad por razones técnicas y/o económicas. Estas regiones se pueden restringir desde la 27 propia codificación o mediante la penalización de aquellas soluciones que incluyan la operación en zona muerta. Para tomar en cuenta la zona muerta desde la codificación de la potencia, se agregó un bit adicional bit_zm a la subcadena para indicar la operación arriba (bit_zm = 1) o debajo (bit_zm = 0) de la zona muerta. Cuando la unidad opera arriba de la zona muerta, el valor entero codificado aumenta en 2L unidades. Cuando se decodifica el valor entero, se debe revisar si la unidad opera en zona muerta (variable hay_zm de la estructura de datos generador). Los límites de potencia que se usan en la expresión para decodificar el valor entero según el valor de bit_zm, son como se muestran en la tabla 3.2. Tabla 3.2 Límites de potencia usados en la decodificación del valor entero Pcod según el valor de bit_zm. Expresión para decodificar valor entero Pcod bit_zm Pmín Pmáx 1 Pzmfin Pmáx 0 Pmín Pzmini Pi = P min i + Pcod ( P max i − P min i ) 2 Li − 1 Por ejemplo, para representar el rango de 122 a 489 se requieren 12 bits, L=12. La figura 3.7 muestra los valores extremos de la codificación de una unidad con zona muerta definida en el rango ini_zm = 260, fin_zm = 320 MW; y con límites de potencia Pmín=122 MW y Pmáx= 489 MW. (decimal) (entero) P Pcod [MW] 8191 489.0 bit zm 15 15 260.0 4095 320.0 4096 122.0 0 15 15 14 14 14 14 13 13 13 13 12 11 10 1 1 12 11 10 0 1 1 1 12 11 10 1 0 0 12 11 10 0 0 0 9 1 8 1 9 1 8 1 9 0 7 8 6 7 5 6 4 5 3 4 2 3 1 2 0 1 1 0 2 0 0 1 1 0 3 0 1 1 1 0 4 0 2 1 1 0 5 0 3 1 1 0 6 0 4 1 1 0 7 0 5 1 1 0 8 0 6 1 1 0 9 0 7 1 0 0 1 0 0 0 Figura 3.3 Representación de diferentes valores de potencia a través del bit_zm para una unidad con zona muerta. 28 3.4 Evaluación Este módulo calcula la aptitud de cada individuo. Entrada: Tamaño de la población: tam_pob Archivo con tam_pob individuos Coeficientes de funciones de costo: coeficientes aibicieifi, modelo de 3 puntos (MW, kcal/MWh) de PIE. Factores de penalización por incumplimiento de BP: FP_IBP Incio y fin de zona muerta: ini_zmi, fin_zmi 1 ≤ i ≤ Us Salida: Archivo con aptitudes de los individuos de la población Para evaluar la función es necesario decodificar cada uno de los valores enteros de cada individuo. 3.4.1 Aptitud de los individuos La función objetivo del problema de DE fue utilizada directamente para evaluar la aptitud de los individuos: n ⎛ n ⎞ aptitud = ∑ Fi ( Pi ) + FP _ IBP⎜ ∑ Pi − demanda ⎟ + P _ ZM i =1 ⎝ i=1 ⎠ n P _ ZM = 0.1∑ Fi ( Pi ) i =1 La función objetivo incluye los costos de generación de cada unidad, la penalización por incumplimiento de balance de potencia FP_IBP y la penalización por operar en zona muerta P_ZM. Se utilizaron divisores para escalar la aptitud de los individuos de tal forma que quedara representada con 3 dígitos. El FP_IBP también fue atenuado con el mismo divisor en los algoritmos, pero en los resultados se hace referencia a su valor original para no causar confusión. Tabla 3.3 Factores de escalamiento de aptitud para cada caso de estudio. divisor caso 1 1000 caso 2 10000 caso 3 10 29 3.4.2 Función de costo. En los casos de estudio se evalúan 3 tipos de funciones de costo: Tabla 3.4 Tipos de funciones de costo de los casos de estudio. Tipo función de costo Descripción Convexa de segundo grado Funciones de costo clásicas, coeficientes abc No convexa de segundo grado Modelo especial de PIE. No convexa: de segundo grado + senoidal Para modelar punto de válvula Para los dos primeros casos se evalúa directamente la función de costo. Los coeficientes abcef tienen las unidades apropiadas para obtener el costo en $/h. El DE se realiza para un periodo determinado y en los casos de estudio es de 1h. Tabla 3.5 Unidades de los coeficientes abcef de la función general de costo. a b c e f [$/MW2h] [$/MWh] [$/h] [$/h] adimensional Para el tercer tipo, el PIE proporciona 3 puntos de operación de una curva de consumo específico o régimen térmico, con unidades kcal / kWh. Los precios de los combustibles se actualizan diariamente. Los valores en $/MWh mostrados en la fig. 2.2 fueron convertidos con un precio de 267.4 $/gcal. Para obtener el costo de valores de potencia entre estos tres puntos, se utilizó el método de interpolación lineal. La tabla 3.6 muestra en negrita los tres puntos proporcionados por el PIE, y los demás son costos interpolados para diferentes puntos de operación. Tabla 3.6 Tabla de costos del PIE CC Mexicali. Potencia Consumo específico costo [kcal / [MW] kWh] [$/MWh] [$/h] 49 1,837.0 491 24,020 98 1,845.3 493 48,257 495 60,456 122 1,849.4 147 1,853.5 496 72,710 196 1,861.8 498 97,380 500 122,266 245 1,870.1 260 1,865.5 499 129,700 293 1,855.7 496 145,592 320 1,847.9 494 158,124 342 1,841.4 492 168,543 367 1,834.2 490 179,878 391 1,827.0 489 191,119 440 1,812.7 485 213,319 481 235,143 489 1,798.3 30 3.5 Selección Este módulo selecciona por torneo a los mejores individuos de acuerdo con su aptitud. Entrada: Archivo con aptitudes de los individuos de la población. Tamaño de la población: tam_pob Salida: Archivo con individuos seleccionados por torneo. 3.5.1 Selección por torneo Se escogen a los ganadores de una competencia entre dos individuos seleccionados aleatoriamente. El ganador es el que tenga una evaluación menor (cuando el problema es de maximizar, el ganador es el que tiene una evaluación mayor). El individuo más apto es seleccionado tantas veces como haya sido puesto a competir (aleatoriamente), y el que tiene la peor evaluación mayor nunca pasa a la siguiente generación. Este tipo de selección es muy fácil de implementar y tiene la ventaja sobre otros métodos porque no necesita ordenar a los individuos. 3.6 Nuevas generaciones. El módulo Hijos implementa los operadores de cruza y mutación, que aplicados a los individuos seleccionados por el módulo de selección dan paso a una nueva generación. Entrada: Archivo con tam_pob individuos seleccionados Probabilidad de cruza: Pc Probabilidad de mutación: Pm. Longitud de subcadena: Li 1 ≤ i ≤ Us Salida: Archivo con tam_pob individuos de una nueva generación 3.6.1 Mutación y cruza. Se utilizó una probabilidad de cruza Pc= 0.8 y una probabilidad de mutación Pm=0.01 durante todo el proceso evolutivo. Se pueden usar uno o dos puntos de cruza pcruza y su valor se elige de forma aleatoria para cada par de padres. Un par de padres genera un par de hijos. Los padres se leen de forma secuencial de un archivo y se cruzan con una probabilidad Pc. Después cada bit del cromosoma es 31 revisado con el operador de mutación. En la figura 3.4 se muestra la operación de cruza a nivel de bits con un punto de cruza pcruza = 14 en una cadena de 33 bits que representa a 3 unidades. El valor de pcruza se escoge entre 1 y 33. Padre 1 7 6 Padre 2 5 4 3 2 1 0 7 6 5 4 3 2 1 0 Pcod 7 6 5 4 3 1 1 0 0 0 1 0 0 0 1 0 1570 U1 1 7 7 6 6 5 5 4 4 3 3 2 3 4 5 6 7 8 9 10 11 2 1 0 7 6 5 4 3 2 1 0 Pcod 1 1 1 0 1 1 0 0 1 1 1 1895 U2 12 13 14 15 16 17 18 2 1 0 7 6 5 4 19 20 3 2 23 24 25 26 27 28 29 30 1 0 Pcod 6 6 5 4 3 7 6 5 4 3 7 6 7 6 5 4 3 2 1 0 1 2 3 4 5 6 7 8 9 10 11 2 1 0 7 6 5 4 3 2 1 0 Pcod 562 Pcod 12 13 14 15 16 17 18 2 1 0 7 6 5 4 19 20 3 2 21 22 1 0 31 32 33 23 24 25 26 27 28 29 30 Pcod 361 31 32 33 Hijo 2 5 4 3 2 1 6 0 0 0 1 0 1 1 0 1 0 0 1 1 0 7 6 5 4 3 2 1 0 Pcod 7 6 5 4 3 1 1 0 0 0 1 0 0 0 1 0 1570 U1 7 1 1 1 1 0 0 0 0 0 0 1 0 1794 865 U3 Hijo 1 7 7 21 22 0 1 1 0 1 1 0 0 0 0 1 2 0 1 0 0 0 1 1 0 0 1 0 5 5 4 4 3 3 2 3 4 5 6 7 8 9 10 11 13 14 15 16 17 18 2 1 0 7 6 5 4 19 20 3 2 23 24 25 26 27 28 29 30 7 6 5 4 3 21 22 1 0 0 1 1 0 1 1 0 0 0 0 1 Pcod 562 2 1 2 1 0 7 6 5 4 3 2 1 0 Pcod 1 1 1 0 1 1 0 0 1 1 1 1794 U2 12 0 0 1 0 0 0 1 1 0 0 1 0 Pcod 7 6 5 4 3 361 U3 31 32 33 1 2 0 3 7 4 6 5 5 6 4 7 3 8 2 9 1 10 11 2 1 0 7 6 5 4 3 2 1 0 Pcod 1 1 1 0 1 1 0 0 1 1 1 1895 12 13 14 15 16 17 18 2 1 0 7 6 5 4 19 20 21 22 0 Pcod 0 1 1 0 1 1 0 0 0 0 1 865 3 23 24 25 26 27 28 29 30 2 1 31 32 33 Figura 3.4 Cruza de 2 individuos a nivel de bits, con pcruza = 14. En el ejemplo anterior, con el operador de cruza se intercambiaron las unidades 2 y 3 de los padres a los hijos, pero ninguna unidad modificó su valor debido a que el punto de cruza cayó en un punto en donde los bits más significativos de las unidades 2 son iguales. Con pcruza = 16, los bits más significativos de las unidades 2 en los padres ya no son iguales y el valor codificado de las unidades 2 en los hijos son diferentes, como se observa en la figura 3.5. 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 Pcod 1 1 1 0 1 0 0 0 0 1 0 1858 U2 12 13 14 15 16 17 18 19 20 21 22 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 Pcod 1 1 1 0 0 1 0 0 1 1 1 1831 12 13 14 15 16 17 18 19 20 21 22 Figura 3.5 Modificación del valor de potencia por operador de cruza, pcruza = 16. Se implementó también un operador de cruza a nivel de unidades y se refiere al intercambio de los valores de potencia asignados a las unidades. En este caso, no es necesario el proceso de codificación-decodificación. En la figura 3.6 se muestra un ejemplo de este operador con dos puntos de cruza. Se muestran los valores 32 decodificados para revisar el valor de potencia que suministran, pero como se dijo antes, no es necesaria la decodificación de los valores enteros. En este caso los puntos de cruza se escogen de forma aleatoria entre 1 y el número total de unidades. Varios puntos de cruza son recomendados cuando el tamaño de la cadena es grande. Total P1 P2 P3 803.7 134.1 226.6 174.7 P4 Padres Total 13.9 225.2 803.7 P5 21.5 P6 7.7 P7 P1 P2 P3 70.6 235.9 113.2 P4 P5 P6 21.0 21.3 27.9 313.9 P7 P4 P5 Hijos Total P1 P2 P3 755.2 134.1 226.6 113.2 P4 P5 P6 21.0 21.3 13.9 225.2 Total 852.2 P7 P1 P2 P3 70.6 235.9 174.7 21.5 P6 7.7 P7 27.9 313.9 Figura 3.6 Operador de cruza a nivel de unidades con dos puntos de cruza, pcruza1 = 2, pcruza2=5 Se observa como se pierde la factibilidad de la solución con el operador de cruza. La demanda que cubrían los padres era de 803.7 unidades y los hijos ya no cumplen con ese valor de demanda. Se puede agregar un algoritmo reparador de la solución que aumente o disminuya la potencia de una o varias unidades para cumplir con el BP. Sin embargo, se mostrará más adelante que el AG va mejorando el BP en cada generación. El operador de mutación revisa bit a bit todo el cromosoma y con una probabilidad muy baja cambia el valor de alguno de ellos. Aún así, si la cadena es larga, la probabilidad de que exista un cambio en algún bit es alta. En la figura 3.7 se muestra como cambia el valor del hijo 1 por el operador de mutación que tuvo efecto en el bit 23 y cambió el valor de potencia de la unidad 3 de 159 a 254. Hijo1, Mutación en el bit 23 del cromosoma Hijo 2, sin mutación hijo 1 hijo 2 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 1570 15 14 13 12 1 1 0 0 0 1 0 0 0 1 0 P1 1 2 3 4 5 6 7 8 9 10 11 antes 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 antes 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 23 24 25 26 27 28 29 30 31 32 33 antes 730 635 antes 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 169 1858 15 14 13 12 0 562 10 11 11 10 9 8 7 6 5 4 3 2 1 83 83 0 1831 1 1 1 0 0 1 0 0 1 1 1 P2 307 12 13 14 15 16 17 18 19 20 307 1385 1 antes 21 22 antes 15 14 13 12 1 0 1 0 1 1 0 1 0 0 1 P3 P1+P2+P3 = 9 0 1 0 0 0 1 1 0 0 1 0 P1 169 1 1 1 0 1 0 0 0 0 1 0 P2 12 13 14 15 16 17 18 19 20 21 22 11 10 11 10 9 8 7 6 5 4 3 2 1 304 304 0 865 0 1 1 0 1 1 0 0 0 0 1 P3 254 23 24 25 26 27 28 29 30 31 32 33 P1+P2+P3 = 159 antes 593 593 antes Figura. 3.7 Operador de mutación modificó bit 23 en una cadena de longitud 33. 33 205 205 3.6.1.1 Zona muerta Con el operador de cruza a nivel de bits, las zonas de operación por arriba o por debajo de la zona muerta se pueden modificar de los padres a los hijos cuando el punto de cruza es tal que divide al padre justo en el bit_zm, y si además el bit_zm de la unidad del otro padre es de valor opuesto. Con el operador de cruza a nivel de unidades, cada unidad conserva su zona de operación. El operador de mutación también opera en el bit_zm para cambiar la zona de operación en una unidad con zona muerta. De esta forma se proporciona más variedad en las soluciones para la siguiente generación. 3.7 Ajuste de los parámetros particulares del AG al PDE Los parámetros utilizados por defecto, en todos los casos de DE que se plantean, son los de la tabla 3.7. Tabla 3.7 Parámetros utilizados por defecto para el AG. Parámetro valor Probabilidad de cruza (Pc) 0.80 Probabilidad de mutación (Pm) 0.01 Punto de cruza: 2 puntos aleatorios Método de selección: Por torneo Tamaño de la población (tam_pob) 40 , 100 Como se explicó en el marco teórico, los valores anteriores han mostrado buenos resultados en muchos problemas y son ampliamente utilizados. No es el propósito de ésta tesis un análisis exhaustivo de todos los parámetros del AG, y sólo se detallan aquellos parámetros que son particulares del problema del DE. Para el caso del tamaño de la población, se realizaron pruebas para valores de 40 y 100 individuos. Los parámetros de la tabla 3.8 son los particulares al PDE que se va a resolver. Tabla 3.8 Parámetros a determinar para el AG Parámetro Factor de penalización por incumplimiento del balance de potencia (FP_IBP) Factor de penalización por zona muerta (FP_ZM) Las gráficas, en general, fueron generadas con cinco valores de semillas aleatorias diferentes (100, 200, 300, 400 y 500). Cada curva es el promedio de estas cinco pruebas. 34 3.7.1 Tamaño de la población. 1,000 590 950 580 900 570 850 700 150 140 130 120 110 90 100 núm . generaciones núm . generaciones Pob 40 80 0 150 140 130 120 110 90 100 80 70 60 50 40 30 500 20 550 490 0 600 500 70 650 510 60 520 750 50 530 800 40 540 30 550 20 560 10 aptitud promedio 600 10 ap titud del mejor individu o Al incrementar el tamaño de la población, se evalúan en paralelo un mayor número de individuos en el espacio de solución y es más probable encontrar mejores soluciones; sin embargo, éste no debe ser muy grande porque el proceso sería semejante a una búsqueda aleatoria. La figura 3.8 muestra la convergencia del AG aplicado al caso 1, con poblaciones de 40 y 100 individuos. Los resultados fueron ligeramente mejores con 100 individuos. Después de 150 generaciones, la aptitud del mejor individuo mejoró en 0.86% y la aptitud promedio de cada generación sólo lo hizo en 0.8%. Respecto al BP la convergencia fue muy similar. Pob 40 Pob 100 a) Pob 100 b) Balance de Potencia, BP [MW] 50 40 30 20 10 150 140 130 120 110 100 90 80 70 60 50 40 30 20 0 10 0 núm . generaciones c) Pob 40 Pob 100 Figura 3.8 a) aptitud mejor individuo b) aptitud promedio de cada generación c) balance de potencia BP, para poblaciones de 40 y 100 individuos, caso 1. FP_IBP = 2 500 35 El efecto del tamaño de la población para el caso 2 de 36 unidades se muestra en la figura 3.9. La aptitud del mejor individuo mejoró sólo un 0.12%; la aptitud promedio de cada generación mejoró en promedio 0.1 % y la convergencia del BP fue muy similar. Se utilizó un FP_IBP = 563. 470 465 aptitud promedio 455 450 460 455 450 300 250 100 200 0 300 250 150 100 50 0 200 núm . generaciones núm . generaciones Pob 40 150 445 445 50 aptitud del mejor individuo 460 Pob 40 Pob 100 a) Pob 100 b) Balance de potencia, BP [MW] 150 100 50 300 250 200 150 100 50 0 0 núm . generaciones c) Pob 40 Pob 100 Figura 3.9 a) aptitud mejor individuo b) aptitud promedio de cada generación c) balance de potencia BP, para poblaciones de 40 y 100 individuos, caso 2. Al incrementar el tamaño de la población en un 150 % se observan mejorías muy pequeñas en el desempeño del AG mientras que se incrementa en la misma proporción el número de operaciones. Debido a esto será utilizado el tamaño de población de 40 individuos para las pruebas finales del AG, cuyos mejores resultados serán comparables con las heurísticas que se presentan en los capítulos 4 y 5. 36 3.7.2 Elitismo El elitismo consiste en conservar al mejor individuo generado durante todo el proceso del AG. En cada generación se escoge al individuo con mejor aptitud y se pasa automáticamente a la siguiente generación, sin ningún cambio. De esta forma se evita que un individuo con excelente aptitud, producido en las primeras generaciones, se pierda por las operaciones de cruza y mutación subsecuentes. En la figura 3.10 se muestra el desempeño promedio de 5 pruebas del AG con y sin elitismo, aplicado al caso de estudio 1 de 7 unidades, con semillas de 100 a 500 y FP_IBP = 2500. Después de 500 generaciones, se obtuvo una mejora de 1.03% en la aptitud del mejor individuo. 50 Balance de Potencia, BP [MW] 610 590 570 550 530 510 490 45 40 35 30 25 20 15 10 5 núm . generaciones sin elitismo 500 400 300 200 0 500 400 300 200 100 0 0 100 aptitud del mejor individuo 630 núm . generaciones sin elitismo con elitismo a) con elitismo b) Figura 3.10 Comparación de la convergencia del AG con y sin elitismo, a) aptitud del mejor individuo, b) balance de potencia, caso 1. Puede parecer extraño que la curva de aptitud del mejor individuo del caso “sin elitismo” esté por debajo del caso “con elitismo” en algunas zonas. La explicación es porque los individuos de sus poblaciones son diferentes. Cuando no se usó elitismo, se generaron mejores individuos en algunas generaciones. Aunque se usaron las mismas semillas aleatorias, es muy probable que desde la primera generación las poblaciones de ambos casos hayan sido distintas en al menos un individuo. Se dice que es muy probable porque la probabilidad de cruza es alta (0.8) y la probabilidad de mutación es muy baja (0.01) y no se descarta el hecho de que el individuo más apto haya pasado a la siguiente generación sin cambios, por no haber sido afectado por los operadores generacionales. La población de la primera generación pudo haber sido la misma en ambos casos, pero lo más probable es que en algún punto de las primeras generaciones, las poblaciones de los dos casos fueron diferentes en al menos un individuo. La figura 3.11 corresponde a la aplicación del AG al caso 2. Se usó elitismo y un FP_IBP=563. La mejora al final de 500 generaciones fue de 0.43% respecto al mejor individuo obtenido con el AG sin elitismo. La mejora más notable fue en el BP. 37 120 Balance de Potencia, BP [MW] 455 450 445 100 80 60 40 20 núm . generaciones sin elitismo 500 400 300 200 0 500 400 300 200 100 0 0 100 aptitud del mejor individuo 460 núm . generaciones con elitismo sin elitismo con elitismo Figura 3.11 Comparación de la convergencia del AG con y sin elitismo, caso 2. Para el caso 2, que es un problema mucho más grande respecto al caso 1, se observó la dificultad en la convergencia en BP, y el uso de elitismo hizo que la solución final fuera factible. Por último, se observa en las gráficas anteriores la rápida convergencia que se tuvo en las primeras generaciones, después de las cuales el AG perdió efectividad. Se vislumbra entonces la posibilidad de utilizar un algoritmo de búsqueda local para mejorar la solución después de la generación número 75 para el caso 1, y después de la generación 150 para el caso 2. 3.7.3 Factor de penalización por incumplimiento del balance de potencia (FP_IBP). El factor de penalización FP_IBP castiga a las soluciones que no cumplen con el BP, modificando en forma negativa su aptitud. Este factor debe ser ajustado adecuadamente para cada instancia del problema. Valores pequeños hacen que la solución converja a un costo menor al óptimo a expensas de un BP negativo, lo cuál significa que la suma de las potencias asignadas sea menor a la demanda. Por el contrario, valores grandes de FP_IBP conducen a soluciones que cumplen con el BP, pero resultan en costos superiores al óptimo. En la tabla 3.9 se muestran los resultados de tres valores del FP_IBP aplicados al caso 1. Se escogieron algunos valores extremos para acentuar el resultado final. Tabla 3.9 Resultados del AG para distintos valores del FP_IBP y solución óptima del caso 1. solución AG Demanda FP_IBP [MW] 308.3 869.8 870.0 870.0 100 1000 10000 P1 [MW] P2 [MW] P3 [MW] P4 [MW] P5 [MW] P6 [MW ] 40.0 85.2 52.4 62.0 200.8 143.1 62.3 235.3 243.7 7.0 7.0 13.8 7.0 7.4 10.1 8.0 8.1 14.7 45.9 248.0 248.0 7.0 7.0 8.0 38 b) a) Cos to de Penalización operación [$] por IBP 122.0 271,920 56,173 326.1 493,582 155 392.1 518,069 -424 P7 [MW] 306.1 487,018 Aptitud (a+b) 328,093 493,737 517,645 error costo [%] -44.2 1.3 6.3 solución óptima error en BP [%] -64.57 -0.02 0.00 Con un valor pequeño de FP_IBP (100) se obtuvo un menor costo de operación respecto al óptimo, pero el error en BP fue grande y no se cubrió ni la mitad de la demanda. Con un FP_IBP grande (10000) no hubo error en BP, pero el costo fue 6.3% superior al óptimo. Un valor de FP_IBP de 1000 proporcionó mejores resultados, tanto en costo como en BP. Los valores más adecuados se obtuvieron bajo el siguiente razonamiento: un error de 1 MW en el BP debe ser comparable con el costo más grande que tiene una unidad al aumentar o disminuir esa misma potencia unitaria, para que el error sea debidamente penalizado. El costo por aumentar o disminuir un MW en cada unidad a partir de un punto de operación se denomina costo incremental CI y se obtiene de derivar la función de costo F. Por ejemplo, supóngase que se tienen 50 unidades baratas operando con un CI= 1 $/MW, y una unidad cara operando con CI = 50 $/MW. Resulta en el mismo costo que las 50 unidades aumenten 1 MW, con un total de 50 MW de incremento, que si lo hace en 1 MW la unidad cara. La penalización por una diferencia de 1 MW en el BP debe ser similar al costo de aumentar 1 MW en la unidad con CI más alto. Entonces el valor de FP_IBP puede establecerse en un valor similar al CI más alto de todas las unidades. 2,750 (27, 2500) 2,500 $/MWh 2,250 2,000 1,750 1,500 1,250 0 5 10 15 20 25 30 35 40 MW CI 4 CI 5 CI 6 Figura 3.12 Curvas de las unidades con mayor costo incremental del caso1. En la fig. 3.12 se muestra el costo incremental más alto (2500 $/MWh) de las unidades del caso 1 y corresponde a la unidad 4 en su límite de potencia de 27 MW. En la figura 3.13 se muestra el desempeño del AG con valores de FP_IBP de 2000, 2500 y 3000. Los resultados para los dos primeros valores fueron muy similares y se podrían utilizar indistintamente. 39 10 Balance de potencia, BP [MW] 555 545 535 525 515 505 8 5 3 2500 300 250 200 150 0 300 250 150 100 50 0 200 núm . generaciones núm . generaciones 2000 100 0 495 50 aptitud del mejor individuo 565 2000 3000 2500 3000 Figura 3.13 Convergencia en aptitud y en BP del AG, con valores de FP_IBP de 2000, 2500 y 3000, caso 1. Para el caso 2, el costo incremental más alto es de 563 $/MWh y corresponde a la unidad 23, en su límite de potencia de 498 MW, ver fig. 3.14. En la figura 3.15 se muestra el desempeño del AG con valores de FP_IBP cercanos a 563. Se obtuvieron mejores aptitudes con FP_IBP = 500, pero también se tuvo la peor curva en cuanto a BP. La curva correspondiente a FP_IBP = 563 presentó el mejor balance entre aptitud y BP. 580 (498, 563) 560 CI23 540 CI26 $/MWh 520 CI16 500 CI27 CI25 480 460 440 420 400 50 150 250 350 450 550 650 MW CI16 CI23 CI25 CI26 CI27 Figura 3.14 Curvas de las unidades con mayor costo incremental del caso 2. 40 200 Balance de Po tencia, BP [MW] 458 456 454 452 450 448 446 160 120 80 40 núm . generaciones 500 563 500 400 300 200 0 500 400 300 200 100 0 0 100 aptitud del mejor individuo 460 núm . generaciones 500 700 563 700 Figura 3.15. Convergencia en aptitud y en BP del AG aplicado al caso 2, con distintos valores de FP_IBP. Para el caso 3 (DEPV) se revisaron los costos incrementales y el más alto fue de 20.6 $/MW, correspondiente a la unidad 3 a una potencia de 179 MW. Se hicieron pruebas con valores de FP_IBP de 15, 20 y 25 usando elitismo. En la figura 3.16 se muestran la convergencia en aptitud y BP. El mejor valor de FP_IBP fue el de 25, ya que da una buena convergencia tanto en BP como en aptitud. Los valores superiores como 30 y 50 dan buena convergencia en cuanto a costo, pero no sucede igual en cuanto a BP. 30 8600 15 20 8500 25 8400 Balance de Potencia, BP [MW] 8300 25 20 15 20 15 25 10 5 núm . generaciones 500 400 300 200 0 500 400 300 200 100 0 0 100 aptit ud mejor individuo 8700 núm. generaciones Figura 3.16. Convergencia en aptitud y en BP del AG aplicado al caso 3, con distintos valores de FP_IBP. Los mejores valores de FP_IBP que se determinaron para cada caso se muestran en la tabla 3.10. Tabla 3.10 Ajustes del FP_IBP y número de generaciones para cada caso de estudio. FP_IBP 2 500 563 25 Caso 1 Caso 2 Caso 3 41 Generaciones 300 500 400 3.8 Resumen de resultados del AG (DE con funciones convexas). La tabla 3.11 muestra los resultados de la aplicación del AG a cada uno de los casos de estudio, donde se utilizaron los siguientes parámetros: tamaño de la población = 40, elitismo, 2 puntos de cruza aleatorio, probabilidad de cruza = 0.8, probabilidad de mutación = 0.01, selección por torneo. Tabla 3.11Resultados del AG para los casos de estudio 1, 2 y 3 (con funciones de costo convexas). Caso 2 Caso 3 (36 unidades) (3 unidades con pv) Caso1 (7 unidades) Generaciones = Generaciones = 400 Generaciones = 300 500 8 241.1 Costo mínimo 490,719 4,449,024 8 500.2 Costo máximo 503,999 4,455,664 8 327.4 Costo promedio 496,491 4,452,219 89.4 desv. Est. 3,915 2,454 0.085 %error 1) 0.76 0.16 1.133 %error_prom 1) 1.95 0.23 0.26 tiempo usuario 0.45 3.1 1) Respecto al costo de la solución optima. 42 3.9 ALGORITMO GENÉTICO HÍBRIDO El AGH se integra con el AG y con algunas heurísticas que son agregadas a la entrada y salida del AG con la intención de mejorar la rapidez de convergencia y la calidad de la solución final. Estas heurísticas son: - Algoritmo de Satisfacción de Restricciones (SR) para crear población inicial Algoritmo de fase de construcción del GRASP (fc_GRASP) para crear población inicial Algoritmo de BL para mejorar la calidad de la solución y la rapidez de convergencia. La población inicial con soluciones no factibles da una mayor diversidad en los valores que puede tomar cada unidad, aunque no se cumpla en lo más mínimo con el BP. Se ha visto que el AG reduce rápidamente el error en BP, pero luego emplea demasiadas iteraciones para llegar a un valor aceptable. En este capítulo se revisa el efecto de iniciar el AG con poblaciones iniciales factibles creadas a partir de algoritmos de SR y fc_GRASP. Con el algoritmo de SR se asegura que las soluciones creadas cumplan con el BP, pero no se tiene en cuenta el costo de estas soluciones. Con fc_GRASP las soluciones cumplen con el BP y además se toma en cuenta el costos de generación a través de una función miope. 3.9.1 Población inicial factible a partir de un algoritmo de satisfacción de restricciones. Como valores posibles de potencia para una unidad se consideran, en un principio, sus límites de potencia (dominio inicial). Pero aplicando SR se modifica este dominio inicial al verificar que el valor de potencia, asignado de forma aleatoria, permita seleccionar valores posteriores a las demás unidades. En el PDE las unidades participantes han sido seleccionadas previamente y deben despacharse con algún valor de potencia, por lo menos en su límite mínimo de potencia. Para entender mejor porque se deben restringir los valores de potencia en el proceso de asignación aleatoria de potencia, se muestra el siguiente ejemplo: Tabla 3.12 Datos para el ejemplo de SR. Pmín Pmáx demanda U1 35 210 400 U2 130 325 U3 125 315 43 Según los datos de la tabla 3.12, no es posible elegir un valor de potencia de 150 para la primera unidad, ya que la mínima potencia que podrían suministrar las otras 2 unidades sería de 255, dando un total de 455 y no se cumpliría con la demanda de 400. En la tabla 3.13 se muestra el algoritmo de SR que permite generar soluciones factibles. Tabla 3.13 Algoritmo para crear una solución factible por SR. 1. inicio 2. dr ← dem 3. i=1 4. Haz 5. NDi = nuevo_dominio (i, dr) 6. Pi ← aleat(NDi) 7. dr ← dr - Pi 8. i ←i+1 9. hasta i=n 10. Pn ← dr 11. fin Nuevo_dominio(i, dr) inicio NPmaxi ← dr - Suma(Pmink), k>i NPmini ← dr - Suma(Pmaxk), k>i fin si NP max i < P max i ⎧ NP max i NP max i = ⎨ caso ⎩ P max i otro 5a 5b 5c 5d ⎧ NP min i NP min i = ⎨ ⎩ P min i si NP min i > P min i otro caso dem - demanda n - número de unidades Pi - potencia asignada a la unidad i, 1 <= i < n Di - dominio de la unidad i, determinado por los límites de potencia de cada unidad, Di = [Pmini, Pmaxi], 1 <= i < n dr - demanda restante NDi – Nuevo dominio de la unidad i por SR, NDi = [NPmini, NPmaxi], 1 <= i < n Siguiendo este algoritmo se tiene que (2) se asigna a dr el valor de la demanda, dr= 400. (3,5) Se calcula el nuevo dominio de la unidad 1. (5b) se obtiene el valor máximo NPmax que se puede asignar a la unidad 1: NPmax1 = dr – Pmin2 - Pmin3 = 400 – 130 – 125 = 145 44 (5c) el valor mínimo NPmin1 se determina como sigue: NPmin1 = dr – Pmax2 - Pmax3 = 400 – 325 – 315 = - 240 Como el valor NPmin1 es menor que el límite de potencia Pmin1, entonces este límite no se modifica, y los nuevos límites para la U1 son: Pmin1 ≤ P1 ≤ NPmax1 o sea, 35 ≤ P1 ≤ 145 (ND1) (6) ahora se puede escoger un valor permisible de potencia P1, entre 145 y 240 MW. (7) Se modifica el valor de la demanda restante dr = 400 – P1, y se repite el proceso para las siguientes unidades. (10) Finalmente, a la última unidad U3, se le asigna el valor de la demanda que falta por cubrir P = dr = Demanda – P1 – P2. De esta forma, se escoge un valor aleatorio para cada unidad que permite elegir valores de potencia para las unidades restantes. 3.9.2 Población inicial generada por fase de construcción del GRASP La fase de construcción del GRASP ofrece la ventaja de que en la formación de las soluciones factibles se considera también el costo de generación a través de una función miope, que revisa la conveniencia inmediata de agregar un elemento a la solución. El funcionamiento a detalle de este algoritmo se explica en el capítulo 5. La tabla 3.14 muestra poblaciones de 10 individuos creados por SR y fc_GRASP para el caso 1. En la tabla 3.15 se muestra un resumen de estos datos. El costo promedio de las soluciones creadas por el fc_GRASP resultó mejor en un 2.1% respecto el costo promedio de las soluciones del SR, pero la mejor solución del fc_GRASP lo fue en un 6.7%. Cuando se usa elitismo en el AG, esta mejora resulta de mayor importancia. MW 870 870 870 870 870 870 870 870 870 870 Tabla 3.14 Soluciones creadas con a) SR b) fc_GRASP. P1 P2 P3 P4 P5 P6 P7 aptitud costo [$] 528 527,547 129 231 190 20 7 15 277 551 550,350 118 75 228 15 15 17 401 581 580,221 113 141 109 14 26 26 441 550 549,613 132 202 138 24 15 11 347 563 562,983 128 187 139 10 25 25 357 567 566,697 148 193 96 19 24 12 379 552 551,113 149 70 210 13 16 12 399 563 562,258 124 169 88 16 25 11 437 538 537,407 73 190 134 11 8 26 428 607 606,271 141 212 65 22 25 29 375 560 559,446 promedio a) 45 MW 870 870 870 870 870 870 870 870 870 870 P1 P2 P3 79 158 143 160 158 141 50 40 102 136 231 225 242 207 168 204 138 216 136 150 138 192 181 248 240 214 191 189 188 225 P4 P5 7 27 27 27 11 10 21 8 21 18 7 23 24 26 24 24 12 7 11 15 P6 P7 14 394 22 223 19 235 30 174 11 258 9 268 23 436 8 401 20 390 30 296 promedio aptitud costo [$] 509 508,108 579 578,255 572 571,061 595 594,139 541 540,568 531 530,107 548 547,794 495 494,590 549 548,069 566 564,824 549 547,752 b) Tabla 3.15 Comparativo del costo de las soluciones creadas por SR y fc_GRASP. Caso 1 (7 Us). SR fc_GRASP [$] [$] % mejora 527,547 494,590 6.7 minimo 606,271 594,139 2.0 máximo 559,446 547,752 2.1 promedio 3.9.3 Adición de Búsqueda local al AG El AG se encarga de dirigir la búsqueda hacia zonas prometedoras donde el algoritmo de BL agiliza la convergencia hacia una solución de mejor calidad. El algoritmo de BL se basa en la generación de vecindades que se describió en la sección 2.3. Después de un número de generaciones iniciales (AGini) el AG ha reducido de forma notable la aptitud de los individuos, entonces se busca una solución con error pequeño en BP, según la precisión que se requiera. En caso de no encontrar un individuo en la población que cumpla con este criterio, se activa el AG para producir una generación más, hasta cumplir con el criterio de BP. El error en BP es asignado a una de las unidades Usel con capacidad suficiente. En la tabla 3.16 se muestra el seudocódigo del AGH. 46 Tabla 3.16 Algoritmo Genético Híbrido (AGH). BEGIN AGH Generar población inicial n = AGini DO FOR i = 1 TO n DO Evaluar población Seleccionar padres para nueva población Cruzar padres para generar hijos Mutar hijos (se tiene una nueva población) END FOR Buscar individuo con menor DP n=1 WHILE (DP > 0.1) PUsel PUsel + DP Algoritmo de BL END AGH En la tabla 3.17 se muestran los valores de AGini para cada caso de estudio a partir del cuál se puede empezar la búsqueda local. Estos valores se obtuvieron de las gráficas 3.10, 3.11 y 3.16. Para el caso 2 de 36 unidades se observa que el desempeño del AG respecto a la aptitud de las soluciones disminuye a partir de la generación 150; respecto al BP, se estabiliza hasta la generación 450. Por eso para este caso se probaron valores de 150, 300 y 500 para el AGini. Tabla 3.17 Generaciones iniciales n del AGH para cada caso de estudio. AGini caso 1 75 caso 2 150, 300, 500 caso 3 150 La figura 3.17 muestra el desempeño del AGH aplicado al caso 1 con poblaciones iniciales generadas aleatoriamente, con el algoritmo SR y con el fc_GRASP.. Las gráficas muestran el promedio de 5 pruebas, no se usó elitismo para poder observar la mejora de los individuos en cada generación. Después de la generación 75 se muestran las soluciones finales aplicando BL, con k0 (vecindades generadas) = 100. 47 9.0 545 Balance d e potencia, BP [MW] 535 525 515 505 495 485 8.0 7.0 6.0 5.0 4.0 3.0 2.0 1.0 núm . generaciones no factibles factibles (SR) 75 70 65 60 55 50 45 40 35 30 25 20 15 5 0 75 BL 70 65 60 55 50 45 40 35 30 25 20 15 5 10 0 0.0 10 aptitud del mejor individuo 555 núm . ge neraciones no factibles factibles (fc_grasp) factibles (SR) factibles (fc_grasp) Figura 3.17 Convergencia del AGH con diferentes poblaciones iniciales, caso 1. Se observa en las gráficas anteriores que con el algoritmo de BL las soluciones del AGH son independientes de la calidad de los individuos de la población inicial. También se observa que el desempeño del AG fue menor cuando se utilizaron soluciones de buena calidad al inicio, porque el porcentaje de mejora fue mucho menor que cuando se utilizaron soluciones no factibles. La tabla 3.18 registra los porcentajes de mejora de la aptitud de los individuos al inicio y después de 75 y 150 generaciones. Las soluciones proporcionadas por el fc_GRASP fueron de tan buena calidad que el AG difícilmente las pudo mejorar, después de 150 generaciones la mejora del mejor individuo fue de sólo 0.1%. Sin embargo, el trabajo del AG se puede observar si se revisan las aptitudes promedio de cada generación, en este caso se tuvo un 5.5% de mejora. Se puede decir que la secuencias (fc_GRASP + AG + BL) da resultados similares a una secuencia (fc_GRASP + BL = GRASP). El AG tuvo el mejor desempeño cuando se utilizó en su forma más simple, sin la adición de operaciones que depuren las soluciones aleatorias para asegurar la factibilidad. Los porcentajes de mejoría fueron de 8.5% para el mejor individuo y de 38.6% para toda la generación. Tabla 3.18 Comparativo de aptitudes después de 75 y 150 generaciones, para el AG con diferentes tipos de población inicial, caso 1. Mejor individuo Soluciones factibles por SR Soluciones factibles por fc_GRASP Soluciones no factibles aptitud inicial a) aptitud después de 75 generaciones b) aptitud después de 150 generaciones a) mejora aptitud [%] b) mejora aptitud [%] 521 510 503 1.9 3.4 498 547 499 500 498 500 -0.2 8.5 0.1 8.6 48 Promedio generación Soluciones factibles por SR Soluciones factibles por fc_GRASP Soluciones no factibles aptitud inicial a) aptitud después de 75 generaciones b) aptitud después de 150 generaciones a) mejora aptitud [%] b) mejora aptitud [%] 557 541 531 2.8 4.7 553 522 523 5.7 5.5 847 520 520 38.6 38.6 La figura 3.18 muestra el desempeño del AG (sin BL) para el caso 3 con población inicial factible y no factible. El resultado fue similar a lo observado para el caso 1: no hay dependencia en la convergencia por la calidad de las soluciones de la población inicial, por lo tanto se usará el AGH en su forma simple, con población inicial compuesta por soluciones no factibles, generadas de forma aleatoria. aptitud d el mejor individuo 8,700 8,600 8,500 8,400 8,300 987 929 871 813 755 697 639 581 523 465 407 349 291 233 175 117 1 59 8,200 generaciones factibles no factibles Figura 3.18 Desempeño del AG con población inicial de soluciones factibles y no factibles para el caso 3 (DEPV de 3 unidades). La intensidad de la búsqueda local se controla con el parámetro k0. Se hicieron pruebas con diferentes valores de este parámetro para obtener un valor mínimo aceptable para los casos 1, 2 y 3. En la tabla 3.19, 3.20 y 3.21 se muestran los resultados de estas pruebas. Para el caso 1 los mejores resultados se obtuvieron con k0=500. Tabla 3.19 Ajuste del parámetro k0 para el caso 1 (7 U’s). AGini= 75, k0= 100 200 300 400 500 750 Costo mínimo 487,101.360 487,030.999 487,027.493 487,027.493 487,027.493 487,027.493 Costo máximo Costo promedio desv. Est. %error 1) %error prom 1) tiempo usuario 490,405 487,717 487,166 487,105 487,073 487,290 488,052 1,195 0.017 0.21 0.09 487,182 213 0.003 0.03 0.11 487,079 45 0.002 0.01 0.11 487,064 20 0.002 0.01 0.11 487,061 15 0.002 0.01 0.09 487,086 73 0.002 0.01 0.09 1) Respecto al costo de la solución óptima 49 Para el caso 2 se probaron diferentes valores de AGini debido a que en las pruebas del AG se alcanzó el máximo desempeño en aptitud a partir de la generación 150, pero fue un poco inestable en cuanto a BP, estabilizándose hasta la generación 450. Los mejores resultados se obtuvieron con AGini = 500 y k0= 750. Aunque con k0 = 500 se tuvieron resultados similares a k0=500, se prefirió el primero por la mejor combinación del costo promedio y la desviación estándar de los resultados. Tabla 3.20 Ajuste del parámetro k0 para el caso 2 (36 U’s). AGini = k0 = 150 300 500 750 500 750 500 750 500 750 500 750 Costo mínimo 4,448,120 4,446,023 4,445,094 4,444,916 4,443,826 4,443,442 4,443,979 4,443,751 Costo máximo Costo promedio 4,455,488 4,454,994 4,452,809 4,452,706 4,447,857 4,447,401 4,452,644 4,452,312 4,451,212 4,450,385 4,448,034 4,447,578 4,446,233 4,445,964 4,446,640 4,446,053 desv. Est. 2,042 2,358 2,446 2,413 1,240 1,284 2,809 2,476 %error 1) 0.137 0.090 0.069 0.065 0.040 0.032 0.044 0.039 %error prom 1) 0.21 0.19 0.14 0.12 0.09 0.09 0.10 0.09 tiempo usuario 1.12 1.03 2.06 2.13 3.37 3.19 4.76 4.75 1) Respecto al costo de la solución óptima Los mejores resultados para el caso 3 fueron con k0=500, según se observa en la tabla 3.21 por la mejor combinación de menor costo promedio y desviación estándar. Tabla 3.21 Ajuste del parámetro k0 para el caso 3 (3 U’s). k0 = Costo mínimo 100 8,234.4 200 8,234.4 300 8,234.4 400 8,234.3 500 8,234.1 Costo máximo Costo promedio 8,356.0 8,356.0 8,355.6 8,252.3 8,252.3 8,265.6 8,256.7 8,253.3 8,240.4 8,239.6 35.8 0.004 36.2 0.004 36.7 0.004 7.0 0.002 7.3 0.000 0.38 0.28 0.23 0.08 0.07 0.10 0.10 0.10 0.10 0.10 desv. Est. %error 1) %error prom 1) tiempo usuario 1) Respecto al costo de la mejor solución encontrada La tabla 3.22 muestra los resultados de la aplicación del AGH a cada uno de los casos de estudio, donde se utilizaron los siguientes parámetros: tamaño de la población = 40, elitismo, dos puntos de cruza aleatorio, probabilidad de cruza = 0.8, probabilidad de mutación = 0.01, selección por torneo y los valores de AGini y k0 obtenidos en párrafos anteriores. 50 3.10 Resumen de resultados del AGH (DE con funciones convexas). Tabla 3.22 Resultados del AGH para los casos de estudio 1, 2 y 3 (con funciones de costo convexas). Caso1 Caso 2 Caso 3 (7 unidades) (36 unidades) (3 unidades con pv) AGini = 75, k0 = 500 AGini = 500, k0 = 750 AGini = 150, k0 = 500 8, 234 Costo mínimo 487, 027 4, 443, 442 8, 252 Costo máximo 487, 073 4, 447, 401 8, 240 Costo promedio 487, 061 4, 445, 964 7.3 desv. Est. 15.2 1, 284.2 0.00 %error 0.002 0.03 0.07 %error_prom 0.01 0.09 0.10 tiempo usuario 0.11 3.2 51 Capítulo 4. IMPLEMENTACIÓN DEL ALGORITMO DE RECOCIDO SIMULADO 4.1 Introducción El ARS es un algoritmo de búsqueda de la mejor solución y se basa en la analogía del comportamiento de sistemas termodinámicos simples. En el ARS, la aceptación de soluciones está gobernada por un parámetro denominado “Temperatura''. Las soluciones que mejoran el costo actual siempre son aceptadas y aquellas que lo empeoran también pueden ser aceptadas con cierta probabilidad, que será alta al inicio de la búsqueda. A medida que la búsqueda progresa la temperatura disminuye y la probabilidad de aceptación de soluciones peores también disminuye. Hacia el final de la ejecución sólo las mejores soluciones son aceptadas. La implementación de este algoritmo es muy sencilla, prácticamente sólo se debe trabajar con el algoritmo que genera la solución inicial factible, que debe cumplir con el BP y con el hecho de que las potencias asignadas a los generadores deben estar dentro de sus límites operativos. Para la consideración de zonas muertas, el algoritmo generador de soluciones factibles y el algoritmo de búsqueda en vecindades deberán desechar los números aleatorios que estén en la región prohibida. Las funciones no convexas y las funciones discontinuas no tienen ninguna consideración especial, basta con la implementación de una función que evalué cada solución generada. 52 El programa de recocido simulado aplicado al PDE consta de tres módulos, el primero despacho_RS es el programa principal con la secuencia propia del ARS, el segundo sol_ini, genera la solución inicial y el tercero, vecindades, implementa la búsqueda local. 4.2 Descripción del programa Entrada: Solución inicial (P10, P20, …, Pn0) Número de unidades, Us Unidades que operan en zona muerta Uzmi Rango de zona muerta, ini_zm, fin_zm Límites de potencia, Pmini, Pmaxi, Demanda Salida: solución mejorada (P1s, P2s, …, Pns) Despacho_RS es el programa principal y utiliza los módulos sol_ini y vecindades para implementar el ARS. Módulos: - Despacho_RS: Implementa el ARS, integrado los módulos anteriores. - Sol_ini: Genera solución inicial factible S0 = P10 + P20 +… Pn0 = Demanda - Vecindades: Genera soluciones vecinas. 4.3 Solución inicial Módulo Sol_ini. Entrada: Us, Uzmi, zona_muertai, Pmini, Pmaxi, Demanda 1 ≤ i ≤ Us Salida: Solución inicial S0 = P10 + P20 + P30 = Demanda El algoritmo utilizado es el de SR que se describió en la sección 3.7.1. 4.3.1 Zona muerta Antes de asignar las potencias de cada unidad, se decide en forma aleatoria si la unidad con zona muerta operará abajo o arriba de esta zona. La decisión es simple, se genera un valor aleatorio entre 0 y 1. Si el valor está entre 0 y 0.5, entonces la unidad opera por debajo de la zona muerta y se modifica temporalmente su potencia máxima Pmax, igualándose al inicio de la zona muerta, Pmax = Pzmini, En caso contrario, la unidad opera arriba de la zona muerta y el parámetro que se redefine temporalmente es la potencia mínima: Pmin = Pzmfin. 53 4.4 Vecindades Módulo busqueda_local. Entrada: Us, Uzmi, zona_muertai, Pmini, Pmaxi, Demanda 1 ≤ i ≤ Us Salida: Solución vecina Sv = P1v + P2v +…+ PUsv = Demanda Las vecindades a una solución dada, se determinan al incrementar o disminuir la potencia de una unidad seleccionada aleatoriamente. El movimiento hacia arriba o hacia abajo también es aleatorio: sube si x ≥ 0.5 baja si x < 0.5 x es una variable aleatoria entre 0 y 1. La cantidad de MW que se mueve la unidad es aleatoria y está limitada por las potencias máximas y mínimas de las unidades. El movimiento de la unidad seleccionada en forma aleatoria debe ser cubierto por las demás unidades de tal manera que no se modifique el valor de demanda suministrado. El movimiento de todas las unidades es aleatorio a excepción de la última unidad, la cuál tendrá que absorber la diferencia que falte por cubrir. Tabla 4.1 Datos del ejemplo para el cálculo de una solución vecina. Ejemplo 4.1: P1 P2 P3 Pmin 35 130 125 Pmax 210 325 315 Demanda = 400 Solución inicial: P1= 40 P2= 160 P3=200 Movimiento seleccionado: subir (aleatorio) Unidad seleccionada: 2 (aleatorio) Los rangos permisibles de movimiento para cada unidad se muestran en la tabla 4.2. 54 Tabla 4.2 Rangos permisibles de movimiento a partir de la solución inicial del ejemplo 4.1. P1 P2 P3 baja (máx) 5 30 75 sube (máx) 170 165 115 MW a mover: 25 (aleatorio) Para P1 se selecciona un número aleatorio entre 0 y 5 (rango permisible hacia abajo), digamos 3, P1= 40-3= 37 demanda restante : 25-3=22 La demanda restante es proporcionado por la unidad 3: P3=200-22= 178 P2=160+25= 185 El movimiento es exitoso porque se cumple con la demanda y con los rangos disponibles de potencia de cada unidad. solución inicial: (40, 160,200) solución vecina: (37,178,185) Cuando un movimiento no es permisible porque rebasa los límites de potencia, entonces es no exitoso y se sigue un proceso aleatorio de movimientos que sean permisibles para encontrar la vecindad. 4.4.1 Zona muerta Cuando existe zona muerta en una unidad, la solución vecina respeta la zona de operación de la unidad en la solución actual, arriba o debajo de la zona muerta. 4.4 Ajuste de los parámetros de ARS Los parámetros de control del ARS son: T: temperatura k0: número de aceptaciones por cada nivel de T criterio de paro (un valor suficientemente bajo de T) alfa: factor de disminución de temperatura 55 Los parámetros utilizados por defecto son los de la tabla 4.3. Tabla 4.3 Parámetros utilizados por defecto para el ARS. Parámetro valor Criterio de paro T = 10 Factor de disminución por 0.9, 0.95 temperatura, alfa 4.5.1 Temperatura El criterio de Metrópolis del ARS utiliza la función de distribución de Boltzman para aceptar una nueva solución. La tabla 4.4 muestra los elementos de la función. Tabla 4.4 Criterio de Metrópolis para aceptación de una solución. si ( F (i ) − F ( j ) r< e T se acepta la solución j, que tiene un costo mayor al de la solución actual i Fc(i): Función de costo de la mejor solución Fc(j): Función de costo de la solución actual r es un número aleatorio en el intervalo [0,1] El valor de T debe ser tal que el término exponencial pueda se comparable con r cuyo rango es [0, 1]. El valor tendiente a 1 se obtiene cuando las funciones de costo de las soluciones comparadas son iguales. El valor 0 se obtiene cuando T ∞. Una buena opción es establecer el valor de T de acuerdo con la máxima diferencia en costo mdc dentro del espacio de soluciones. Este valor se obtiene de la diferencia en costo de las unidades operando a potencia máxima y mínima. La tabla 4.5 muestra la máxima diferencia en costo mdc para el caso 1 de 7 unidades. Tabla 4.5 Máxima diferencia en costo mdc para el caso 1 con funciones convexas. Pmáx [MW] Pmín [MW] U1 160 40 U2 248 62 U3 248 62 U4 27 7 U5 26 7 U6 30 8 U7 489 122 mdc: F [$] 767,816 271,858 495,958 En la figura 4.1 se muestra la evaluación de la función de Boltzman para valores de T referidos a la mdc del caso 1. Con T= mdc/4 se cubre la mayor parte del rango [0,1] y la posibilidad de que se acepten soluciones con grandes diferencias en costo es menor respecto a las otras asignaciones de T. Una solución con una diferencia de 300 mil pesos, respecto al costo de la solución actual, sería aceptada con una probabilidad de 0.1 con T= mdc/4, y con una probabilidad de 0.74 con T=mdc*2. El número total de vecindades que se generan depende sólo de la temperatura inicial T, si el factor de disminución de temperatura alfa, el número de aceptaciones k0 y el criterio de paro son fijos. Al disminuir T, se revisa un número 56 menor de soluciones, además de tener menos variedad en ellas. Por lo tanto, se debe buscar un balance adecuado con el valor de T que permita variedad en las soluciones y generar un número suficiente de soluciones. 1.0 0.9 0.8 0.7 T= mdc*2 0.6 T= mdc 0.5 T= mdc/2 0.4 T= mdc/4 0.3 0.2 0.1 0.0 0 50 100 150 200 250 300 350 400 450 500 diferencia en costo [miles $] Figura 4.1 Evaluación de la función de Boltzman con valores de T referidos a la mdc del caso 1 Se hicieron pruebas con diferentes asignaciones de T para los casos 1,2 y 3. Los valores de mdc fueron ajustados a cifras cerradas para su mejor presentación. En la tabla 4.6 se muestran los ajustes de mdc y los valores utilizados para cada caso. También se muestran los criterios de paro utilizados y que se refieren a un valor de temperatura de 10 unidades, que se consideró adecuado para el caso 1. Se utilizó un divisor de costo para su mejor presentación en las gráficas. Los valores afectados por el divisor de costo aparecen subrayados. Tabla 4.6 Valores de mdc y criterios de paro para los casos de estudio 1,2 y 3. caso 1 caso 2 caso 3 Costo máximo 767,816 5,478,376 12,521 Costo mínimo 271,858 3,450,115 2,972 mdc 500,000 2,000,000 10,000 divisor costo 1,000 10,000 100 mdc 500 200 100 mdc *2 1000 400 500 mdc /2 250 100 50 mdc / 4 125 50 25 criterio de paro, T> 10/1000) 10/10000) 10/10) En las figuras 4.2, 4.3 y 4.4 se muestra el desempeño del ARS aplicado a los casos 1,2 y 3, con los valores de T de la tabla 4.6. En las primeras fases de enfriamiento se explora un espacio de solución más amplio, donde se permiten 57 peores soluciones con mayor probabilidad. En las últimas fases casi no se permiten soluciones de calidad inferior a la solución en curso. 605 585 costo 565 545 525 505 10000 9000 8000 7000 6000 5000 4000 3000 2000 1000 0 485 núm ero solución aceptada T=mdc/4 T=mdc/2 T=mdc*2 T=mdc Fig. 4.2 Desempeño del ARS para diferentes valores de T, caso 1 (7 U’s). 465 463 461 costo 459 457 455 453 451 449 11000 9000 10000 8000 7000 6000 5000 4000 3000 2000 1000 0 447 núm ero solución aceptada T=mdc*2 T=mdc T=mdc/2 T=mdc/4 Fig. 4.3 Desempeño del ARS para diferentes valores de T, caso 2 (36 U’s). 880 870 costo 860 850 840 830 4500 4000 3500 3000 2500 2000 1500 1000 500 0 820 núm ero solución aceptada T=mdc*2 T=mdc T=mdc/2 T=mdc/4 Fig. 4.4 Desempeño del ARS para diferentes valores de T, caso 3 (3 U’s). 58 Tabla 4.7 Resultados para diferentes valores de T. Resaltados los valores de referencia para el cálculo de los porcentajes. El valor mínimo y el valor promedio son de 10 pruebas. % % mejora desv. soluciones incremento T mínimo promedio (mínimo) Est. soluciones caso1 mdc*2 487.024 487.063 0.020 11000 22.2 0.000 10300 14.4 mdc 487.024 487.036 0.015 mdc/2 487.028 487.042 0.018 9700 7.8 0.001 0.000 mdc/4 487.024 487.047 0.020 9000 caso 2 mdc*2 446.477 447.243 0.390 25200 19.4 0.050 mdc 447.104 447.510 0.355 23800 12.8 0.191 447.288 0.566 22500 6.6 mdc/2 446.252 0.041 mdc/4 446.433 446.859 0.326 21100 caso 3 mdc*2 823.430 824.585 0.680 5100 64.5 0.002 824.335 0.911 4400 41.9 mdc 823.412 3800 22.6 0.098 mdc/2 824.215 824.690 0.609 0.754 0.004 mdc/4 823.447 824.039 3100 En la tabla 4.7 se muestran los resultados de diez pruebas usando diferentes valores de T, referidos al mdc. Para el caso 1 parece indiferente el uso de cualquiera de los valores propuestos de T, respecto de la solución final. Aunque se observan pequeñas ventajas al utilizar T=mdc (500) por tener menor variabilidad en los costos. Para los casos 2 y 3 el costo mínimo, el mejor promedio y la desviación estándar más pequeña no coinciden para un mismo valor de T. Sin embargo, es deseable escoger el valor de T donde se tenga la mejor combinación de costo promedio y variabilidad. Así que para el caso 2 se utilizará T=mdc/4 (50) y para el caso 3, T=mdc/4 (25). En la tabla 4.8 se resumen los parámetros del ARS para cada caso de estudio. Tabla 4.8 Parámetros del ARS para cada caso de estudio. T T alfa mdc = 500 000 caso 1 (7 U’s) 500 0.90 mdc / 4 = 500 000 caso 2 (36 U’s) 50 0.95 mdc / 4 = 2 500 caso 3 (3 U’s) 25 0.90 4.5.2 Ajuste de k0 en la búsqueda local. Las tablas 4.9, 4.10 y 4.11 muestran los resultados de las pruebas realizadas para diferentes valores de k0. Se destacan en negrita los valores de k0 con los mejores resultados, referentes a el mejor costo promedio y su menor desviación estándar. 59 % mejora (promedio) 0.006 0.001 0.002 0.086 0.146 0.096 0.066 0.036 0.079 Tabla 4.9 Ajuste de la búsqueda local a través del parámetro k0 para caso 1 (7 U’s). k0 Costo mínimo Costo máximo Costo promedio desv. Est. %error 1) %error prom 2) tiempo usuario 25 487,022.3 487,072.4 50 487,026.2 487,082 75 487,022.2 487,101.5 100 487,024.7 487,077 200 487,027.2 487,095.0 487,050.6 21.8 0.001 0.007 0.01 487,044.3 18.2 0.002 0.005 0.03 487,055.3 27.1 0.001 0.008 0.05 487,047.1 20.5 0.001 0.006 0.12 487,060.0 22.9 0.002 0.009 0.14 Tabla 4.10 Ajuste de la búsqueda local a través del parámetro k0 para caso 2 (36 U’s). k0 100 200 500 600 700 800 Costo mínimo 4,461,458 4,458,141 4,456,795 4,455,173 4,456,227 4,456,305 Costo máximo Costo promedio desv. Est. 4,473,159 4,463,719 4,459,826 4,459,448 4,461,707 4,458,577 4,466,278 3,916 4,461,620 1,620 4,458,160 899 4,457,871 1,252 4,458,139 1,644 4,457,151 780 %error %error prom 0.44 0.36 0.33 0.30 0.32 0.32 0.55 0.5 0.44 1.0 0.36 2.5 0.36 3.0 0.36 3.5 0.34 4.0 tiempo usuario Tabla 4.11 Ajuste de la búsqueda local a través de parámetro k0 para caso 3 (3 U’s). k0 = Costo mínimo Costo máximo Costo promedio desv. Est. %error 1) %error prom 1) tiempo usuario 50 8,234.6 8,286.1 100 8,234.1 8,257.0 150 8,234.1 8,275.4 200 8,234.3 8,250.4 8,250.2 18.0 0.006 0.20 0.00 8,243.7 6.9 0.001 0.12 0.01 8,247.2 12.8 0.000 0.16 0.02 8,242.3 3.9 0.003 0.10 0.03 4.6 Resumen de resultados del ARS (DE con funciones convexas). Finalmente, la tabla 4.12 muestra una tabla resumen con los resultados para cada caso de acuerdo con el valor elegido de k0. Tabla 4.12 Resultados del ARS para los casos de estudio 1, 2 y 3 (con funciones de costo convexas). Caso1 Caso 2 Caso 3 (7 U’s) (36 U’s) (3 U’s con pv) T= 500 000, k0 = 50 T= 500 000, k0 = 800 T= 2 500, k0 = 200 Costo mínimo 487,026.2 4,456,305 8,234.3 Costo máximo 487,082 4,458,577 8,250.4 Costo promedio 487,044.3 4,457,151 8,242.3 desv. Est. 18.2 780 3.9 %error 0.002 0.32 0.003 %error_prom 0.10 0.005 0.34 tiempo usuario 0.03 4.0 0.03 60 Capítulo 5. IMPLEMENTACIÓN DEL GRASP 5.1 Introducción La implementación del GRASP para el DE queda muy natural, debido a que la fase constructora guía la forma de construir una solución factible, y asegura que ésta pueda tener diversidad en cada ejecución. La fase de búsqueda local fue prácticamente tomada del ARS. El método GRASP consta de una fase constructora y una fase de búsqueda local. La fase constructora crea una solución factible, que es mejorada por el algoritmo de búsqueda local y la mejor solución es guardada dentro del proceso iterativo. El algoritmo utilizado se muestra en la tabla 5.1. Tabla 5.1 Algoritmo general GRASP para el DE. f* ← ∞ for i ≤ imáx do fase constructora(g(.), α,x) x ← búsqueda local(x) if f(x) < f* then f* ← f(x) x* ← x end if end for regresar x* donde imáx es el número máximo de iteraciones. g(.) es la función miope que evalúa la incorporación de cada elemento x es el conjunto solución, que contiene las potencias asignadas a las N unidades f(x) es el costo de la solución x f* es el costo de la mejor solución encontrada x* es la mejor solución encontrada α es un factor [0,1], que establece el grado de aleatoriedad o miopes del algoritmo 61 5.2 Descripción del programa El programa despacho_grasp es el programa principal y utiliza los módulos de la fase de construcción y el de búsqueda local. Entrada: Número de iteraciones, Nitr Número de unidades, Us Unidades que operan en zona muerta, Uzmi Rango de zona muerta, ini_zm, fin_zm Límites de potencia, Pmini, Pmaxi Demanda Factor de aleatoriedad-miopía, α 0≤α≤1 Salida: solución (P1s, P2s, …, PUss), P1s + P2s+ …+ PUss = demanda 5.3 Fase constructora Entrada: Datos de unidades, Us, Uzmi, ini_zm, fin_zm, Pmini, Pmaxi Demanda Número de vecindades k0 Salida: Una solución factible x ∈P P representa el espacio de soluciones factibles La solución en la fase constructora se genera bajo el siguiente algoritmo: Tabla 5.2 Algoritmo GRASP (fase constructora) para el DE. 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. inicio x = {}; dem_resto ← Demanda Inicializar lista de candidatos C mientras |C| ≠ 1 do calcula Nuevos límites NPmini, NPmaxi | i∈ C pi ← aleatorio(NPmini, NPmaxi) | i ∈ C calcula fmiope(pi) | i ∈ C f ← mín{ fmiope(pi) | i ∈ C } f+ ← máx{ fmiope(pi) | i ∈ C } RCL ← { p ∈ C | fmiope(pi) ≤ f + α( f+ – f) } 62 11. 12. 13. 14. 15. 16. 17. selección aleatoria de p de RCL x ← x ∪ {p} C ← C – {p} dem_resto ← dem_resto – p end mientras p {C} ← dem_resto fin Donde Demanda: es la demanda que deben cubrir todas las unidades C: lista de candidatos RCL: lista restrictiva de candidatos x: conjunto solución pi: elemento i de la solución factible p {c} : ultimo elemento en la lista de candidatos Descripción del algoritmo. El algoritmo forma una solución factible x = {p1, p2, … pi, …,pn}. Al principio, el conjunto solución x está vacío (1), la variable dem_resto inicia con el valor de demanda que deben cubrir las N unidades y reduce su valor conforme se asignan potencias a cada elemento de la solución. La lista de candidatos inicial C está integrada por todas las unidades C = { U1, U2, …, Ui, …, Un}. Posteriormente, a cada unidad se le asigna una potencia aleatoria (6) dentro de los dominios restringidos, calculados (5) por un algoritmo de satisfacción de restricciones. La aplicación de este algoritmo permite asignar valores a una unidad para que luego, en etapas posteriores, sea posible la asignación de potencias a las unidades restantes. La función miope (7) es la función de costo de generación que evalúa a cada generador de acuerdo con su potencia asignada de forma aleatoria. La lista restrictiva RCL contendrá a las unidades con menor costo que estén dentro del rango determinado en 10. El elemento que se agrega a la solución se escoge, de forma aleatoria, de la lista RCL (11). Luego se actualizan el conjunto solución (12), la lista de candidatos (13) y la demanda por cubrir (14). En cada ciclo se agrega un elemento a la solución hasta que la lista de candidatos contenga un sólo elemento. A esta última unidad se le asigna la demanda restante dem_resto. Ejemplo 5.1 A continuación, se aplica el algoritmo GRASP para el caso de estudio 2, de 7 unidades térmicas, para encontrar una solución factible. 63 Tabla 5.3 Datos del ejemplo 5.1. Aplicación del GRASP. demanda Pmax [MW] Pmin [MW] coef. A coef. B coef. C 804 MW U1 U2 160 248 40 62 1.28 368.0 22770 0.56 158.5 33830 U3 248 62 U4 27 7 U5 26 7 U6 30 8 U7 489 122 0.56 158.5 33830 24.92 1154 13330 19.45 1204 16680 21.16 1190 16660 0.029 467.7 6957 Una solución factible es cualquier asignación de potencias a las N unidades, que cumpla con el BP y con los límites de generación de cada una de ellas. El costo de generación total no es precisamente el más barato. Aplicación del algoritmo de la fase constructora: 1. x = {} 2. dem_resto = 804 3. se inicializa conjunto C, C = {P1, P2, P3, P4, P5, P6, P7} 4. |C| = 7 5. Nuevos límites NPmáx NPmín U1 160 40 U2 248 62 U3 248 62 U4 27 7 U5 26 7 U6 30 8 U7 489 122 Los nuevos límites NPmin, NPmax, son iguales a los originales, esto quiere decir que cualquier asignación de potencias dentro de los límites originales, hace posible una asignación de potencias de las demás unidades para cubrir la demanda. 6, 7. fmiope(P) = (coef. a (P)2 + coef. b (P) + coef. c) / P [$/ MW] P1 P2 P3 P4 P5 P6 P7 P aleat [MW] 130 95 247 9 26 24 247 fmiope [$/MW] 710 568 435 2,859 2,351 2,392 503 8, 9 f-= f+= En RCL fmiope(P) ≤ 1,647 435 2,859 10. Se observa como el valor de α determina el grado de miopía o aleatoriedad, ya que un valor de α=0, hará al algoritmo totalmente dependiente de la evaluación de la función miope, y se la RCL estará integrada solamente por el elemento con la mejor evaluación. Por otra parte con α=1, se permite que integren a la RCL, todos los elementos de C. RCL = { P1 130 P2 95 P3 247 64 P7 247 } 11 Se selecciona de forma aleatoria un elemento de RCL, digamos el elemento 2 12, 13, 14. x= {(P2 = 95)}, C = {P1, P3, P4, P5, P6, P7}, dem-resto = 804 – 95 = 709 Siguiente ciclo, |C| = 6 5. Nuevos límites NPmáx NPmín U1 160 40 U2 U3 248 62 U4 27 7 U5 26 7 U6 30 8 U7 489 218 El límite inferior de U7 ha sido modificado. Una asignación de potencia inferior a 218 para U7, no permitiría cubrir la demanda restante de 709, aún asignando a U1, U3, U4, U5, U6 con sus valores máximos 6, 7. P1 P2 P3 P4 P5 P6 P7 P aleat [MW] 104 64 20 21 16 295 fmiope [$/MW] 720 723 2,319 2,407 2,570 500 8, 9, 10. f-= f+= RCL = { En RCL fmiope(P) ≤ 1,535 500 2,570 P1 104 P3 64 P7 295 11 Se selecciona de forma aleatoria un elemento de RCL, digamos el elemento 1 12. x= {(P2 = 95), (P1 = 104)} 13. C = {P3, P4, P5, P6, P7} 14. dem_resto = 709 – 104 = 605 Siguiente ciclo, |C| = 5 5. Nuevos límites U1 NPmáx NPmín U2 U3 248 62 U4 27 7 6, 7. P aleat [MW] P1 P2 P3 P4 P5 P6 P7 99 19 24 15 287 fmiope [$/MW] 556 2,329 2,366 2,618 500 65 U5 26 7 U6 30 8 U7 489 274 } 8, 9, 10. f-= f+= En RCL fmiope(P) ≤ 1,559 500 2,618 RCL = { P3 99 P7 287 } 11 Se selecciona de forma aleatoria un elemento de RCL, digamos el elemento 1 12. x= {(P2 = 95), (P1 = 104), (P3 = 99)} 13. C = {P4, P5, P6, P7} 14. dem_resto = 605 – 99 = 506 Siguiente ciclo, |C| = 4 5. Nuevos límites U1 U2 U3 U4 27 7 NPmáx NPmín U5 26 7 U6 30 8 U7 484 423 6, 7. P aleat [MW] P1 P2 P3 P4 P5 P6 P7 21 19 27 471 fmiope [$/MW] 2,312 2,451 2,378 496 8, 9, 10. f-= f+= En RCL fmiope(P) ≤ 1,474 496 2,451 RCL = { P7 471 11 Se selecciona de forma aleatoria un elemento de RCL, no queda más opción que 1 12. x= {(P2 = 95), (P1 = 104), (P3 = 99), (P7 = 471)} 13. C = {P4, P5, P6} 14. dem_resto = 506 – 471 = 35 Siguiente ciclo, |C| = 3 5. Nuevos límites U1 U2 U3 U4 20 7 NPmáx NPmín 66 U5 20 7 U6 21 8 U7 } 6, 7. P aleat [MW] P1 P2 P3 P4 P5 P6 P7 20 9 19 fmiope [$/MW] 2,319 3,232 2,469 8, 9, 10. f-= f+= En RCL fmiope(P) ≤ 2,776 2,319 3,232 RCL = { P4 20 } P6 19 11 Se selecciona de forma aleatoria un elemento de RCL, sea el elemento 2 12. x= {(P2 = 95), (P1 = 104), (P3 = 99), (P7 = 471), (P6 = 19)} 13. C = {P4, P5} 14. dem_resto = 35 – 19 = 16 Siguiente ciclo, |C| = 2 5. Nuevos límites U1 U2 U3 U4 9 7 NPmáx NPmín U5 9 7 U6 U7 6, 7. P aleat [MW] P1 P2 P3 P4 P5 P6 P7 8 9 fmiope [$/MW] 3,020 3,232 8, 9, 10. f-= f+= En RCL fmiope(P) ≤ 3,126 3,020 3,232 RCL = { P4 8 } 11 Se selecciona de forma aleatoria un elemento de RCL, sólo hay una opción, elemento 1 67 12. x= {(P2 = 95), (P1 = 104), (P3 = 99), (P7 = 471), (P6 = 19), (P4 = 8)} 13. C = {P5} 14. dem_resto = 16 – 8 = 8 Se detiene el ciclo, |C| = 1 16. P5 = 8 FIN Solución: x = {104, 95, 99, 8, 8, 19, 471} costo de la solución: 516 138. costo solución óptima: 487 018. desviación: 6% 5.4 Fase búsqueda local Entrada: solución factible, x = (P1o, P2o, …, PUso) Salida: solución mejorada, s = (P1s, P2s, …, PUss) El algoritmo utilizado es el mismo que se utilizó en para el ARS, y se describe en la sección 4.3. EL parámetro k0 determina cuantas soluciones vecinas se generan. 5.5 Zona muerta En la solución inicial (fase constructora) y en la generación de vecindades (BL), se decide de forma aleatoria y antes de asignar las potencias a cada unidad, en que zona operarán las unidades con zona muerta. Si en la solución inicial la unidad opera arriba de la zona muerta, en la búsqueda local se buscan soluciones arriba de la zona muerta también. 5.6 Ajuste de parámetros, Nitr, α El algoritmo GRASP es de los algoritmos más sencillos en cuanto a parámetros de control. Una vez definidos los algoritmos de las fases constructora y de búsqueda local, basta con ajustar el número de iteraciones (N_itr) y el grado de aletoriedadmiopía de la fase constructora (α). Como se describió anteriormente, un valor de α= 1, permite escoger de forma aleatoria cualquier elemento candidato para formar parte de la solución. Con α= 0, se escoge al mejor elemento evaluado por una función miope para ser agregado a la solución. Un término medio de α= 0.5, permite formar una lista restringida de candidatos integrada por los mejores elementos, de donde se elege, de forma aleatoria, al siguiente elemento que 68 formara parte de la solución. Con N_itr= 5000 y un número de vecinos k0= 100 que genera la fase de búsqueda local, se revisan 5x105 soluciones, que es una cifra pequeña si se compara con el espacio de solución del caso de estudio 1 de 7 unidades, que es de 1.27 x 1014. La tabla 5.4 muestra los resultados del programa GRASP aplicado al caso 1, usando valores extremos y un valor intermedio para α. Se hicieron 10 pruebas para cada valor de α. Tabla 5.4 Resultados del GRASP al caso 1, con k0 = 100 y distintos valores de α (0.0, 1.0 y 0.5). Numero de iteraciones= 5000 α =0.5 α=0.0 487,022 487,025 0.001 0.001 487,023 487,025 0.001 0.001 mejor solución iteración promedio α =0.5 α =0.0 mejores tres soluciones α=0.5 costo mejor solucion costo promedio error mejor solución [%] error costo promedio [%] 1873 3338 α =0.0 α = 1.0 487,023 487,026 0.001 0.002 solución óptima 487,018 α = 1.0 2873 α = 1.0 iteración mín* 1498 1556 1333 iteración máx 3580 3732 3763 El desempeño de este algoritmo para el caso de estudio 1 de 7 unidades fue excelente. El error de la mejor solución fue muy pequeño para los tres valores de α utilizados. Se prefirió un valor de α= 0.5 porque la mejor solución se encontró, en promedio, en un número de iteraciones menor (1873), y también encontró a las tres mejores soluciones en un rango menor (1498 a 3580). En las figuras 5.1 a 5.3 se muestra el desempeño del algoritmo GRASP. Se observó que cuando α= 0, las variaciones en el costo de las soluciones mejoradas es menor porque no se permite elegir a elementos que aumenten el costo de la solución. Con alfa = 1.0, la elección de los elementos que se incorporan a la solución es totalmente aleatorio y la solución es generalmente más costosa. Por eso se observaron soluciones con costos más altos que con α= 0.0. Con α= 0.5 se balancea la aleatoriedad y miopía en la generación de las soluciones. 69 α = 0.5 515 510 505 500 495 490 1500 1250 1000 750 500 250 485 0 costo mejor solución 520 iteración Figura 5.1 Costo de las soluciones de cada iteración, fase de construcción con α=0.5, caso 1 (7 U’s). α = 1.0 515 510 505 500 495 490 1500 1250 1000 750 500 250 485 0 costo mejor solución 520 iteración Figura 5.2 Costo de las soluciones de cada iteración, fase de construcción con α=1, caso 1 (7 U’s). α = 0.0 515 510 505 500 495 490 1500 1250 1000 750 500 250 485 0 costo mejor solución 520 iteración Figura 5.3 Costo de las soluciones mejoradas de cada iteración, fase de construcción con α=0, caso 1 (7 U’s). 70 Se probaron otras combinaciones de N_itr y k0 con el fin de tener una referencia mínima de estos valores. En las columnas a y b de la tabla 5.5b se muestran mejores resultados con la intensificación de la búsqueda local a la vez que se redujo el número de iteraciones, conservando así el número total de soluciones generadas. La mejor solución en la columna b se encontró en promedio en la iteración 329, lo cuál nos indica que no es necesario generar tantas como 500 soluciones iniciales. Por lo tanto se realizaron pruebas con N_itr = 400 y N_itr=300, y se probaron diferentes valores de k0 en la búsqueda local. Los resultados mostrados en las columnas f y g muestran un deterioro en la calidad de las soluciones. Los mejores resultados se obtuvieron con Nitr = 500 y Nitr = 300. Tabla 5.5 Resultados del GRASP al caso 1, con diferentes combinaciones de N_itr y k0. a b c d e f g 5000 100 500 1000 400 750 300 500 300 400 300 300 200 400 487,022 487,025 1.90 0.001 0.001 487,018 487,020 1.06 0.000 0.000 487,019 487,021 1.39 0.000 0.001 1873 329 175 162 147 144 162 1498 3580 220 427 90 305 91 227 75 216 73 226 57 162 N_itr k0 costo mejor solucion costo promedio desv. Est. error mejor solución [%] error costo promedio [%] mejor solución iteración promedio solución óptima 487,019 487,019 487,018 487,020 487,021 487,021 487,022 487,022 1.65 0.96 2.96 1.98 0.000 0.000 0.000 0.000 0.001 0.001 0.001 0.001 487,018 mejores tres soluciones iteración mín* iteración máx En la tabla 5.6 se muestran los resultados para un ajuste mas detallado de k0 con los mejores valores de Nitr de la tabla 5.5. Aunque el mejor caso se observa con Nitr=500 y k0 = 500, se prefirió la combinación Nitr=300 y k0 = 400 porque emplea la mitad del tiempo con resultados muy similares. Tabla 5.6 Ajuste de k0 para el caso 1 (7 U’s). Nitr k0 = 500 500 500 300 300 300 Costo mínimo 1000 750 500 500 400 300 487,018.4 487,018.7 487,018.5 487,018.5 487,019.4 487,019.4 Costo máximo Costo promedio 487,022.3 487,022.7 487,021.1 487,023.6 487,022.2 487,025.2 487,020.1 487,020.0 487,020.2 487,020.8 487,020.7 487,022.2 desv. Est. %error 1) %error prom 1) tiempo usuario 1.3 0.000 0.000 3.85 1.2 0.000 0.000 2.88 0.7 0.000 0.000 1.88 71 1.4 0.000 0.001 1.13 1.0 0.000 0.001 0.89 1.7 0.000 0.001 0.66 Para el caso 2 de 36 unidades se utilizó un valor de α= 0.5. Las pruebas realizadas consideraron 5 combinaciones diferentes de los parámetros N_itr y k0. Recuérdese que con N_itr se ajusta el número de soluciones factibles que genera la fase de construcción, y con k0 se controla la cantidad de vecindades que se revisan en la búsqueda local. Las combinaciones de N_itr y k0 consideradas dan como máximo la generación de 2x106 soluciones en las dos fases del GRASP. El espacio de solución es de 1.76x1073, así que el número de soluciones revisadas es insignificante. Reduciendo el valor de N_itr se pretendió generar un menor número de soluciones y hacer más intensa la búsqueda local para mejorar la calidad de la solución final. En la tabla 5.7 se muestran los resultados de aplicar el GRASP al DE del caso de estudio 2. Se observa el mejor desempeño del GRASP con Nitr=1000 donde la mejor solución tuvo un error de 0.05% y el costo promedio de 0.09% respecto de la solución óptima. Tabla 5.7 Resultados del GRASP para el DE del caso 2, con diferentes combinaciones de N_itr y k0. N_itr k0 5000 100 500 000 soluciones costo mejor solucion costo promedio error mejor solución [%] error costo promedio [%] 2500 200 500 000 1250 400 500 000 4,449,397 4,446,597 4,447,128 4,451,485 4,449,132 4,448,376 0.17 0.10 0.11 0.21 0.16 0.14 mejor solución iteración * 500 2000 1 000 000 1000 1000 1 000 000 4,445,020 4,445,910 0.07 0.09 4,444,244 4,446,048 0.05 0.09 2930 1303 700 260 440 1866 3968 590 1807 306 995 132 344 287 726 solución óptima 4,442,037 mejores tres soluciones iteración mín * iteración máx* promedio de las10 pruebas Los resultados para Nitr= 1000 y k0 = 1000 muestran que, en promedio, la mejor solución se obtuvo en las primeras 500 iteraciones, por lo que se utilizaron valores semejantes de Nitr para hacer un mejor ajuste del parámetro k0 respecto al tiempo de ejecución, ver tabla 5.8. La mejor solución se obtuvo con k0 = 1000, y valores grandes de Nitr. Si no se tienen limitantes de tiempo, se pueden utilizar valores tan grandes como se desee, pero las mejoras en la calidad de la solución son mínimas. La combinación Nitr = 500 y k0 = 1000 proporciona casi los mismos resultados que la combinación de valores más grande (Nitr=800 y k0 = 1000) en un tiempo de 60% menos. Para este caso, en donde los tiempos de ejecución son significativos, se usó regresión lineal para poder estimar los tiempos de ejecución respecto del número de soluciones generadas por el grasp (Ts = Nitr x k0) : t = 0.1427 Ts + 2.461x 10 -5. Tabla 5.8 Ajuste de k0 para el caso 2 (36 U’s). 72 Nitr k0 800 600 500 1000 750 500 1000 750 500 1000 750 500 Costo mínimo 4,444,245 4,445,224 4,445,971 4,444,245 4,445,224 4,445,971 4,444,245 4,446,688 4,447,301 Costo máximo Costo promedio 4,447,653 4,448,801 4,449,765 4,448,312 4,448,801 4,450,183 4,448,312 4,449,563 4,449,564 4,446,193 4,447,183 4,448,036 4,446,259 4,447,226 4,448,448 4,446,539 4,447,686 4,448,719 1,126 1,031 1,009 1,235 1,035 1,207 1,115 994 972 0.05 0.07 0.09 0.05 0.07 0.09 0.05 0.10 0.12 0.094 0.116 0.135 0.095 0.117 0.144 0.101 0.127 0.150 19.8 15.0 10.0 14.9 11.2 7.5 12.4 9.4 6.3 desv. Est. %error %error prom tiempo Por último, en las tablas 5.9 y 5.10 se muestran los resultados para el caso 3. Los ajustes de de N_itr y k0 del caso 1 son muy grandes para este caso y se probaron valores más bajos. Con N_itr = 100 y k0=100 fue suficiente para obtener buenas soluciones. Tabla 5.9 Resultados del GRASP para el DE del caso 3, con diferentes combinaciones de N_itr y k0. N_itr 1250 700 100 k0 400 400 100 Mejor Solución soluciones GRASP/espacio solución [%] 2.2 1.2 0.04 costo mejor solucion 8,234.07 8,234.07 8,234.10 costo promedio 8,234.07 8,234.07 8,234.11 error mejor solución [%] 0.00 0.00 0.00 error costo promedio [%] 0.00 0.00 0.00 658 497 40 313 723 143 562 34 71 mejor solución iteración * rango mejores tres soluciones mín* máx* Tabla 5.10 Ajuste de k0 para el caso 3 (3 U’s). Nitr k0 = Costo mínimo Costo máximo Costo promedio desv. Est. %error 1) %error prom 1) tiempo usuario 100 100 8,234.078 8,234.2 8,234.1 0.02 0.000 0.000 0.04 73 80 125 8,234.072 8,234.2 8,234.1 0.04 0.00 0.000 0.04 125 80 8,234.085 8,234.3 8,234.1 0.06 0.000 0.001 0.04 8,234.07 En la tabla 5.11 se resumen los mejores ajustes de los parámetros del GRASP para cada caso de estudio. Tabla 5.11 Parámetros del GRASP determinados para cada caso de estudio. alfa N_itr k0 caso 1 300 400 0.5 caso 2 500 1000 0.5 caso 3 100 100 0.5 5.7 Resumen de resultados del GRASP (DE con funciones convexas). En la tabla 5.12 se muestra un resumen de los resultados para cada caso de estudio, donde se usaron los ajustes obtenidos para Nitr y k0 y funciones de costo convexas. Tabla 5.12 Resultados del GRASP para los casos de estudio 1, 2 y 3 (con funciones de costo convexas). Caso1 Caso 2 Caso 3 (7 U’s) (36 U’s) (3 U’s con pv) Nitr= 300, k0 = Nitr= 500, k0 = 1000 Nitr= 100, k0 = 100 400 Costo mínimo 4,444,245 8,234.1 487,019.4 Costo máximo 4,448,312 8,234.2 487,022.2 Costo promedio 4,446,539 8,234.1 487,020.7 desv. Est. 1115.1 0.02 1.0 %error 0.050 0.000 0.000 %error_prom 0.101 0.000 0.001 tiempo usuario 12.38 0.04 0.89 74 Capítulo 6. RESULTADOS FINALES 6.1 Introducción. En este capítulo se muestran los resultados finales de la aplicación de cada heurística a cada caso de estudio. Primeramente se presenta una tabla resumen con los ajustes de los parámetros obtenidos en las secciones anteriores. Las tablas de resultados se obtuvieron a partir de diez pruebas donde se utilizaron semillas aleatorias fijas con valores de 100, 200, 300, … , 900 y 1000. Con el fin de ser breve en la exposición de resultados, sólo se presenta el detalle de los valores de potencia de las unidades para el caso 1 (de 7 U’s) y para los demás casos sólo se presentan tablas con estadísticas de las 10 pruebas realizadas. Para cada caso se muestran resultados del DE con funciones de costo convexas y con funciones de costo no convexas y zona muerta. Se muestran también los resultados comparativos de los casos 1 y 3 al utilizar funciones de costo ajustadas, de segundo grado convexas, y las funciones reales no convexas. No se considera la zona muerta con el propósito de evaluar solamente los costos adicionales que se tienen por utilizar las curvas ajustadas de segundo grado. Para el caso 2 de 36 unidades, se muestran resultados con la combinación de funciones de costo: 32 unidades con funciones de costo convexas de segundo grado, 3 unidades con punto de válvula y una unidad con el modelo del PIE CC Mexicali. 75 6.2. Resultados para el caso de estudio, 7 U’s. Los ajustes de los parámetros de cada heurística que se obtuvieron en las secciones anteriores se resumen en la tabla 6.1. Tabla 6.1 Ajustes de los parámetros de las heurísticas, caso 1 (7 U’s). AG AGH ARS GRASP Generaciones 300 75 - Nitr - - 300 FP_IBP 2 500 2 500 K0 500 50 400 alfa 0.9 0.5 Temperatura 500 000 - Detalle de resultados del AG. Los resultados del AG tuvieron mucha variabilidad y en ninguna prueba se obtuvo la asignación de potencia de la solución óptima para el caso de funciones de costo convexas (ver tabla 6.2a). Aún en la prueba 9, que es la de menor costo, los valores de potencia despachados a las unidades 1, 2, 3 y 7 son muy diferentes. El valor de potencia de la unidad 7 en la solución óptima es de 306.1 MW, que en la realidad no sería tomado como punto de operación por estar dentro de la zona muerta (260 a 320 MW). La unidad 7 sería operada en 320 MW que es el límite más cercano fuera de la zona muerta y la diferencia en el BP sería de 13.9 MW. Esta diferencia tendría que ser contrarestado por las demás unidades. Esto indica que habría que resolver otro problema de DE, en donde se determinaría la forma más económica de reducir esos 13.9 MW entre las 6 unidades restantes. En la tabla 6.2b se observa el cumplimiento de la restricción de la zona muerta de la unidad 7 en todas las pruebas, ya que fue tratada desde la codificación. El costo más barato fue el de la prueba 1 ($487,876) y es más caro que cuando no se considera la restricción de la zona muerta ($487,018), aunque hay que resaltar que las funciones de costo con que se evaluó la unidad 7 son distintas. El AG implementado no tiene un algoritmo de reparación de soluciones, por lo que la aptitud difiere de la función de costo total por el escalamiento (1000) y la penalización por el incumplimiento del balance de potencia. 76 Tabla 6.2 Caso 1. Aplicación del AG. Número de generaciones = 300, FP_IBP = 2500, probabilidad de cruza = 0.8, probabilidad de mutación = 0.01. a) todas las unidades con funciones de costo convexas, b) unidad 7 con función de costo no convexa y zona muerta. MW $ Pt P1 P2 P3 1 870.0 90.6 248.0 155.0 7.2 7.0 8.1 P4 P5 P6 354.2 P7 499,190 Ft P_IBP Aptitud 0.0 499.2 2 870.0 103.7 224.7 155.0 8.4 7.2 8.1 362.8 503,874 0.1 504.0 3 870.0 81.2 201.5 201.5 7.3 7.7 8.0 362.8 496,544 0.1 496.6 4 870.0 64.9 177.9 194.2 7.0 7.0 8.0 411.0 498,094 0.0 498.1 5 870.0 98.3 224.7 230.6 7.0 7.0 8.0 294.4 492,941 0.0 493.0 6 869.9 73.1 148.0 224.6 7.0 7.0 8.0 402.4 500,050 0.0 500.1 7 870.0 66.8 212.2 195.7 7.0 7.0 8.0 373.3 494,168 0.0 494.2 8 870.0 65.9 230.3 178.2 7.0 7.0 8.0 373.7 494,742 0.0 494.8 9 870.0 74.3 224.3 227.6 7.0 7.0 8.0 321.8 490,697 0.0 490.7 10 869.9 95.0 200.8 236.3 7.0 7.0 8.0 315.9 494,257 0.0 494.3 248.0 7.0 7.0 8.0 306.1 487,018 0.0 487.0 1) 870.0 45.9 248.0 1) solución óptima a) MW $ Pt P1 P2 P3 P4 P5 P6 P7 1 870.0 59.4 221.7 236.4 7.0 7.0 8.0 330.5 487,876 0.0 487.9 2 870.0 60.6 108.4 223.7 7.0 7.0 8.0 455.2 501,272 0.0 501.3 3 870.0 54.9 155.0 248.0 7.5 12.7 8.5 383.3 500,944 0.0 501.0 4 870.0 56.7 227.6 201.5 7.2 7.0 8.0 362.0 489,671 0.0 489.7 5 870.0 67.6 153.5 206.6 7.0 7.0 8.0 420.3 496,182 0.0 496.2 6 870.0 50.7 192.0 152.0 7.0 7.0 8.1 453.2 496,270 0.0 496.3 7 870.0 122.5 203.0 201.2 7.0 7.0 8.0 321.2 499,795 0.0 499.8 8 870.0 47.0 213.1 241.5 7.0 7.0 8.1 346.4 487,842 0.0 487.8 9 870.0 53.3 208.1 186.9 7.0 7.0 8.0 399.7 491,619 0.0 491.6 10 870.0 112.2 207.0 198.6 7.0 7.0 8.0 330.2 497,617 0.0 497.6 b) 77 Ft FP_IBP aptitud Detalle de resultados del AGH. A diferencia del AG, con el AGH los resultados son más homogéneos. Los valores de potencia de cada unidad en todas las pruebas son muy similares y por lo tanto también los costos totales. Cuando se considera la zona muerta (tabla 6,3b) se observa que la unidad 7 es llevada al límite inferior de su zona muerta e incluso el costo de generación es inferior al mostrado en la tabla 6.3a para la solución óptima. Esto es debido a que han sido evaluadas con diferentes funciones de costo. Tabla 6.3 Caso 1. Aplicación del AG Híbrido. AGini = 75, K0 = 500, FP_IBP = 2500, probabilidad de cruza = 0.8, probabilidad de mutación = 0.01. a) todas las unidades con funciones de costo convexas, b) unidad 7 con función de costo no convexa y zona muerta. MW Pt P1 P2 P3 $ P4 P5 P6 P7 Ft 1 870.0 40.0 247.9 247.9 7.0 7.0 8.0 312.1 487,070 2 870.0 41.1 248.0 247.9 7.0 7.0 8.0 310.9 487,050 3 870.0 40.0 247.9 247.9 7.0 7.0 8.0 312.2 487,073 4 870.0 40.0 247.9 247.9 7.0 7.0 8.0 312.2 487,073 5 870.0 43.7 247.9 248.0 7.0 7.0 8.0 308.3 487,027 6 870.0 40.0 248.0 247.9 7.0 7.0 8.0 312.1 487,069 7 870.0 40.0 248.0 248.0 7.0 7.0 8.0 312.1 487,067 8 870.0 40.0 248.0 247.9 7.0 7.0 8.0 312.1 487,068 9 870.0 41.7 248.0 247.9 7.0 7.0 8.0 310.4 487,044 10 870.0 40.0 247.9 248.0 7.0 7.0 8.0 312.1 487,068 1) 870.0 45.9 248.0 1) solución óptima 248.0 7.0 7.0 8.0 306.1 487,018 a) MW Pt $ P1 P2 P3 1 870.0 40.0 243.9 244.1 7.0 7.0 8.0 P4 P5 P6 320.0 P7 486,003 Ft 2 870.0 40.0 243.8 244.2 7.0 7.0 8.0 320.0 486,003 3 870.0 40.0 242.9 245.1 7.0 7.0 8.0 320.0 486,004 4 870.0 40.0 242.4 245.6 7.0 7.0 8.0 320.0 486,006 5 870.0 40.0 242.8 245.2 7.0 7.0 8.0 320.0 486,004 6 870.0 40.0 243.5 244.4 7.0 7.0 8.0 320.0 486,003 7 870.0 40.0 244.5 243.4 7.0 7.0 8.0 320.0 486,010 8 870.0 40.0 243.7 244.3 7.0 7.0 8.0 320.0 486,003 9 870.0 40.0 247.6 240.4 7.0 7.0 8.0 320.0 486,018 10 870.0 40.0 241.4 246.6 7.0 7.0 8.0 320.0 486,014 b) 78 Detalle de resultados del ARS. Los resultados del ARS fueron muy similares al AGH cuando se usaron funciones convexas. La variabilidad en el costo total fue de 19 contra 15 del AGH. En este algoritmo las soluciones generadas son factibles y no hay penalización por incumplimiento de BP. Cuando se utilizó la función no convexa en la unidad 7, la mitad de las soluciones llevaron a la unidad 7 a una operación en el límite inferior y la otra mitad al límite superior de la zona muerta, siendo estos últimos de menor costo. Los resultados del AGH fueron en general mejores que los del ARS, ya que en todos ellos la unidad 7 se asignó en el límite superior de la zona muerta. Tabla 6.4 Caso 1. Aplicación del Algoritmo de Recocido Simulado. T= 500 000, k0 = 50, a) todas las unidades con funciones de costo convexas, b) unidad 7 con función de costo no convexa y zona muerta. MW Pt P1 P2 P3 $ P4 P5 P6 P7 Ft 1 870.0 43.8 248.0 248.0 7.0 7.0 8.0 308.2 487,043 2 870.0 42.9 248.0 247.9 7.0 7.0 8.0 309.2 487,036 3 870.0 44.3 248.0 247.9 7.0 7.0 8.0 307.8 487,025 4 870.0 40.0 248.0 247.9 7.0 7.0 8.0 312.1 487,069 5 870.0 42.0 248.0 247.9 7.0 7.0 8.0 310.0 487,047 6 870.0 42.5 248.0 248.0 7.0 7.0 8.0 309.5 487,041 7 870.0 47.0 248.0 247.9 7.0 7.0 8.0 305.2 487,029 8 870.0 40.0 248.0 248.0 7.0 7.0 8.0 312.0 487,082 9 870.0 43.2 247.9 248.0 7.0 7.0 8.0 308.9 487,032 10 870.0 47.5 1) 247.9 247.9 7.0 7.0 8.0 304.6 487.030 870.0 45.9 248.0 1) solución óptima 248.0 7.0 7.0 8.0 306.1 487,018 a) MW Pt $ P1 P2 P3 1 870.0 40.0 240.1 247.9 7.0 7.0 8.0 P4 P5 P6 320.0 P7 486,020 Ft 2 870.0 92.0 248.0 248.0 7.0 7.0 8.0 260.0 488,993 3 870.0 40.0 247.8 240.2 7.0 7.0 8.0 320.0 486,031 4 870.0 92.2 248.0 248.0 7.0 7.0 8.0 259.9 489,011 5 870.0 40.0 245.0 243.0 7.0 7.0 8.0 320.0 486,025 6 870.0 40.0 248.0 240.0 7.0 7.0 8.0 320.0 486,029 7 870.0 40.0 242.9 245.1 7.0 7.0 8.0 320.0 486,004 8 870.0 92.1 248.0 248.0 7.0 7.0 8.0 260.0 488,999 9 870.0 92.2 248.0 247.9 7.0 7.0 8.0 259.9 489,014 10 870.0 92.2 248.0 247.9 7.0 7.0 8.0 259.9 489,018 b) 79 Detalle de resultados del GRASP. Los resultados del GRASP mostraron poca variabilidad (desv. est. = 1) y es que, a diferencia de los algoritmos AG y ARS, éste no da opción de aceptar peores soluciones. Véase en la tabla 6.5 la homogeneidad de los resultados en todas las pruebas. El inconveniente es que es el GRASP requiere de mayor tiempo de ejecución. Los tiempos de ejecución de cada algoritmo se muestran en la siguiente sección. Tabla 6.5 Caso 1. Aplicación del GRASP. Nitr = 300, k0 = 400, a) todas las unidades con funciones de costo convexas, b) unidad 7 con función de costo no convexa y zona muerta. MW Pt P1 P2 P3 $ P4 P5 P6 P7 Ft 1 870.0 44.8 248.0 248.0 7.0 7.0 8.0 307.3 487,022 2 870.0 45.4 248.0 248.0 7.0 7.0 8.0 306.6 487,020 3 870.0 44.9 248.0 248.0 7.0 7.0 8.0 307.1 487,020 4 870.0 46.3 247.9 248.0 7.0 7.0 8.0 305.8 487,022 5 870.0 46.2 248.0 248.0 7.0 7.0 8.0 305.9 487,020 6 870.0 45.3 248.0 248.0 7.0 7.0 8.0 306.7 487,020 7 870.0 45.2 248.0 247.9 7.0 7.0 8.0 306.9 487,022 8 870.0 46.1 248.0 248.0 7.0 7.0 8.0 305.9 487,019 9 870.0 45.2 248.0 248.0 7.0 7.0 8.0 306.8 487,021 10 870.0 46.5 248.0 247.9 7.0 7.0 8.0 305.6 487,022 1) 870.0 45.9 248.0 1) solución óptima 248.0 7.0 7.0 8.0 306.1 487,018 a) MW Pt P1 P2 P3 $ P4 P5 P6 P7 Ft 1 870.0 40.0 244.0 244.0 7.0 7.0 8.0 320.0 486,003 2 870.0 40.0 243.9 244.1 7.0 7.0 8.0 320.0 486,003 3 870.0 40.0 243.9 244.1 7.0 7.0 8.0 320.0 486,003 4 870.0 40.0 244.0 244.0 7.0 7.0 8.0 320.0 486,003 5 870.0 40.0 243.9 244.1 7.0 7.0 8.0 320.0 486,003 6 870.0 40.0 243.9 244.1 7.0 7.0 8.0 320.0 486,003 7 870.0 40.0 244.0 244.0 7.0 7.0 8.0 320.0 486,003 8 870.0 40.0 244.0 244.0 7.0 7.0 8.0 320.0 486,003 9 870.0 40.0 243.9 244.1 7.0 7.0 8.0 320.0 486,003 10 870.0 40.0 243.8 244.2 7.0 7.0 8.0 320.0 486,003 b) RESUMEN CASO 1, 7 U’s. En los resultados del AG las soluciones tienen mucha variabilidad (3,915) y el error promedio con respecto al costo de la solución óptima (487,018) fue de 1.95%. 80 En la tabla 6.6 se observa que la calidad de las soluciones es buena para el AG y excelente para los algoritmos AGH, ARS y GRASP. El algoritmo más estable es el GRASP con una desviación estándar de 1, aunque requirió más de 10 veces el tiempo reportado para el AGH y el ARS. Como ya se ha comentado, el AG mejora rápidamente las soluciones iniciales, pero la calidad de la solución final es pobre y muy variable. Las estadísticas del AG que se muestran son muy similares desde la generación número 100, pero se muestra el resultado de 300 generaciones para mostrar que la calidad de la solución ya no mejora significativamente. El algoritmo que mejor se desempeñó fue el ARS, por la calidad de sus soluciones en un menor tiempo de ejecución. Tabla 6.6 Resumen de la aplicación de los métodos heurísticos al caso 1 con funciones de costo convexas. AG AGH ARS GRASP Generaciones =300 AGini = 75 T = 500 000 Nitr=300 k0=500 k0=50 K0=400 Costo mínimo 490,719 487,027 487,025 487,019 Costo máximo Costo promedio 503, 999 487,073 487,082 487,022 496,491 487,061 487,043 487,021 3,915 15 19 1 %error 1) 0.76 0.002 0.001 0.000 %error prom 2) 1.95 0.01 0.01 0.00 tiempo usuario 0.45 0.09 0.03 0.89 desv. Est. 1 2 costo mínimo respecto al costo de la solución óptima costo promedio respecto al costo de la solución óptima Los resultados para el caso 1 cuando se considera la zona muerta y la función no convexa en la U7 se muestran en la tabla 6.7. Tabla 6.7 Resumen de la aplicación de los métodos heurísticos al caso 1, con zona muerta y función de costo no convexa para unidad 7. AG AGH ARS GRASP Generaciones=300 AGini=75 T = 500 000 Nitr=300 k0=500 k0=50 k0=400 Costo mínimo 487,843 486,003 486,004 486,003 Costo máximo Costo promedio 501,288 486,018 489,018 486,003 494,925 486,007 487,514 486,003 desv. Est. 5 271.2 5.2 1 573 0.03 0.379 0.000 0.000 1.84 0.00 0.31 0.44 0.09 0.05 %error 1 %error prom 2 tiempo usuario 1 costo mínimo respecto al mejor costo obtenido (GRASP) 2 costo promedio respecto al mejor costo obtenido (GRASP) 81 1.52 En este caso, la solución óptima no es conocida, por las restricciones impuestas a la unidad 7. Las mejores soluciones las proporcionó nuevamente el GRASP y las soluciones en todas las pruebas fueron prácticamente las mismas. El AGH mostró ahora mejor desempeño que el ARS y aún cuando se incrementó k0 para que en cuestión de tiempo de ejecución fuera comparable con el AGH, los resultados no mejoraron, ver tabla 6.8. Tabla 6.8 Resultados del ARS con zona muerta y función no convexa en U7, k0 = 100. ARS T = 500 000 k0=100 Costo mínimo 486,016 489,022 487,516 1,572 Costo máximo Costo promedio desv. est. %error 1 0.003 2 %error prom tiempo usuario 0.31 0.14 Se comparó el DE con los dos tipos de funciones, convexa y no convexa, para la unidad 7 del PIE CC Mexicali. A la primera se hará referencia como la función de costo ajustada y a la segunda, como la función de costo real, pues es la que proporciona el permisionario para la facturación de la energía entregada. Los resultados en la tabla 6.9(1) son los que se obtienen con el método simplex, utilizando funciones de costo de segundo grado convexas; en 6.9(2) se evalúa a la unidad 7 con la función de costo real; en 6.9(3), la mejor solución obtenida de los cuatro métodos heurísticos, que la proporcionó el GRASP. Tabla 6.9 Evaluación de funciones de costo, caso 1 (7Us) sin zona muerta. Demanda = 870 MW potencia Pt P1 P2 P3 P4 Costo P5 P6 P7 P1 P2 P3 P4 P5 P6 P7 total 1 870.0 45.9 248.0 248.0 7.0 7.0 8.0 306.1 42,358 107,796 107,796 22,629 26,061 27,534 152,845 487,018 2 870.0 45.9 248.0 248.0 7.0 7.0 8.0 306.1 42,358 107,796 107,796 22,629 26,061 27,534 151,601 485,774 3 870.0 40.1 248.0 248.0 7.0 7.0 8.0 311.9 39,569 107,796 107,796 22,629 26,061 27,534 154,347 485,732 1) solución óptima, U7 evaluada con función de costo ajustada de segundo grado convexa. 2) solución óptima, U7 evaluada con función de costo no convexa. 3) mejor solución GRASP, usando función de costo no convexa para U7. 82 La tabla 6.10 muestra la comparación de resultados de las heurísticas. Con excepción del AG, todas las heurísticas obtuvieron costos menores a los obtenidos con el simplex, tanto en costo mínimo como en costo promedio. Tabla 6.10 Resultados de las heurísticas para el caso 1. U7 con función de costo real. Demanda = 870 MW. AG AGH RS GRASP AGini=75 T = 500 000 Nitr=300 SIMPLEX 1 demanda 870 300 generaciones 487,830 k0=500 485,733 k0=50 485,734 k0=400 485,732 Costo máximo 499,938 485,806 Costo promedio 494,006 485,745 desv. Est. 4,216 23 2 %error 0.42 -0.01 2 %error prom 1.69 -0.01 1 costo de la unidad 7 evaluado con función real, no convexa 485,744 485,739 4 -0.01 -0.01 485,732 485,732 0 -0.01 -0.01 Costo mínimo 2 485,774 respecto de la solución del simplex La mejor solución que se obtuvo con el GRASP en diez pruebas tuvo un costo total de 485 732, que es menor en $42 al que se obtendría indirectamente con el simplex 6.9 (2). Tomando en cuenta que los métodos heurísticos no garantizan la obtención de una solución óptima, se puede decir que para una demanda de 870 el DE que se obtuvo utilizando la función ajustada tuvo un error de al menos $42 y representa el 0.01% del costo total de generación. La diferencia en costo de la U7 evaluada con los dos tipos de funciones es de $1 244 (6.9 1,2) y, como se aprecia en la figura 6.1, en este punto de operación de 306 MW, ambas funciones son muy cercanas. Función de costo 301500 251500 $/h 201500 real 151500 ajustada 101500 51500 306 1500 120 160 200 240 280 320 360 400 440 480 MW Figura 6.1 Punto de operación de la unidad 7 (306 MW), caso 1 con 870 MW de demanda. 83 Se resolvió el DE con otros valores de demanda para exponer los resultados cuando la U7 opera en regiones donde las curvas están más alejadas, por ejemplo de 122 A 160 MW ó de 420 a 489 MW. En la tabla 6.10 se muestran los resultados para una demanda de 700 MW en donde el despacho de la U7, con la función de costo ajustada, es de 139.9 MW. La diferencia en costo de las dos curvas es de $3 660 (tabla 6.11 1,2). Los resultados del GRASP, utilizando la función real de costo para la U7, la despachan en 130.3 MW. Entonces el error por usar la función de costo ajustada fue de al menos $125 (0.03%). Tabla 6.11 Evaluación de funciones de costo, caso 1 (7Us). Demanda = 700 MW. potencia Pt P1 P2 P3 P4 Costo P5 P6 P7 P1 P2 P3 P4 P5 P6 P7 total 1 700.0 42.1 248.0 248.0 7.0 7.0 8.0 139.9 40,542 107,796 107,796 22,629 26,061 27,534 72,946 405,304 2 700.0 42.1 248.0 248.0 7.0 7.0 8.0 139.9 40,542 107,796 107,796 22,629 26,061 27,534 69,286 401,644 3 700.0 51.7 248.0 248.0 7.0 7.0 8.0 130.3 45,220 107,796 107,792 22,629 26,061 27,534 64,486 401,518 1) solución óptima, U7 evaluada con función de costo ajustada 2) solución óptima, U7 evaluada con función de costo real 3) mejor solución GRASP, usando función de costo real en la U7 La tabla 6.12 muestra la comparación de resultados de las heurísticas. De igual manera, se obtienen mejores costos con las heurísticas, con excepción del AG. Tabla 6.12 Resultados de las heurísticas para el caso 1. U7 con función de costo real. Demanda = 700 MW. AG AGH RS GRASP 300 AGini=75 T = 500 000 Nitr=300 generaciones k0=500 k0=50 k0=400 SIMPLEX 1 demanda 700 Costo mínimo 402,072 401,582 401,526 401,518 Costo máximo Costo promedio 416,216 409,245 401,773 401,663 401,614 401,557 401,526 401,522 29 -0.03 -0.02 2 -0.03 -0.03 desv. Est. 5,187 2 %error 0.11 2 %error prom 1.89 1 costo de la unidad 7 evaluado con función real, no convexa 2 61 -0.02 0.00 401,644 respecto de la solución SIMPLEX En la tabla 6.13 se muestran los resultados para una demanda de 1 050 MW. El despacho de la U7 con la función de costo ajustada es de 482.1 MW y la diferencia en costo de las dos curvas es de $7 089 (6.13 1,2). Al compararse con 84 los resultados del GRASP, la U7 se despacha en 489.0 MW y el error por usar la función de costo ajustada fue de al menos $302 (0.05%). Tabla 6.13 Evaluación de funciones de costo, caso 1 (7 Us). Demanda = 1 050 MW. potencia Pt P1 P2 P3 Costo P4 P5 P6 P7 P1 P2 P3 P4 P5 P6 P7 total 1 1050.0 49.9 248.0 248.0 7.0 7.0 8.0 482.1 44,319 107,796 107,796 22,629 26,061 27,534 239,195 575,330 2 1050.0 49.9 248.0 248.0 7.0 7.0 8.0 482.1 44,319 107,796 107,796 22,629 26,061 27,534 232,106 568,241 3 1050.0 43.0 248.0 248.0 7.0 7.0 8.0 489.0 40,971 107,791 107,792 22,629 26,061 27,534 235,161 567,939 1) solución óptima, U7 evaluada con función de costo ajustada 2) solución óptima, U7 evaluada con función de costo real 3) mejor solución GRASP, usando función de costo real en la U7 La tabla 6.14 muestra la comparación de resultados de las heurísticas. De igual manera, se obtienen mejores costos con las heurísticas, con excepción del AG y el AGH en el costo promedio. Tabla 6.14 Resultados de las heurísticas para el caso 1. U7 con función de costo real. Demanda = 1 050 MW. AG AGH RS GRASP 300 AGini=75 T = 500 000 Nitr=300 generaciones k0=500 k0=50 k0=400 SIMPLEX 1 demanda 1 050 Costo mínimo 570,777 567,942 567,941 567,939 Costo máximo Costo promedio 584,783 578,826 567,963 567,949 568,112 567,966 567,941 567,940 52 -0.05 -0.05 1 -0.05 -0.05 desv. Est. 4,380 2 %error 0.45 2 %error prom 1.86 1 costo de la unidad 7 evaluado con función real, no convexa 2 respecto de la solución SIMPLEX 85 6 -0.05 -0.05 568,241 6.3 Resultados para el caso de estudio 2, 36 Unidades. Los ajustes de los parámetros de cada heurística se resumen en la tabla 6.15. Tabla 6.15 Ajustes de los parámetros de las heurísticas, caso 2 (36 U’s). AG AGH ARS FP_IBP 563 563 Generaciones 500 500 - Nitr - - 500 GRASP K0 750 800 1000 alfa Temperatura 500 000 0.95 0.5 - RESUMEN CASO 2, 36 U’s. La tabla 6.16 muestra el mejor desempeño del AGH al tener el menor costo y el mejor costo promedio con una variabilidad aceptable respecto a las demás heurísticas. El GRASP presentó resultados similares al AGH pero con un tiempo que es cuatro veces superior. Tabla 6.16 Resumen de la aplicación de los métodos heurísticos al caso 2 con funciones de costo convexas. AG Generaciones=500 Costo mínimo 4,449,024 AGH AGini=500 k0= 750 4,443,442 Costo máximo Costo promedio 4,455,664 4,447,401 4,458,577 4,448,312 4,452,219 4,445,964 4,457,366 4,446,539 2,454 1,284.2 719 1,115 0.16 0.03 0.32 0.05 0.23 0.09 0.35 0.10 3.1 3.2 4.0 12.4 desv. Est. 1 %error %error prom 1 tiempo usuario 1 ARS T=500 000 k0= 800 4,456,305 GRASP Nitr=500 k0= 1000 4,444,245 respecto al costo de la solución óptima En la tabla 6.17 se observa que la variabilidad de las soluciones se incrementa para las heurísticas AG, AGH y ARS. Esto es porque al considerar la zona muerta de la unidad 36, las soluciones presentan brincos en la potencia de la unidad 36, alrededor de los límites de la zona muerta. Tabla 6.17 Resumen de la aplicación de los métodos heurísticos al caso 2, con zona muerta y función no convexa para la unidad 36. AG Generaciones=500 Costo mínimo 3,850,923 AGH AGini=500 k0=750 3,843,912 ARS T=500 000 k0=800 3,850,720 GRASP Nitr=500 k0=1000 3,845,360 Costo máximo 3,863,661 3,853,344 3,870,634 3,847,561 Costo promedio 3,856,027 3,848,348 3,857,610 3,846,342 desv. Est. 4,725 3,860 7,593 831 %error 1 %error_prom 0.14 0.28 -0.04 0.08 0.14 0.32 0.000 0.03 tiempo usuario 3.1 3.3 4.1 16.4 1 1 respecto al mejor costo obtenido (AGH) 86 6.4 Resultados para el caso de estudio 3, 3 Unidades. Los ajustes de los parámetros de cada heurística para el caso 3 se resumen en la tabla 6.18. Tabla 6.18 Ajustes de los parámetros de las heurísticas, caso 3 (3 U’s). AG AGH ARS Generaciones 400 150 - Nitr - - 100 GRASP FP_IBP 25 25 k0 500 200 100 Alfa 0.9 0.5 Temperatura 2 500 - RESUMEN CASO 3, 3 U’s. La tabla 6.19 muestra el desempeño de las heurísticas para el caso 3. En este caso todas las heurísticas proporcionaron soluciones bastante aceptables, destacando el ARS por la calidad de las soluciones en cuanto a variabilidad y tiempo de ejecución. Tabla 6.19 Resumen de la aplicación de los métodos heurísticos al caso 3 (3 Us). AG AGH ARS GRASP mdc/4 Gen =400 AG = 150 T =2 500 Nitr=100 k0=500 k0=200 k0=100 Costo mínimo 8,241.1 8,234.2 8,234.1 Costo máximo 8,500.2 8,254.1 8,252.0 8,234.08 8,234.2 Costo promedio 8,327.4 8,241.7 8,241.81 8,234.11 desv. Est. 89.4 7.4 5.1 0.02 %error 1) 0.085 0.001 0.000 0.000 %error prom 1) 1.133 0.093 0.094 0.000 tiempo usuario 0.26 0.10 0.03 0.04 1 respecto al mejor costo obtenido (GRASP) La figura 6.2 muestra las funciones de costo que se analizan en este caso. Se recuerda que las funciones en color más grueso representan un comportamiento más aproximado del costo del combustible por la apertura y cierre de válvulas en el control de potencia de la unidad. Los métodos heurísticos pueden evaluar este tipo de funciones en el problema de DE y los resultados comparativos con las soluciones del método clásico que utiliza las funciones de segundo grado se muestran en la tabla 6.20. 87 8,000 7,000 6,000 $/h 5,000 4,000 3,000 2,000 1,000 0 50 150 250 350 450 550 650 MW U1 U2 U3 Figura 6.2 Funciones de costo del caso 3 (3 Us). Tabla 6.20 Resultados del DE para el caso 3 (3 Us). potencia [MW] Costo [$] U2 U3 U1 U2 U3 1 850.0 392.1 Pt U1 335.4 122.5 3,984 3,250 1,252 8,486 diferencia [$] total 2 850.0 300.3 400.0 149.7 3,087 3,767 1,380 8,234 252 error [%] 3.1 1) solución óptima, con funciones de costo de segundo grado convexas 2) mejor solución GRASP, con funciones de costo que consideran los puntos de válvula En este caso el empleo de las heurísticas para evaluar el punto de válvula de las unidades térmicas muestra un mejor despacho con un ahorro del 3.1% en el costo total de generación 88 CONCLUSIONES Al comparar los desempeños de las heurísticas utilizadas, el GRASP presentó la mejor calidad en las soluciones en cuanto a costo y a variabilidad; aunque requirió de mayor tiempo de ejecución para las instancias de 7 y 36 unidades. Al reducir el tiempo de ejecución del GRASP a los tiempos en los que el AGH y el ARS dieron buenos resultados, el GRASP mostró desventajas porque las soluciones fueron de menor calidad. Por otra parte, aumentando los tiempos de ejecución del AGH y el ARS a los tiempos del GRASP, éste continuó siendo mejor, pues los otros ya no mejoraron la calidad de sus soluciones. Sin embargo, los resultados que se obtuvieron para la solución del DE fueron bastante satisfactorios y las cuatro heurísticas presentadas mostraron consistencia en la obtención de buenos soluciones con la consideración de funciones de costo no convexas y las discontinuidades que representan las zonas muertas. La mejor solución del GRASP para el caso de 7 unidades, evidenció la ventaja de evaluar la función no convexa al obtener menores costos en el despacho, del orden de 0.01% al 0.05%, dependiendo de la separación de las curvas analizadas en el punto de operación de la unidad. Para el caso de 3 unidades, donde se evaluó el punto de válvula, la mejor solución del GRASP resultó en un costo de generación menor en un 3.1%. Las ventajas del GRASP son evidentes en este problema y aunque los tiempos de ejecución son superiores a los de las demás heurísticas, éstos no son de consideración para su aplicación. Sin embargo, la adición de restricciones es una desventaja para este algoritmo, al igual que lo es para el ARS, por la dificultad de crear una solución inicial. Es más fácil para el AG considerar más restricciones debido a que sólo es necesario incorporar factores de penalización a la función objetivo y además se tiene la posibilidad de poder considerarlas desde la codificación, aunque esto último requiere de mayor habilidad. Por otra parte, se carece en el CENACE de modelos que consideren los puntos de válvula, u otro tipo de curvas más aproximadas que se obtendrían de medir el régimen térmico en un mayor número de puntos y que actualmente se limitan a la medición de tres puntos, que son los suficientes para ajustar una función de segundo grado. 89 Actualmente, no se han explorado nuevos modelos por las limitaciones que impone el programa computacional que obtiene el despacho económico. La incorporación de métodos heurísticos a las rutinas de solución del despacho económico permitiría utilizar cualquier tipo de curva o serie de puntos que mejor modelaran el régimen térmico de las unidades, con el fin de lograr reducciones, por mínimas que sean, en el despacho de generación. Cualquier mejora en el despacho de generación resulta en ahorros importantes si consideramos los costos de producción por combustibles y costos variables que se tienen en el Sistema Interconectado Nacional, que por ejemplo en el año 2006, totalizaron 86 mil millones de pesos. Una disminución mínima del costo de generación, por ejemplo del 0.01 por ciento representa ahorros de 8.6 millones de pesos anuales. La disminución en el costo de generación que se puede obtener al utilizar métodos heurísticos para considerar curvas de cualquier tipo, como las aquí tratadas, dependerá del mayor número de unidades que las consideren y de la diferencia entre las curvas en los modelos utilizados. Para el caso de 7 unidades, se evaluó la restricción en una de siete unidades. En el Sistema Interconectado Nacional, existen diez PIE’s que utilizan curvas no convexas en su régimen térmico, dentro de un promedio de 250 unidades despachadas económicamente. Como se comentó al inicio de este trabajo, el despacho económico es un subproblema del problema de asignación de unidades. El despacho económico es un problema puntual, donde el espacio de tiempo es generalmente de una hora. En el problema de asignación de unidades se amplía el horizonte de tiempo y se incorporan un mayor número de restricciones que acoplan al despacho actual con los despachos de horas anteriores, por ejemplo tiempos mínimos de arranque y paro, rampas de carga, disponibilidad de combustibles, etc. La metodología actual utiliza la programación lineal para resolver el PDE y programación dinámica para el de asignación de unidades. Para trabajos futuros se recomienda la incorporación de métodos heurísticos al programa computacional que resuelve el despacho económico, o incluso para resolver el problema de asignación de unidades, pues para estos trabajos existen un gran número de trabajos publicados que han mostrado excelentes resultados. 90 REFERENCIAS [1] Aboytes, F., Guerrero, J.J.: Despacho económico, flujos óptimos y control de generación. Curso de Capacitación en Sistemas de Potencia, CENACE. México, D.F., 2001. [2] Cai, X., Lo, K.: Unit Commitment by a genetic algorithm. Nonlinear Analysis, Theory, Methods & Applications, Vol. 30, No. 7, pp. 4289-4299, 1997. [3] Goldberg, D. E., Genetic Algorithms in Search, Optimization, and Machina Learning, The University of Alabama, Adison-Wesley publishing Company, 1989 [4] Gutiérrez A. M. A. “La técnica de Recocido Simulado y sus aplicaciones”, Tesis para obtener el grado de Doctor en Ingeniería. UNAM, México, 1991 [5] Li, F.: A comparison of genetic algorithms with conventional techniques on a spectrum of power economic dispatch problems. Expert Systems with Applications 15, 133-142, 1998. [6] Li, F., Morgan, R., Williams, D.: Hybrid genetic to ramping rate constrained dynamic economic dispatch. Electric Power Systems Research 43, 97-103, 1997. [7] Olachea, A.: Aplicación de la técnica de algoritmos genéticos al problema de despacho económico. Tesis para obtener el grado de MC en Ing. Eléctrica. Universidad Autónoma de Nuevo León, 2003. [8] Ongsakul, W.: Real-time economic dispatch using merit order loading for linear decreasing and staircase incremental cost functions. Electric Power Systems Research 51, 167-173, 1999. [9] Reeves, R.: Modern Heuristic Techniques for Combinatorial Problems. Edited by Colin R. Reeves, Mc Graw Hill, 1995 [10] Resende, M.: Greedy Randomized adaptive search procedure (GRASP), AT&T Labs Research Technical Report: 98.41.1. December 22, 1998. 91 [11] Sudhakaran, M., Slochanal, S.M.R., Sreeram, R., Chandrasekhar, N.: Application of refined genetic algorithm to combined economic and emission dispatch. IE (I) Journal-EL. Vol. 85, September 2004. [12] Wood & Wollenberg: Power generation operation and control. Ed. John Wiley and Sons Inc.,1984. [13] Walters, D., Sheble, G.: Genetic algorithm solution of economic dispatch with valve point loading. IIE Transactions on Power Systems, Vol. 8, No. 3, 1993 [14] Barr,S. R., Golden, L. B., Kelly, J. P., Resende, M., Stewart, W.: Designing and Reporting on Computational Heuristic Methods. Journal of Heuristics, I: 932, 1995. 92 APENDICE I Solución analítica al caso de estudio 1 (7 Us) por el método del lagrangiano. APENDICE I. Solución analítica al caso de estudio 1 (7 Us) por el método del lagrangiano. La formulación del problema de DE sin pérdidas es la siguiente: minimizar : n ∑ F (Pi) i =1 i sujeto a: n ∑ P = demanda i =1 i Pmini ≤ Pi ≤ Pmaxi Donde: n: número de unidades generadoras Fi : Función de costo del generador i Pi : Potencia del generador i Pmini : Potencia mínima que puede suministrar el generador i Pmaxi : Potencia máxima que puede suministrar el generador i Se utiliza un multiplicador de Lagrange para incorporar a la función objetivo la restriccion de igualdad (balance generación-demanda). Función lagrangeana: ⎛ n ⎞ L( P, λ ) = ∑ Fi ( Pi ) + λ ⎜ ∑ Pi − demanda ⎟ i =1 ⎝ i =1 ⎠ n El mínimo de la función se obtiene a partir del gradiente, dando lugar a las siguientes condiciones de optimalidad: ∂L dFi = + λ = 0; i = 1,..., n ∂Pi dPi n ∂L = ∑ Pi − demanda = 0; ∂λ i =1 Datos del caso de estudio: AI-1 Demanda: 804 MW coeficientes Pmin central tipo [MW] Pmax a b [MW] [$/MWh ] 2 P P [$/MWh] c [$] Presidente Juárez U1 vapor convencional 40 160 1.28000 368.0 22770 Presidente Juárez U2 ciclo combinado 62 248 0.56350 158.5 33830 Presidente Juárez U3 ciclo combinado 62 248 0.56350 158.5 33830 Ciprés U4 turbogás 7 27 24.92000 1154.0 13330 Mexicali U5 turbogás turbogás U6 7 26 19.45000 1204.0 16680 8 30 21.16000 1190.0 16660 122 489 0.02908 467.7 6957 308 1,228 Tijuana CC Mexicali 1) U7 ciclo combinado Total 1) Coeficientes abc de la curva ajustada a los tres puntos del consumo específico proporcionado por el Productor Independiente Sustituyendo los coeficientes abc en las ecuaciones de optimalidad: d (1.28P1 + 368P1 + 22770) + λ = 0; dP1 2 d (0.5635P2 + 158.5P2 + 33830) + λ = 0; dP2 2 d (0.5635P3 + 158.5 P3 + 33830) + λ = 0; dP3 2 d (24.92 P4 + 1154 P4 + 13330) + λ = 0; dP4 2 d (19.45P5 + 1204P5 + 16680) + λ = 0; dP5 2 d (21.16 P6 + 1190 P6 + 16660) + λ = 0; dP6 2 d (0.0291P7 + 467.7 P7 + 6957) + λ = 0; dP7 P1 + P2 + P3 + P4 + P5 + P6 + P7 = 804 2 AI-2 Estas derivadas generan el siguiente sistema de ecuaciones lineales: Ap=B Matriz p Matriz A Matriz B λ U1 U2 U3 U4 U5 U6 U7 2.560 0 0 0 0 0 0 1 P1 -368 0 1.127 0 0 0 0 0 1 P2 -158.5 0 0 1.127 0 0 0 0 1 P3 -158.5 B B B B B B B B B B B B B B = 0 0 0 49.840 0 0 0 1 P4 0 0 0 0 38.900 0 0 1 P5 -1154 0 0 0 0 0 42.320 0 1 P6 -1190 0 0 0 0 0 0 0.058 1 P7 -467.7 1 1 1 1 1 1 1 0 λ 804 B p -1204 p = A -1 B P P A -1 P P U1 U2 U3 U4 U5 U6 U7 λ 0.3828 -0.0178 -0.0178 -0.0004 -0.0005 -0.0005 -0.3457 0.0201 -368 44.3 -0.0178 0.8468 -0.0405 -0.0009 -0.0012 -0.0011 -0.7853 0.0457 -158.5 286.5 -0.0178 -0.0405 0.8468 -0.0009 -0.0012 -0.0011 -0.7853 0.0457 -158.5 -0.0004 -0.0009 -0.0009 0.0200 0.0000 0.0000 -0.0178 0.0010 -1154 -0.0005 -0.0012 -0.0012 0.0000 0.0257 0.0000 -0.0228 0.0013 -1204 -0.0005 -0.0011 -0.0011 0.0000 0.0000 0.0236 -0.0209 0.0012 -0.3457 -0.7853 -0.7853 -0.0178 -0.0228 -0.0209 1.9776 0.0201 0.0457 0.0457 0.0010 0.0013 0.0012 0.8850 B B B B B B B B B B B B B B revisión límites min 160 Sup 62 248 286.5 Sup 62 248 -13.5 Inf 7 27 -18.6 Inf 7 26 -1190 -16.7 Inf 8 30 0.8850 -467.7 235.5 122 489 -0.0515 804 -481.4 = El resultado muestra que se han violado los límites de potencia de 5 unidades generadoras. Para encontrar una solución, se sustituyen los valores fuera de límite por los límites que violaron, mínimo o máximo, y se resuelve nuevamente el sistema de ecuaciones. Ap=B Matriz p Matriz A U1 B B U2 B B U3 B B U4 B B U5 B B U6 B B U7 B B Matriz B λ 2.560 0 0 0 0 0 0 1 P1 -368 0 1.127 0 0 0 0 0 1 P2 -158.5 0 0 1.127 0 0 0 0 1 P3 -158.5 0 0 0 49.840 0 0 0 1 P4 0 0 0 0 38.900 0 0 1 P5 0 0 0 0 0 42.320 0 1 P6 -1190 0 0 0 0 0 0 0.058 1 P7 -467.7 1 1 1 1 1 1 1 0 λ 804 AI-3 max 40 = -1154 -1204 A -1 P U1 P B p revisión límites λ U2 U3 U4 U5 U6 0.3819 -0.0222 -0.0222 -0.0222 -0.0222 -0.0222 -0.3819 0.0222 -368 44.4 40 160 0.0000 1.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 -248 248.0 62 248 0.0000 0.0000 1.0000 0.0000 0.0000 0.0000 0.0000 0.0000 -248 248.0 62 248 0.0000 0.0000 0.0000 1.0000 0.0000 0.0000 0.0000 0.0000 -7 7.0 7 27 0.0000 0.0000 0.0000 0.0000 1.0000 0.0000 0.0000 0.0000 -7 7.0 7 26 B B B B B B B B B B B B U7 B B min = 0.0000 0.0000 0.0000 0.0000 0.0000 1.0000 0.0000 0.0000 -8 8.0 -0.3819 -0.9778 -0.9778 -0.9778 -0.9778 -0.9778 0.3819 0.9778 -467.7 241.6 0.0222 0.0569 0.0569 0.0569 0.0569 0.0569 0.9778 -0.0569 804 -481.7 8 30 122 489 El costo incremental del sistema es λ=481.7. Se calculan los costos incrementales de las unidades fuera de límites y se revisan las condiciones de optimalidad de Kuhn-Tucker: dFi =λ dPi para P min i < Pi < P maxi dFi ≤λ dPi para Pi = P maxi dFi ≥λ dPi para Pi = P min i P2 = Pmax2 P3 = Pmax3 P4 = Pmin4 P5 = Pmin5 P6 = Pmin6 B B B B B B B B B B B B B B B B B B B B λ2 = 1.127 (248) + 158.5 = 438.0 λ3 = 1.127 (248) + 158.5 = 438.0 λ4 = 49.84 (7) + 1 154.0 = 1 502.9 λ5 = 38.90 (7) + 1 204.0 = 1 476.3 λ6 = 42.32 (8) + 1 190.0 = 1 528.6 B B B B B B B B B B λ2 < λ λ3 < λ λ4 > λ λ5 > λ λ6 > λ B B B B B B B B B B cumple cumple cumple cumple cumple La solución encontrada cumple con todos los límites de potencia, con las condiciones de optimalidad de Kuhn-Tucker y con el BP. En la Tabla 6.1 se muestra la evaluación del costo de esta solución óptima. Fc(P) = aP 2 + bP + c P1 P2 P3 P4 P5 P6 P7 Σ (P1..P7) 44.4 248.0 248.0 7.0 7.0 8.0 241.6 804.0 Costo Fc(P1) Fc(P2) Fc(P3) Fc(P4) Fc(P5) Fc(P6) Fc(P7) Σ (Fc) 41,649 107,796 107,796 22,629 26,061 27,534 121,635 455,099 Costo real Fcr(7) R=Σ (Fcr) 120,767 454,231 Tabla 6.1 Solución analítica, con funciones de costo cuadráticas; y evaluación con la función de costo real de la U7. AI-4 max APENDICE II. Código fuente de los programas en lenguaje C. Programas Principales Algoritmo Genético. “AG2.c”. #include "ag.h" int main(int argc,char **argv) { short poblacion_ini[Tam_pob][Us], ganador[Tam_pob],nueva_poblacion[Tam_pob][Us]; real aptitudes[Tam_pob][2]; real P_cruza,P_mutacion; int i,j,k, semilla; Unidad unidades []= { { 1.28, 368.0, 22770.0, 0.0, 0.0, 40.0, 160.0, 11, 0, 40.0, 40.0}, { 0.5635, 158.5,33830.0, 0.0, 0.0, 62.0, 248.0, 11, 0, 62.0, 62.0}, { 0.5635, 158.5,33830.0, 0.0, 0.0, 62.0, 248.0, 11, 0, 62.0, 62.0}, { 24.92, 1154.0,13330.0, 0.0, 0.0, 7.0, 27.0, 8, 0, 7.0, 7.0}, { 19.45, 1204.0,16680.0, 0.0, 0.0, 7.0, 26.0, 8, 0, 7.0, 7.0}, { 21.16, 1190.0,16660.0, 0.0, 0.0, 8.0, 30.0, 8, 0, 8.0, 8.0}, { 0.02908, 467.7,6957.0, 0.0, 0.0, 122.0, 489.0, 12, 0,260.0, 320.0} }; real modelo_cc[][5]= { {0.04528,489.0,-0.07852, 519.3, 245.0} }; P_cruza = 0.8; P_mutacion=0.01; if (argc > 1) {semilla = strtoul(argv[1],NULL,10); srand(semilla);} else { srand(time(NULL));} pob_ini2(poblacion_ini, unidades, Tam_pob, AG); evaluacion2(poblacion_ini, aptitudes, unidades, modelo_cc); for (i=1; i<=300; i++) { selec_torneo2(poblacion_ini, aptitudes, ganador); hijos2(poblacion_ini,ganador,nueva_poblacion,unidades,P_cruza, P_mutacion); evaluacion2(nueva_poblacion, aptitudes, unidades, modelo_cc); for (j=0; j<Tam_pob;j++) { for (k=0; k< Us; k++) { poblacion_ini[j][k]=nueva_poblacion[j][k]; nueva_poblacion[j][k]=0;} } } for (j=0; j<Tam_pob;j++) {for (k=0; k< Us; k++) printf("%d ",poblacion_ini[j][k]); printf("\n");} salir(); return (0); } Algoritmo Genético Híbrido (AGH). “AGH.c”. #include "ag.h" AII-1 int main(int argc,char **argv) { short poblacion_ini[Tam_pob][Us], ganador[Tam_pob],nueva_poblacion[Tam_pob][Us]; real aptitudes[Tam_pob][2]; real P_cruza, P_mutacion,*P_sol,costo; int i,j,k,lineas,veces,iteraciones,iteraciones_ini; int semilla; short estado; Unidad unidades []= { { 1.28, 368.0, 22770.0, 0.0, 0.0, 40.0, 160.0, 11, 0, 40.0, 40.0}, { 0.5635, 158.5,33830.0, 0.0, 0.0, 62.0, 248.0, 11, 0, 62.0, 62.0}, { 0.5635, 158.5,33830.0, 0.0, 0.0, 62.0, 248.0, 11, 0, 62.0, 62.0}, { 24.92, 1154.0,13330.0, 0.0, 0.0, 7.0, 27.0, 8, 0, 7.0, 7.0}, { 19.45, 1204.0,16680.0, 0.0, 0.0, 7.0, 26.0, 8, 0, 7.0, 7.0}, { 21.16, 1190.0,16660.0, 0.0, 0.0, 8.0, 30.0, 8, 0, 8.0, 8.0}, { 0.02908, 467.7,6957.0, 0.0, 0.0, 122.0, 489.0, 12, 0,260.0, 320.0} }; real modelo_cc[][5]= { {0.04528,489.0,-0.07852, 519.3, 245.0} }; P_cruza=0.8; P_mutacion=0.01; estado=0; despedidas(); if (argc > 1) {semilla = strtoul(argv[1],NULL,10); srand(semilla);} else { srand(time(NULL));} P_sol=crea_vector_real(Us); iteraciones_ini=75; iteraciones=iteraciones_ini; veces=-1; pob_ini2(poblacion_ini, unidades, Tam_pob, AG); evaluacion2(poblacion_ini, aptitudes, unidades, modelo_cc); do { for (i=1; i<=iteraciones; i++) { selec_torneo2(poblacion_ini, aptitudes, ganador); hijos2(poblacion_ini,ganador,nueva_poblacion,unidades,P_cruza, P_mutacion); evaluacion2(nueva_poblacion, aptitudes, unidades, modelo_cc); for (j=0; j<Tam_pob;j++) { for (k=0; k< Us; k++) { poblacion_ini[j][k]=nueva_poblacion[j][k]; nueva_poblacion[j][k]=0;} } } estado=busqueda_local(poblacion_ini, aptitudes, unidades, modelo_cc,P_sol); iteraciones=1; veces++; } while(estado==0); for (i=0;i<Us;i++) printf("P%d: %f\n",i,P_sol[i]); printf(" %u generaciones\n",iteraciones_ini+veces*iteraciones); salir(); return (0); } Algoritmo de Recocido Simulado (ARS). “sa.c”. #include "ag.h" int main(int argc,char **argv) { AII-2 Unidad unidades []= { { 1.28, 368.0, 22770.0, 0.0, 0.0, 40.0, 160.0, 11, 0, 40.0, 40.0}, { 0.5635, 158.5,33830.0, 0.0, 0.0, 62.0, 248.0, 11, 0, 62.0, 62.0}, { 0.5635, 158.5,33830.0, 0.0, 0.0, 62.0, 248.0, 11, 0, 62.0, 62.0}, { 24.92, 1154.0,13330.0, 0.0, 0.0, 7.0, 27.0, 8, 0, 7.0, 7.0}, { 19.45, 1204.0,16680.0, 0.0, 0.0, 7.0, 26.0, 8, 0, 7.0, 7.0}, { 21.16, 1190.0,16660.0, 0.0, 0.0, 8.0, 30.0, 8, 0, 8.0, 8.0}, { 0.02908, 467.7,6957.0, 0.0, 0.0, 122.0, 489.0, 12, 0,260.0, 320.0} }; real modelo_cc[][5]= { {0.04528,489.0,-0.07852, 519.3, 245.0} }; int i,j,k,desplazamiento, U_selec,tam,Pi_cod[Us]; real adonde,*vecino,costo_mejor, costo_vecino, Pmin_aux[Us], Pmax_aux[Us], P[Us]; int sol_mej, semilla; real Tot_pot_min, *fitness, movimiento_max, dif_costo,max_baja,max_sube,alfa_RS; double aleatorio, T,boltzman; char sol_ini[60]; FILE *desc_r; if (argc > 1) {semilla = strtoul(argv[1],NULL,10); srand(semilla);} else { srand(time(NULL));} strcpy(sol_ini,"/home/benjamin/tesis/bin/sol_ini.dat"); pob_ini(sol_ini, unidades, 1, RS); /*pob_ini_fc(sol_ini, unidades, modelo_cc, 1, RS);/*arreglar para que escriba reales*/ if ((desc_r=fopen(sol_ini,"r"))==NULL) abort(); for (j=0;j<Us;j++){ /*fscanf(desc_r,"%u", &Pi_cod[j]); P[j]=decodifica(Pi_cod[j], &unidades[j]);}*/ fscanf(desc_r,"%f", &P[j]);} i=0; sol_mej=0; T=500.0; /*mdc=500 Para caso 7 unidades, divisor 1000*/ /*T=50;/*mdc/4=50 para caso 36 unidades, divisor 10000;*/ /*T=50; /*mdc=25,50 divisor 10 para caso 3 Us Punto valvula*/ alfa_RS=0.9;/*0.95 para caso 36 Us; 0.9 para 7u y 3u*/ vecino=crea_vector_real(Us); U_selec=rand_int(0,Us-1); for (i=0; i< Us;i++){ Pmin_aux[i] = unidades[i].Pmin; Pmax_aux[i] = unidades[i].Pmax; if (unidades[i].hay_zm){/* si tiene zona muerta, decide en que region operara */ if (P[i]>unidades[i].ini_zm) /*arriba zona muerta */ Pmin_aux[i] = unidades[i].fin_zm; else /*abajo zona muerta */ Pmax_aux[i]=unidades[i].ini_zm; } } costo_mejor=costo_tot(P, unidades,modelo_cc); adonde=baja; U_selec=rand_int(0,Us-1); movimiento_max=(P[U_selec]-Pmin_aux[U_selec]); k=0; while (T>10.0/pot_uni) { while (k<K0)/*K0: nùmero de iteraciones o transiciones generadas por el algoritmo de generacion)*/ { vecino=vecindad(P,Pmin_aux,Pmax_aux,movimiento_max,U_selec,adonde);/*solucion vecina*/ costo_vecino=costo_tot(vecino, unidades,modelo_cc); dif_costo=costo_mejor-costo_vecino; if (dif_costo>0.0) { AII-3 copia_vector_real(P,vecino,Us); costo_mejor=costo_vecino; sol_mej++;} else { aleatorio=(double)rand_real(); boltzman=exp(1.0*(double)dif_costo/T); if (aleatorio< boltzman){ copia_vector_real(P,vecino,Us); costo_mejor=costo_vecino;} } /*printf("%f\n",costo_mejor);*/ k=k+1; U_selec=rand_int(0,Us-1); if (rand_real()>0.5) {adonde=sube; movimiento_max=(Pmax_aux[U_selec]-P[U_selec]);} else {adonde=baja; movimiento_max=(P[U_selec]-Pmin_aux[U_selec]);} } T=alfa_RS*T; k=0; } printf("# soluciones vecinas mejores: %u\n",sol_mej); for (i=0;i<Us;i++) printf("P%d: %f\n",i,P[i]); corta_vector_real(vecino); return(0); } Algoritmo GRASP . grasp.c #include "ag.h" int main(int argc,char **argv) { int Nmax_itr,mejores,i, semilla; real *Psol, *Pmejor,Pmin_aux[Us], Pmax_aux[Us]; real fcosto_mejor, fcosto; Unidad unidades []= { { 1.28, 368.0, 22770.0, 0.0, 0.0, 40.0, 160.0, 11, 0, 40.0, 40.0}, { 0.5635, 158.5,33830.0, 0.0, 0.0, 62.0, 248.0, 11, 0, 62.0, 62.0}, { 0.5635, 158.5,33830.0, 0.0, 0.0, 62.0, 248.0, 11, 0, 62.0, 62.0}, { 24.92, 1154.0,13330.0, 0.0, 0.0, 7.0, 27.0, 8, 0, 7.0, 7.0}, { 19.45, 1204.0,16680.0, 0.0, 0.0, 7.0, 26.0, 8, 0, 7.0, 7.0}, { 21.16, 1190.0,16660.0, 0.0, 0.0, 8.0, 30.0, 8, 0, 8.0, 8.0}, { 0.02908, 467.7,6957.0, 0.0, 0.0, 122.0, 489.0, 12, 0,260.0, 320.0} }; real modelo_cc[][5]= { {0.04528,489.0,-0.07852, 519.3, 245.0} }; Nmax_itr=300; mejores=0; fcosto_mejor=9999999.; Psol=crea_vector_real(Us); Pmejor=crea_vector_real(Us); if (argc > 1) {semilla = strtoul(argv[1],NULL,10); srand(semilla);} else { srand(time(NULL));} for (i=0;i<=Nmax_itr;i++){ fase_constructora(unidades, modelo_cc, Psol, Pmin_aux, Pmax_aux); fase_BL(unidades, modelo_cc, Psol, Pmin_aux, Pmax_aux); AII-4 fcosto=costo_tot(Psol, unidades, modelo_cc); /*printf("%f\n",fcosto);*/ if (fcosto<fcosto_mejor){ fcosto_mejor=fcosto; copia_vector_real(Pmejor,Psol,Us); mejores++; } } for (i=0;i<Us;i++) printf("V%d: %f\n",i,Pmejor[i]); printf("# soluciones mejores: %u\n",mejores); corta_vector_real(Psol); corta_vector_real(Pmejor); salir(); return (0); } Algoritmo de búsqueda local . “BL.c”. #include "ag.h" /*Busca mejor solucion del AG y hace una busqueda en sus vecindades */ short busqueda_local(short poblacion[][Us],real evaluaciones[][2],Unidad *unidades,real modelo_cc[][5], real *P_sol) { int i,k, U_selec,*indices; real *P,adonde,*vecino, costo_mejor, costo_vecino, Pmin_aux[Us], Pmax_aux[Us]; short sol_mej,mejor; real movimiento_max, dif_costo,dp[Tam_pob]; indices=crea_vector_int(Tam_pob); P=crea_vector_real(Us); for (i=0;i<Tam_pob;i++) { dp[i]= evaluaciones[i][1]; indices[i]=i; } ordena(indices,dp,1,Tam_pob);/*ordena dp, indices guarda las posiciones originales;*/ /*mejor=0; while ((mejor<Tam_pob)&&(dp[mejor]>=0.1)) { mejor++;}*/ if (dp[0]>=0.1) return(0); else { /*printf("Encontre uno\n");*/ for (i=0;i<Us;i++) { P[i]=decodifica(poblacion[indices[0]][i],&unidades[i]); /*printf("V%d: %f\n",i,P[i]);*/} k=0; sol_mej=0; vecino=crea_vector_real(Us); for (i=0; i< Us;i++){ Pmin_aux[i] = unidades[i].Pmin; Pmax_aux[i] = unidades[i].Pmax; if (unidades[i].hay_zm){/* si tiene zona muerta, decide en que region operara */ if (P[i]>unidades[i].ini_zm) /*arriba zona muerta */ Pmin_aux[i] = unidades[i].fin_zm; else /*abajo zona muerta */ Pmax_aux[i]=unidades[i].ini_zm; } } costo_mejor=costo_tot(P, unidades,modelo_cc); adonde=baja; U_selec=rand_int(0,Us-1); movimiento_max=(P[U_selec]-Pmin_aux[U_selec]); P[Us-1]=P[Us-1]+ DP_NA(P); while (k<K0)/*K0: numero de transiciones del algoritmo de generacion)*/ AII-5 { vecino=vecindad(P,Pmin_aux,Pmax_aux,movimiento_max,U_selec,adonde);/*solucion vecina*/ costo_vecino=costo_tot(vecino, unidades,modelo_cc); dif_costo=costo_mejor-costo_vecino; if (dif_costo>0.0){ copia_vector_real(P,vecino,Us); costo_mejor=costo_vecino; /*for (i=0;i<Us;i++) printf("V%d: %f\n",i,vecino[i]); printf("costoV: %f\n",costo_vecino);*/ sol_mej++;} k=k+1; U_selec=rand_int(0,Us-1); if (rand_real()>0.5) {adonde=sube; movimiento_max=(Pmax_aux[U_selec]-P[U_selec]);} /*max_sube*/ else {adonde=baja; movimiento_max=(P[U_selec]-Pmin_aux[U_selec]);} /*max_baja*/ } copia_vector_real(P_sol,P,Us); /*printf("# soluciones vecinas mejores: %u\n",sol_mej);*/ /*corta_vector_real(vecino); corta_vector_real(P); corta_vector_short(indices);*/ return(1); } } “pob_ini_nf2.c”. /************************************************************************************ * Programa pob_ini_nf2: Genera aleatoriamente una poblacion inicial con soluciones * * no factibles. Cada cromosoma consta de N enteros cortos, que representan la * * potencia de cada unidad generadora * ************************************************************************************/ #include "ag.h" void pob_ini2(short poblacion[][Us], Unidad *unidades, int Total,bool algortimo) { short i,j; for (j=0;j<Total;j++) { for (i=0;i<Us;i++) { poblacion[j][i] = (short)rand_int(0,(int)pow(2.0,unidades[i].L)-1); if (unidades[i].hay_zm){/* si tiene zona muerta, decide en que region operara */ if (rand_real()>0.5) /*arriba zona muerta */ poblacion[j][i] = poblacion[j][i]+ (short)pow(2.0,unidades[i].L); } } } } “pob_ini_fc.c”. /************************************************************************************ * Programa pob_ini_fc: Genera poblacion inicial con soluciones factibles a partir * * de la fase constructora del GRASP * ************************************************************************************/ #include "ag.h" void pob_ini_fc(char *archivo, Unidad *unidades, real modelo_cc[][5], int Total, bool algoritmo_G) { short i,j; AII-6 short P_cod; FILE *desc; real P_sol[Us],Pmin_aux[Us], Pmax_aux[Us]; desc=fopen(archivo,"w"); for (j=0;j<Total;j++) { fase_constructora(unidades, modelo_cc, P_sol, Pmin_aux, Pmax_aux); for (i=0;i<Us;i++) { if (!algoritmo_G) {fprintf(desc,"%f ",P_sol[i]);} else {P_cod = codifica(P_sol[i], &unidades[i]); fprintf(desc,"%u ",P_cod);} } fprintf(desc,"\n"); } fclose(desc); } “pob_ini.c”. /************************************************************************************ * Programa pob_ini: Genera poblacion inicial con soluciones factibles por algoritmo * * de satisfaccion de restricciones. * ************************************************************************************/ #include "ag.h" void nuevos_limites(int , real *, real *, real *, real *, real); void pob_ini(char *archivo, Unidad *unidades, int Total, bool algoritmo) { short i,j; short P_cod; FILE *desc; real dr,P_real,NPmin,NPmax; real Paux_min [Us], Paux_max[Us]; desc=fopen(archivo,"w"); for (j=0;j<Total;j++) { dr= Demanda; for (i=0; i< Us;i++){ Paux_min[i] = unidades[i].Pmin; Paux_max[i] = unidades[i].Pmax; if (unidades[i].hay_zm){/* si tiene zona muerta, decide en que region operara */ if (rand_real()>0.5) /*arriba zona muerta */ Paux_min[i] = unidades[i].fin_zm; else /*abajo zona muerta */ Paux_max[i]=unidades[i].ini_zm; } } for (i=0;i<Us-1;i++) { nuevos_limites(i, Paux_min, Paux_max, &NPmin, &NPmax, dr); P_real = NPmin+rand_real()*(NPmax-NPmin); if (algoritmo) {P_cod = codifica(P_real, &unidades[i]); fprintf(desc,"%u ",P_cod);} else {fprintf(desc,"%f ",P_real);} dr = dr-P_real; } if (algoritmo) {P_cod = codifica(dr, &unidades[i]); fprintf(desc,"%u ",P_cod);} else {fprintf(desc,"%f ",dr);} AII-7 fprintf(desc,"\n"); } fclose(desc); } /* Calcula los nuevos limites de una unidad, de acuerdo con las asignaciones de potencia */ void nuevos_limites(int unidad, real *Pmin,real *Pmax, real *NLmin,real *NLmax ,real dem) { real suma_min, suma_max; int j; suma_min= 0.0; suma_max= 0.0; for (j=unidad+1; j< Us;j++) { suma_min = suma_min + Pmin[j]; suma_max = suma_max + Pmax[j]; } *NLmax = dem - suma_min; *NLmin = dem - suma_max; if (*NLmax>Pmax[unidad]) *NLmax=Pmax[unidad]; if (*NLmin<Pmin[unidad]) *NLmin=Pmin[unidad]; } “evaluacion2.c”. #include "ag.h" void evaluacion2(short poblacion[][Us], real aptitudes[][2], Unidad *unidades, real modelo_cc[][5]) { int i,j; int Pi_cod; real P_ini[Us], fc[Tam_pob], desbalance[Tam_pob]; real fct, fitness, mejor_fitness,suma_fitness,desbalance_mf,PF_zm[Tam_pob]; bool u_zm[]= {0,0,0,0,0,0,1}; /*bool u_zm[]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};*/ /* cuando se codifica zona muerta, poner u_zm en ceros y unidades.hay_zm = 1 en U's con zm */ /* cuando se trata por penalizacion, poner u_zm=1 y unidades.hay_zm = 0 en U's con zm */ for (i=0;i<Tam_pob;i++) { PF_zm[i]=0.0; for (j=0;j<Us;j++) { P_ini[j]=decodifica((short)poblacion[i][j], &unidades[j]); if (u_zm[j]){ if ((P_ini[j] > unidades[j].ini_zm) && (P_ini[j] < unidades[j].fin_zm)) PF_zm[i]=0.1; } } fc[i]=costo_tot(P_ini, unidades, modelo_cc); desbalance[i]=DP(P_ini); } mejor_fitness=9999999999.; suma_fitness=0.; for (i=0;i<Tam_pob;i++) { fitness=fc[i]+PF*desbalance[i]+PF_zm[i]*fc[i]; if (fitness<mejor_fitness) { mejor_fitness=fitness; desbalance_mf=desbalance[i];} suma_fitness=suma_fitness+fitness; aptitudes[i][0]=fitness; aptitudes[i][1]=desbalance[i]; } AII-8 printf("%f %f %f\n",mejor_fitness, suma_fitness/(real)Tam_pob,desbalance_mf); } “selec_torneo2.c”. /******************************************************************************* * Crea una poblacion de padres para la siguiente generacion. * * Escoge de forma aleatoria a 2 individuos de la poblacion y selecciona al de * * mejor aptitud * *******************************************************************************/ #include "ag.h" void selec_torneo2(short poblacion[][Us], real aptitudes[][2], short *ganador) { int *indices, tam, competidor1, competidor2,torneos; real fitness[Tam_pob]; int i,j; indices=crea_vector_int(Tam_pob); /* guarda la posicion original de los individuos */ torneos=Tam_pob; for (i=0;i<Tam_pob;i++) /*lee aptitudes e inicializa indices*/ { fitness[i]=aptitudes[i][0]; indices[i]=i;} /*elitismo*/ if (elitismo) torneos=torneos-1; /*elige aleatoriamente elementos a competir y selecciona a los ganadores*/ for (i=0;i<torneos;i++)/* -1 por elitismo */ { competidor1=rand_int(0,Tam_pob-1); competidor2=rand_int(0,Tam_pob-1); if (fitness[competidor1]<fitness[competidor2]) ganador[i]=competidor1; else ganador[i]= competidor2; } /*Elitismo, escribe al final al mejor individuo*/ if (elitismo) { ordena(indices,fitness,1,Tam_pob); ganador[i]=indices[0]; } } “hijos2.c”. /**************************************************************************************** * Crea a la siguiente generacion a partir de la poblacion de padres. A esta les aplica * * los operadores de cruza y mutacion * ***************************************************************************************** #include "ag.h" void hijos2(short poblacion[][Us],short ganador[], short nueva_poblacion[][Us], Unidad *unidades, real Pcruza, real Pmuta) { int i,j,tot_hijos,long_cadena; short **ap_pob, **ap_nuevapob; long_cadena=0; /*for (i=0;i<Us;i++) long_cadena= long_cadena+unidades[i].L+unidades[i].hay_zm;*/ tot_hijos=Tam_pob; /*elitismo*/ if (elitismo) AII-9 tot_hijos=tot_hijos-2; for (i=0;i<tot_hijos;i=i+2) { cruza_1(&poblacion[ganador[i]][0], &poblacion[ganador[i+1]][0], &nueva_poblacion[i][0], &nueva_poblacion[i+1][0], Pcruza); for (j=0;j<Us;j++) { nueva_poblacion[i][j] = mutacion(nueva_poblacion[i][j],unidades[j].L,unidades[j].hay_zm,Pmuta); nueva_poblacion[i+1][j] = mutacion(nueva_poblacion[i+1][j],unidades[j].L,unidades[j].hay_zm,Pmuta); } } /*ELITISMO, pasan a la siguiente generacion 2 ultimos individuos, el ultimo es el mejor individuo*/ if (elitismo){ for (i=0;i<Us;i++){ nueva_poblacion[tot_hijos][i]=poblacion[ganador[tot_hijos]][i]; nueva_poblacion[tot_hijos+1][i]=poblacion[ganador[tot_hijos+1]][i];} } } Encabezados “ag.h” /****************************************************************************** * Contiene los encabezados de los procedimientos, tipos de datos, * * definicion de valores de parametros * ******************************************************************************/ /* headers requeridos */ #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <math.h> #include <fcntl.h> #include "aleatorio.h" #include "salir.h" /*Parametros generales*/ #define Demanda 700.0 #define Us 7 #define Nterm 6 #define Ncc 1 #define AG 1 #define RS 0 #define pot_uni 1000.0 /*RS: 1000 7u*/ /*10000.0 36u*/ /* 100.0 para 3u pv*/ /*Parametros AG */ #define Tam_pob 40 /*numero par*/ #define PF 2.500 /*7u (2.5), 36u (.0563), 25 (3upv) */ #define elitismo 1 /*Parametros BL*/ #define K0 500 #define sube 1.0 #define baja -1.0 /*Parametros GRASP*/ #define alfa 0.5 struct generador { real coef_a; real coef_b; real coef_c; real coef_e; real coef_f; real Pmin; real Pmax; int L; AII-10 bool hay_zm; real ini_zm; real fin_zm; /*bool es_CC;*/ }; struct RT_CC { real puntos [10][2]; }; typedef struct generador Unidad; typedef struct RT_CC Reg_term_CC; /* Prototipos de las funciones */ void pob_ini(char *, Unidad *, int, bool); void pob_ini2(short [Tam_pob][Us], Unidad *, int, bool); void pob_ini_fc(char *, Unidad *, real [][5], int ,bool ); void evaluacion(char *, char *, Unidad *, real [][5]); void evaluacion2(short [Tam_pob][Us], real [Tam_pob][2], Unidad *, real [][5]); void selec_torneo(char *, char *, char *); void selec_torneo2(short [][Us], real [][2], short *); void hijos(char *, char *, Unidad *, real , real ); void hijos2(short [][Us],short *, short [][Us], Unidad *, real, real); short busqueda_local(short [][Us],real [][2],Unidad *,real [][5], real *); real *vecindad(real *,real *, real *,real , int , real ); void fase_constructora(const Unidad *, real [][5], real *, real *, real *); void fase_BL(const Unidad *, real [][5], real *, real *, real *); void ruleta(int *, real *,int *); void error1(void); void errorn(void); void error_opcion(void); int cuad(int); short complemento(short); short vector_bits_a_short(short *,int); short *short_a_vector_bits(short,int); short mutacion(short, int, bool, real); void cruza(short *, short *, short *, short *, const Unidad *, int , real ); void cruza_1(short *, short *, short *, short *, real ); void copia_normal(short *, short *, short *, short *, int , int ); void copia_cruzado(short *, short *, short *, short *, int , int ); real decodifica(short , const Unidad *); short codifica(real , const Unidad *); real fx(real *,real [][3]); void f_recta(real ,real ,real ,real , real *, real *); real DP(real *); real DP_NA(real *); real costo_tot(real *, const Unidad *, real [][5]); int subir(real *, int , real , real *, real *, short *); int bajar(real *, int , real , real *, real *, short *); real fitnessK(real *,const Unidad *, real [][5]); void estandariza(real *); int particion_vector(int *, real *, short, short); void ordena(int *, real *, int , int); void N_lim(real *, real *, real *, real * , real ,int *, int ); Utilerias “Util.c” #include "ag.h" /********** Calcula el cuadrado de un numero entero **************/ int cuad(int x) { return (x^2); AII-11 } real fx(real *P,real modelo_term[][3]) { real Fct; int i; Fct= 0; for (i=0;i<Nterm;i++) { Fct=Fct+modelo_term[i][0]*P[i]*P[i]+modelo_term[i][1]*P[i]+modelo_term[i][2]; } return (Fct); } real DP(real *P) { int i; real suma_P, desbalance; suma_P=0; for (i=0;i<Us;i++) { suma_P=suma_P+P[i]; } desbalance=absol(Demanda-suma_P); return (desbalance); } real DP_NA(real *P) { int i; real suma_P, desbalance; suma_P=0; for (i=0;i<Us;i++) { suma_P=suma_P+P[i]; } desbalance=Demanda-suma_P; return (desbalance); } void f_recta(real x1,real y1,real x2,real y2, real *m, real *b) { *m = (y2-y1)/(x2-x1); *b = y1-*m*x1; } real costo_tot(real *P, const Unidad *unidades, real modelo_cc[][5]) { /*El arreglo model_cc tiene los parametros de las 2 rectas m,b, y el punto P2 */ /* P2 es el punto donde cambia la pendiente o punto comun a las dos rectas)*/ /* modelo_cc[i,j] = {m1,b1,m2,b2,P2}*/ real costo_cc,costo_term,costo; int i; costo_cc=0.; costo_term= 0.; costo=0.; for (i=0;i< Nterm;i++) { /*costo_term=costo_term+(unidades[i].coef_a*P[i]*P[i]+unidades[i].coef_b*P[i]+unidades[i].coef_c)/pot_uni;*/ costo_term=costo_term+(unidades[i].coef_a*P[i]*P[i]+unidades[i].coef_b*P[i]+unidades[i].coef_c+absol(unidades[i].coef_e*si n(unidades[i].coef_f*(unidades[i].Pmin-P[i]))))/pot_uni; } AII-12 for (i=0;i < Ncc; i++) { if (P[Nterm+i]<=modelo_cc[i][4]) /*P > P2*/ costo_cc= costo_cc+(P[Nterm+i]*(modelo_cc[i][0]*P[Nterm+i]+modelo_cc[i][1]))/pot_uni; /* P(m1 P + b1) */ else costo_cc= costo_cc+(P[Nterm+i]*(modelo_cc[i][2]*P[Nterm+i]+modelo_cc[i][3]))/pot_uni; /* P(m2 P + b2) */ } costo=costo_term+costo_cc; return costo; } int subir(real *Pot, int U, real cantidad, real *max_baja, real *max_sube,short *idx) { int i; real desp_x,x; /*if (cantidad>max_sube[U]) x=max_sube[U]; else x=cantidad;*/ x=cantidad; if (x>0.1) { desp_x=rand_real() * x; x=desp_x; /*printf("U%d sube:%f MW\n",U,desp_x);*/ Pot[idx[0]]=Pot[idx[0]]+sube*desp_x; for (i=1;i<Us-1;i++) { desp_x=rand_real() * x; if (desp_x>max_baja[idx[i]]) desp_x=max_baja[idx[i]]; Pot[idx[i]]=Pot[idx[i]]+baja*desp_x; x=x-desp_x; if (x<0.01) break; } if (x>max_baja[idx[Us-1]]) return 0; else { Pot[idx[Us-1]]=Pot[idx[Us-1]]+baja*x; return 1;} } return 0; } int bajar(real *Pot, int U, real cantidad, real *max_baja, real *max_sube, short *idx) { int i; real desp_x, x; /*if (cantidad>max_baja[U]) x=max_baja[U]; else*/ x=cantidad; if (x>0.01) /*basta conque x<>0), se supone que no puede tomar valores negativos)*/ { desp_x=rand_real() * x; x=desp_x; /*printf("U%d baja:%f MW\n",U,desp_x);*/ Pot[idx[0]]=Pot[idx[0]]+baja*desp_x; for (i=1;i<Us-1;i++){ desp_x=rand_real() * x; if (desp_x>max_sube[idx[i]]) desp_x=max_sube[idx[i]]; Pot[idx[i]]=Pot[idx[i]]+sube*desp_x; x=x-desp_x; if (x<0.01) break; } AII-13 if (x>max_sube[idx[Us-1]]) return 0; else {Pot[idx[Us-1]]=Pot[idx[Us-1]]+sube*x; return 1;} } return 0; } real fitnessK(real *P_sol,const Unidad *unidades, real modelo_cc[][5]) { real fitness,costo_FPK; int i; real suma_P; fitness= 0.; suma_P=0; for (i=1;i<=Us;i++) { suma_P=suma_P+P_sol[i]; } costo_FPK=absol(PF*(suma_P-Demanda)); /*PF factor de penalizacion K*/ fitness=costo_tot(P_sol,unidades,modelo_cc)+costo_FPK; return (fitness); } real *vecindad(real *Psol,real *Pmin, real *Pmax,real tam_mov, int U_selec, real adonde) { int i,exito,contador; real *P, *incr_max,*decr_max; short *indice ; P=crea_vector_real(Us); incr_max=crea_vector_real(Us); decr_max=crea_vector_real(Us); copia_vector_real(P,Psol,Us); indice=crea_vector_short(Us); contador=0; do { for (i=0;i<Us;i++) { indice[i]=i; incr_max[i]=Pmax[i]-P[i]; decr_max[i]=P[i]-Pmin[i]; } indice[0]=U_selec; indice[U_selec]=0; if (adonde==sube) exito=subir(P, U_selec, tam_mov, decr_max, incr_max, indice); else exito=bajar(P, U_selec, tam_mov, decr_max, incr_max, indice); if (exito==0) {copia_vector_real(P,Psol,Us); contador++;} }while ((exito==0) && (contador<10)); corta_vector_short(indice); corta_vector_real(incr_max); corta_vector_real(decr_max); return (P); } void ruleta(int *indices, real *fitness, int *lista_seleccion) { int i,j; real ref_aleat, *fitness_acum, suma, min, max; /*fitness normalizado y acumulado */ AII-14 fitness_acum=crea_vector_real(Tam_pob); min=min_vector(fitness,Tam_pob); max=max_vector(fitness,Tam_pob); /*Seleccion por jerarquìa, habilitar si fitness bajo es mejor y deshabilitar (a) */ /*for (i=0;i<Tam_pob;i++) fitness_acum[i]=min+((max-min)*(real)(Tam_pob-i))/(real)(Tam_pob-1);*/ copia_vector_real(fitness_acum,fitness,Tam_pob); /* (a) */ suma=suma_vector(fitness_acum,Tam_pob); for (i=0;i<Tam_pob;i++) fitness_acum[i]=fitness_acum[i]/suma; for (i=1;i<Tam_pob;i++) fitness_acum[i]=fitness_acum[i]+fitness_acum[i-1]; /*seleccion por ruleta*/ srand( (int)suma ); for (j=0;j<Tam_pob;j++) { ref_aleat=rand_real(); if (j==0) printf("random: %f\n",ref_aleat); for (i=0;i<Tam_pob;i++) { if (fitness_acum[i]>ref_aleat) { lista_seleccion[j]=indices[i]; break;} } } corta_vector_real(fitness_acum); } short complemento(short bit) { if (bit==0) return 1; else return 0; } /* convierte un vector de bits en un numero entero*/ short vector_bits_a_short(short *bits, int l) { int i; short numero; numero=bits[l-1]; for(i=l-2;i>=0;i--) { numero=numero<<1; numero=numero|bits[i]; } return (numero); } /* guarda cada bit de un entero corto en un vector*/ short *short_a_vector_bits(short numero, int l_subcadena) { int i; short *bits; bits=crea_vector_short(l_subcadena); for (i=0;i<l_subcadena;i++) { bits[i]=numero&1; numero=numero>>1; } return (bits); } short mutacion(short cromosoma, int l_subcadena, bool hay_zm,real P_mutacion) AII-15 { short aux,*bits; int i; short prueba; /*l_subcadena no incluye bit de zona muerta */ bits=short_a_vector_bits(cromosoma, l_subcadena+hay_zm);/*tambien puede mutar bit_zm*/ for(i=0;i<l_subcadena;i++){ if (rand_real()<P_mutacion) bits[i]=complemento(bits[i]);} aux=vector_bits_a_short(bits,l_subcadena+hay_zm); corta_vector_short(bits); return aux; } /* cruza 2 individuos para generar 2 hijos; punto_cruza:aleatorio*/ /* el punto de cruza es a nivel de bits de la cadena completa*/ /* */ void cruza(short *P1, short *P2, short *h1, short *h2, const Unidad *unidades, int l_tot, real Pcruza) { short *upper, *lower, copiador_alto, copiador_bajo; int i, punto_cruza, unidad, modulo,bits; real aleatorio; unidad=-1; bits=0; aleatorio=rand_real(); if (aleatorio<Pcruza) { punto_cruza=rand_int(1,l_tot); do { unidad = unidad + 1; bits=bits+unidades[unidad].L+unidades[unidad].hay_zm; }while (bits<punto_cruza); modulo=bits-punto_cruza; /*crea copiadores de bits de acuerdo a punto de cruza*/ upper=crea_vector_short(unidades[unidad].L+unidades[unidad].hay_zm); lower=crea_vector_short(unidades[unidad].L+unidades[unidad].hay_zm); for (i=0;i<modulo;i++){ upper[i]=0; lower[i]=1;} for (i=modulo;i<(unidades[unidad].L+unidades[unidad].hay_zm);i++){ upper[i]=1; lower[i]=0;} copiador_alto=vector_bits_a_short(upper,unidades[unidad].L+unidades[unidad].hay_zm); copiador_bajo=vector_bits_a_short(lower,unidades[unidad].L+unidades[unidad].hay_zm); for (i=0;i<unidad;i++) /*unidad-1*/ {h1[i]=P1[i]; h2[i]=P2[i];} h1[unidad]=P1[unidad]&copiador_alto|P2[unidad]&copiador_bajo; h2[unidad]=P2[unidad]&copiador_alto|P1[unidad]&copiador_bajo; for (i=unidad+1;i<Us;i++)/*unidad*/ {h1[i]=P2[i]; h2[i]=P1[i];} corta_vector_short(upper); corta_vector_short(lower); } else { copia_vector_short(h1,P1,Us); copia_vector_short(h2,P2,Us); } } /* cruza 2 individuos para generar 2 hijos; 2 puntos de cruza aleatorios*/ /* se combinan unidades */ /* zona muerta se pasa de padre a hijo */ void cruza_1(short *P1, short *P2, short *h1, short *h2, real Pcruza) { real aleatorio; int pc_1, pc_2, aux; AII-16 aleatorio=rand_real(); if (aleatorio<Pcruza) { pc_1=rand_int(0,Us-1); pc_2=rand_int(0,Us-1); if (pc_2<pc_1){ aux=pc_1; pc_1=pc_2; pc_2=aux;} copia_normal(P1, P2, h1, h2, 0, pc_1); copia_cruzado(P1, P2, h1, h2, pc_1+1, pc_2); copia_normal(P1, P2, h1, h2, pc_2+1, Us-1); } else { copia_vector_short(h1,P1,Us); copia_vector_short(h2,P2,Us); } } void copia_normal(short *P1, short *P2, short *h1, short *h2, int desde, int hasta) { int i; for (i=desde;i<=hasta;i++){ h1[i]=P1[i]; h2[i]=P2[i];} } void copia_cruzado(short *P1, short *P2, short *h1, short *h2, int desde, int hasta) { int i; for (i=desde;i<=hasta;i++){ h1[i]=P2[i]; h2[i]=P1[i];} } /****decodifica: decodifica valor entero corto a valor real de Potencia **************/ real decodifica(short x, const Unidad *unidades) { real valor, Pmin_aux, Pmax_aux; short suma, bit_1; suma=0; Pmin_aux= unidades->Pmin; Pmax_aux= unidades->Pmax; bit_1 = (short)(pow(2.0,(double)unidades->L)); if (unidades->hay_zm) {/*revisa si hay zona muerta*/ if (x >= bit_1){ Pmin_aux = unidades->fin_zm;/* arriba zona muerta */ suma =bit_1;} else {Pmax_aux = unidades->ini_zm;} /* valor abajo de zona muerta */ } x=x-suma; valor=Pmin_aux+((real)x*(Pmax_aux-Pmin_aux))/((pow(2.0,(double)unidades->L)-1.0)); return (valor); } /****codifica: codifica valor real de Potencia a entero corto **************/ short codifica(real valor, const Unidad *unidades) { short x,suma; real Pmin_aux, Pmax_aux; suma=0; Pmin_aux= unidades->Pmin; AII-17 Pmax_aux= unidades->Pmax; if (unidades->hay_zm) {/*revisa si hay zona muerta*/ if (valor >= unidades->fin_zm){ Pmin_aux = unidades->fin_zm; suma =(short)(pow(2.0,(double)unidades->L));}/*indicara zona muerta */ else {Pmax_aux = unidades->ini_zm;} } x = (short)((valor-Pmin_aux)*(pow(2.0,(double)unidades->L)-1.0)/(Pmax_aux-Pmin_aux)); x= x+suma;/* si hay zona muerta, pone bit L en 1, con el valor de suma */ return (x); } void estandariza(real *fi) { int i,negativo; real suma, suma_abs, promedio_abs, min_abs; /* l=long_vector(fi);*/ negativo=0; /*falso */ /* verifica si hay un numero negativo*/ for (i=0;i<Tam_pob;i++) { if (fi[i]<0.0) { negativo=1; /*verdadero*/ break; } } /*estandariza el vector si hay valores negativos */ if (negativo==1) { suma_abs=suma_abs_vector(fi,Tam_pob); promedio_abs=suma_abs/(real)Tam_pob; min_abs=minimo_abs_vector(fi,Tam_pob); for (i=0;i<Tam_pob;i++) fi[i]=fi[i]+promedio_abs+min_abs; } } int particion_vector(int *subindices,real *subvector, short pos_ini, short pos_fin) { short i, menores , mayores, tam, val_ind, *aux_ind ; short pos_pivote; real *vector_aux, val_pivote; menores=0; mayores=0; tam=pos_fin-pos_ini+1;/* indice de subvector: 0..tam*/ vector_aux=crea_vector_real(tam); aux_ind=crea_vector_short(tam);/** añadido*/ pos_pivote=pos_ini-1;/*-1 porque indice del vector comienza en 0 */ val_pivote=subvector[pos_pivote]; /* se toma como pivote al primer elemento */ val_ind=subindices[pos_pivote];/** añadido*/ for (i=pos_ini;i<pos_fin;i++) { if (subvector[i]<val_pivote) { vector_aux[menores]=subvector[i]; aux_ind[menores] =subindices[i];/** añadido*/ menores++; } else { vector_aux[pos_fin-pos_ini-mayores]=subvector[i]; aux_ind[pos_fin-pos_ini-mayores]=subindices[i];/** añadido*/ AII-18 mayores++; } } /* se copia vector_aux en subvector con particion de acuerdo a pivote*/ pos_pivote=pos_ini+menores; vector_aux[menores]=val_pivote; aux_ind[menores]=val_ind;/** añadido*/ for (i=pos_ini-1;i<pos_fin;i++) {subvector[i]=vector_aux[i-pos_ini+1]; subindices[i]=aux_ind[i-pos_ini+1];/** añadido*/} corta_vector_real(vector_aux); corta_vector_short(aux_ind); return pos_pivote; } void ordena(int *indices, real *vector, int pos_ini, int pos_fin) { int pivote; if (pos_fin>pos_ini) { pivote=particion_vector(indices,vector, pos_ini, pos_fin); ordena(indices,vector, pos_ini, pivote-1); ordena(indices,vector, pivote+1, pos_fin); } } void N_lim(real *Lmin, real *Lmax, real *NLmin, real *NLmax , real dem,int *Id, int n) { real suma_min, suma_max; int i,j; suma_min= 0.0; suma_max= 0.0; for (i=0; i<n; i++) { suma_min = suma_min + Lmin[Id[i]]; suma_max = suma_max + Lmax[Id[i]]; } for (j=0; j< n;j++) { NLmax[Id[j]]= dem - suma_min + Lmin[Id[j]]; NLmin[Id[j]]= dem - suma_max + Lmax[Id[j]]; if (NLmax[Id[j]] > Lmax[Id[j]]) NLmax[Id[j]] = Lmax[Id[j]]; if (NLmin[Id[j]] < Lmin[Id[j]]) NLmin[Id[j]] = Lmin[Id[j]]; } } void fase_constructora(const Unidad *unidades,real modelo_cc[][5],real *Psol, real *Paux_min, real *Paux_max) { int *C,*RCL; int N,tam_RCL,i,j,k,Pos_RCL_selec; real *Paleat,*fmiope,*NLmax,*NLmin; /*real Paux_min [Us], Paux_max[Us]; */ real smin,smax, criterioRCL,dem_resto; C=crea_vector_int(Us); RCL=crea_vector_int(Us); NLmax=crea_vector_real(Us); NLmin=crea_vector_real(Us); Paleat=crea_vector_real(Us); fmiope=crea_vector_real(Us); N=Us; dem_resto=Demanda; AII-19 /*Inicializa conjunto candidato C*/ for (i=0;i<N;i++) C[i]=i; for (i=0; i< Us;i++){ Paux_min[i] = unidades[i].Pmin; Paux_max[i] = unidades[i].Pmax; if (unidades[i].hay_zm){/* si tiene zona muerta, decide en que region operara */ if (rand_real()>0.5) /*arriba zona muerta */ Paux_min[i] = unidades[i].fin_zm; else /*abajo zona muerta */ Paux_max[i]=unidades[i].ini_zm; } } for (k=0;k<Us-1;k++) {/*forma solucion, elemento por elemento*/ smin=9999999.9; smax=0; j=0; N_lim(Paux_min, Paux_max, NLmin, NLmax , dem_resto, C, N); for (i=0;i<N;i++) {/*Potencia aleatoria a conjunto C y funcion miope */ Paleat[C[i]]=rr2(NLmin[C[i]],NLmax[C[i]]); fmiope[C[i]]=(unidades[C[i]].coef_a*Paleat[C[i]]*Paleat[C[i]]+unidades[C[i]].coef_b*Paleat[C[i]]+unidades[C[i]].coef_c+absol(u nidades[C[i]].coef_e*sin(unidades[C[i]].coef_f*(unidades[C[i]].Pmin-Paleat[C[i]]))))/Paleat[C[i]]; if (fmiope[C[i]]<smin) smin=fmiope[C[i]]; if (fmiope[C[i]]>smax) smax=fmiope[C[i]]; } criterioRCL=smin+alfa*(smax-smin); for (i=0;i<N;i++) {/*Crea conjunto RCL Restricted Candidate List*/ if (fmiope[C[i]]<=criterioRCL) { RCL[j]=C[i]; j++;} } tam_RCL=j; Pos_RCL_selec=rand_int(0,tam_RCL-1);/* seleccion aleatoria de RCL */ Psol[RCL[Pos_RCL_selec]]=Paleat[RCL[Pos_RCL_selec]]; dem_resto=dem_resto-Paleat[RCL[Pos_RCL_selec]]; elimina_int_vector(C ,RCL[Pos_RCL_selec],&N);/*actualiza conjunto candidato C */ inicia_vector_int(RCL,tam_RCL); /*inicializa conjunto RCL */ } Psol[C[0]]=dem_resto;/* potencia asignada a ultimo elemento de conjunto C */ } void fase_BL(const Unidad *unidades, real modelo_cc[][5], real *P, real *Pmin_aux, real *Pmax_aux) { real adonde,*vecino, costo_mejor, costo_vecino; int i,k, U_selec; short sol_mej; real Tot_pot_min, Tot_pot_max,movimiento_max, dif_costo,max_baja,max_sube; k=0; sol_mej=0; vecino=crea_vector_real(Us); /* Tot_pot_min=0; Tot_pot_max=0; for (i=0; i< Us; i++){ Tot_pot_min=Tot_pot_min + unidades[i].Pmin; Tot_pot_max=Tot_pot_max + unidades[i].Pmax;} max_baja=Demanda-Tot_pot_min; max_sube=Tot_pot_max-Demanda;*/ costo_mejor=costo_tot(P, unidades,modelo_cc); adonde=baja; U_selec=rand_int(0,Us-1); movimiento_max=(P[U_selec]-Pmin_aux[U_selec]); while (k<K0)/*K0: numero de iteraciones max del algoritmo de generacion)*/ { vecino=vecindad(P,Pmin_aux,Pmax_aux,movimiento_max,U_selec,adonde);/*solucion vecina*/ costo_vecino=costo_tot(vecino, unidades,modelo_cc); AII-20 dif_costo=costo_mejor-costo_vecino; if (dif_costo>0.0){ copia_vector_real(P,vecino,Us); costo_mejor=costo_vecino; sol_mej++;} k=k+1; U_selec=rand_int(0,Us-1); if (rand_real()>0.5) {adonde=sube; movimiento_max=(Pmax_aux[U_selec]-P[U_selec]);} /*max_sube*/ else {adonde=baja; movimiento_max=(P[U_selec]-Pmin_aux[U_selec]);} /*max_baja*/ } /* copia_vector_real(P_sol,P,Us);/* No es necesario, revisar al unificar con busqueda_local */ /* printf("# soluciones vecinas mejores: %u\n",sol_mej);*/ corta_vector_real(vecino); } /************** Rutinas de manejo de errores.**********************/ void error1(void) { perror("\a Faltan argumentos \n"); abortar(); } void errorn(void) { perror("\a Demasiados argumentos \n"); abortar(); } void error_opcion(void) { perror("\a Opción invalida\n"); abortar(); } Archivos de descripción “make_AG” #************************************************************************ #* Compila el programa de Algortimo Genetico con poblacion inicial #* de soluciones no factibles generadas de forma aleatoria * #************************************************************************ * COMPILADOR=gcc FUENTE= $(HOME)/tesis/fuente/util/util.c $(HOME)/tesis/fuente/pob_ini/pob_ini_nf2.c $(HOME)/tesis/fuente/evaluacion/evaluacion2.c $(HOME)/tesis/fuente/seleccion/selec_torneo2.c $(HOME)/tesis/fuente/hijos/hijos2.c AG2.c OBJS=$(FUENTE:.c=.o) HEADER= ag.h LIB=GA PROG=AG2 CC: $(OBJS) $(COMPILADOR) $(OBJS) -L$(HOME)/tesis/lib -l$(LIB) -lm -o $(HOME)/tesis/bin/$(PROG) @- echo "Compilación terminada" LIMPIA: @- rm -f $(OBJS) @- echo "Borrado de objetos terminado" AII-21 BORRA: @- rm -f $(OBJS) $(PROG) @- echo "Borrado de archivos terminado" .c.o: $(COMPILADOR) -g -I$(HOME)/tesis/fuente/incl/ -c $*.c -o $*.o $(OBJS): $(HOME)/tesis/fuente/incl/$(HEADER) $(HOME)/tesis/lib/lib$(LIB).a “make_AGH” #********************************************************************************* #* Compila el programa de Algoritmo Genetico Hibrido con poblacion inicial #* de soluciones no factibles generadas de forma aleatoria. * #********************************************************************************* * COMPILADOR=gcc FUENTE= $(HOME)/tesis/fuente/util/util.c $(HOME)/tesis/fuente/pob_ini/pob_ini_nf2.c $(HOME)/tesis/fuente/evaluacion/evaluacion2.c $(HOME)/tesis/fuente/seleccion/selec_torneo2.c $(HOME)/tesis/fuente/hijos/hijos2.c $(HOME)/tesis/fuente/BL/busqueda_local.c AGH.c OBJS=$(FUENTE:.c=.o) HEADER= ag.h LIB=GA PROG=AGH CC: $(OBJS) $(COMPILADOR) $(OBJS) -L$(HOME)/tesis/lib -l$(LIB) -lm -o $(HOME)/tesis/bin/$(PROG) @- echo "Compilación terminada" LIMPIA: @- rm -f $(OBJS) @- echo "Borrado de objetos terminado" BORRA: @- rm -f $(OBJS) $(PROG) @- echo "Borrado de archivos terminado" .c.o: $(COMPILADOR) -g -I$(HOME)/tesis/fuente/incl/ -c $*.c -o $*.o $(OBJS): $(HOME)/tesis/fuente/incl/$(HEADER) $(HOME)/tesis/lib/lib$(LIB).a “make_AGH_FC” #********************************************************************************* #* Compila el programa de Algoritmo Genetico Hibrido con poblacion inicial #* de soluciones factibles generadas por fase constructora del GRASP #********************************************************************************* * * COMPILADOR=gcc FUENTE= $(HOME)/tesis/fuente/util/util.c $(HOME)/tesis/fuente/pob_ini/pob_ini_fc.c $(HOME)/tesis/fuente/evaluacion/evaluacion.c $(HOME)/tesis/fuente/seleccion/selec_torneo.c $(HOME)/tesis/fuente/hijos/hijos.c $(HOME)/tesis/fuente/BL/busqueda_local.c AGH.c OBJS=$(FUENTE:.c=.o) HEADER= ag.h LIB=GA PROG=AGH_FCgrasp CC: $(OBJS) $(COMPILADOR) $(OBJS) -L$(HOME)/tesis/lib -l$(LIB) -lm -o $(HOME)/tesis/bin/$(PROG) @- echo "Compilación terminada" LIMPIA: @- rm -f $(OBJS) @- echo "Borrado de objetos terminado" BORRA: AII-22 @- rm -f $(OBJS) $(PROG) @- echo "Borrado de archivos terminado" .c.o: $(COMPILADOR) -g -I$(HOME)/tesis/fuente/incl/ -c $*.c -o $*.o $(OBJS): $(HOME)/tesis/fuente/incl/$(HEADER) $(HOME)/tesis/lib/lib$(LIB).a “make_AGH_SR” #************************************************************************ #* Compila el programa de Algortimo Genetico con poblacion inicial #* de soluciones factibles generadas por algoritmo SR * #************************************************************************ * COMPILADOR=gcc FUENTE= $(HOME)/tesis/fuente/util/util.c $(HOME)/tesis/fuente/pob_ini/pob_ini.c $(HOME)/tesis/fuente/evaluacion/evaluacion.c $(HOME)/tesis/fuente/seleccion/selec_torneo.c $(HOME)/tesis/fuente/hijos/hijos.c $(HOME)/tesis/fuente/BL/busqueda_local.c AGH.c OBJS=$(FUENTE:.c=.o) HEADER= ag.h LIB=GA PROG=AGH_SR CC: $(OBJS) $(COMPILADOR) $(OBJS) -L$(HOME)/tesis/lib -l$(LIB) -lm -o $(HOME)/tesis/bin/$(PROG) @- echo "Compilación terminada" LIMPIA: @- rm -f $(OBJS) @- echo "Borrado de objetos terminado" BORRA: @- rm -f $(OBJS) $(PROG) @- echo "Borrado de archivos terminado" .c.o: $(COMPILADOR) -g -I$(HOME)/tesis/fuente/incl/ -c $*.c -o $*.o $(OBJS): $(HOME)/tesis/fuente/incl/$(HEADER) $(HOME)/tesis/lib/lib$(LIB).a “make_RS” #************************************************************************ #* Compila el programa de Recocido Simulado * #************************************************************************ COMPILADOR=gcc FUENTE= $(HOME)/tesis/fuente/util/util.c $(HOME)/tesis/fuente/pob_ini/pob_ini.c sa.c OBJS=$(FUENTE:.c=.o) HEADER= ag.h LIB=GA PROG=RS CC: $(OBJS) $(COMPILADOR) $(OBJS) -L$(HOME)/tesis/lib -l$(LIB) -lm -o $(HOME)/tesis/bin/$(PROG) @- echo "Compilación terminada" LIMPIA: @- rm -f $(OBJS) @- echo "Borrado de objetos terminado" BORRA: @- rm -f $(OBJS) $(PROG) @- echo "Borrado de archivos terminado" .c.o: $(COMPILADOR) -g -I$(HOME)/tesis/fuente/incl/ -c $*.c -o $*.o AII-23 $(OBJS): $(HOME)/tesis/fuente/incl/$(HEADER) $(HOME)/tesis/lib/lib$(LIB).a “make_GRASP” #************************************************************************ #* Compila el programa GRASP * #************************************************************************ COMPILADOR=gcc FUENTE= $(HOME)/tesis/fuente/util/util.c grasp.c OBJS=$(FUENTE:.c=.o) HEADER= ag.h LIB=GA PROG=grasp CC: $(OBJS) $(COMPILADOR) $(OBJS) -L$(HOME)/tesis/lib -l$(LIB) -lm -o $(PROG) @- echo "Compilación terminada" LIMPIA: @- rm -f $(OBJS) @- echo "Borrado de objetos terminado" BORRA: @- rm -f $(OBJS) $(PROG) @- echo "Borrado de archivos terminado" .c.o: $(COMPILADOR) -g -I$(HOME)/tesis/fuente/incl/ -c $*.c -o $*.o $(OBJS): $(HOME)/tesis/fuente/incl/$(HEADER) $(HOME)/tesis/lib/lib$(LIB).a Nota: Los archivos evaluacion.c, selec_torneo.c, hijos.c (no incluídos) son similares a los archivos evaluacion2.c, selec_torneo2.c, hijos2.c, respectivamente, con la diferencia que los primeros escriben los datos de salida en un archivo. AII-24