Испавил ген.алгоритм, надо только нормально по папочкам расскидать (мне сного шутить, что у меня нет папы?)
This commit is contained in:
parent
0c55d4912a
commit
82e6075f3f
@ -1,11 +1,15 @@
|
||||
import json
|
||||
from datetime import datetime, timedelta
|
||||
import random
|
||||
from typing import Dict, List
|
||||
from typing import Dict, List, Tuple, Any
|
||||
from fastapi import FastAPI, HTTPException, Request
|
||||
|
||||
def load_graph_from_request(request) -> Dict[str, Dict[str, List]]:
|
||||
from schemas import TripRequest
|
||||
|
||||
|
||||
def load_graph_from_request(request: TripRequest) -> Tuple[Dict[str, Dict[str, List[Any]]], str, str, List[Dict]]:
|
||||
graph = {}
|
||||
flights_data = []
|
||||
|
||||
# Загрузить данные о полетах из запроса
|
||||
flights = request.flights
|
||||
@ -19,6 +23,15 @@ def load_graph_from_request(request) -> Dict[str, Dict[str, List]]:
|
||||
departure_time = datetime.fromisoformat(flight.departureTime)
|
||||
destination_time = datetime.fromisoformat(flight.destinationTime)
|
||||
|
||||
# Сохранение данных о полете для вывода
|
||||
flights_data.append({
|
||||
"id": flight.id,
|
||||
"departurePoint": departure_point,
|
||||
"destinationPoint": destination_point,
|
||||
"departureTime": departure_time,
|
||||
"destinationTime": destination_time
|
||||
})
|
||||
|
||||
# Проверка наличия вершин в графе и их создание при необходимости
|
||||
if departure_point not in graph:
|
||||
graph[departure_point] = {}
|
||||
@ -28,9 +41,9 @@ def load_graph_from_request(request) -> Dict[str, Dict[str, List]]:
|
||||
# Добавление ребра в граф
|
||||
graph[departure_point][destination_point] = [flight.distance, departure_time, destination_time]
|
||||
|
||||
return graph, start_point, end_point
|
||||
return graph, start_point, end_point, flights_data
|
||||
|
||||
|
||||
# Функция для вычисления длины и времени пути с учетом минимального интервала времени
|
||||
def path_length_and_time(path, graph):
|
||||
length = 0
|
||||
if path[0] not in graph or path[1] not in graph[path[0]]:
|
||||
@ -49,8 +62,8 @@ def path_length_and_time(path, graph):
|
||||
end_time = graph[path[i]][path[i + 1]][2]
|
||||
return length, start_time, end_time
|
||||
|
||||
# Функция для генерации начальной популяции
|
||||
def generate_population(size, start, end, graph, max_attempts=100):
|
||||
|
||||
def generate_population(size, start, end, graph, max_attempts=1000):
|
||||
population = []
|
||||
for i in range(size):
|
||||
attempts = 0
|
||||
@ -74,13 +87,12 @@ def generate_population(size, start, end, graph, max_attempts=100):
|
||||
attempts += 1
|
||||
return population
|
||||
|
||||
# Функция для селекции родителей
|
||||
|
||||
def select_parents(population, graph):
|
||||
sorted_population = sorted(population, key=lambda p: path_length_and_time(p, graph)[0])
|
||||
return sorted_population[:len(sorted_population) // 2]
|
||||
|
||||
|
||||
# Функция для скрещивания (кроссинговера)
|
||||
def crossover(parent1, parent2):
|
||||
crossover_point = len(parent1) // 2
|
||||
child = parent1[:crossover_point]
|
||||
@ -90,7 +102,6 @@ def crossover(parent1, parent2):
|
||||
return child
|
||||
|
||||
|
||||
# Функция для мутации
|
||||
def mutate(child):
|
||||
if len(child) <= 2:
|
||||
return child # Если путь состоит из одной вершины, мутация не требуется
|
||||
@ -100,9 +111,18 @@ def mutate(child):
|
||||
return child
|
||||
|
||||
|
||||
# Главная функция генетического алгоритма
|
||||
def genetic_algorithm(start, end, graph, population_size=100, generations=100):
|
||||
def update_best_paths(best_paths, path, graph, max_best_paths=3):
|
||||
length, _, _ = path_length_and_time(path, graph)
|
||||
if path not in best_paths:
|
||||
best_paths[path] = length
|
||||
if len(best_paths) > max_best_paths:
|
||||
worst_path = max(best_paths, key=best_paths.get)
|
||||
del best_paths[worst_path]
|
||||
|
||||
|
||||
def genetic_algorithm(start, end, graph, flights_data, population_size=100, generations=100):
|
||||
population = generate_population(population_size, start, end, graph)
|
||||
best_paths = {} # Словарь для хранения уникальных лучших маршрутов и их длин
|
||||
for generation in range(generations):
|
||||
parents = select_parents(population, graph)
|
||||
new_population = parents[:]
|
||||
@ -112,8 +132,35 @@ def genetic_algorithm(start, end, graph, population_size=100, generations=100):
|
||||
child = crossover(parent1, parent2)
|
||||
if random.random() < 0.1: # Вероятность мутации
|
||||
child = mutate(child)
|
||||
new_population.append(child)
|
||||
if child[-1] == end:
|
||||
new_population.append(child)
|
||||
update_best_paths(best_paths, tuple(child), graph)
|
||||
population = new_population
|
||||
best_path = min(population, key=lambda p: path_length_and_time(p, graph)[0])
|
||||
best_length, start_time, end_time = path_length_and_time(best_path, graph)
|
||||
return best_path, best_length, start_time, end_time
|
||||
|
||||
best_paths = sorted(best_paths.items(), key=lambda item: item[1])
|
||||
top_paths = [list(path) for path, _ in best_paths[:3]]
|
||||
|
||||
result = []
|
||||
for path in top_paths:
|
||||
path_data = []
|
||||
for i in range(len(path) - 1):
|
||||
for flight in flights_data:
|
||||
if flight['departurePoint'] == path[i] and flight['destinationPoint'] == path[i + 1]:
|
||||
path_data.append({
|
||||
"id": flight['id'],
|
||||
"departurePoint": flight['departurePoint'],
|
||||
"destinationPoint": flight['destinationPoint']
|
||||
})
|
||||
break
|
||||
length, start_time, end_time = path_length_and_time(path, graph)
|
||||
# Проверка на корректность длины пути и времени
|
||||
if length == float('inf') or start_time is None or end_time is None:
|
||||
continue
|
||||
result.append({
|
||||
"to": path_data,
|
||||
"start_time": start_time.isoformat() if start_time else None,
|
||||
"end_time": end_time.isoformat() if end_time else None,
|
||||
"best_length": length
|
||||
})
|
||||
|
||||
return result
|
||||
|
@ -17,9 +17,11 @@ router = APIRouter(
|
||||
|
||||
@router.post("/get_flight/")
|
||||
async def get_flight(request: TripRequest):
|
||||
graph, start_point, end_point = load_graph_from_request(request)
|
||||
best_path, best_length, start_time, end_time = genetic_algorithm(start_point, end_point, graph)
|
||||
return best_path, best_length, start_time, end_time
|
||||
graph, start_point, end_point, flights_data = load_graph_from_request(request)
|
||||
result = genetic_algorithm(start_point, end_point, graph, flights_data)
|
||||
if not result:
|
||||
raise HTTPException(status_code=404, detail="No valid paths found")
|
||||
return result
|
||||
|
||||
@router.get("/negative")
|
||||
async def get_class_names() -> List[str]:
|
||||
|
Loading…
Reference in New Issue
Block a user