Untitled
unknown
plain_text
2 years ago
9.4 kB
8
Indexable
# Inicialización de variables
pCrossover = 0.75 # probabilidad de cruce
pMutación = 0.05 # probabilidad de mutación
poblacion = 10
ciclos = int(input("Ingresa el número de ciclos: "))
cantGenes = 30
cromosomas = []
cromosomasValor = []
cromosomasFuncObj = []
cromosomasFitness = []
nueva_generacion = []
maxFuncObj = 0
elitismo = True
torneo = True
cantCromosomasElite = 2
cantTorneo = 4
nombre_Excel = "TP1.xlsx"
# Definición de funciones
# Inicializa un archivo de Excel para almacenar los resultados
def inicializarExcel():
global worksheet, workbook
workbook = xlsxwriter.Workbook(nombre_Excel)
worksheet = workbook.add_worksheet()
worksheet.write(0, 0, "Ciclo")
worksheet.write(0, 1, "Mínimo")
worksheet.write(0, 2, "Máximo")
worksheet.write(0, 3, "Promedio")
worksheet.write(0, 4, "Cromosoma máximo decimal")
worksheet.write(0, 5, "Cromosoma máximo")
# Cierra el archivo de Excel una vez que se han guardado todos los datos
def cerrarExcel():
# Cerrar el archivo de Excel
workbook.close()
# Guarda los resultados de cada ciclo en el archivo de Excel
def guardarDatos(i):
cont = i + 1
worksheet.write(cont, 0, i + 1)
worksheet.write(cont, 1, min(cromosomasFuncObj))
worksheet.write(cont, 2, maxFuncObj)
worksheet.write(cont, 3, sum(cromosomasFuncObj) / len(cromosomasFuncObj))
worksheet.write(cont, 4, max(cromosomasValor))
worksheet.write(cont, 5, max(cromosomas))
# Selecciona los cromosomas con mayor aptitud para la siguiente generación y se agregan a la lista de cromosomas élite
def aplicarElitismo():
global cromosomas, cromosomasFitness
cromosomasElite = []
cromos = cromosomasFitness[:]
indice_maximo = cromosomasFitness.index(max(cromos))
cromosomasElite.append(cromosomas[indice_maximo])
cromos.pop(indice_maximo)
indice_maximo = cromosomasFitness.index(max(cromos))
cromosomasElite.append(cromosomas[indice_maximo])
""" for i in range(cantCromosomasElite):
#seleccionar cromosoma con mayor fitness
print(f' tamaño cromo {len(cromos)}')
print(f' tamaño indice {indice_maximo}')
cromos.pop(indice_maximo )"""
return cromosomasElite
# Realiza una selección basada en el método de la ruleta
def seleccionRuleta():
parejas = [] # Lista que almacenará las dos parejas
for i in range(2):
numero_aleatorio = random.uniform(0, 1)
probabilidad_acumulada = 0
for j, probabilidad in enumerate(cromosomasFitness):
probabilidad_acumulada += probabilidad
if probabilidad_acumulada >= numero_aleatorio:
parejas.append(
j
) # Agregamos el elemento seleccionado a la lista de parejas
break
return parejas # Retornamos la lista con las dos parejas seleccionadas
# Realiza una selección basada en el método del torneo
def seleccionTorneo():
parejas = [] # Lista que almacenará las dos parejas
torneo = []
for _ in range(2):
for _ in range(cantTorneo):
index = random.randrange(poblacion) # seleccion de poblacion para eltorneo
torneo.append(cromosomasFitness[index])
seleccionado = max(torneo) # ganador del torneo
indice = cromosomasFitness.index(seleccionado)
parejas.append(
indice
) # Agregamos el elemento seleccionado a la lista de parejas
return parejas
# Calcula la aptitud de un cromosoma dividiendo su valor de función objetivo entre la suma de todas las funciones objetivo de la población
def funcFitness(valorFuncObj):
return valorFuncObj / sum(cromosomasFuncObj)
# Calcula la función objetivo para un valor dado
def funcObjetivo(x):
return x / ((2**30) - 1)
def iniciarCromosomas():
global maxFuncObj
for i in range(0, poblacion):
genes = (
np.random.rand(cantGenes) < 0.5
) # genera una lista aleatoria de genes con true o false
# Genera la cadena de genes binario
genes_binario = ""
for g in genes:
genes_binario += str(int(g))
# Agrega los genes a la lista de cromosomas, el valor entero y valor de la funcion objetivo
cromosomas.append(genes_binario)
cromosomasValor.append(int(genes_binario, 2))
cromosomasFuncObj.append(funcObjetivo(cromosomasValor[i]))
# Agrega los cromosomas a la lista de cromosomas fitness
for x in cromosomasFuncObj:
cromosomasFitness.append(funcFitness(x))
maxFuncObj = max(cromosomasFuncObj)
# Genera una nueva generación de cromosomas a partir de dos cromosomas padre seleccionados
def nuevaGenracion(cromo1, cromo2):
cromosoma1 = cromosomas[cromo1]
cromosoma2 = cromosomas[cromo2]
# crossover o cruce
if (random.uniform(0, 1)) < pCrossover:
rango = random.randrange(cantGenes) # punto de corte de los genes
aux1 = cromosoma1[:rango] + cromosoma2[rango:]
aux2 = cromosoma2[:rango] + cromosoma1[rango:]
cromosoma1 = aux1
cromosoma2 = aux2
# mutacion
""" for i in range(cantGenes):
if random.uniform(0, 1) < pMutación:
cromosoma1 = cromosoma1[:i] + str(int(not int(cromosoma1[i]))) + cromosoma1[i+1:]
if random.uniform(0, 1) < pMutación:
cromosoma2 = cromosoma2[:i] + str(int(not int(cromosoma2[i]))) + cromosoma2[i+1:] """
pm1 = random.uniform(0, 1)
pm2 = random.uniform(0, 1)
cromosoma1_lista = list(cromosoma1)
cromosoma2_lista = list(cromosoma2)
if pm1 < pMutación:
gen = random.randrange(cantGenes)
if cromosoma1[gen] == 0:
cromosoma1_lista[gen] = 1 # Intercambio
else:
cromosoma1_lista[gen] = 0
if pm2 < pMutación:
gen = random.randrange(cantGenes)
if cromosoma2[gen] == 0:
cromosoma2_lista[gen] = 1 # Intercambio
else:
cromosoma2_lista[gen] = 0
# print("".join(str(x) for x in cromosoma1_lista))
cromosoma1 = "".join(str(x) for x in cromosoma1_lista)
cromosoma2 = "".join(str(x) for x in cromosoma2_lista)
# print("".join(str(x) for x in cromosoma2_lista))
return cromosoma1, cromosoma2
# Calcula los valores de los cromosomas, las funciones objetivo y la aptitud para una nueva generación
def calcularValores(nueva_generacion):
global cromosomasFitness, maxFuncObj
i = 0
cromosomasFitness = []
for genes in nueva_generacion:
cromosomasValor.append(int(genes, 2))
cromosomasFuncObj.append(funcObjetivo(cromosomasValor[i]))
i += 1
for x in cromosomasFuncObj:
cromosomasFitness.append(funcFitness(x))
maxFuncObj = max(cromosomasFuncObj)
# Función principal que ejecuta el algoritmo genético
def iniciar():
global cromosomas, cromosomasValor, cromosomasFuncObj
# iniciar primera generacion
iniciarCromosomas()
# generar nuevas generaciones
nueva_generacion = cromosomas.copy()
for i in range(ciclos):
cromosomas = nueva_generacion
print("---------------------------------------------")
print(f"GENERACION {i+1}")
print(f"Cromosomas, {cromosomas}")
print(f"valores, {cromosomasValor}")
print(f"Funcion objetivo, {cromosomasFuncObj}")
print(f"Funcion Fitness, {cromosomasFitness}")
# valores a guardar
guardarDatos(i)
print(f"maximo cromosomas: {max(cromosomas)} ")
print(f"maximo cromosomas decimal: {max(cromosomasValor)} ")
print(f"Minimo funcObj, {min(cromosomasFuncObj)}")
print(f"Maximo funcObj, {maxFuncObj}")
print(f"Promedio funcObj, {sum(cromosomasFuncObj)/len(cromosomasFuncObj)}")
nueva_generacion = []
cromosomasValor = []
cromosomasFuncObj = []
if elitismo:
cromosomasElite = aplicarElitismo()
nueva_generacion.append(cromosomasElite[0])
nueva_generacion.append(cromosomasElite[1])
for i in range(int((poblacion - cantCromosomasElite) / 2)):
# Seleccion de parejas
if torneo:
parejas = seleccionTorneo()
else:
parejas = seleccionRuleta()
# Generar nueva generacion
result = nuevaGenracion(parejas[0], parejas[1])
nueva_generacion.append(result[0])
nueva_generacion.append(result[1])
calcularValores(nueva_generacion)
else:
for i in range(int(poblacion / 2)):
# Seleccion de parejas
if torneo:
parejas = seleccionTorneo()
else:
parejas = seleccionRuleta()
# print(parejas)
# Generar nueva generacion
result = nuevaGenracion(parejas[0], parejas[1])
nueva_generacion.append(result[0])
nueva_generacion.append(result[1])
calcularValores(nueva_generacion)
inicializarExcel()
iniciar()
cerrarExcel() # Se cierra el archivo de Excel y se guardan los datos
Editor is loading...