Anexo 2 Código del lenguaje de programación AG I Código del lenguaje de programación AG I Option Base 1 Public veces, generaciones As Integer Dim tam, lugar, num, diferente, columna As Integer Dim madre, padre As String Dim Primerpadre, Segundopadre As Double Dim matriz1, matriz2 Dim MatrizFlujo() As Single Dim MatrizDistancia() As Single Dim MatrizDiferentes() As Integer Dim MatrizCantidad() As Integer Dim MAleatoria() As Integer Dim MOrdenada() As Integer Dim MNueva() As Integer Dim MTemp() As Integer Dim MInmigrante() As Integer Dim MatrizPadres() As Integer Dim MatrizPadresRed() As Integer Dim MatrizHijos() As Integer Dim MatrizHijosRed() As Integer Dim MatrizResultados() As Integer Sub CORRIDAS() 'En la Hoja "Corridas" guarda resultados obtenidos Application.ScreenUpdating = False Sheets("Flujo").Activate Range(Cells(1, 1), Cells(1, 1).End(xlToRight)).Select tam = Selection.Cells.Count num = 0 contador = 0 GUARDADISTANCIA GUARDAFLUJO Sheets("Corridas").Activate numveces = 0 For i = 1 To veces PRINCIPAL ActiveSheet.Cells(i, 1) = Primerpadre ActiveSheet.Cells(i, 2) = Segundopadre ActiveSheet.Cells(i, 3) = matriz1 ActiveSheet.Cells(i, 4) = matriz2 numveces = numveces + 1 Porcentaje = numveces / veces With Generacion .ProgressBar1.Value = Porcentaje * 100 .ProgressBar1.Refresh End With Next i Unload Generacion End Sub Sub PRINCIPAL() 'Obtiene las generaciones de dos permutaciones iniciales y devuelve la mejor ReDim MatrizCantidad(tam, tam) As Integer POBLACIONINICIAL MejordeTodos = FUNCIONOBJETIVO(MatrizPadres(), 1) MejorMatriz = MOSTRARMATRIZ(MatrizPadres(), 1, tam) Do Until contador = generaciones CUENTAPOSICION If FUNCIONOBJETIVO(MatrizPadres(), 1) = FUNCIONOBJETIVO(MatrizPadres(), 2) Then cuentainmigrante = cuentainmigrante + 1 INMIGRANTE For p = 1 To tam MatrizPadres(2, p) = MInmigrante(p) Next p End If SELECCION ESCOGEPADRES contador = contador + 1 Loop Primerpadre = FUNCIONOBJETIVO(MatrizPadres(), 1) Segundopadre = FUNCIONOBJETIVO(MatrizPadres(), 2) matriz1 = MOSTRARMATRIZ(MatrizPadres(), 1, tam) matriz2 = MOSTRARMATRIZ(MatrizPadres(), 2, tam) End Sub Sub GUARDADISTANCIA() 'Guarda la matriz de las distancias entre sitios Sheets("Distancia").Activate ReDim MatrizDistancia(tam, tam) As Single For y = 1 To tam For z = 1 To tam MatrizDistancia(y, z) = ActiveSheet.Cells(y, z).Value Next z Next y End Sub Sub GUARDAFLUJO() 'Guarda la matriz de flujo entre sitios Sheets("Flujo").Activate ReDim MatrizFlujo(tam, tam) As Single For y = 1 To tam For z = 1 To tam MatrizFlujo(y, z) = ActiveSheet.Cells(y, z).Value Next z Next y End Sub Sub POBLACIONINICIAL() 'Crea la poblacion inicial ReDim MatrizPadres(2, tam) For h = 1 To 2 For i = 1 To tam If i = 1 Then MatrizPadres(h, i) = RANDOM(tam) Else MatrizPadres(h, i) = CALCULADISTANCIAMINIMA(MatrizPadres(), tam, i, h) End If Next i Next h End Sub Sub CREARHIJO() 'Emplea la técnica de inserción para crear los descendientes de un par de padres dados ReDim MatrizPadresRed(2, diferente) ReDim MatrizHijosRed(2, diferente) For b = 1 To diferente argumento = MatrizDiferentes(b) MatrizPadresRed(1, b) = MatrizPadres(1, argumento) MatrizPadresRed(2, b) = MatrizPadres(2, argumento) Next b For w = 1 To diferente If MatrizPadresRed(1, w) = MatrizPadresRed(2, lugar) Then MatrizHijosRed(1, lugar) = MatrizPadresRed(1, w) tope1 = w End If If MatrizPadresRed(2, w) = MatrizPadresRed(1, lugar) Then MatrizHijosRed(2, lugar) = MatrizPadresRed(2, w) tope2 = w End If Next w For v = 1 To 2 If v = 1 Then tope = tope1 Else tope = tope2 End If Select Case lugar Case Is > tope MatrizHijosRed(v, 1) = MatrizPadresRed(v, diferente) If lugar = tope + 1 Then For x = 2 To diferente MatrizHijosRed(v, x) = MatrizPadresRed(v, x - 1) Next x Else For zz = tope + 1 To lugar - 1 MatrizHijosRed(v, zz) = MatrizPadresRed(v, zz) Next zz If tope >= 2 Then For y = 2 To tope MatrizHijosRed(v, y) = MatrizPadresRed(v, y - 1) Next y End If If lugar <= diferente Then For z = lugar + 1 To diferente MatrizHijosRed(v, z) = MatrizPadresRed(v, z - 1) Next z End If End If Case Is < tope If tope = lugar + 1 Then MatrizHijosRed(v, tope) = MatrizPadresRed(v, lugar) Else For z = lugar + 1 To tope MatrizHijosRed(v, z) = MatrizPadresRed(v, z - 1) Next z End If If lugar >= 2 Then For x = 1 To lugar - 1 MatrizHijosRed(v, x) = MatrizPadresRed(v, x) Next x End If If tope <= diferente - 1 Then For y = tope + 1 To diferente MatrizHijosRed(v, y) = MatrizPadresRed(v, y) Next y End If End Select Next v REORDEN End Sub Sub SELECCION() 'Selecciona los elementos que pasarán automáticamente de padres a hijos '(fijos, no se mueven con inserción) diferente = 0 ReDim MatrizHijos(2, tam) As Integer For i = 1 To tam If MatrizPadres(1, i) = MatrizPadres(2, i) Then MatrizHijos(1, i) = MatrizPadres(1, i) MatrizHijos(2, i) = MatrizPadres(1, i) Else diferente = diferente + 1 ReDim Preserve MatrizDiferentes(1 To diferente) MatrizDiferentes(diferente) = i End If Next i lugar = RANDOM(diferente) CREARHIJO End Sub Sub REORDEN() 'Reacomoda la matriz después de la inserción For s = 1 To diferente argumento = MatrizDiferentes(s) MatrizHijos(1, argumento) = MatrizHijosRed(1, s) MatrizHijos(2, argumento) = MatrizHijosRed(2, s) Next s End Sub Sub ESCOGEPADRES() 'Escoge los padres de una generacion posterior de entre los 2 descendientes y los padres anteriores Hijo1 = FUNCIONOBJETIVO(MatrizHijos(), 1) Hijo2 = FUNCIONOBJETIVO(MatrizHijos(), 2) Mama = FUNCIONOBJETIVO(MatrizPadres(), 1) Papa = FUNCIONOBJETIVO(MatrizPadres(), 2) If Hijo1 < Hijo2 Then If Mama < Papa Then If Hijo1 < Mama Then decision = MASPARECIDO(MatrizHijos(), 1) For w = 1 To tam MatrizPadres(decision, w) = MatrizHijos(1, w) Next w Else For w = 1 To tam MatrizPadres(2, w) = MatrizHijos(1, w) Next w End If Else If Hijo2 < Papa Then decision = MASPARECIDO(MatrizHijos(), 1) For w = 1 To tam MatrizPadres(decision, w) = MatrizHijos(1, w) Next w Else For w = 1 To tam MatrizPadres(1, w) = MatrizHijos(1, w) Next w End If End If Else If Mama < Papa Then If Hijo2 < Mama Then decision = MASPARECIDO(MatrizHijos(), 2) For w = 1 To tam MatrizPadres(decision, w) = MatrizHijos(2, w) Next w Else For w = 1 To tam MatrizPadres(2, w) = MatrizHijos(2, w) Next w End If Else If Hijo2 < Papa Then decision = MASPARECIDO(MatrizHijos(), 2) For w = 1 To tam MatrizPadres(decision, w) = MatrizHijos(2, w) Next w Else For w = 1 To tam MatrizPadres(1, w) = MatrizHijos(2, w) Next w End If End If End If End Sub Sub CUENTAPOSICION() 'Actualiza la matriz que guarda el número de veces que un número ha estado en cierto lugar For g = 1 To 2 For h = 1 To tam numero = MatrizPadres(g, h) MatrizCantidad(numero, h) = MatrizCantidad(numero, h) + 1 Next h Next g End Sub Sub INMIGRANTE() 'Crea al "inmigrante" que permite ampliar el conjunto de soluciones intergeneracionales For f = 1 To tam If f = 1 Then ReDim Preserve MAleatoria(1) aleatorio = RANDOM(tam) MAleatoria(f) = aleatorio Else ReDim Preserve MAleatoria(1 To f) MAleatoria(f) = DIFERENTEANTERIORES(MAleatoria(), f) End If Next f ReDim MInmigrante(1 To tam) For g = 1 To tam columna = MAleatoria(g) If g = 1 Then ENCUENTRAMINIMO MInmigrante(columna) = MOrdenada(1, 1) Else contando = 1 ENCUENTRAMINIMO resultante = MOrdenada(1, contando) For h = 1 To g - 1 For n = 1 To g - 1 If MInmigrante(MAleatoria(n)) = resultante Then checa = True contando = contando + 1 Exit For Else checa = False End If Next n resultante = MOrdenada(1, contando) If checa = False Or h = g - 1 Then MInmigrante(columna) = resultante Exit For End If Next End If Next g End Sub Sub ENCUENTRAMINIMO() 'Devuelve un arreglo ordenado ascendentemente de los valores que se han usado en la matriz de posiciones para una columna dada ReDim MOrdenada(2, tam) MOrdenada(1, 1) = 1 MOrdenada(2, 1) = MatrizCantidad(1, columna) For i = 2 To tam x = MatrizCantidad(i, columna) If x >= MOrdenada(2, i - 1) Then MOrdenada(1, i) = i MOrdenada(2, i) = MatrizCantidad(i, columna) Else For j = 1 To i - 1 y = MOrdenada(2, j) If y > x Then ReDim MNueva(2, 1) MNueva(1, 1) = MOrdenada(1, j) MNueva(2, 1) = MOrdenada(2, j) For k = j + 1 To i ReDim MTemp(2, 1) MTemp(1, 1) = MOrdenada(1, k) MTemp(2, 1) = MOrdenada(2, k) MOrdenada(1, k) = MNueva(1, 1) MOrdenada(2, k) = MNueva(2, 1) MNueva(1, 1) = MTemp(1, 1) MNueva(2, 1) = MTemp(2, 1) Next k MOrdenada(1, j) = i MOrdenada(2, j) = x Exit For End If Next j End If Next i End Sub Private Function DIFERENTEANTERIORES(matriz() As Integer, ByVal d As Integer) 'Función que checa si los elementos de un arreglo son ditintos entre sí y están en el rango correcto checa = True Do While checa = True aleat = RANDOM(tam) For g = 1 To d - 1 If matriz(g) = aleat Then checa = True Exit For Else checa = False End If Next g Loop DIFERENTEANTERIORES = aleat End Function Public Function FUNCIONOBJETIVO(matriz() As Integer, ByVal k As Integer) 'Función que obtiene la distancia total caminada para un arreglo dado ReDim resultado(1 To 2) distanciaminima = 0 For i = 1 To tam For j = 1 To tam arg1 = matriz(k, i) arg2 = matriz(k, j) distanciaminima = distanciaminima + (MatrizDistancia(i, j) * MatrizFlujo(arg1, arg2)) Next j Next i FUNCIONOBJETIVO = distanciaminima End Function Private Function RANDOM(tamano) 'Función que selecciona aleatoriamente un número de un rango dado tammenosuno = tamano - 1 RANDOM = Round(Rnd() * tammenosuno + 1, 0) End Function Private Function MASPARECIDO(matrix() As Integer, r As Integer) 'Función que escoge el padre más parecido para un hijo dado (bajo ciertas condiciones) cuentamama = 0 cuentapapa = 0 For i = 1 To tam Select Case matrix(r, i) Case Is = MatrizPadres(1, i) cuentamama = cuentamama + 1 Case Is = MatrizPadres(2, i) cuentapapa = cuentapapa + 1 End Select Next i If cuentamama >= cuentapapa Then MASPARECIDO = 1 Else MASPARECIDO = 2 End If End Function Private Function CALCULADISTANCIAMINIMA(matriz() As Integer, ByVal tama, ByVal posicion, ByVal reng) 'Función que escoge el sitio más cercano para un arreglo de sitios distintos ReDim MatrizResultados(2, tama - posicion + 1) cuenta = 0 For t = 1 To tama For w = 1 To posicion - 1 If matriz(reng, w) = t Then semejanza = True Exit For Else semejanza = False End If Next w If semejanza = False Then cuenta = cuenta + 1 MatrizResultados(1, cuenta) = t MatrizResultados(2, cuenta) = DISTANCIA(MatrizPadres(), t, posicion - 1, reng) End If Next t If tam - posicion + 1 = 1 Then CALCULADISTANCIAMINIMA = MatrizResultados(1, 1) Else mejorfuncion = MatrizResultados(2, 1) mejorlugar = 1 For x = 2 To tama - posicion + 1 If MatrizResultados(2, x) < mejorfuncion Then mejorlugar = x mejorfuncion = MatrizResultados(2, x) End If Next x CALCULADISTANCIAMINIMA = MatrizResultados(1, mejorlugar) End If End Function Private Function DISTANCIA(matriz2() As Integer, ByVal numero As Integer, ByVal pos As Integer, ByVal rengl As Integer) 'Función que calcula la distancia entre un sitio y otro TOTAL = 0 For f = 1 To pos argumento11 = matriz2(rengl, f) argumento12 = numero TOTAL = TOTAL + (MatrizDistancia(argumento11, argumento12) * MatrizFlujo(argumento11, argumento12)) Next f DISTANCIA = TOTAL End Function Private Function MOSTRARMATRIZ(matriz() As Integer, ByVal renglon As Integer, ByVal size As Integer) 'Función que muestra un arreglo conc1 = " " For g = 1 To size conc1 = conc1 & " " & matriz(renglon, g) Next g MOSTRARMATRIZ = conc1 End Function