IMPLEMENTACION EN VISUAL BASIC


EASYGA




Esta aplicación nos muestra el funcionamiento de un control ActiveX usando como contenedor una aplicación desarrollada en Visual Basic. En control que usa está en el fichero EASYGA.OCX. Este control ejecuta un algoritmo genético a partir de los parámetros siguientes:


* size: indica la longitud del cromosoma

* rango: indica el intervalo [-rango/2, rango/2], para los valores de cada gen en el cromosoma

* PopSize: número de individuos de la población

* Generaciones: indica cuántas generaciones se ejecutará el algoritmo genético. Como máximo será 19.


Estos valores serán los que use el control ActiveX para ejecutarse.
Una vez introducidos los valores, pulsamos el botón "Inicio".

Cuando se termina la ejecución, el programa nos muestra una gráfica que indica cómo ha ido evolucionando el mejor individuo de la población a lo largo de las distintas generaciones.
También podemos obtener otra gráfica pulsando el botón "Gráfica generación n", que nos muestra el "fitness" de los individuos en cada generación. Mediante esta gráfica se puede apreciar cómo la adaptación de los individuos mejora a medida que el algoritmo avanza en su ejecución.
En el cuadro "Datos recibidos", podemos ver los valores del fitness de los individuos, y cómo éstos aumentan, indicando que están mejor adaptados.
Mediante el botón "Salir", terminamos la ejecución de la aplicación.



Implementación



El funcionamiento del programa se describe a continuación. Una vez que se han introducido los valores antes mencionados y se pulsa el botón de "Inicio", el programa ejecuta la función "Command1_Click()". Esta función comprueba, en primer lugar, que todos los cuadros de texto de los valores estén rellenos y contengan valores válidos.

Si se supera la comprobación, entonces se ejecuta la instrucción "EasyGA1.calculo = True" que es la que llama al control y hace que éste ejecute el algoritmo genético.

Una vez ejecutado el algoritmo, obtenemos en el array "fitness", los valores de los diferentes fitness de los individuos de la población. A continuación se normalizan estos valores al intervalo [0,1], y se almacenan los resultados en el vector "Datos", que será el vector que se use como parámetro a la hora de dibujar la gráfica de mejor individuo/generación.

Para dibujar las gráficas que nos muestran la evolución de la población, hacemos uso de la función "Command3_Click()". Esta función recorre el array "fitness", de modo que se accede al valor [generación, individuo] de dicho array. Se muestran tantas gráficas como generaciones, y en cada una aparece el fitness de cada individuo. Estas gráficas se dibujan por medio de un control ActiveX denominado "MSChart", al que se le pasan los argumentos adecuados para su funcionamiento.

Las gráficas se muestran con un intervalo de un segundo entre cada una. Para ello se hace uso de otro control ActiveX, denominado "Timer", que se programa para que se active a intervalos de un segundo.


Código

VERSION 5.00
Object = "{02B5E320-7292-11CF-93D5-0020AF99504A}#1.0#0"; "MSCHART.OCX"
Object = "{751B7FC3-C0D1-11D2-806D-444553540000}#1.0#0"; "EASYGA.OCX"
Begin VB.Form Form1 
   AutoRedraw      =   -1  'True
   Caption         =   "EasyGA ActiveX"
   ClientHeight    =   7710
   ClientLeft      =   705
   ClientTop       =   780
   ClientWidth     =   10410
   LinkTopic       =   "Form1"
   ScaleHeight     =   7710
   ScaleWidth      =   10410
   Begin VB.Timer Timer1 
      Left            =   6120
      Top             =   480
   End
   Begin VB.CommandButton Command4 
      Caption         =   "Acerca de ..."
      Height          =   495
      Left            =   3480
      TabIndex        =   16
      Top             =   4200
      Width           =   1335
   End
   Begin VB.CommandButton Command3 
      Caption         =   "&Gráfica generación n"
      Height          =   495
      Left            =   3480
      TabIndex        =   15
      Top             =   6000
      Width           =   1335
   End
   Begin VB.TextBox Text4 
      Height          =   285
      Left            =   480
      TabIndex        =   3
      Top             =   6360
      Width           =   855
   End
   Begin EASYGALib.EasyGA EasyGA1 
      Height          =   615
      Left            =   480
      TabIndex        =   12
      Top             =   240
      Visible         =   0   'False
      Width           =   1695
      _Version        =   65536
      _ExtentX        =   2990
      _ExtentY        =   1085
      _StockProps     =   0
   End
   Begin MSChartLib.MSChart MSChart1 
      Height          =   2655
      Left            =   240
      OleObjectBlob   =   "EasyGA.frx":0000
      TabIndex        =   11
      Top             =   1320
      Width           =   4455
   End
   Begin VB.Frame Frame2 
      Caption         =   "Datos recibidos"
      Height          =   2535
      Left            =   5880
      TabIndex        =   6
      ToolTipText     =   "Datos calculados"
      Top             =   4920
      Width           =   2295
      Begin VB.Label Label5 
         AutoSize        =   -1  'True
         Caption         =   "Label5"
         Height          =   195
         Left            =   240
         TabIndex        =   10
         Top             =   360
         Width           =   480
      End
   End
   Begin VB.CommandButton Command2 
      Caption         =   "&Salir"
      Height          =   495
      Left            =   3480
      TabIndex        =   5
      ToolTipText     =   "Salir de la aplicación"
      Top             =   5040
      Width           =   1335
   End
   Begin VB.CommandButton Command1 
      Caption         =   "&Inicio"
      Height          =   495
      Left            =   3480
      TabIndex        =   4
      ToolTipText     =   "Iniciar cálculo"
      Top             =   480
      Width           =   1335
   End
   Begin VB.TextBox Text3 
      Height          =   285
      Left            =   480
      TabIndex        =   2
      Text            =   "Text1"
      Top             =   5760
      Width           =   855
   End
   Begin VB.TextBox Text2 
      Height          =   285
      Left            =   480
      TabIndex        =   1
      Text            =   "Text1"
      Top             =   5160
      Width           =   855
   End
   Begin VB.TextBox Text1 
      Height          =   285
      Left            =   480
      TabIndex        =   0
      Text            =   "Text1"
      Top             =   4560
      Width           =   855
   End
   Begin MSChartLib.MSChart MSChart2 
      Height          =   2655
      Left            =   5400
      OleObjectBlob   =   "EasyGA.frx":250B
      TabIndex        =   14
      Top             =   1320
      Width           =   5055
   End
   Begin VB.Label Label4 
      Caption         =   "Generaciones"
      Height          =   255
      Left            =   480
      TabIndex        =   13
      Top             =   6120
      Width           =   1335
   End
   Begin VB.Label Label3 
      Caption         =   "Rango"
      Height          =   255
      Left            =   480
      TabIndex        =   9
      Top             =   4920
      Width           =   1335
   End
   Begin VB.Label Label2 
      Caption         =   "PopSize"
      Height          =   255
      Left            =   480
      TabIndex        =   8
      Top             =   5520
      Width           =   1335
   End
   Begin VB.Label Label1 
      Caption         =   "Size"
      Height          =   255
      Left            =   480
      TabIndex        =   7
      Top             =   4320
      Width           =   1335
   End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Dim gen As Integer
Dim datos1() As Variant
Dim fitness() As Variant







Private Sub Command1_Click()
    
    Dim Datos() As Variant
         
    MSChart2.Visible = False
    
    If (Text1.Text = "" Or Text2.Text = "" Or Text3.Text = "" Or Text4.Text = "") Then
        MsgBox "Faltan datos"
    
    Else
        Label5.Caption = ""
        EasyGA1.Size = Text1.Text
        EasyGA1.range = Text2.Text
        EasyGA1.PopSize = Text3.Text
        EasyGA1.numGenerations = Text4.Text
        
        'Comprobaciones de rango
        
        rango_valido = True
        If Text4.Text > 19 Then
            MsgBox ("El máximo número de generaciones es 19")
            rango_valido = False
        End If
        
        If Text1.Text <= 0 Or Text2.Text <= 0 Or Text3.Text <= 0 Or Text4.Text <= 0 Then
            MsgBox ("Los valores deben ser positivos")
            rango_valido = False
        End If
        
        
        If rango_valido = True Then
            EasyGA1.calculo = True
        
        
        
             Max = EasyGA1.fitness(EasyGA1.numGenerations - 1, 0)
            
            'Hacemos un cambio a la escala [0,1]
             ReDim fitness(EasyGA1.numGenerations, EasyGA1.PopSize)
             
             For i = 0 To EasyGA1.numGenerations - 1
                 For j = 0 To EasyGA1.PopSize - 1
                     fitness(i + 1, j + 1) = EasyGA1.fitness(i, j) / Max
                 Next j
             Next i
        
             ReDim Datos(EasyGA1.numGenerations)
            
             For i = 0 To EasyGA1.numGenerations - 1
                 Label5.Caption = Label5.Caption & vbLf & fitness(i + 1, 1)
                 Datos(i + 1) = fitness(i + 1, 1)
             Next i
             
             MSChart1 = Datos
             MSChart1.Visible = True
        End If
    End If

End Sub

Private Sub Command2_Click()
    
    Unload Form2
    Unload Form1

End Sub

Private Sub Command3_Click()

    Dim fitness As Variant
    
    ReDim fitness(Form1.EasyGA1.numGenerations, Form1.EasyGA1.PopSize)
    
    Max = Form1.EasyGA1.fitness(Form1.EasyGA1.numGenerations - 1, 0)
    
    gen = 1
    
    For i = 0 To Form1.EasyGA1.numGenerations - 1
        For j = 0 To Form1.EasyGA1.PopSize - 1
            fitness(i + 1, j + 1) = Form1.EasyGA1.fitness(i, j) / Max
        Next j
    Next i
    
    
    ReDim datos1(Form1.EasyGA1.PopSize)
    
    Timer1.Enabled = False
    Timer1.Interval = 1000
    Timer1.Enabled = True
        
    
End Sub


Private Sub Command4_Click()
    
    frmAbout.Show
    
End Sub

Private Sub Form_Load()
    
    Text1.Text = ""
    Text2.Text = ""
    Text3.Text = ""
    Text4.Text = ""
    Label5.Caption = ""
    Form2.Text1 = ""
    MSChart1.Visible = False
    MSChart2.Visible = False
    
End Sub

 Sub MSChart2_ChartUpdated(flag As Integer)


    MSChart2.Refresh
    
    
End Sub
Private Sub Timer1_Timer()

    
    For i = 0 To Form1.EasyGA1.PopSize - 1
            datos1(i + 1) = fitness(gen, i + 1)
    Next i
    gen = gen + 1
    Form1.MSChart2.TitleText = "Fitness Generacion " & gen - 1
    Form1.MSChart2 = datos1
    
    
    Form1.MSChart2.Visible = True
    If gen = Form1.EasyGA1.numGenerations + 1 Then
        Form1.Timer1.Enabled = False
    End If
    

End Sub




ControlGA_VB




Esta es otra aplicación que muestra el uso de un control ActiveX. El control de que hace uso esta aplicación es el CONTROLGA.OCX. Los parámetros para su ejecución son los mismos que los usados para la aplicación EASYGA, con la salvedad de que ahora podemos indicar qué función de evaluación se usará: sumatoria ó potencia. En esta aplicación obtenemos dos gráficas: la que nos muestra el fitness de los individuos antes de llamar al control, y la que nos muestra el fitness después de la ejecución del algoritmo genético que contiene el control.



Implementación



La implementación de esta aplicación es parecida a EASYGA. En este caso, en vez de asignar el valor True a la propiedad "calculo" del control, se llama al método "sumatoria" o al método "sumaPotencia", del control ActiveX, dependiendo de la opción que el usuario marque. A continuación se dibujan dos gráficas haciendo uso del control ActiveX "MSChart", una para visualizar el fitness de los individuos antes de la ejecución del algoritmo, y otra para ver el resultado final. La forma de operar con el valor de los fitness es igual que en la aplicación anterior: se normalizan y se almacenan los valores en un array auxiliar, que se usará para visualizar las diferentes gráficas.


Código

VERSION 5.00
Object = "{02B5E320-7292-11CF-93D5-0020AF99504A}#1.0#0"; "MSCHART.OCX"
Object = "{0E12C863-2E36-11D3-B0EA-EE4C2C44F238}#1.0#0"; "CONTROLGA.OCX"
Begin VB.Form Form1 
   AutoRedraw      =   -1  'True
   Caption         =   "ControlGA_VB ActiveX"
   ClientHeight    =   7710
   ClientLeft      =   705
   ClientTop       =   780
   ClientWidth     =   10410
   LinkTopic       =   "Form1"
   ScaleHeight     =   7710
   ScaleWidth      =   10410
   Begin CONTROLGALib.ControlGA ControlGA1 
      Left            =   1200
      Top             =   360
      _Version        =   65536
      _ExtentX        =   238
      _ExtentY        =   53
      _StockProps     =   0
   End
   Begin VB.OptionButton Option2 
      Caption         =   "Potencia"
      Height          =   375
      Left            =   6360
      TabIndex        =   14
      Top             =   5160
      Width           =   1215
   End
   Begin VB.OptionButton Option1 
      Caption         =   "Sumatoria"
      Height          =   375
      Left            =   6360
      TabIndex        =   13
      Top             =   4680
      Value           =   -1  'True
      Width           =   1215
   End
   Begin VB.CommandButton Command4 
      Caption         =   "Acerca de ..."
      Height          =   495
      Left            =   3480
      TabIndex        =   12
      Top             =   4200
      Width           =   1335
   End
   Begin VB.TextBox Text4 
      Height          =   285
      Left            =   480
      TabIndex        =   3
      Top             =   6360
      Width           =   855
   End
   Begin MSChartLib.MSChart MSChart1 
      Height          =   2655
      Left            =   240
      OleObjectBlob   =   "ControlGA_VB.frx":0000
      TabIndex        =   9
      Top             =   1320
      Width           =   4455
   End
   Begin VB.CommandButton Command2 
      Caption         =   "&Salir"
      Height          =   495
      Left            =   3480
      TabIndex        =   5
      ToolTipText     =   "Salir de la aplicación"
      Top             =   5040
      Width           =   1335
   End
   Begin VB.CommandButton Command1 
      Caption         =   "&Inicio"
      Height          =   495
      Left            =   3480
      TabIndex        =   4
      ToolTipText     =   "Iniciar cálculo"
      Top             =   480
      Width           =   1335
   End
   Begin VB.TextBox Text3 
      Height          =   285
      Left            =   480
      TabIndex        =   2
      Text            =   "Text1"
      Top             =   5760
      Width           =   855
   End
   Begin VB.TextBox Text2 
      Height          =   285
      Left            =   480
      TabIndex        =   1
      Text            =   "Text1"
      Top             =   5160
      Width           =   855
   End
   Begin VB.TextBox Text1 
      Height          =   285
      Left            =   480
      TabIndex        =   0
      Text            =   "Text1"
      Top             =   4560
      Width           =   855
   End
   Begin MSChartLib.MSChart MSChart2 
      Height          =   2655
      Left            =   5400
      OleObjectBlob   =   "ControlGA_VB.frx":24FF
      TabIndex        =   11
      Top             =   1320
      Width           =   5055
   End
   Begin VB.Label Label6 
      Caption         =   "Función de evaluación:"
      Height          =   255
      Left            =   5760
      TabIndex        =   15
      Top             =   4440
      Width           =   1815
   End
   Begin VB.Label Label4 
      Caption         =   "Generaciones"
      Height          =   255
      Left            =   480
      TabIndex        =   10
      Top             =   6120
      Width           =   1335
   End
   Begin VB.Label Label3 
      Caption         =   "Rango"
      Height          =   255
      Left            =   480
      TabIndex        =   8
      Top             =   4920
      Width           =   1335
   End
   Begin VB.Label Label2 
      Caption         =   "PopSize"
      Height          =   255
      Left            =   480
      TabIndex        =   7
      Top             =   5520
      Width           =   1335
   End
   Begin VB.Label Label1 
      Caption         =   "Size"
      Height          =   255
      Left            =   480
      TabIndex        =   6
      Top             =   4320
      Width           =   1335
   End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Dim gen As Integer
Dim datos1() As Variant
Dim potencia As Boolean
Dim sumatoria As Boolean
Dim fitness() As Variant
Private Sub Command1_Click()
    
    Dim datos() As Variant
         
    MSChart2.Visible = False
    
    If (Text1.Text = "" Or Text2.Text = "" Or Text3.Text = "" Or Text4.Text = "") Then
        MsgBox "Faltan datos"
    
    Else
        ControlGA1.Size = Text1.Text
        ControlGA1.range = Text2.Text
        ControlGA1.popSzie = Text3.Text + 1
        ControlGA1.generations = Text4.Text
        
        'Comprobaciones de rango
        
        rango_valido = True
        If Text4.Text > 19 Then
            MsgBox ("El máximo número de generaciones es 19")
            rango_valido = False
        End If
        
        If Text1.Text <= 0 Or Text2.Text <= 0 Or Text3.Text <= 0 Or Text4.Text <= 0 Then
            MsgBox ("Los valores deben ser positivos")
            rango_valido = False
        End If
        
        'Según sea la función de evaluación
        'se llama al control con un método u otro
        
        If rango_valido = True Then
                          
            If (sumatoria = True) Then
                ControlGA1.sumatoria
            ElseIf (potencia = True) Then
                    ControlGA1.sumaPotencia
            End If
            
        
             Max = ControlGA1.fitness(ControlGA1.generations, 2)
            
            
            'Hacemos un cambio a la escala [0,1]
             ReDim fitness(ControlGA1.generations, ControlGA1.popSzie)
             
             For i = 1 To ControlGA1.generations
                 For j = 1 To ControlGA1.popSzie
                     fitness(i, j) = ControlGA1.fitness(i, j) / Max
                 Next j
             Next i
        
            'Se calculan los datos para las gráficas
             ReDim datos(ControlGA1.popSzie - 1)
             ReDim datos1(ControlGA1.popSzie - 1)
             For i = 1 To Form1.ControlGA1.popSzie
                datos(i - 1) = fitness(1, i)
                datos1(i - 1) = fitness(2, i)
             Next i
             
             MSChart1 = datos
             MSChart1.Visible = True
             Form1.MSChart2 = datos1
             Form1.MSChart2.Visible = True
    
        End If
    End If

End Sub

Private Sub Command2_Click()
    
    Unload Form1

End Sub



Private Sub Command4_Click()
    
    frmAbout.Show
    
End Sub

Private Sub Form_Load()
    
    'Se asignan valores iniciales a diferentes variables
    
    Text1.Text = ""
    Text2.Text = ""
    Text3.Text = ""
    Text4.Text = ""
    MSChart1.Visible = False
    MSChart2.Visible = False
    sumatoria = True
    potencia = False
    
End Sub

Private Sub Option1_Click()
    Form1.Option2.Value = False
    potencia = False
    sumatoria = True
End Sub

Private Sub Option2_Click()
    Form1.Option1.Value = False
    sumatoria = False
    potencia = True
End Sub