diff --git a/genetic_algorithm/genetic_algorithm.py b/genetic_algorithm/genetic_algorithm.py index ff5697b..385e1ff 100644 --- a/genetic_algorithm/genetic_algorithm.py +++ b/genetic_algorithm/genetic_algorithm.py @@ -1,5 +1,5 @@ import json -from datetime import datetime, timedelta +from datetime import datetime, timedelta, date import random from typing import Dict, List, Tuple, Any from fastapi import FastAPI, HTTPException, Request @@ -7,7 +7,9 @@ from fastapi import FastAPI, HTTPException, Request 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 = {} flightsDataTo = [] 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] + print(graphTo) 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 if path[0] not in graph or path[1] not in graph[path[0]]: return float('inf'), None, None @@ -87,11 +90,21 @@ def path_length_and_time(path, graph): for i in range(len(path) - 1): if path[i] not in graph or path[i + 1] not in graph[path[i]]: 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] - 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] + 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 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, 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')] return valid_parents[:len(valid_parents) // 2] @@ -144,20 +156,19 @@ 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, max_best_paths=10): if path not in best_paths: - best_paths[path] = length + best_paths[path] = None 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=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) best_paths = {} # Словарь для хранения уникальных лучших маршрутов и их длин for generation in range(generations): - parents = select_parents(population, graph) + parents = select_parents(population, graph, departure_date) # Если не удалось выбрать родителей, завершить алгоритм if not parents: @@ -172,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)) population = new_population 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'] }) 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({ type: path_data, })