ML-INTA commited on
Commit
d8c09b0
1 Parent(s): 7345a4d

Delete pages

Browse files
pages/Ejecucion.py DELETED
@@ -1,108 +0,0 @@
1
- import streamlit as st
2
-
3
- from pages.vrp.Origen import Grafo, Vehiculos
4
- from pages.vrp.Algoritmo_genético import Algoritmo_Genetico
5
-
6
- #######################
7
- ## FUNCIONES AUXILIARES
8
- #######################
9
-
10
- def grafar(reparto : list[list[int]]):
11
-
12
- result = "digraph { \n"
13
-
14
- for ruta in reparto:
15
- result += "Almacén ->"
16
- for nodo in ruta:
17
- result += str(nodo) + "\n"
18
- result += str(nodo) + "->"
19
- result += "Almacén \n"
20
-
21
- result += "}"
22
-
23
- return result
24
-
25
- def presentar(reparto : list[list[int]]):
26
-
27
- result = ""
28
-
29
- for i in range(len(reparto)):
30
- result += "Camion " + str(i) + ": " + "Almacén -> "
31
- for parada in reparto[i]:
32
- result += str(parada) + " -> "
33
- result += "Almacén \n"
34
-
35
- return result
36
-
37
- st.set_page_config(page_title="LupercAI", page_icon= "🚛")
38
-
39
- st.title("LupercAI 🚛")
40
-
41
- valores_vitales = ["distancias", "demandas_clientes", "capacidad_vehiculos"]
42
- importado = True
43
- for valor in valores_vitales: importado = importado and valor in st.session_state
44
-
45
- if not importado:
46
- st.warning("Faltan datos", icon="⚠️")
47
- else:
48
- #if "num_nodos" not in st.session_state: st.session_state["num_nodos"] = len(st.session_state["demandas_clientes"])
49
- #if "num_vehiculos" not in st.session_state: st.session_state["num_vehiculos"] = len(st.session_state["capacidad_vehiculos"])
50
-
51
- grafo = Grafo(st.session_state["distancias"], st.session_state["demandas_clientes"])
52
- vehiculos = Vehiculos(st.session_state["capacidad_vehiculos"])
53
-
54
- if "activar_generaciones" in st.session_state:
55
- if st.session_state["activar_generaciones"]:
56
- if "alg_genetico" not in st.session_state: st.session_state["alg_genetico"] = Algoritmo_Genetico(tamano_poblacion = st.session_state["tamano_poblacion"],
57
- generaciones = st.session_state["generaciones"], tamano_torneo = st.session_state["tamano_torneo"],
58
- crossover_prob = st.session_state["crossover_prob"], mutation_prob = st.session_state["mutation_prob"])
59
- else:
60
- if "alg_genetico" not in st.session_state: st.session_state["alg_genetico"] = Algoritmo_Genetico()
61
- else:
62
- if "alg_genetico" not in st.session_state: st.session_state["alg_genetico"] = Algoritmo_Genetico()
63
-
64
- alg_genetico = st.session_state["alg_genetico"]
65
-
66
- from threading import Thread
67
- Thread(target=alg_genetico.generar, args = (grafo, vehiculos)).start()
68
-
69
-
70
- #Computación:
71
-
72
- empty_latest_iteration = st.empty()
73
- empty_mejor_coste = st.empty()
74
-
75
- st.subheader("Barra de progreso")
76
- barra_progreso = st.progress(0)
77
-
78
- st.subheader("Grafo del mejor recorrido actual")
79
-
80
- empty_txt = st.empty()
81
-
82
- empty_grafo = st.empty()
83
-
84
- i = 0
85
- while alg_genetico.generacion_actual < alg_genetico.generaciones:
86
- #Generación por escrito
87
- empty_latest_iteration.write("Generación: " + str(alg_genetico.generacion_actual))
88
-
89
- #Barra de progreso
90
- barra_progreso.progress( alg_genetico.generacion_actual/alg_genetico.generaciones)
91
-
92
- #Mejor coste actual (texto)
93
- empty_mejor_coste.write("**Mejor coste**: " + str(alg_genetico.mejor_candidato[1]))
94
-
95
- #Descarga de grafo
96
- empty_txt.download_button("Mejor recorrido 🔽", presentar(alg_genetico.mejor_candidato[0]), file_name="Mejor reparto - Generacion " + str(alg_genetico.generacion_actual) + ".txt", key=str(i))
97
- i += 1
98
-
99
- #Mostrar el grafo
100
- empty_grafo.graphviz_chart(grafar(alg_genetico.mejor_candidato[0]))
101
-
102
-
103
- #Ultima iteracion
104
- empty_latest_iteration.write("Generación: " + str(alg_genetico.generacion_actual))
105
- barra_progreso.progress( alg_genetico.generacion_actual/alg_genetico.generaciones)
106
- empty_mejor_coste.write("**Mejor coste**: " + str(alg_genetico.mejor_candidato[1]))
107
- empty_txt.download_button("Mejor recorrido 🔽", presentar(alg_genetico.mejor_candidato[0]), file_name="Mejor reparto - Generacion " + str(alg_genetico.generacion_actual) + ".txt", key=str(i))
108
- empty_grafo.graphviz_chart(grafar(alg_genetico.mejor_candidato[0]))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
pages/vrp/Algoritmo_genético.py DELETED
@@ -1,84 +0,0 @@
1
- #VERSIÓN 4: VERSIÓN SEMI-ORIENTADA A OBJETOS
2
- #(F): A añadir en (F)uturas versiones
3
-
4
- ### CLASES DEL ALGORITMO ###
5
-
6
- from .Reparto import Reparto, division_rutas
7
-
8
- class Algoritmo_Genetico:
9
- def __init__(self, tamano_poblacion : int = 50, generaciones : int = 100, tamano_torneo : int = 5,
10
- crossover_prob : float = 0.8, mutation_prob : float = 0.2):
11
-
12
- #Variables del algoritmo (int)
13
- self.tamano_poblacion = tamano_poblacion
14
- self.generaciones = generaciones
15
- self.tamano_torneo = tamano_torneo
16
-
17
- #Variables del algoritmo (%)
18
- self.crossover_prob = crossover_prob
19
- self.mutation_prob = mutation_prob
20
-
21
- #Variables en ejecución
22
- self.generacion_actual = 0
23
- self.mejor_candidato = ([[1,2,3],[4]], float("inf"))
24
-
25
-
26
- def _poblar(self, grafo, vehiculos):
27
- Reparto.grafo = grafo
28
- Reparto.vehiculos = vehiculos
29
- return crear_poblacion(self)
30
-
31
- def generar(self, grafo, vehiculos):
32
-
33
- #print("##############\n##EMPEZAMOS \n##############")
34
-
35
- Poblacion = self._poblar(grafo, vehiculos)
36
- poblacion = Poblacion()
37
-
38
- from time import sleep
39
-
40
- for _ in range(self.generaciones):
41
- sleep(0.1)
42
- poblacion = poblacion.evolucionar()
43
- self.generacion_actual = self.generacion_actual + 1
44
- self.mejor_candidato = (division_rutas(poblacion.poblacion[0]), poblacion.poblacion[0].coste)
45
-
46
- from .Evolucion import mejor_individuo
47
-
48
- return mejor_individuo(poblacion.poblacion)
49
-
50
- def crear_poblacion(alg_genetico : Algoritmo_Genetico): #quizas haga falta , clase_Reparto : type = Reparto
51
- import random
52
-
53
- from .Evolucion import Evolucion
54
-
55
- class Poblacion:
56
- def __init__(self, poblacion : list[Reparto] = [Reparto()]*alg_genetico.tamano_poblacion):
57
- self.poblacion = poblacion
58
-
59
- def evolucionar(self):
60
- new_poblacion = [Evolucion.elitismo(self.poblacion)]
61
-
62
- for _ in range(alg_genetico.tamano_poblacion - 1):
63
- new_poblacion += [self._evolucionar_individuo()]
64
-
65
- return Poblacion(new_poblacion)
66
-
67
- def _evolucionar_individuo(self):
68
- parent1 = Evolucion.torneo(self.poblacion, alg_genetico.tamano_torneo)
69
-
70
- child = parent1
71
-
72
- if random.random() < alg_genetico.crossover_prob: #Cruce %
73
- parent2 = Evolucion.torneo(self.poblacion, alg_genetico.tamano_torneo)
74
- child = Evolucion.crossover(parent1, parent2)
75
- if random.random() < alg_genetico.mutation_prob: #Mutación %
76
- child = Evolucion.mutate(child)
77
-
78
- return child
79
-
80
- return Poblacion
81
-
82
-
83
-
84
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
pages/vrp/Evolucion.py DELETED
@@ -1,57 +0,0 @@
1
- #VERSIÓN 4: VERSIÓN SEMI-ORIENTADA A OBJETOS
2
- #(F): A añadir en (F)uturas versiones
3
-
4
- ### FUNCIONES AUXILIARES ###
5
-
6
- import random
7
-
8
- from .Reparto import Reparto
9
-
10
-
11
- def mejor_individuo(list_individuos : list[Reparto]) -> Reparto: #paralelizable
12
- mejor_individuo = list_individuos[0]
13
- for individuo in list_individuos[1:]:
14
- mejor_individuo = individuo if individuo.coste < mejor_individuo.coste else mejor_individuo
15
- #print("mejor_individuo: ", mejor_individuo.ruta, mejor_individuo.coste)
16
- return mejor_individuo
17
-
18
- class Evolucion:
19
-
20
- @staticmethod
21
- def elitismo(poblacion : list[Reparto]) -> Reparto: #mejor ruta de la poblacion
22
- return mejor_individuo(poblacion)
23
-
24
- @staticmethod
25
- def torneo(poblacion : list[Reparto], tamano_torneo) -> list[Reparto]: #mejor ruta de una parte de la poblacion
26
- selected_individuos = random.sample(poblacion, tamano_torneo)
27
- return mejor_individuo(selected_individuos)
28
-
29
- @staticmethod
30
- def mutate(ruta : Reparto) -> Reparto: #intercambia dos posiciones en la ruta
31
- idx1, idx2 = random.sample(range(Reparto.grafo.num_nodos + Reparto.vehiculos.num_vehiculos - 2), 2)
32
- lista = ruta.ruta.copy()
33
- lista[idx1], lista[idx2] = lista[idx2], lista[idx1]
34
- return Reparto(lista)
35
-
36
- @staticmethod
37
- def crossover(parent1 : Reparto, parent2 : Reparto) -> Reparto: #cruza dos rutas, pegando un cacho de la primera en la segunda
38
- num_total = Reparto.grafo.num_nodos + Reparto.vehiculos.num_vehiculos - 2
39
- #-1 por el Almacén
40
- #-1 porque si hay n vehiculos, solo añadimos n-1 simbolos
41
-
42
- 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)
43
- end = random.randint(start, num_total - 1)
44
-
45
- child = [None] * num_total
46
-
47
- for i in range(start, end+1):
48
- child[i] = parent1.ruta[i]
49
- remaining = [item for item in parent2.ruta if item not in child]
50
- remaining_index = 0
51
- for i in range(num_total):
52
- if child[i] == None:
53
- child[i] = remaining[remaining_index]
54
- remaining_index += 1
55
-
56
- return Reparto(child)
57
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
pages/vrp/Origen.py DELETED
@@ -1,28 +0,0 @@
1
- #VERSIÓN 5: VRP
2
- #(F): A añadir en (F)uturas versiones
3
-
4
- ### CLASES DEL GRAFO ###
5
- class Grafo:
6
- def __init__(self, distancias: list[list[float]], demandas_clientes: list[float], num_nodos: int = None):
7
- if num_nodos == None: num_nodos = len(distancias)
8
-
9
- if len(demandas_clientes) == num_nodos:
10
- self.num_nodos = num_nodos
11
- self.distancias = distancias
12
- self.demandas_clientes = demandas_clientes ##El almacén ya está incluido
13
- else:
14
- raise IndexError("Las demandas no son igual al número de clientes")
15
-
16
- class Vehiculos:
17
- def __init__(self, capacidad_vehiculos: list[float], num_vehiculos: int = None):
18
- if num_vehiculos == None: num_vehiculos = len(capacidad_vehiculos)
19
-
20
- if len(capacidad_vehiculos) == num_vehiculos or num_vehiculos == None:
21
- self.num_vehiculos = num_vehiculos
22
- self.capacidad_vehiculos = sorted(capacidad_vehiculos)
23
- else:
24
- raise IndexError("Las capacidades no son igual al número de vehiculos")
25
-
26
-
27
-
28
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
pages/vrp/Reparto.py DELETED
@@ -1,80 +0,0 @@
1
-
2
- from .Origen import Grafo, Vehiculos
3
-
4
- class Reparto:
5
- grafo = None
6
- vehiculos = None
7
-
8
- def __init__(self, ruta = None):
9
- if type(self.grafo) == Grafo and type(self.vehiculos) == Vehiculos:
10
- if ruta == None:
11
- ruta = list(range(-self.vehiculos.num_vehiculos + 1, self.grafo.num_nodos))
12
- ruta.remove(0)
13
-
14
- self.ruta = ruta
15
- self.coste = self._coste()
16
-
17
- def __str__(self):
18
- return str((self.ruta,self.coste))
19
-
20
- def _coste(self):
21
- # Función de aptitud para evaluar la calidad de las soluciones
22
- (distancia_total , demanda_total) = (0,0)
23
- capacidades_actual = self.vehiculos.capacidad_vehiculos.copy()
24
-
25
- rutas = division_rutas(self)
26
-
27
- i = 1
28
- for ruta in rutas:
29
- distancia_total += coste_1ruta(ruta)
30
- (demanda_actual, capacidades_actual) = capacidad_1ruta(ruta, capacidades_actual)
31
- demanda_total += demanda_actual
32
- i += 1
33
-
34
- if demanda_total < float('inf'):
35
- return distancia_total
36
- else:
37
- return float('inf')
38
-
39
-
40
- def coste_1ruta(ruta : list[int]) -> int: #ruta = [1,2,3] sin #
41
- recorrido = [0] + ruta + [0] #recorrido = [0,1,2,3,0]
42
-
43
- distacia_total = 0
44
-
45
- prev_nodo = 0
46
- for nodo in recorrido[1:]:
47
-
48
- distacia_total += Reparto.grafo.distancias[prev_nodo][nodo]
49
- prev_nodo = nodo
50
-
51
- return distacia_total
52
-
53
- def capacidad_1ruta(ruta : list[int], capacidades_actual : list[int]) -> int: #ruta = [1,2,3] sin #
54
- demanda_total = 0
55
-
56
- for nodo in ruta:
57
- demanda_total += Reparto.grafo.demandas_clientes[nodo]
58
-
59
- if demanda_total <= capacidades_actual[-1]:
60
- indice_capacidad = 0
61
- while demanda_total > capacidades_actual[indice_capacidad]:
62
- indice_capacidad += 1
63
- capacidades_actual.pop(indice_capacidad)
64
- return (demanda_total, capacidades_actual)
65
- else:
66
- return (float('inf'), capacidades_actual)
67
-
68
- def division_rutas(reparto : Reparto) -> list[list[int]]:
69
- result = []
70
- ruta = []
71
- for nodo in reparto.ruta:
72
- if nodo >= 0:
73
- ruta += [nodo]
74
- else:
75
- result += [ruta.copy()]
76
- ruta = []
77
- result += [ruta.copy()]
78
- return result
79
-
80
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
pages/vrp/__init__.py DELETED
File without changes