LupercAI / pages /vrp /Evolucion.py
ML-INTA's picture
Upload 10 files
1c5e165
raw
history blame
2.39 kB
#VERSIÓN 4: VERSIÓN SEMI-ORIENTADA A OBJETOS
#(F): A añadir en (F)uturas versiones
### FUNCIONES AUXILIARES ###
import random
from .Reparto import Reparto
def mejor_individuo(list_individuos : list[Reparto]) -> Reparto: #paralelizable
mejor_individuo = list_individuos[0]
for individuo in list_individuos[1:]:
mejor_individuo = individuo if individuo.coste < mejor_individuo.coste else mejor_individuo
#print("mejor_individuo: ", mejor_individuo.ruta, mejor_individuo.coste)
return mejor_individuo
class Evolucion:
@staticmethod
def elitismo(poblacion : list[Reparto]) -> Reparto: #mejor ruta de la poblacion
return mejor_individuo(poblacion)
@staticmethod
def torneo(poblacion : list[Reparto], tamano_torneo) -> list[Reparto]: #mejor ruta de una parte de la poblacion
selected_individuos = random.sample(poblacion, tamano_torneo)
return mejor_individuo(selected_individuos)
@staticmethod
def mutate(ruta : Reparto) -> Reparto: #intercambia dos posiciones en la ruta
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: #cruza dos rutas, pegando un cacho de la primera en la segunda
num_total = Reparto.grafo.num_nodos + Reparto.vehiculos.num_vehiculos - 2
#-1 por el Almacén
#-1 porque si hay n vehiculos, solo añadimos n-1 simbolos
start = random.randint(0, num_total - 1) #random.randint(a, b) toma un número entero al azar entre [a,b], no entre [a,b)
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)