bam1006 / SistemasP3

practica 3 de sistemas
0 stars 0 forks source link

Configurar los parámetros y operadores del algoritmo genético que permita obtener el calendario de turnos más óptimo posible. #2

Open bam1006 opened 10 months ago

bam1006 commented 10 months ago
import turnosenfermeria as clase
import random
from deap import base, tools

longitud = 7*3*len(enfermeros)
tam_poblacion = 200
toolbox=base.Toolbox()
toolbox.register("ceroOrUno",random.randint,0,1)
toolbox.register("individual",tools.initRepeat,list,toolbox.ceroOrUno, longitud)
toolbox.register("creaPoblacion",tools.initRepeat,list,toolbox.individual)
poblacion=toolbox.creaPoblacion(n=tam_poblacion)
turno = clase.TurnosEnfermeria(enfermeros, preferencias, 7)
turno.getCoste(poblacion[0])
psv1002 commented 10 months ago

import turnosenfermeria as clase import random from deap import base, tools

longitud = 73len(enfermeros) tam_poblacion = 200 num_generaciones = 50 prob_cruce = 0.9 prob_mutacion = 0.1

Creamos la clase

toolbox=base.Toolbox() toolbox.register("ceroOrUno",random.randint,0,1) toolbox.register("individual",tools.initRepeat,list,toolbox.ceroOrUno, longitud) toolbox.register("creaPoblacion",tools.initRepeat,list,toolbox.individual) poblacion=toolbox.creaPoblacion(n=tam_poblacion)

Añado los operadores

toolbox.register("select", tools.selTournament, tournsize=3) toolbox.register("mate", tools.cxOnePoint) toolbox.register("mutate", tools.mutFlipBit, indpb=1.0/longitud)

turno = clase.TurnosEnfermeria(enfermeros, preferencias, 7) turno.getCoste(poblacion[0])

psv1002 commented 10 months ago

import turnosenfermeria as clase import random from deap import base, tools

longitud = 73len(enfermeros) tam_poblacion = 200 num_generaciones = 50 prob_cruce = 0.9 prob_mutacion = 0.1

Creamos la clase

toolbox=base.Toolbox() toolbox.register("ceroOrUno",random.randint,0,1) toolbox.register("individual",tools.initRepeat,list,toolbox.ceroOrUno, longitud) toolbox.register("creaPoblacion",tools.initRepeat,list,toolbox.individual) poblacion=toolbox.creaPoblacion(n=tam_poblacion)

toolbox.register("select", tools.selTournament, tournsize=3) toolbox.register("mate", tools.cxOnePoint) toolbox.register("mutate", tools.mutFlipBit, indpb=1.0/longitud)

turno = clase.TurnosEnfermeria(enfermeros, preferencias, 7)

Dado que se requiere obtener el calendario de turnos más óptimo posible

def costeInfracciones(individual): return turno.getCoste(individual),

toolbox.register("evaluate", costeInfracciones)

bam1006 commented 10 months ago

he copiado gran parte de n reinas y onemax y he cambiado los tipos de cruces porque me salian costes muy muy bajos

bam1006 commented 10 months ago

y ademas he añadido lo de media, desviacion estandar y tal

bam1006 commented 10 months ago

creo que hay que cambiar cosillas porque tengo que entender alguna cosa pero bueno

bam1006 commented 10 months ago
from deap import creator, base, tools
import numpy as np
import elitism
from deap import algorithms
import random
import turnosenfermeria as clase

longitud = 7*3*len(enfermeros)
tam_poblacion = 200
num_generaciones = 50
prob_cruce = 0.9
prob_mutacion = 0.1
turno = clase.TurnosEnfermeria(enfermeros, preferencias, 7)

toolbox=base.Toolbox()
creator.create("AjusteMin", base.Fitness, weights=(-1.0,))
creator.create("Individuo",list, fitness=creator.AjusteMin)

#modificamos la definición de invididuo para incluir la función de ajuste:
toolbox.register("ceroOrUno",random.randint,0,1)
toolbox.register("individual",tools.initRepeat,creator.Individuo,toolbox.ceroOrUno, longitud)
toolbox.register("creaPoblacion",tools.initRepeat,list,toolbox.individual)
toolbox.register("evaluate",turno.getCoste) 
poblacion=toolbox.creaPoblacion(n=tam_poblacion)

toolbox.register("evaluate",turno.getCoste)

toolbox.register("select", tools.selTournament, tournsize=2)
# toolbox.register("mate", tools.cxPartialyMatched)
toolbox.register("mate", tools.cxTwoPoint)
toolbox.register("mutate", tools.mutFlipBit,indpb=1.0/longitud)

stats=tools.Statistics(lambda ind: ind.fitness.values)
stats.register("avg",np.mean)
stats.register("std",np.std)
stats.register("max",np.max)
stats.register("min",np.min)

hof=tools.HallOfFame(50)

poblacion_final, logbook= elitism.eaSimpleWithElitism(poblacion, toolbox,
                                             cxpb=prob_cruce, mutpb=prob_mutacion,
                                             ngen=num_generaciones,
                                             stats=stats,halloffame=hof,
                                             verbose=True)
# print(poblacion_final, logbook,hof)
for e in poblacion:
    print(turno.getCoste(e))
bam1006 commented 10 months ago

hay una funcion de cruce que esta comentada porque creo que son parecidas de buenas las dos

bam1006 commented 10 months ago
from deap import creator, base, tools
import numpy as np
import elitism
from deap import algorithms
import random
import turnosenfermeria as clase

longitud = 7*3*len(enfermeros)
tam_poblacion = 200
num_generaciones = 50
prob_cruce = 0.9
prob_mutacion = 0.1
turno = clase.TurnosEnfermeria(enfermeros, preferencias, 6)

toolbox=base.Toolbox()
creator.create("AjusteMin", base.Fitness, weights=(-1.0,))
creator.create("Individuo",list, fitness=creator.AjusteMin)

#modificamos la definición de invididuo para incluir la función de ajuste:
toolbox.register("ceroOrUno",random.randint,0,1)
toolbox.register("individual",tools.initRepeat,creator.Individuo,toolbox.ceroOrUno, longitud)
toolbox.register("creaPoblacion",tools.initRepeat,list,toolbox.individual)
toolbox.register("evaluate",turno.getCoste) 
poblacion=toolbox.creaPoblacion(n=tam_poblacion)

toolbox.register("evaluate",turno.getCoste)
toolbox.register("select", tools.selTournament, tournsize=3)
toolbox.register("mate", tools.cxUniform, indpb=0.5)
toolbox.register("mutate", tools.mutShuffleIndexes, indpb=1.0/longitud)

stats=tools.Statistics(lambda ind: ind.fitness.values)
stats.register("avg",np.mean)
stats.register("std",np.std)
stats.register("max",np.max)
stats.register("min",np.min)

hof=tools.HallOfFame(50)

poblacion_final, logbook= elitism.eaSimpleWithElitism(poblacion, toolbox,
                                             cxpb=prob_cruce, mutpb=prob_mutacion,
                                             ngen=num_generaciones,
                                             stats=stats,halloffame=hof,
                                             verbose=True)
# print(poblacion_final, logbook,hof)

# para ver de todos los calendarios cual tiene menor coste
lista = []
for e in poblacion:
    lista.append(turno.getCoste(e))
print(min(lista))    
# print(turno.getCoste(poblacion[0]))
# print(turno.countInfracionesTurnosMismoDia(turno.getTurnosEnfermeria(poblacion[0])))
# print(turno.mostrarInfoCalendario(poblacion[0]))
# print(poblacion[0])
bam1006 commented 10 months ago

los costes mas bajos me han salido con este mate y mutate

psv1002 commented 10 months ago
#Con esto vemos los resultados a modo de gráfica
def plot_evolucion(log, titulo="Evolución en las Generaciones"):
    import matplotlib.pyplot as plt
    import numpy as np
    gen=log.select("gen")
    fit_mins=log.select("min")
    fit_maxs= log.select("max")
    fit_means=log.select("avg")

    fig,ax = plt.subplots()

    ax.plot(gen,fit_mins,color="green")
    ax.plot(gen,fit_maxs,color="red")
    ax.plot(gen,fit_means,linestyle="--", color="blue")
    fit_mins=np.array(fit_mins)
    fit_maxs=np.array(fit_maxs)   
    ax.fill_between(gen,fit_mins,fit_maxs,where=(fit_maxs>=fit_mins), facecolor='y', alpha=0.2)

    ax.set_xlabel("Generación")
    ax.set_ylabel("Ajuste (fitness)")
    ax.set_ylim([0,110])
    ax.legend(["Min","Max","Media"])
    ax.set_title(titulo)
    plt.grid(True)

plot_evolucion(logbook)