File size: 5,520 Bytes
668267d f76f41d 668267d 2a62559 668267d 2a62559 668267d 2a62559 f76f41d 2a62559 668267d 2a62559 |
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 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import numpy as np
import random
from typing import List
class InputData(BaseModel):
data: List[float] # Lista de caracter铆sticas num茅ricas (flotantes)
data2: List[int]
app = FastAPI()
# ------------- algoritmo genetico -------------
# Funci贸n para generar una poblaci贸n inicial aleatoria
def generar_poblacion(num_individuos, num_ciudades):
poblacion = []
for _ in range(num_individuos):
individuo = list(range(num_ciudades))
random.shuffle(individuo)
poblacion.append(individuo)
return poblacion
# Funci贸n para evaluar la aptitud de un individuo (distancia total del recorrido)
def calcular_aptitud(individuo, distancias, coordenadas):
distancia_total = 0
coordenadas_iguales = all(coord == coordenadas[0] for coord in coordenadas)
if not coordenadas_iguales:
for i in range(len(individuo) - 1):
ciudad_actual = individuo[i]
siguiente_ciudad = individuo[i + 1]
distancia_total += distancias[ciudad_actual][siguiente_ciudad]
distancia_total += distancias[individuo[-1]][individuo[0]]
return distancia_total
# Funci贸n para seleccionar individuos para la reproducci贸n (torneo binario)
def seleccion_torneo(poblacion, distancias, coordenadas):
seleccionados = []
for _ in range(len(poblacion)):
torneo = random.sample(poblacion, 2)
aptitud_torneo = [
calcular_aptitud(individuo, distancias, coordenadas) for individuo in torneo
]
seleccionado = torneo[aptitud_torneo.index(min(aptitud_torneo))]
seleccionados.append(seleccionado)
return seleccionados
# Funci贸n para realizar el cruce de dos padres para producir un hijo
def cruzar(padre1, padre2):
punto_cruce = random.randint(0, len(padre1) - 1)
hijo = padre1[:punto_cruce] + [
gen for gen in padre2 if gen not in padre1[:punto_cruce]
]
return hijo
# Funci贸n para aplicar mutaciones en la poblaci贸n
def mutar(individuo, probabilidad_mutacion):
if random.random() < probabilidad_mutacion:
indices = random.sample(range(len(individuo)), 2)
individuo[indices[0]], individuo[indices[1]] = (
individuo[indices[1]],
individuo[indices[0]],
)
return individuo
# Funci贸n para generar distancias aleatorias entre ciudades y sus coordenadas bidimensionales
def generar_distancias(num_ciudades, puntos_array):
distancias = [[0] * num_ciudades for _ in range(num_ciudades)]
coordenadas = []
for i in range(0, len(puntos_array), 2):
if i+1 < len(puntos_array):
coordenadas.append((puntos_array[i], puntos_array[i+1]))
for i in range(num_ciudades):
for j in range(i + 1, num_ciudades):
distancias[i][j] = distancias[j][i] = (
sum((x - y) ** 2 for x, y in zip(coordenadas[i], coordenadas[j])) ** 0.5
)
return distancias, coordenadas
def algoritmo_genetico(num_generaciones,num_ciudades,num_individuos,probabilidad_mutacion,distancias,coordenadas):
poblacion = generar_poblacion(num_individuos, num_ciudades)
for generacion in range(num_generaciones):
poblacion = sorted(
poblacion, key=lambda x: calcular_aptitud(x, distancias, coordenadas)
)
mejor_individuo = poblacion[0]
mejor_distancia = calcular_aptitud(mejor_individuo, distancias, coordenadas)
seleccionados = seleccion_torneo(poblacion, distancias, coordenadas)
nueva_poblacion = []
for i in range(0, len(seleccionados), 2):
padre1, padre2 = seleccionados[i], seleccionados[i + 1]
hijo1 = cruzar(padre1, padre2)
hijo2 = cruzar(padre2, padre1)
hijo1 = mutar(hijo1, probabilidad_mutacion)
hijo2 = mutar(hijo2, probabilidad_mutacion)
nueva_poblacion.extend([hijo1, hijo2])
poblacion = nueva_poblacion
mejor_solucion = poblacion[0]
mejor_distancia = calcular_aptitud(mejor_solucion, distancias, coordenadas)
return mejor_solucion, mejor_distancia
# Ruta de predicci贸n
@app.post("/predict/")
async def predict(data: InputData):
print(f"Data: {data}")
try:
# Convertir la lista de entrada a un array de NumPy para la predicci贸n
input_data = np.array(data.data).reshape(
1, -1
) # Asumiendo que la entrada debe ser de forma (1, num_features)
num_ciudades = int(input_data[0][0])
num_individuos = int(input_data[0][1])
probabilidad_mutacion = float(input_data[0][2])
num_generaciones = int(input_data[0][3])
puntos_array = data.data2
distancias, coordenadas = generar_distancias(num_ciudades, puntos_array)
mejor_solucion, mejor_distancia = algoritmo_genetico(num_generaciones,num_ciudades,num_individuos,probabilidad_mutacion,distancias,coordenadas)
#print(type(mejor_solucion),mejor_solucion
respuesta = list(mejor_solucion)
print(respuesta)
prediction = respuesta
#return {"prediction": prediction.tolist()}
return {
"num_ciudades": num_ciudades,
"distancia": int(mejor_distancia),
"prediction": prediction,
"cromosoma": mejor_solucion # Esto ya es un array de ints
}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e)) |