Пожалуйста, все бога, который существуют в этом мире, я надеюсь, что допишу 1 проверку и все это заработает
This commit is contained in:
parent
8bb6a784bf
commit
01514fa2fa
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user