На всякий сейвлю свою "трассировку". Если это чудо наконец то заработает, я абалдею. Я из за него на улицу не выхожу :(
This commit is contained in:
parent
48eb02fca7
commit
8bb6a784bf
@ -1,5 +1,5 @@
|
|||||||
import json
|
import json
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta, date
|
||||||
import random
|
import random
|
||||||
from typing import Dict, List, Tuple, Any
|
from typing import Dict, List, Tuple, Any
|
||||||
from fastapi import FastAPI, HTTPException, Request
|
from fastapi import FastAPI, HTTPException, Request
|
||||||
@ -7,7 +7,9 @@ from fastapi import FastAPI, HTTPException, Request
|
|||||||
from schemas import TripRequest
|
from schemas import TripRequest
|
||||||
|
|
||||||
|
|
||||||
def load_graph_from_request(request: TripRequest) -> Tuple[Dict[str, Dict[str, List[Any]]], str, str, List[Dict]]:
|
def load_graph_from_request(request: TripRequest) -> tuple[
|
||||||
|
dict[str, dict[Any, Any]], dict[str, dict[Any, Any]], str, str, list[dict[str, datetime | str | int]], list[
|
||||||
|
dict[str, datetime | str | int]], date, date | None]:
|
||||||
graphTo = {}
|
graphTo = {}
|
||||||
flightsDataTo = []
|
flightsDataTo = []
|
||||||
graphBack = {}
|
graphBack = {}
|
||||||
@ -73,10 +75,11 @@ def load_graph_from_request(request: TripRequest) -> Tuple[Dict[str, Dict[str, L
|
|||||||
# Добавление ребра в граф
|
# Добавление ребра в граф
|
||||||
graphBack[departure_point][destination_point] = [flight.distance, departure_time, destination_time]
|
graphBack[departure_point][destination_point] = [flight.distance, departure_time, destination_time]
|
||||||
|
|
||||||
|
print(graphTo)
|
||||||
return graphTo,graphBack, start_point, end_point, flightsDataTo, flightsDataBack, departure_date, departure_date_return
|
return graphTo,graphBack, start_point, end_point, flightsDataTo, flightsDataBack, departure_date, departure_date_return
|
||||||
|
|
||||||
|
|
||||||
def path_length_and_time(path, graph):
|
def path_length_and_time(path, graph, departure_date):
|
||||||
length = 0
|
length = 0
|
||||||
if path[0] not in graph or path[1] not in graph[path[0]]:
|
if path[0] not in graph or path[1] not in graph[path[0]]:
|
||||||
return float('inf'), None, None
|
return float('inf'), None, None
|
||||||
@ -87,11 +90,21 @@ def path_length_and_time(path, graph):
|
|||||||
for i in range(len(path) - 1):
|
for i in range(len(path) - 1):
|
||||||
if path[i] not in graph or path[i + 1] not in graph[path[i]]:
|
if path[i] not in graph or path[i + 1] not in graph[path[i]]:
|
||||||
return float('inf'), start_time, end_time
|
return float('inf'), start_time, end_time
|
||||||
|
|
||||||
|
if departure_date != start_time.date():
|
||||||
|
return float('inf'), start_time, end_time
|
||||||
|
|
||||||
|
if i > 0:
|
||||||
|
print("Start time:", start_time)
|
||||||
|
print("graph date:", graph[path[i]][path[i + 1]][1])
|
||||||
|
if start_time + timedelta(minutes=180) > graph[path[i]][path[i + 1]][1]:
|
||||||
|
print("Departure date and start time date do not match")
|
||||||
|
return float('inf'), start_time, end_time
|
||||||
|
|
||||||
length += graph[path[i]][path[i + 1]][0]
|
length += graph[path[i]][path[i + 1]][0]
|
||||||
if i > 0: # Пропуск первой вершины
|
|
||||||
if end_time + timedelta(minutes=180) > graph[path[i]][path[i + 1]][1]:
|
|
||||||
return float('inf'), start_time, end_time # Неприемлемый путь
|
|
||||||
end_time = graph[path[i]][path[i + 1]][2]
|
end_time = graph[path[i]][path[i + 1]][2]
|
||||||
|
start_time = end_time
|
||||||
|
|
||||||
return length, start_time, end_time
|
return length, start_time, end_time
|
||||||
|
|
||||||
|
|
||||||
@ -119,10 +132,9 @@ def generate_population(size, start, end, graph, max_attempts=100):
|
|||||||
attempts += 1
|
attempts += 1
|
||||||
return population
|
return population
|
||||||
|
|
||||||
|
def select_parents(population, graph, departure_date):
|
||||||
def select_parents(population, graph):
|
sorted_population = sorted(population, key=lambda p: path_length_and_time(p, graph, departure_date)[0])
|
||||||
sorted_population = sorted(population, key=lambda p: path_length_and_time(p, graph)[0])
|
valid_parents = [p for p in sorted_population if path_length_and_time(p, graph, departure_date)[0] != float('inf')]
|
||||||
valid_parents = [p for p in sorted_population if path_length_and_time(p, graph)[0] != float('inf')]
|
|
||||||
return valid_parents[:len(valid_parents) // 2]
|
return valid_parents[:len(valid_parents) // 2]
|
||||||
|
|
||||||
|
|
||||||
@ -144,20 +156,19 @@ def mutate(child):
|
|||||||
return child
|
return child
|
||||||
|
|
||||||
|
|
||||||
def update_best_paths(best_paths, path, graph, max_best_paths=10):
|
def update_best_paths(best_paths, path, max_best_paths=10):
|
||||||
length, _, _ = path_length_and_time(path, graph)
|
|
||||||
if path not in best_paths:
|
if path not in best_paths:
|
||||||
best_paths[path] = length
|
best_paths[path] = None
|
||||||
if len(best_paths) > max_best_paths:
|
if len(best_paths) > max_best_paths:
|
||||||
worst_path = max(best_paths, key=best_paths.get)
|
worst_path = max(best_paths, key=best_paths.get)
|
||||||
del best_paths[worst_path]
|
del best_paths[worst_path]
|
||||||
|
|
||||||
|
|
||||||
def genetic_algorithm(start, end, graph, flights_data, type, departure_date, population_size=2000, generations=100):
|
def genetic_algorithm(start, end, graph, flights_data, type, departure_date, population_size=5, generations=5):
|
||||||
population = generate_population(population_size, start, end, graph)
|
population = generate_population(population_size, start, end, graph)
|
||||||
best_paths = {} # Словарь для хранения уникальных лучших маршрутов и их длин
|
best_paths = {} # Словарь для хранения уникальных лучших маршрутов и их длин
|
||||||
for generation in range(generations):
|
for generation in range(generations):
|
||||||
parents = select_parents(population, graph)
|
parents = select_parents(population, graph, departure_date)
|
||||||
|
|
||||||
# Если не удалось выбрать родителей, завершить алгоритм
|
# Если не удалось выбрать родителей, завершить алгоритм
|
||||||
if not parents:
|
if not parents:
|
||||||
@ -172,7 +183,7 @@ def genetic_algorithm(start, end, graph, flights_data, type, departure_date, pop
|
|||||||
child = mutate(child)
|
child = mutate(child)
|
||||||
if child[-1] == end:
|
if child[-1] == end:
|
||||||
new_population.append(child)
|
new_population.append(child)
|
||||||
update_best_paths(best_paths, tuple(child), graph)
|
update_best_paths(best_paths, tuple(child))
|
||||||
population = new_population
|
population = new_population
|
||||||
|
|
||||||
best_paths = sorted(best_paths.items(), key=lambda item: item[1])
|
best_paths = sorted(best_paths.items(), key=lambda item: item[1])
|
||||||
@ -190,12 +201,6 @@ def genetic_algorithm(start, end, graph, flights_data, type, departure_date, pop
|
|||||||
"destinationPoint": flight['destinationPoint']
|
"destinationPoint": flight['destinationPoint']
|
||||||
})
|
})
|
||||||
break
|
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
|
|
||||||
if datetime(start_time.year, start_time.month, start_time.day).date() != departure_date:
|
|
||||||
continue
|
|
||||||
result.append({
|
result.append({
|
||||||
type: path_data,
|
type: path_data,
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user