Пожалуйста, все бога, который существуют в этом мире, я надеюсь, что допишу 1 проверку и все это заработает

This commit is contained in:
maksim 2024-06-11 17:15:03 +04:00
parent 8bb6a784bf
commit 01514fa2fa

View File

@ -1,15 +1,12 @@
import json
from datetime import datetime, timedelta, date
from datetime import datetime, timedelta
import random
from typing import Dict, List, Tuple, Any
from fastapi import FastAPI, HTTPException, Request
from schemas import TripRequest
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]:
def load_graph_from_request(request: TripRequest) -> Tuple[Dict[Tuple[str, str], List[Any]], Dict[Tuple[str, str], List[Any]], str, str, List[Dict], List[Dict], datetime, datetime]:
graphTo = {}
flightsDataTo = []
graphBack = {}
@ -41,14 +38,12 @@ def load_graph_from_request(request: TripRequest) -> tuple[
"destinationTime": destination_time
})
# Проверка наличия вершин в графе и их создание при необходимости
if departure_point not in graphTo:
graphTo[departure_point] = {}
if destination_point not in graphTo:
graphTo[destination_point] = {}
# Проверка наличия ребра в графе и его создание при необходимости
if (departure_point, destination_point) not in graphTo:
graphTo[(departure_point, destination_point)] = []
# Добавление ребра в граф
graphTo[departure_point][destination_point] = [flight.distance, departure_time, destination_time]
graphTo[(departure_point, destination_point)].append([flight.distance, departure_time, destination_time])
# Добавить каждый полет в граф
for flight in flightsBack:
@ -66,65 +61,54 @@ def load_graph_from_request(request: TripRequest) -> tuple[
"destinationTime": destination_time
})
# Проверка наличия вершин в графе и их создание при необходимости
if departure_point not in graphBack:
graphBack[departure_point] = {}
if destination_point not in graphBack:
graphBack[destination_point] = {}
# Проверка наличия ребра в графе и его создание при необходимости
if (departure_point, destination_point) not in graphBack:
graphBack[(departure_point, destination_point)] = []
# Добавление ребра в граф
graphBack[departure_point][destination_point] = [flight.distance, departure_time, destination_time]
graphBack[(departure_point, destination_point)].append([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, departure_date):
def path_length_and_time(path, graph):
length = 0
if path[0] not in graph or path[1] not in graph[path[0]]:
if (path[0], path[1]) not in graph:
return float('inf'), None, None
start_time = graph[path[0]][path[1]][1]
start_time = graph[(path[0], path[1])][0][1]
end_time = start_time
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], path[i + 1]) not in graph:
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]
end_time = graph[path[i]][path[i + 1]][2]
start_time = end_time
flight = graph[(path[i], path[i + 1])][0]
length += flight[0]
if i > 0: # Пропуск первой вершины
if end_time + timedelta(minutes=180) > flight[1]:
return float('inf'), start_time, end_time # Неприемлемый путь
end_time = flight[2]
return length, start_time, end_time
def generate_population(size, start, end, graph, max_attempts=100):
population = []
nodes = list(set([k[0] for k in graph.keys()] + [k[1] for k in graph.keys()]))
for i in range(size):
attempts = 0
while attempts < max_attempts:
path = [start]
visited = set(path)
while path[-1] != end:
if path[-1] not in graph or not graph[path[-1]]:
next_nodes = [k[1] for k in graph.keys() if k[0] == path[-1]]
if not next_nodes:
break
next_node = random.choice(list(graph[path[-1]].keys()))
next_node = random.choice(next_nodes)
if next_node in visited:
break
path.append(next_node)
visited.add(next_node)
# Если длина пути превышает количество узлов в графе, выйти из цикла
if len(path) > len(graph):
if len(path) > len(nodes):
break
if path[-1] == end:
population.append(path)
@ -132,9 +116,10 @@ def generate_population(size, start, end, graph, max_attempts=100):
attempts += 1
return population
def select_parents(population, graph, departure_date):
sorted_population = sorted(population, key=lambda p: path_length_and_time(p, graph, departure_date)[0])
valid_parents = [p for p in sorted_population if path_length_and_time(p, graph, departure_date)[0] != float('inf')]
def select_parents(population, graph):
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)[0] != float('inf')]
return valid_parents[:len(valid_parents) // 2]
@ -156,19 +141,20 @@ def mutate(child):
return child
def update_best_paths(best_paths, path, max_best_paths=10):
def update_best_paths(best_paths, path, graph, max_best_paths=10):
length, _, _ = path_length_and_time(path, graph)
if path not in best_paths:
best_paths[path] = None
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, type, departure_date, population_size=5, generations=5):
def genetic_algorithm(start, end, graph, flights_data, type, departure_date, population_size=2000, generations=100):
population = generate_population(population_size, start, end, graph)
best_paths = {} # Словарь для хранения уникальных лучших маршрутов и их длин
for generation in range(generations):
parents = select_parents(population, graph, departure_date)
parents = select_parents(population, graph)
# Если не удалось выбрать родителей, завершить алгоритм
if not parents:
@ -183,7 +169,7 @@ def genetic_algorithm(start, end, graph, flights_data, type, departure_date, pop
child = mutate(child)
if child[-1] == end:
new_population.append(child)
update_best_paths(best_paths, tuple(child))
update_best_paths(best_paths, tuple(child), graph)
population = new_population
best_paths = sorted(best_paths.items(), key=lambda item: item[1])
@ -205,4 +191,4 @@ def genetic_algorithm(start, end, graph, flights_data, type, departure_date, pop
type: path_data,
})
return result
return result