From 9b79d87813c983c0e575f64b606392c030a7999a Mon Sep 17 00:00:00 2001 From: maksim Date: Tue, 11 Jun 2024 17:59:36 +0400 Subject: [PATCH] =?UTF-8?q?=D0=A7=D0=B5=D1=81=D1=82=D0=BD=D0=BE,=D0=BC?= =?UTF-8?q?=D0=BD=D0=B5=20=D0=BA=D0=B0=D0=B6=D0=B5=D1=82=D1=81=D1=8F=20?= =?UTF-8?q?=D0=B4=D0=BE=20=D1=81=D0=B8=D1=85=20=D0=BF=D0=BE=D1=80,=20?= =?UTF-8?q?=D1=87=D1=82=D0=BE=20=D1=82=D0=B0=D0=BC=20=D1=87=D1=82=D0=BE=20?= =?UTF-8?q?=D1=82=D0=BE=20=D0=BD=D0=B5=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=B0=D0=B5=D1=82,=20=D0=BD=D0=BE=20=D1=8F=20=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=BE=20=D0=B2=D0=B5=D1=80=D1=8E=20=D0=B2=20?= =?UTF-8?q?=D1=87=D1=83=D0=B4=D0=BE...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- genetic_algorithm/genetic_algorithm.py | 50 +++++++++++++++++--------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/genetic_algorithm/genetic_algorithm.py b/genetic_algorithm/genetic_algorithm.py index 0c2e2ef..38e0e40 100644 --- a/genetic_algorithm/genetic_algorithm.py +++ b/genetic_algorithm/genetic_algorithm.py @@ -6,7 +6,10 @@ from fastapi import FastAPI, HTTPException, Request from schemas import TripRequest -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]: + +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 = {} @@ -71,7 +74,10 @@ def load_graph_from_request(request: TripRequest) -> Tuple[Dict[Tuple[str, str], 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, start_point, end_point, departure_date): + if path[0] != start_point or path[-1] != end_point: + return float('inf'), None, None + length = 0 if (path[0], path[1]) not in graph: return float('inf'), None, None @@ -79,6 +85,9 @@ def path_length_and_time(path, graph): start_time = graph[(path[0], path[1])][0][1] end_time = start_time + if start_time.date() != departure_date: + return float('inf'), start_time, end_time + for i in range(len(path) - 1): if (path[i], path[i + 1]) not in graph: return float('inf'), start_time, end_time @@ -91,7 +100,7 @@ def path_length_and_time(path, graph): return length, start_time, end_time -def generate_population(size, start, end, graph, max_attempts=100): +def generate_population(size, start, end, graph, departure_date, 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): @@ -111,15 +120,20 @@ def generate_population(size, start, end, graph, max_attempts=100): if len(path) > len(nodes): break if path[-1] == end: - population.append(path) + # Проверка даты вылета первого рейса + first_leg = (path[0], path[1]) + if first_leg in graph and graph[first_leg][0][1].date() == departure_date: + population.append(path) break attempts += 1 return population -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')] +def select_parents(population, graph, start_point, end_point, departure_date): + sorted_population = sorted(population, + key=lambda p: path_length_and_time(p, graph, start_point, end_point, departure_date)[0]) + valid_parents = [p for p in sorted_population if + path_length_and_time(p, graph, start_point, end_point, departure_date)[0] != float('inf')] return valid_parents[:len(valid_parents) // 2] @@ -141,8 +155,8 @@ def mutate(child): return child -def update_best_paths(best_paths, path, graph, max_best_paths=10): - length, _, _ = path_length_and_time(path, graph) +def update_best_paths(best_paths, path, graph, start_point, end_point, departure_date, max_best_paths=10): + length, _, _ = path_length_and_time(path, graph, start_point, end_point, departure_date) if path not in best_paths: best_paths[path] = length if len(best_paths) > max_best_paths: @@ -151,10 +165,10 @@ def update_best_paths(best_paths, path, graph, max_best_paths=10): def genetic_algorithm(start, end, graph, flights_data, type, departure_date, population_size=2000, generations=100): - population = generate_population(population_size, start, end, graph) + population = generate_population(population_size, start, end, graph, departure_date) best_paths = {} # Словарь для хранения уникальных лучших маршрутов и их длин for generation in range(generations): - parents = select_parents(population, graph) + parents = select_parents(population, graph, start, end, departure_date) # Если не удалось выбрать родителей, завершить алгоритм if not parents: @@ -169,7 +183,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), graph) + update_best_paths(best_paths, tuple(child), graph, start, end, departure_date) population = new_population best_paths = sorted(best_paths.items(), key=lambda item: item[1]) @@ -187,8 +201,12 @@ def genetic_algorithm(start, end, graph, flights_data, type, departure_date, pop "destinationPoint": flight['destinationPoint'] }) break - result.append({ - type: path_data, - }) - return result + # Финальная проверка пути + if path[0] == start and path[-1] == end and path_length_and_time(path, graph, start, end, departure_date)[ + 0] != float('inf'): + result.append({ + type: path_data, + }) + + return result \ No newline at end of file