|
|
|
|
|
|
|
|
|
|
|
import random |
|
|
|
from .Reparto import Reparto |
|
|
|
|
|
def mejor_individuo(list_individuos : list[Reparto]) -> Reparto: |
|
mejor_individuo = list_individuos[0] |
|
for individuo in list_individuos[1:]: |
|
mejor_individuo = individuo if individuo.coste < mejor_individuo.coste else mejor_individuo |
|
|
|
return mejor_individuo |
|
|
|
class Evolucion: |
|
|
|
@staticmethod |
|
def elitismo(poblacion : list[Reparto]) -> Reparto: |
|
return mejor_individuo(poblacion) |
|
|
|
@staticmethod |
|
def torneo(poblacion : list[Reparto], tamano_torneo) -> list[Reparto]: |
|
selected_individuos = random.sample(poblacion, tamano_torneo) |
|
return mejor_individuo(selected_individuos) |
|
|
|
@staticmethod |
|
def mutate(ruta : Reparto) -> Reparto: |
|
idx1, idx2 = random.sample(range(Reparto.grafo.num_nodos + Reparto.vehiculos.num_vehiculos - 2), 2) |
|
lista = ruta.ruta.copy() |
|
lista[idx1], lista[idx2] = lista[idx2], lista[idx1] |
|
return Reparto(lista) |
|
|
|
@staticmethod |
|
def crossover(parent1 : Reparto, parent2 : Reparto) -> Reparto: |
|
num_total = Reparto.grafo.num_nodos + Reparto.vehiculos.num_vehiculos - 2 |
|
|
|
|
|
|
|
start = random.randint(0, num_total - 1) |
|
end = random.randint(start, num_total - 1) |
|
|
|
child = [None] * num_total |
|
|
|
for i in range(start, end+1): |
|
child[i] = parent1.ruta[i] |
|
remaining = [item for item in parent2.ruta if item not in child] |
|
remaining_index = 0 |
|
for i in range(num_total): |
|
if child[i] == None: |
|
child[i] = remaining[remaining_index] |
|
remaining_index += 1 |
|
|
|
return Reparto(child) |
|
|
|
|