Untitled
unknown
plain_text
a year ago
9.4 kB
1
Indexable
Never
# 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