en otra ventana

Anuncio
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
Descargar