Está en la página 1de 36

U4 ALGORITMOS GENÉTICOS

I NTELI GENCI A ARTI FI CI AL 2021


Facultad de Ingeniería - UNJu
Mg. Ing. Sergio L. Martínez
4.2 - ALGORITMOS GENÉTICOS EJEMPLOS
• Concepto/definición > (Gestal M. et al., 2010) Introducción a los Algoritmos
Genéticos y la Programación Genética.
• Algoritmo genético canónico
> (García G., 2010) Introduccion a la Resolucion de

REFERENCIAS
• Operación en Matlab Problemas con Algoritmos Genéticos.
• Ejemplo 1

(Aula Virtual)
> (García Martínez R. et al., 2003). Sistemas Inteligentes.
• Problema del viajante Cap. 3: Algoritmos genéticos.

• Ejemplo 2 (Coley D., 1999) An Introduction To Genetic Algorithms


For Scientists And Engineers.
• Mínimo de una función
(Rello R. M.) Algoritmos genéticos - Introducción,
• Ejemplo 3 métodos de búsqueda y optimización. Dpto.
ELECTRÓNICA I+D, ORBIS TECNOLOGÍA
• Resolución de sistema de
ELÉCTRICA
ecuaciones
(Matworks) Optimization function toolbox.
Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #1/36
U4 ALGORITMOS GENÉTICOS

CONCEPTO / DEFINICIÓN

Los Algoritmos Genéticos son


algoritmos de búsqueda basados en la
mecánica de selección natural y de la
genética natural. Combinan la super-
vivencia del más apto entre estructuras
David E. Goldberg
de secuencias con un intercambio de
información estructurado, aunque aleatorizado, para
constituir así un algoritmo de búsqueda que tenga algo
de las genialidades de las búsquedas humanas”
(Goldberg, 1989)

Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #2/36


U4 ALGORITMOS GENÉTICOS

AG SIMPLE O CANÓNICO - descripción


Teniendo el método de codificación de las
soluciones del problema, como cromosomas,
un AG se desarrolla como:

Paso 1 – Inicializar una población.


Paso 2 – Evaluar cada cromosoma en la población. Si está la solución,
detener → decodificar.
Paso 3 – Crear nuevos cromosomas apareando los actuales, por cruza de
pares. Mutar/invertir.
Paso 4 – Eliminar los padres u otros, para mantener la cantidad inicial de
individuos.
Paso 5 – Evaluar que el nuevo cromosoma esté en el universo e insertarlo en
la población.
Paso 6 – Si se alcanza la condición de detención, finalizar y presentar el
mejor cromosoma. De otra forma, volver al paso 3.

Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #3/36


U4 ALGORITMOS GENÉTICOS

OPERACIÓN EN MATLAB
Desde la línea de comando:
>> [x, fval] = ga(@fitnessfun, nvars, options)
donde
• @fitnessfun: función de ajuste.
• nvars: número de variables independientes de la función de
ajuste.
• options: estructura que contiene las opciones operativas del
algoritmo. Si no se especifica usa las opciones por defecto.
produce los siguientes resultados
• x: Punto correspondiente al valor final.
• fval: Valor final de la función objetivo.
Ref. [MathWorks] Global Optimization Toolbox User’s Guide. 2018.

Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #4/36


U4 ALGORITMOS GENÉTICOS

OPERACIÓN EN MATLAB
Variantes desde la línea de comando:

[x,fval] = ga(fitnessfcn,nvars)
[x,fval] = ga(fitnessfcn,nvars,A,b)
[x,fval] = ga(fitnessfcn,nvars,A,b,Aeq,beq)
[x,fval] = ga(fitnessfcn,nvars,A,b,Aeq,beq,LB,UB)

fitnessfcn = función de ajuste.


nvars = número de variables.
A , b = parámetros de desigualdad lineal  A*x ≤ b
Aeq , beq = parámetros de igualdad lineal  Aeq*x = beq
LB = límite inferior  x ≥ LB
UB = límite superior  x ≤ LB
x = valor de la variable en el mínimo.
fval = valor de la función en el mínimo.
Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #5/36
U4 ALGORITMOS GENÉTICOS

OPERACIÓN EN MATLAB
Desde la línea de comando >> optimtool(‘ga’) Parámetros y
opciones gráficas
Elegir
solver ga

Función
ajuste

Nro.
variables

Restric- Menú
ciones ayuda

Ejecu-
ción

Resultados
fitness(x)
Punto X

Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #6/36


U4 ALGORITMOS GENÉTICOS

EJEMPLO 1
Problema del viajante: Una persona debe recorrer varias ciudades distintas,
con la condición de pasar solamente una vez por cada una y volver a la ciudad
de origen, recorriendo la menor distancia posible.

Este problema tiene muchísimas variantes y una gran cantidad de enfoques de


resolución.

En este caso ha sido restringido y simplificado para ser presentado como un problema
didáctico que se resuelve mediante algoritmos genéticos.

La simplificación es restringir la cantidad de


ciudades a cuatro y disponerlas en los vértices
de un cuadrado.

Con tal disposición, la solución es accesible


a simple vista. La didactica del problema son
las estragias empleadas para su resolución.

Extraído de RELLO R. M. “Algoritmos genéticos. Introducción métodos de búsqueda y


optimización”. Dpto. Electrónica I+D, Orbis Tecnología Eléctrica.
Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #7/36
U4 ALGORITMOS GENÉTICOS

EJEMPLO 1
Problema del viajante: Introducción... (continuación)
El viajante parte inicialmente de la ciudad A y puede ir hacia cualquiera de las
restantes ciudades. En la figura se muestran todas las posibles combinaciones
que puede realizar el viajante.

Como puede verse, las


soluciones óptimas
son la 1ª y la 2ª pues
en ambas se recorren
todas las ciudades una
vez con la menor
distancia.

Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #8/36


U4 ALGORITMOS GENÉTICOS

EJEMPLO 1
Problema del viajante: Codificación... (continuación)
Para la formulación de los individuos se ha optado por codificar la existencia
de tramos recorridos. Los tramos posibles son seis: AB, BC, CD, DA, AC y BD,
luego los individuos pueden representarse como cadenas binarias de 6 bits.
individuo genérico
wi = [b5 b4 b3 b2 b1 b0] = [AB BC CD DA AC BD]

Si bi = 1  el tramo se recorre
Si bi = 0  el tramo no se recorre

Dist=4 Dist=4 wi = [1 1 1 1 0 0]

Dist = 2 + 2 2
wi = [1 0 1 0 1 1]

Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #9/36


U4 ALGORITMOS GENÉTICOS

EJEMPLO 1
Problema del viajante: Codificación... (continuación)
wi = [b5 b4 b3 b2 b1 b0] = [AB BC CD DA AC BD]
Se pueden generar representaciones incorrectas:

wi = [1 1 1 0 0 0]
No vuelve al origen

wi = [1 1 1 1 1 0]
Pasa 2 veces por
la misma ciudad

Estos individuos deberían tener menos posibilidades de evolucionar a


siguientes generaciones.
Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #10/36
U4 ALGORITMOS GENÉTICOS

EJEMPLO 1
Problema del viajante: Evaluación... (continuación)
wi = [b5 b4 b3 b2 b1 b0] = [AB BC CD DA AC BD]
El procedimiento utiliza dos funciones de evaluación parciales para controlar
dos condiciones importantes del problema. Luego se unifican.
Requerimientos de la 1º función de evaluación:
El número de tramos recorridos debe ser igual a 4. Requiere que se maximice
la ecuación:
L-1
C¯ åb
i=0
i

Fitness1(w i ) = 1 ¯
C
donde C es el número de ciudades, L es la longitud de la cadena de bits y bi es
el bit i-ésimo de la cadena de bits. De esta forma los individuos que recorran
sólo cuatro tramos obtendrán el valor máximo de la función de evaluación, es
decir:
Fitness1(wi)Sbi=4 = 1
Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #11/36
U4 ALGORITMOS GENÉTICOS

EJEMPLO 1
Problema del viajante: Evaluación... (continuación)
wi = [b5 b4 b3 b2 b1 b0] = [AB BC CD DA AC BD]

Requerimiento de la 2º función de evaluación:


La distancia recorrida debe ser mínima. En este caso la ecuación a minimizar
es:
L-1 L-1

å b .T i i å b .T i i

Fitness2(w i ) = i =0
L-1
Fitness2(w i ) = i =0
L-1

åb i
(corrección) åT
i =0
i
i =0

donde L es la longitud de la cadena de bits y bi es el bit i-ésimo de la cadena de


bits, Ti es la distancia del tramo i. Para i = 5, T5 es la distancia del tramo AB y
para i = 0, T0 es la distancia del tramo BD.

Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #12/36


U4 ALGORITMOS GENÉTICOS

EJEMPLO 1
Problema del viajante: Evaluación... (continuación)

Para satisfacer ambas condiciones, se configura una función combinada que


represente la aptitud de cada individuo:

Fitness(wi) = Fitness1(wi) – 0,1*Fitness2(wi)

La aptitud depende 10 veces más de la primera condición que de la segunda;


esto es así porque es indispensable que se recorran sólo 4 tramos, mientras
que la segunda condición da idea de qué individuo es el mejor dentro de los
seleccionados como válidos con la primera opción.

CONDICIÓN DE PARADA: se ha supuesto que un individuo es la solución


óptima si durante cinco generaciones su aptitud es la mayor de la población
y además no cambia.

Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #13/36


U4 ALGORITMOS GENÉTICOS

EJEMPLO 1
Problema del viajante: Población inicial... (continuación)
• 6 individuos iniciales elegidos de forma aleatoria.
(Heurística de Población = longitud de la cadena).
• La probabilidad de cruce PRcruce es del 40%.
• La probabilidad de mutación PRmut es del 1%.
• La selección de los individuos se realiza por selección
estocástica (dependiente de la aptitud relativa).
• Cruce monopunto.

FitTOT = 4,8638
Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #14/36
U4 ALGORITMOS GENÉTICOS

EJEMPLO 1
Problema del viajante: Evolución... (continuación)

Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #15/36


U4 ALGORITMOS GENÉTICOS

EJEMPLO 1
Problema del viajante: Conclusión... (continuación)

Se llega a la conclusión de que la 5º generación es más apta


que la anterior puesto que el valor de FitTOT actual (5,5936) es
mayor que el inicial (4,8638).

Si se deja evolucionar esta población durante 15 ciclos más, se


llega a la condición de parada ya que el individuo w3 tiene una
cadena (111100) constante durante 5 ciclos seguidos.

Extraído de RELLO R. M. “Algoritmos genéticos. Introducción métodos de búsqueda y


optimización”. Dpto. Electrónica I+D, Orbis Tecnología Eléctrica.
Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #16/36
U4 ALGORITMOS GENÉTICOS

EJEMPLO 2
Ejemplo desde la línea de comando:
Encontrar el mínimo de f(x)

function two_min.m
[x,fval] = ga(fitnessfcn,nvars)
>> [x,fval]=ga(@two_min,1)
Optimization terminated: average change in the fitness value less than options.
TolFun.
x = 0.0028
fval = -1.0000 (Parámetros por defecto)

No encuentra mínimo global porque no hay suficiente diversidad


de individuos → x  [0,1]
Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #17/36
U4 ALGORITMOS GENÉTICOS

EJEMPLO 2
Ejemplo desde la línea de comando:
Encontrar el mínimo de f(x)

function two_min.m

[x,fval] = ga(fitnessfcn,nvars,A,b,Aeq,beq,LB,UB)
>> [x,fval] = ga(@two_min,1,[ ],[ ],[ ],[ ],5,30)
Optimization terminated: average change in the fitness value less than options.
TolFun.
x = 21.0000
fval = -1.3679
Reconfigurando los límites encuentra el mínimo global → x  [5,30]
Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #18/36
U4 ALGORITMOS GENÉTICOS

EJEMPLO 3
Resolución de sistemas de ecuaciones
Idea general

Función de ajuste

Codificación de individuos

Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #19/36


U4 ALGORITMOS GENÉTICOS

EJEMPLO 3
Resolución de sistemas de ecuaciones
Función de ajuste
Esto se Esto se datos
busca mide

datos

incógnitas

m
Fitness = å bisistema - bicalculado
i =1

Para acercarse a la solución, el proceso requiere de minimización. Eso significa que


debe disminuir el fitness.

Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #20/36


U4 ALGORITMOS GENÉTICOS

EJEMPLO 3
Resolución de sistemas de ecuaciones
Sistema de 3 x 3
Parámetros del AG
§ Tamaño de población:
10 individuos
§ Elitismo: 2 individuos
§ Algoritmo selección:
torneo determinístico+aleatorio
§ Algoritmo cruce: 1 punto
§ Tasa de Cruce (Pc): 90%
§ Tasa de Mutación (Pm): 2.5%
§ Algoritmo mutación: puntual

Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #21/36


U4 ALGORITMOS GENÉTICOS

EJEMPLO 3
Resolución de sistemas de ecuaciones 3x3
estos rangos
se estiman →
codificación →
Generación 0

Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #22/36


U4 ALGORITMOS GENÉTICOS

EJEMPLO 3
Resolución de sistemas de ecuaciones 3x3
Generación temporal 0 - 1
primera inserción

elitismo →

elitismo →

Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #23/36


U4 ALGORITMOS GENÉTICOS

EJEMPLO 3
Resolución de sistemas de ecuaciones 3x3
Primer cruce: Se seleccionan dos individuos mediante el algoritmo de torneo
determinístico (p=2), por ej. 3 y 8 de la población; queda el que tenga mejor
fitness (3), que será el primer progenitor. El segundo progenitor se
seleccionará al azar, por ejemplo el individuo número 7.
Se deberá determinar si se procede o no la cruza, aplicando la probabilidad de
cruza (Pc=0.9 ; 90%). Se genera un número al azar en [0 ; 1] y, si este es
menor que la tasa de cruce Pc, se procede. Supóngase que el número
aleatorio generado es 0,69 la cruza procede. Se selecciona un punto de cruce
aleatorio entre 1 y 2, resultando 1.
I 3 - fitness 28,97

I 7 - fitness 91,02 cruza


Pc=0.69

Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #24/36


U4 ALGORITMOS GENÉTICOS

EJEMPLO 3
Resolución de sistemas de ecuaciones 3x3
Mutación luego del primer cruce: Se generan dos números aleatorios para
determinar si procede la mutación, que deben ser menores a la tasa de
mutación (Pm=0,025 ; 2,5%).
Sea por ejemplo N1=0,013 y N2=0,234. La mutación será para el primer
descendiente. Se selecciona un gen (casillero) al azar, siendo el número 2.

Desc. 1 - fitness 107,27 Desc. 1 mutado - fitness 128,60


muta

Operador de mutación --> cambio aleatorio

En este caso, al contrario de lo ocurrido con la operación de cruce, el nuevo


individuo presenta un peor ajuste que el original. Esta situación no es extraña
ni tiene porqué ser perjudicial, puede ayudar a diversificar la población.

Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #25/36


U4 ALGORITMOS GENÉTICOS

EJEMPLO 3
Resolución de sistemas de ecuaciones 3x3

Generación temporal 0 - 1
segunda inserción

elitismo →
elitismo →
2º descendiente
de cruza →
1º desc. de
cruza mutado →

Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #26/36


U4 ALGORITMOS GENÉTICOS

EJEMPLO 3
Resolución de sistemas de ecuaciones 3x3
Segundo cruce: Se seleccionan dos individuos, por ej. 8 y 9 de la población;
queda el que tenga mejor fitness (8), que será el primer progenitor. El segundo
progenitor se seleccionará al azar, por ejemplo el individuo número 3.

Se deberá determinar si se procede o no la cruza, aplicando la probabilidad


de cruza (Pc=0,9 ; 90%). Se genera un número al azar en [0 ; 1]. En este caso
el número aleatorio generado es 0,97 y la cruza NO procede.
Los individuos seleccionados pasan directamente a la población temporal.

I 8 - fitness 117,15
4,50 0,69 -4,58
directamente a la
I 3 - fitness 28,97 cruza población temporal
-6,36 5,67 0,74

Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #27/36


U4 ALGORITMOS GENÉTICOS

EJEMPLO 3
Resolución de sistemas de ecuaciones 3x3

Generación temporal 0 - 1
tercera inserción

elitismo →
elitismo →
2º descendiente
de cruza →
I3→
I8→
1º desc. de
cruza mutado →

Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #28/36


U4 ALGORITMOS GENÉTICOS

EJEMPLO 3
Resolución de sistemas de ecuaciones 3x3
Tercer cruce: Se seleccionan dos individuos mediante el algoritmo de torneo
determinístico (p=2), por ej. 8 y 9 de la población; queda el que tenga mejor
fitness (8), que será el primer progenitor. El segundo progenitor se seleccionará
al azar, por ejemplo el individuo número 10.
Se deberá determinar si procede o no la cruza, aplicando la probabilidad de
cruza (Pc=0,9 ; 90%). Se genera un número al azar en [0 ; 1] y, si este es menor
que la tasa de cruce Pc, se procede. El número aleatorio generado es 0,62 la
cruza procede. Se selecciona un punto de cruce aleatorio entre 1 y 2,
resultando 1.
I 8 - fitness 117,15

I 10 - fitness 233,81 cruza

Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #29/36


U4 ALGORITMOS GENÉTICOS

EJEMPLO 3
Resolución de sistemas de ecuaciones 3x3
Mutación luego del tercer cruce: Se generan dos números aleatorios para
determinar si procede la mutación, que deben ser menores a la tasa de
mutación (Pm=0,025 ; 2,5%).
Sea por ejemplo N1=0,731 y N2=0,026. La mutación NO procede.

Desc. 3 - fitness 233,63

directamente a la
muta población temporal
Desc. 4 - fitness 117,33

Los dos nuevos descendientes, sin mutación, pasan a la población temporal


0-1
Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #30/36
U4 ALGORITMOS GENÉTICOS

EJEMPLO 3
Resolución de sistemas de ecuaciones 3x3
Generación temporal 0 - 1
cuarta inserción

elitismo →
elitismo →
2º descendiente
de cruza →
I3→
I8→
4º desc. de
cruza sin mutar →
1º desc. de
cruza mutado →
3º desc. de
cruza sin mutar → C

Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #31/36


U4 ALGORITMOS GENÉTICOS

EJEMPLO 3
Resolución de sistemas de ecuaciones 3x3
Cuarto cruce: Se seleccionan dos individuos mediante el algoritmo de torneo
determinístico (p=2), por ej. 2 y 6 de la población; queda el que tenga mejor
fitness (2), que será el primer progenitor. El segundo progenitor se seleccionará
al azar, por ejemplo el individuo número 8.
Se deberá determinar si procede o no la cruza, aplicando la probabilidad de
cruza (Pc=0,9 ; 90%). Se genera un número al azar en [0 ; 1] y, si este es menor
que la tasa de cruce Pc, se procede. El número aleatorio generado es 0,27 la
cruza procede. Se selecciona un punto de cruce aleatorio entre 1 y 2,
resultando 2.
I 2 - fitness 14,64

I 8 - fitness 117,15 cruza

Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #32/36


U4 ALGORITMOS GENÉTICOS

EJEMPLO 3
Resolución de sistemas de ecuaciones 3x3
Mutación luego del cuarto cruce: Se generan dos números aleatorios para
determinar si procede la mutación, que deben ser menores a la tasa de
mutación (Pm=0,025 ; 2,5%).
Sea por ejemplo N1=0,551 y N2=0,020. La mutación será para el segundo
descendiente (sexto general). Se selecciona un gen (casillero) al azar, siendo
el número 3.

Desc.6 - fitness 11,75 Desc. 6 mutado - fitness 3,08


muta
Op.mutación --> cambio aleatorio

En este caso, la mutación ha mejorado bastante al individuo. Ambos


descendientes se pasan a la generación temporal 0 - 1.

Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #33/36


U4 ALGORITMOS GENÉTICOS

EJEMPLO 3
Resolución de sistemas de ecuaciones 3x3
Generación temporal 0 - 1
quinta inserción

6º desc. de
cruza mutado →
elitismo →
6º desc. de cruza
no mutado →
elitismo →
2º descendiente
de cruza →
I3→
I8→
4º desc. de cruza
sin mutar →
1º desc. de
cruza mutado →
3º desc. de cruza
sin mutar →

Como la generación temporal 0 - 1 está completa, se convierte en la GENERACIÓN 1.


Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #34/36
U4 ALGORITMOS GENÉTICOS

EJEMPLO 3
Resolución de sistemas de ecuaciones 3x3
Generación 1
Se verifica la solución con el mejor
individuo de la Generación 1 → I 1.

Resultado obtenido en una sola iteración


del AG.

Ver la codificación de este ejemplo, para MatLab, en Gestal, pg. 36.

Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #35/36


U4 ALGORITMOS GENÉTICOS

APLICACIONES DE LOS AG
Considerando que la habilidad principal de los AG es la búsqueda y
optimización, tienen aplicaciones en los más diversos campos.
Algunas de estas aplicaciones:
• Diseño de circuitos VLSI.
• Optimización del tamaño de enlaces en una red de comunicaciones.
• Optimización del cableado de circuitos eléctricos.
• Problema del viajante.
• Minimización/maximización de funciones.
• Procesamiento de imágenes.
• Reconocimiento de patrones.
• Optimización de reglas en una base.
Mg. Sergio L. Martínez - Cátedra de Inteligencia Artificial - FI.UNJu 4.2. #36/36

También podría gustarte