File size: 2,772 Bytes
1c5e165
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#VERSIÓN 4: VERSIÓN SEMI-ORIENTADA A OBJETOS
#(F): A añadir en (F)uturas versiones

### CLASES DEL ALGORITMO ###

from .Reparto import Reparto, division_rutas

class Algoritmo_Genetico:
    def __init__(self, tamano_poblacion : int = 50, generaciones : int = 100, tamano_torneo : int = 5, 
                  crossover_prob : float = 0.8, mutation_prob : float = 0.2):
                
        #Variables del algoritmo (int)
        self.tamano_poblacion = tamano_poblacion
        self.generaciones = generaciones
        self.tamano_torneo = tamano_torneo

        #Variables del algoritmo (%)
        self.crossover_prob = crossover_prob
        self.mutation_prob = mutation_prob

        #Variables en ejecución
        self.generacion_actual = 0
        self.mejor_candidato = ([[1,2,3],[4]], float("inf"))


    def _poblar(self, grafo, vehiculos):
        Reparto.grafo = grafo
        Reparto.vehiculos = vehiculos
        return crear_poblacion(self)

    def generar(self, grafo, vehiculos): 

        #print("##############\n##EMPEZAMOS               \n##############")

        Poblacion = self._poblar(grafo, vehiculos)
        poblacion = Poblacion()

        from time import sleep

        for _ in range(self.generaciones):
            sleep(0.1)
            poblacion = poblacion.evolucionar()
            self.generacion_actual = self.generacion_actual + 1
            self.mejor_candidato = (division_rutas(poblacion.poblacion[0]), poblacion.poblacion[0].coste)

        from .Evolucion import mejor_individuo

        return mejor_individuo(poblacion.poblacion)
    
def crear_poblacion(alg_genetico : Algoritmo_Genetico): #quizas haga falta , clase_Reparto : type = Reparto
    import random    

    from .Evolucion import Evolucion

    class Poblacion:
        def __init__(self, poblacion : list[Reparto] = [Reparto()]*alg_genetico.tamano_poblacion):
            self.poblacion = poblacion

        def evolucionar(self):
            new_poblacion = [Evolucion.elitismo(self.poblacion)]

            for _ in range(alg_genetico.tamano_poblacion - 1):
                new_poblacion += [self._evolucionar_individuo()]

            return Poblacion(new_poblacion)

        def _evolucionar_individuo(self):              
            parent1 = Evolucion.torneo(self.poblacion, alg_genetico.tamano_torneo)            

            child = parent1

            if random.random() < alg_genetico.crossover_prob: #Cruce %
                parent2 = Evolucion.torneo(self.poblacion, alg_genetico.tamano_torneo)     
                child = Evolucion.crossover(parent1, parent2)
            if random.random() < alg_genetico.mutation_prob: #Mutación %
                child = Evolucion.mutate(child)

            return child

    return Poblacion