diff --git a/zaharoves/задание 2/.idea/.gitignore b/zaharoves/задание 2/.idea/.gitignore new file mode 100644 index 0000000..b58b603 --- /dev/null +++ b/zaharoves/задание 2/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/zaharoves/задание 2/.idea/inspectionProfiles/profiles_settings.xml b/zaharoves/задание 2/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/zaharoves/задание 2/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/zaharoves/задание 2/.idea/misc.xml b/zaharoves/задание 2/.idea/misc.xml new file mode 100644 index 0000000..1d3ce46 --- /dev/null +++ b/zaharoves/задание 2/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/zaharoves/задание 2/.idea/modules.xml b/zaharoves/задание 2/.idea/modules.xml new file mode 100644 index 0000000..4984091 --- /dev/null +++ b/zaharoves/задание 2/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/zaharoves/задание 2/.idea/vcs.xml b/zaharoves/задание 2/.idea/vcs.xml new file mode 100644 index 0000000..b2bdec2 --- /dev/null +++ b/zaharoves/задание 2/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/zaharoves/задание 2/.idea/задание 2.iml b/zaharoves/задание 2/.idea/задание 2.iml new file mode 100644 index 0000000..b6731d8 --- /dev/null +++ b/zaharoves/задание 2/.idea/задание 2.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/zaharoves/задание 2/Maze_solver.py b/zaharoves/задание 2/Maze_solver.py index e69de29..edf5990 100644 --- a/zaharoves/задание 2/Maze_solver.py +++ b/zaharoves/задание 2/Maze_solver.py @@ -0,0 +1,660 @@ + +import os +import time +import heapq +import csv +import random +from abc import ABC, abstractmethod +from collections import deque +from dataclasses import dataclass +from typing import Optional + + +#1. Модель лабиринта — классы Cell и Maze + +class Cell: + """Клетка лабиринта.""" + + def __init__(self, x: int, y: int, is_wall: bool = False, + is_start: bool = False, is_exit: bool = False, weight: int = 1): + self.x = x + self.y = y + self.is_wall = is_wall + self.is_start = is_start + self.is_exit = is_exit + self.weight = weight # для взвешенного лабиринта (Этап 6 доп.) + + def is_passable(self) -> bool: + return not self.is_wall + + def __repr__(self): + return f"Cell({self.x},{self.y})" + + def __eq__(self, other): + return isinstance(other, Cell) and self.x == other.x and self.y == other.y + + def __hash__(self): + return hash((self.x, self.y)) + + def __lt__(self, other): + return (self.x, self.y) < (other.x, other.y) + + +class Maze: + """Лабиринт — двумерный массив клеток.""" + + def __init__(self, width: int, height: int): + self.width = width + self.height = height + self.cells: list[list[Cell]] = [] + self.start: Optional[Cell] = None + self.exit: Optional[Cell] = None + + def get_cell(self, x: int, y: int) -> Optional[Cell]: + if 0 <= x < self.width and 0 <= y < self.height: + return self.cells[y][x] + return None + + def get_neighbors(self, cell: Cell) -> list[Cell]: + """Возвращает проходимых соседей (вверх, вниз, влево, вправо).""" + directions = [(0, -1), (0, 1), (-1, 0), (1, 0)] + neighbors = [] + for dx, dy in directions: + neighbor = self.get_cell(cell.x + dx, cell.y + dy) + if neighbor and neighbor.is_passable(): + neighbors.append(neighbor) + return neighbors + + +#2. Загрузка лабиринта из файла — паттерн Builder + +class MazeBuilder(ABC): + """Интерфейс строителя лабиринта.""" + + @abstractmethod + def build_from_file(self, filename: str) -> Maze: + pass + + +class TextFileMazeBuilder(MazeBuilder): + + WEIGHT_MAP = {' ': 1, 'S': 1, 'E': 1, '.': 2, '~': 3, '#': 0} + + def build_from_file(self, filename: str) -> Maze: + with open(filename, 'r', encoding='utf-8') as f: + lines = f.read().splitlines() + + if not lines: + raise ValueError("Файл лабиринта пуст") + + height = len(lines) + width = max(len(line) for line in lines) + maze = Maze(width, height) + + for y, line in enumerate(lines): + row = [] + for x in range(width): + ch = line[x] if x < len(line) else ' ' + is_wall = ch == '#' + is_start = ch == 'S' + is_exit = ch == 'E' + weight = self.WEIGHT_MAP.get(ch, 1) + cell = Cell(x, y, is_wall=is_wall, is_start=is_start, + is_exit=is_exit, weight=weight) + row.append(cell) + if is_start: + maze.start = cell + if is_exit: + maze.exit = cell + maze.cells.append(row) + + if maze.start is None: + raise ValueError("В лабиринте не задана стартовая клетка (S)") + if maze.exit is None: + raise ValueError("В лабиринте не задана выходная клетка (E)") + + return maze + + +#3. Стратегии поиска пути — паттерн Strategy + +@dataclass +class SearchStats: + """Статистика одного запуска поиска.""" + time_ms: float = 0.0 + visited_cells: int = 0 + path_length: int = 0 + + +class PathFindingStrategy(ABC): + """Интерфейс стратегии поиска пути.""" + + @abstractmethod + def find_path(self, maze: Maze, start: Cell, exit_cell: Cell) -> list[Cell]: + pass + + def _reconstruct_path(self, parent: dict, start: Cell, exit_cell: Cell) -> list[Cell]: + path = [] + current = exit_cell + while current is not None: + path.append(current) + current = parent.get(current) + path.reverse() + if path and path[0] == start: + return path + return [] + + +class BFSStrategy(PathFindingStrategy): + """Поиск в ширину""" + + def __init__(self): + self.visited_count = 0 + + def find_path(self, maze: Maze, start: Cell, exit_cell: Cell) -> list[Cell]: + queue = deque([start]) + parent: dict[Cell, Optional[Cell]] = {start: None} + self.visited_count = 0 + + while queue: + current = queue.popleft() + self.visited_count += 1 + + if current == exit_cell: + return self._reconstruct_path(parent, start, exit_cell) + + for neighbor in maze.get_neighbors(current): + if neighbor not in parent: + parent[neighbor] = current + queue.append(neighbor) + + return [] + + +class DFSStrategy(PathFindingStrategy): + """Поиск в глубину""" + + def __init__(self): + self.visited_count = 0 + + def find_path(self, maze: Maze, start: Cell, exit_cell: Cell) -> list[Cell]: + stack = [start] + parent: dict[Cell, Optional[Cell]] = {start: None} + self.visited_count = 0 + + while stack: + current = stack.pop() + self.visited_count += 1 + + if current == exit_cell: + return self._reconstruct_path(parent, start, exit_cell) + + for neighbor in maze.get_neighbors(current): + if neighbor not in parent: + parent[neighbor] = current + stack.append(neighbor) + + return [] + + +class AStarStrategy(PathFindingStrategy): + """A* с манхэттенской эвристикой""" + + def __init__(self): + self.visited_count = 0 + + def _heuristic(self, a: Cell, b: Cell) -> int: + return abs(a.x - b.x) + abs(a.y - b.y) + + def find_path(self, maze: Maze, start: Cell, exit_cell: Cell) -> list[Cell]: + g_score = {start: 0} + parent: dict[Cell, Optional[Cell]] = {start: None} + open_heap = [(self._heuristic(start, exit_cell), 0, start)] + closed_set: set[Cell] = set() # уже обработанные клетки + self.visited_count = 0 + counter = 0 # счётчик для устранения неоднозначности + + while open_heap: + _, _, current = heapq.heappop(open_heap) + + if current in closed_set: + continue + closed_set.add(current) + self.visited_count += 1 + + if current == exit_cell: + return self._reconstruct_path(parent, start, exit_cell) + + for neighbor in maze.get_neighbors(current): + if neighbor in closed_set: + continue + tentative_g = g_score[current] + neighbor.weight + if tentative_g < g_score.get(neighbor, float('inf')): + g_score[neighbor] = tentative_g + parent[neighbor] = current + f = tentative_g + self._heuristic(neighbor, exit_cell) + counter += 1 + heapq.heappush(open_heap, (f, counter, neighbor)) + + return [] + + +class DijkstraStrategy(PathFindingStrategy): + """Дейкстра""" + + def __init__(self): + self.visited_count = 0 + + def find_path(self, maze: Maze, start: Cell, exit_cell: Cell) -> list[Cell]: + dist = {start: 0} + parent: dict[Cell, Optional[Cell]] = {start: None} + open_heap = [(0, 0, start)] + self.visited_count = 0 + counter = 0 + + while open_heap: + cost, _, current = heapq.heappop(open_heap) + if cost > dist.get(current, float('inf')): + continue + self.visited_count += 1 + + if current == exit_cell: + return self._reconstruct_path(parent, start, exit_cell) + + for neighbor in maze.get_neighbors(current): + new_cost = dist[current] + neighbor.weight + if new_cost < dist.get(neighbor, float('inf')): + dist[neighbor] = new_cost + parent[neighbor] = current + counter += 1 + heapq.heappush(open_heap, (new_cost, counter, neighbor)) + + return [] + + +#4. Оркестратор — MazeSolver + +class MazeSolver: + """Оркестратор""" + + def __init__(self, maze: Maze, strategy: PathFindingStrategy): + self.maze = maze + self.strategy = strategy + self._observers: list['Observer'] = [] + self._last_path: list[Cell] = [] + + def set_strategy(self, strategy: PathFindingStrategy): + self.strategy = strategy + + def add_observer(self, observer: 'Observer'): + self._observers.append(observer) + + def _notify(self, event: str, **kwargs): + for obs in self._observers: + obs.update(event, **kwargs) + + def solve(self) -> SearchStats: + start = self.maze.start + exit_cell = self.maze.exit + self._notify("search_start", strategy=type(self.strategy).__name__) + + t0 = time.perf_counter() + path = self.strategy.find_path(self.maze, start, exit_cell) + t1 = time.perf_counter() + + self._last_path = path + visited = getattr(self.strategy, 'visited_count', 0) + stats = SearchStats( + time_ms=(t1 - t0) * 1000, + visited_cells=visited, + path_length=len(path) + ) + self._notify("path_found", path=path, stats=stats) + return stats + + def get_last_path(self) -> list[Cell]: + return self._last_path + + +#5.1. Observer — ConsoleView + +class Observer(ABC): + """Интерфейс наблюдателя.""" + + @abstractmethod + def update(self, event: str, **kwargs): + pass + + +class ConsoleView(Observer): + """Консольный вид""" + + SYMBOLS = { + 'wall': '█', + 'path': '·', + 'start': 'S', + 'exit': 'E', + 'player': '@', + 'visited': '°', + 'empty': ' ', + } + + def update(self, event: str, **kwargs): + if event == "search_start": + print(f"\n[Поиск] Алгоритм: {kwargs.get('strategy', '?')}") + elif event == "path_found": + path = kwargs.get('path', []) + stats = kwargs.get('stats') + if path: + print(f"[Готово] Путь найден! Длина: {stats.path_length}, " + f"Посещено: {stats.visited_cells}, Время: {stats.time_ms:.2f} мс") + else: + print("[Готово] Путь не найден!") + elif event == "move": + cell = kwargs.get('cell') + print(f"[Ход] Игрок перемещается в {cell}") + + def render(self, maze: Maze, player_pos: Optional[Cell] = None, + path: Optional[list[Cell]] = None): + """Рисует лабиринт в консоли.""" + path_set = set(path) if path else set() + print() + for y in range(maze.height): + row = '' + for x in range(maze.width): + cell = maze.cells[y][x] + if cell.is_wall: + row += self.SYMBOLS['wall'] + elif player_pos and cell == player_pos: + row += self.SYMBOLS['player'] + elif cell.is_start: + row += self.SYMBOLS['start'] + elif cell.is_exit: + row += self.SYMBOLS['exit'] + elif cell in path_set: + row += self.SYMBOLS['path'] + else: + row += self.SYMBOLS['empty'] + print(row) + print() + + +#5.2. Command — Player и MoveCommand + +class Player: + """Игрок с текущей позицией в лабиринте.""" + + def __init__(self, start_cell: Cell): + self.current_cell = start_cell + + def move_to(self, cell: Cell): + self.current_cell = cell + + +class Command(ABC): + """Интерфейс команды.""" + + @abstractmethod + def execute(self): + pass + + @abstractmethod + def undo(self): + pass + + +class MoveCommand(Command): + """Команда перемещения игрока в указанную клетку.""" + + def __init__(self, player: Player, target_cell: Cell, solver: MazeSolver): + self.player = player + self.target_cell = target_cell + self.previous_cell = player.current_cell + self.solver = solver + + def execute(self): + self.previous_cell = self.player.current_cell + self.player.move_to(self.target_cell) + self.solver._notify("move", cell=self.target_cell) + + def undo(self): + self.player.move_to(self.previous_cell) + self.solver._notify("move", cell=self.previous_cell) + + +#6. Экспериментальная часть + +def generate_maze_file(filename: str, width: int, height: int, + wall_density: float = 0.3, no_exit: bool = False): + """Генерирует случайный лабиринт и сохраняет в файл.""" + random.seed(42) + grid = [] + for y in range(height): + row = [] + for x in range(width): + if x == 0 or y == 0 or x == width - 1 or y == height - 1: + row.append('#') + else: + row.append('#' if random.random() < wall_density else ' ') + grid.append(row) + + # Старт и выход + grid[1][1] = 'S' + grid[height - 2][width - 2] = 'E' + if no_exit: + ex, ey = width - 2, height - 2 + for dx, dy in [(0, -1), (0, 1), (-1, 0), (1, 0)]: + nx, ny = ex + dx, ey + dy + if 0 < nx < width - 1 and 0 < ny < height - 1: + grid[ny][nx] = '#' + + with open(filename, 'w', encoding='utf-8') as f: + for row in grid: + f.write(''.join(row) + '\n') + + +def run_experiments(mazes_config: list[dict], strategies: dict, + runs: int = 5) -> list[dict]: + builder = TextFileMazeBuilder() + results = [] + + for maze_cfg in mazes_config: + name = maze_cfg['name'] + filepath = maze_cfg['file'] + + # Генерируем файл лабиринта + if 'generate' in maze_cfg: + gen = maze_cfg['generate'] + generate_maze_file(filepath, gen['width'], gen['height'], + gen.get('density', 0.3), + gen.get('no_exit', False)) + + try: + maze = builder.build_from_file(filepath) + except Exception as e: + print(f"[Пропуск] {name}: {e}") + continue + + for strat_name, strategy_cls in strategies.items(): + times, visited, lengths = [], [], [] + for _ in range(runs): + strategy = strategy_cls() + solver = MazeSolver(maze, strategy) + stats = solver.solve() + times.append(stats.time_ms) + visited.append(stats.visited_cells) + lengths.append(stats.path_length) + + results.append({ + 'лабиринт': name, + 'стратегия': strat_name, + 'время_мс': round(sum(times) / runs, 4), + 'посещено_клеток': int(sum(visited) / runs), + 'длина_пути': int(sum(lengths) / runs), + }) + print(f" {name} / {strat_name}: " + f"time={results[-1]['время_мс']:.3f}ms, " + f"visited={results[-1]['посещено_клеток']}, " + f"path={results[-1]['длина_пути']}") + + return results + + +def save_csv(results: list[dict], filename: str): + if not results: + return + with open(filename, 'w', newline='', encoding='utf-8-sig') as f: + writer = csv.DictWriter(f, fieldnames=results[0].keys()) + writer.writeheader() + writer.writerows(results) + print(f"\nРезультаты сохранены в {filename}") + + +def print_table(results: list[dict]): + if not results: + print("Нет результатов.") + return + header = f"{'Лабиринт':<20} {'Стратегия':<12} {'Время,мс':>10} {'Посещено':>10} {'Путь':>8}" + print("\n" + "=" * len(header)) + print(header) + print("=" * len(header)) + for r in results: + print(f"{r['лабиринт']:<20} {r['стратегия']:<12} " + f"{r['время_мс']:>10.4f} {r['посещено_клеток']:>10} {r['длина_пути']:>8}") + print("=" * len(header)) + + +#Демонстрация + +def demo_interactive(maze: Maze, solver: MazeSolver, view: ConsoleView): + """Пошаговый режим с Command.""" + path = solver.get_last_path() + if not path: + print("Путь не найден — пошаговый режим недоступен.") + return + + player = Player(maze.start) + history: list[MoveCommand] = [] + view.render(maze, player_pos=player.current_cell, path=path) + + print("Пошаговый режим: [N] — следующий шаг, [U] — отмена, [Q] — выход") + step_index = 1 # 0-й шаг — старт, уже там + + while True: + cmd = input("Команда: ").strip().upper() + if cmd == 'Q': + break + elif cmd == 'N': + if step_index < len(path): + move = MoveCommand(player, path[step_index], solver) + move.execute() + history.append(move) + step_index += 1 + os.system('cls' if os.name == 'nt' else 'clear') + view.render(maze, player_pos=player.current_cell, path=path) + if player.current_cell == maze.exit: + print("🎉 Вы достигли выхода!") + break + else: + print("Вы уже в конце пути.") + elif cmd == 'U': + if history: + move = history.pop() + move.undo() + step_index -= 1 + os.system('cls' if os.name == 'nt' else 'clear') + view.render(maze, player_pos=player.current_cell, path=path) + else: + print("Нечего отменять.") + else: + print("Неизвестная команда.") + + +def main(): + print("=" * 60) + print(" Поиск выхода из лабиринта — ООП + паттерны GoF") + print("=" * 60) + + small_maze_file = "maze_small.txt" + + builder = TextFileMazeBuilder() + maze = builder.build_from_file(small_maze_file) + + #2. Создаём представление (Observer) + view = ConsoleView() + + #3. Демонстрация стратегий + strategies = { + 'BFS': BFSStrategy, + 'DFS': DFSStrategy, + 'A*': AStarStrategy, + 'Дейкстра': DijkstraStrategy, + } + + print(f"\nЛабиринт ({maze.width}×{maze.height}):") + view.render(maze) + + for name, cls in strategies.items(): + strategy = cls() + solver = MazeSolver(maze, strategy) + solver.add_observer(view) + stats = solver.solve() + + #Визуализация пути A* + print("\n--- Путь, найденный A* ---") + a_star = AStarStrategy() + solver = MazeSolver(maze, a_star) + solver.add_observer(view) + solver.solve() + view.render(maze, path=solver.get_last_path()) + + #4. Пошаговый режим Command + ans = input("Запустить пошаговый режим? (y/n): ").strip().lower() + if ans == 'y': + demo_interactive(maze, solver, view) + + #5. Экспериментальная часть + print("\n" + "=" * 60) + print(" Экспериментальная часть") + print("=" * 60) + + mazes_config = [ + { + 'name': 'Маленький 10×10', + 'file': 'maze_small.txt', + }, + { + 'name': 'Средний 50×50', + 'file': 'maze_medium.txt', + }, + { + 'name': 'Большой 100×100', + 'file': 'maze_large.txt', + }, + { + 'name': 'Пустой 50×50', + 'file': 'maze_empty.txt', + }, + { + 'name': 'Без выхода 20×20', + 'file': 'maze_no_exit.txt', + }, + ] + + all_strategies = { + 'BFS': BFSStrategy, + 'DFS': DFSStrategy, + 'A*': AStarStrategy, + 'Дейкстра': DijkstraStrategy, + } + + print("\nЗапуск экспериментов (5 прогонов каждого)...") + results = run_experiments(mazes_config, all_strategies, runs=5) + print_table(results) + save_csv(results, "results.csv") + + print("\nГотово!") + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/zaharoves/задание 2/graphs.py b/zaharoves/задание 2/graphs.py index e69de29..708c983 100644 --- a/zaharoves/задание 2/graphs.py +++ b/zaharoves/задание 2/graphs.py @@ -0,0 +1,57 @@ +import pandas as pd +import matplotlib.pyplot as plt + + +df = pd.read_csv('results.csv', encoding='utf-8-sig') + +print(df) + +# Получаем список лабиринтов +mazes = df['лабиринт'].unique() + +#График времени +for maze in mazes: + subset = df[df['лабиринт'] == maze] + + plt.figure(figsize=(8, 5)) + plt.bar(subset['стратегия'], subset['время_мс']) + + plt.title(f'Время выполнения — {maze}') + plt.xlabel('Алгоритм') + plt.ylabel('Время (мс)') + + plt.tight_layout() + plt.savefig(f'time_{maze}.png') + plt.close() + +#График посещенных клеток +for maze in mazes: + subset = df[df['лабиринт'] == maze] + + plt.figure(figsize=(8, 5)) + plt.bar(subset['стратегия'], subset['посещено_клеток']) + + plt.title(f'Посещённые клетки — {maze}') + plt.xlabel('Алгоритм') + plt.ylabel('Количество клеток') + + plt.tight_layout() + plt.savefig(f'visited_{maze}.png') + plt.close() + +# ===== ГРАФИК ДЛИНЫ ПУТИ ===== +for maze in mazes: + subset = df[df['лабиринт'] == maze] + + plt.figure(figsize=(8, 5)) + plt.bar(subset['стратегия'], subset['длина_пути']) + + plt.title(f'Длина пути — {maze}') + plt.xlabel('Алгоритм') + plt.ylabel('Длина пути') + + plt.tight_layout() + plt.savefig(f'path_{maze}.png') + plt.close() + +print('Графики успешно построены!') \ No newline at end of file diff --git a/zaharoves/задание 2/maze_empty.txt b/zaharoves/задание 2/maze_empty.txt new file mode 100644 index 0000000..c83b6cd --- /dev/null +++ b/zaharoves/задание 2/maze_empty.txt @@ -0,0 +1,50 @@ +################################################## +#S # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# E# +################################################## diff --git a/zaharoves/задание 2/maze_large.txt b/zaharoves/задание 2/maze_large.txt new file mode 100644 index 0000000..1e4f4a3 --- /dev/null +++ b/zaharoves/задание 2/maze_large.txt @@ -0,0 +1,100 @@ +#################################################################################################### +#S ## # ## ## # # # ## ####### ## # # ## ## ## # # ### # # +# # # # # # # # # # # # # # # # ## ### # ## ## ## # ## ## # +# # # # # # ## # # ## ## # # # # # ### # # # ### # # # # ## ## +# ## ## ### # # # # # ### # # # ## # # # ## # +# ## # ## #### # # # # # # ## ## #### ## # # # # +### # # # # # # # # ### #### # # # ## # # # # # # # # # +# # ## ## # ## ##### ## ###### # # ## # ## # # ## #### # +# ## ## ## ## ## ## # # # # # # ## # # # +## # # # # # # # # ## # # # # ## # # ### +## # # # # # # # # ## ## # # # # ### ## # # +## # # # # # ## # ## # ## # # #### ## # ## # # # ## ## # # +# # # # # # ## # # ## # ## # # # # ### # # # # # # ### # # +## # ## ## # # # # ### # ## ## # # ### ## # # +## ## # # ## ### # # # # # # # # ## # # # # # # +# ## # # ## # ### ## # # # ## # # # ## # # # #### # # # # +# # # # # # # ## ## ## # # # # ### # # # +# # # ### # # # # ## # ### # # #### # # # # # # +# # # # # # ## # # # # # # # ## # ### # ## +## # ### ## ## # # # # # # # # # # # # # # ### ## # # +## ## ### # # # # ### ## # # # # ## # # # # # # # # +##### # # # #### # ## # # # # # # ### # ## # # # # # +## # # ### # # # # ## # # # # # # #### # # # ### # +# # ## ## ### # # ## # ## ## ### # # # # # # # ### +## ## # # # # # # # # # # ## ## # # ## +# # # ### # # # # ## # # # ### # # # # # ## ## ## # ## # +# # # # # ##### # ## # # # # # # # # # ## ## # # # ## +# # # # # # # ## # ## # # # # # # ## ### ## # # ##### # +# # # # # ## # # ## # # ## # ## # # # # ## # # # ## # +## ## # # # # # # ### # ## ### ## # ### # ## # # # ## # # ## # # +# # # # #### # ## #### # # # # # # # # # # ### # ## # # +# # ## # # # # # # # # # # ###### # ## # ## # # # #### #### # # +# # ##### # # # ### # # # # # # # # # ## ### # # +# # # # # # # ## # # ## # # ## # # # # # # # ## # # ### +## # ## # # # #### # # ## # ## ## # ## # # ## # # +## # # # ## # # # # # # # # # # # ###### # ## # # ## ### # #### # # +## # # # # # # # # # # # ## # # # # # # ## # # # ## # ## +## # # # ### # # # # # # # # # # # # # # ### +# # ### # # # # # ## ## ## # # ## # ### ### # # # +# # # # # ## # # ## ## # # # # # # ## ## ## # +# ### # # ### # # # # ### # # # # # # # ## # ## +# # ### ## ## ## ## # # ### # ## # # # # ## ## # # # # # # +# ## # # # ## # # # # ## # ### #### # ## ###### ### # +# # # # ### ### # # ## # # # ### ## # ## # # ## ## +# # # ### #### # # # # ### # # # ## ### ## # ## #### # # +# ### ## # # # # # # # # ### # # # # ## # ### ### ## # +# # # # # # # # # # # ### ## ### # ## # # # ## # #### # ## # # +# # # # # # # # # # # ### # # # # # ## # # # # # # # +# ## # # # # ## # # # ## ## ## # # ## # ## # # ## # ## # +# # # ## # # # # ### # # # # # # ## # # # ## # ### ## # # # +## # ## # ## ### ## # # # # ## # # # # # # # +## ## # # ### # # # # # ## # # # # # ## # ## # # # # +# # # ## # ### # ## # # ## # # # # # # # # +# # # # # ## #### # # ### # ## # # ## # # ## # +# # # # ## # ### # ## ## # # # # ### # # # +# # # # # # # # # ## # ## ## ### ### # # ## # # # ## # +# # # # ## # # ### ##### # # # # ## # # # # # ## # # # +## # # # ## # # ## # ## ## # ## # ### # # # # # +# ## ## # ### # ## ### # # ## # # # # # # # # # # # ### +# ## # # # # # # # # # # # ## # # # # # # # # # # # ## # +# # # # ## # # # # # ## # # ## # # ## # # # ### ### # # # ## +# # # # ## # ## # # # # # # # ## # # ## # ### ## +### # # ## ### # ## # # #### # # # # ##### # ## #### # +# # # # # # # #### ## # ### ### # ## # # # # ## # # # # # # ### +# #### # ## # # # # # # ## # # # # # # # # +# ## # # # # # # ## # ## ## # ### #### # # # # ## # +# # ## # ## # # # # ## ## # ## # ## # +# # # # # # # ## # # # # # # ### ## ### # ## # # ### +### # # # ##### # ## ## # # # ## # ## ## # # # # # # +# # # # # # ## ##### # ### # ## # # # ## # ### #### # # +# # ### # ## # # ### ## ## # ## # ### # ## ### # ### +# ## ## ## # # # # # # ### # ## # # ## # # # # +## ## ## # ## # ## # # # ## # ## # ## # ## # # # # +# # # # # # # # ## # # # ####### # ## ## ## ## +# # # # # # # # # ## # # # # # ## # # ### # ## +# # ## #### # # # # # ## ### # ### # ### # ### ## # # # +## # # ## # # # # # # # # ## # ##### # ## ##### #### ### +# # # # ## # ## # # ## # # ### ## ## # ###### +# # ## # # # # # # # # # ## ## # ## ## ## # ## # # +### #### # # ## # # # # # ## # # ## # # # #### # # ## # # +# ## ## # # ## # ## ## # # ## # # # # # #### # # +# ## # # # ## ### ## #### # # # # # # ## ### # # ## +## # # # # # # # ## # ## ### # ## # ## # # # +# # # # # # # # # ### # # # ## # # ## ## # #### # +# # ## # # # # # # # # # # ## ### # # # ## +## ## # ## # # # ## # # # # # #### # # ## ### # +## # ## ## # # # # ### # # ## # # # ## ## # # # # ## # +# ## # ## # # #### # # # # # # ## # # # # # # ### # +# ## # #### # # ## # # # # ### ## # ## ### # ## ## ## +# # # # # # ## # # # ## # #### # ##### # # # # # # # +# # ## ## ### # ### ### # # #### # # # # ## # ## # # # # #### # # +# # # # ## # # ## # # ## # # ## # ## # # # ## ## # +# # ## # # # ## ## # ### ## # ## # # # # # # # ## # # # +# # ## # ## ## ## # # ## # # # # # ## # # # # ### # # +# # # ## # # # # # # # # # # # # ## # # # ## # # # +## # ## # # # # ## # # ## # # # # # # ## # # # # # # # # +# # ## # ## # ### # # ### # ## # # # ## # ### # ## # # +# # # ## # # ## # # # ## # # #### ## # # # ### # ## +# #### ## ### ### # # ### # # ## # # # ### # ####### # ## # E# +#################################################################################################### diff --git a/zaharoves/задание 2/maze_medium.txt b/zaharoves/задание 2/maze_medium.txt new file mode 100644 index 0000000..76efa05 --- /dev/null +++ b/zaharoves/задание 2/maze_medium.txt @@ -0,0 +1,50 @@ +################################################## +#S# # ## ## # # ## ### ######## +# # # # ##### # ## # # ### # # +# # # # # # # # ### ## # # # # # +# # ## ### ### # ## ## ## # # ## ## +## # # # # ## # # ## ## # # +# # # ## ### # # # ### # # # ## +# ## # ## ### ### # # # # # # +## # #### # # # ## # # # # ## ## # +# ## # ## # ## # #### # # # # # # +## ## ## ##### ## # # # +# # ## ## # # # # # ## ### # ## +#### # # # ### # # # # # # # # +# # # # # ## # ## # ## # # ###### +# ## ###### # ## # ## # # # # +# # ## #### ## ### ## ## ### +## ## # ### # # ## # # # +## ## # # # # # ## # # ## ## +# # # # # # ## # # +## # # ## # # ### # # # # # # # # +## # ## ## # ## # # # +# ### ## # # # # # # # # ### +# # ## # ## ## # #### ## ### # # ## +# ## ## # # # ## # # # ## ## # +# # ## # ## ### # # # # ### # +# # # # # # ####### # # ## ### ## +# # #### # # ### # ## ### # # # # +# # ### # ## # # # # # # ## # +# # ## ### # ## # # # # # # # +# # ## # # # # # ### # # ## # ## +### #### # # ## # # # ## # ## # +## # #### # # ## # ## # # +# # # # # ## ## ## # # # +# # ### ### # ## # # # ### +#### # # ## # # ## # ### # # # +# # # #### # ## # ## # # # ## +# # # # # ### # # ## # # # +# # # # #### #### ## # ## # ### ## # +### ## # # # # # # # # # # # # +# # # # # # ### ## # ###### # +## # ### ## # ### ## # # # ## ## # # +# # ### # # ## #### # +#### # #### # ## # # # ### ### ## +# # # ### # ## # # # # # # # +# # # ### ## # # # ## # # +## # # # # #### # # # ### # +## ## ## # # ### # # # # ## # +# # ## #### ### # # # # # # ## # ### # +# ### # ## ## ## # # # # # E# +################################################## diff --git a/zaharoves/задание 2/maze_no_exit.txt b/zaharoves/задание 2/maze_no_exit.txt new file mode 100644 index 0000000..639bf8f --- /dev/null +++ b/zaharoves/задание 2/maze_no_exit.txt @@ -0,0 +1,20 @@ +#################### +#S### # ## ## # # +# # # ## # +# ####### ## # +# # # ## ## # +# ## # # ### +## # # # # # +# # # # # # # +## # # # # # # +# # # ## ### # +## ## ## ## # +# # ## ## ## +# # # # # # +# ## # # ## # +### # # # # # +## ### # ## +# # ### # # # ## +# ## # ## ### +# ### # #E# +#################### diff --git a/zaharoves/задание 2/maze_small.txt b/zaharoves/задание 2/maze_small.txt new file mode 100644 index 0000000..07daed1 --- /dev/null +++ b/zaharoves/задание 2/maze_small.txt @@ -0,0 +1,10 @@ +########## +#S # +# # ###### +# # # # +# # # # # +# # # # # +# # +#### ##### +# E # +########## diff --git a/zaharoves/задание 2/path_Без выхода 20×20.png b/zaharoves/задание 2/path_Без выхода 20×20.png new file mode 100644 index 0000000..6bbf31f Binary files /dev/null and b/zaharoves/задание 2/path_Без выхода 20×20.png differ diff --git a/zaharoves/задание 2/path_Большой 100×100.png b/zaharoves/задание 2/path_Большой 100×100.png new file mode 100644 index 0000000..2d0a2d7 Binary files /dev/null and b/zaharoves/задание 2/path_Большой 100×100.png differ diff --git a/zaharoves/задание 2/path_Маленький 10×10.png b/zaharoves/задание 2/path_Маленький 10×10.png new file mode 100644 index 0000000..aa24ab2 Binary files /dev/null and b/zaharoves/задание 2/path_Маленький 10×10.png differ diff --git a/zaharoves/задание 2/path_Пустой 50×50.png b/zaharoves/задание 2/path_Пустой 50×50.png new file mode 100644 index 0000000..8abd9e9 Binary files /dev/null and b/zaharoves/задание 2/path_Пустой 50×50.png differ diff --git a/zaharoves/задание 2/path_Средний 50×50.png b/zaharoves/задание 2/path_Средний 50×50.png new file mode 100644 index 0000000..3e42168 Binary files /dev/null and b/zaharoves/задание 2/path_Средний 50×50.png differ diff --git a/zaharoves/задание 2/results.csv b/zaharoves/задание 2/results.csv new file mode 100644 index 0000000..6f54560 --- /dev/null +++ b/zaharoves/задание 2/results.csv @@ -0,0 +1,21 @@ +лабиринт,стратегия,время_мс,посещено_клеток,длина_пути +Маленький 10×10,BFS,0.0791,39,14 +Маленький 10×10,DFS,0.0605,30,18 +Маленький 10×10,A*,0.1048,34,14 +Маленький 10×10,Дейкстра,0.114,39,14 +Средний 50×50,BFS,1.9826,1305,95 +Средний 50×50,DFS,0.8278,529,199 +Средний 50×50,A*,0.909,303,95 +Средний 50×50,Дейкстра,3.9224,1305,95 +Большой 100×100,BFS,10.3434,6583,195 +Большой 100×100,DFS,8.13,5190,521 +Большой 100×100,A*,6.0666,1978,195 +Большой 100×100,Дейкстра,20.0361,6583,195 +Пустой 50×50,BFS,3.7195,2304,95 +Пустой 50×50,DFS,2.5223,1223,1129 +Пустой 50×50,A*,7.1408,2304,95 +Пустой 50×50,Дейкстра,7.6677,2304,95 +Без выхода 20×20,BFS,0.2898,193,0 +Без выхода 20×20,DFS,0.2849,193,0 +Без выхода 20×20,A*,0.5278,193,0 +Без выхода 20×20,Дейкстра,0.5431,193,0 diff --git a/zaharoves/задание 2/time_Без выхода 20×20.png b/zaharoves/задание 2/time_Без выхода 20×20.png new file mode 100644 index 0000000..7f21fd2 Binary files /dev/null and b/zaharoves/задание 2/time_Без выхода 20×20.png differ diff --git a/zaharoves/задание 2/time_Большой 100×100.png b/zaharoves/задание 2/time_Большой 100×100.png new file mode 100644 index 0000000..1f77c66 Binary files /dev/null and b/zaharoves/задание 2/time_Большой 100×100.png differ diff --git a/zaharoves/задание 2/time_Маленький 10×10.png b/zaharoves/задание 2/time_Маленький 10×10.png new file mode 100644 index 0000000..325498b Binary files /dev/null and b/zaharoves/задание 2/time_Маленький 10×10.png differ diff --git a/zaharoves/задание 2/time_Пустой 50×50.png b/zaharoves/задание 2/time_Пустой 50×50.png new file mode 100644 index 0000000..470a18b Binary files /dev/null and b/zaharoves/задание 2/time_Пустой 50×50.png differ diff --git a/zaharoves/задание 2/time_Средний 50×50.png b/zaharoves/задание 2/time_Средний 50×50.png new file mode 100644 index 0000000..5aba1c7 Binary files /dev/null and b/zaharoves/задание 2/time_Средний 50×50.png differ diff --git a/zaharoves/задание 2/visited_Без выхода 20×20.png b/zaharoves/задание 2/visited_Без выхода 20×20.png new file mode 100644 index 0000000..0a01f3d Binary files /dev/null and b/zaharoves/задание 2/visited_Без выхода 20×20.png differ diff --git a/zaharoves/задание 2/visited_Большой 100×100.png b/zaharoves/задание 2/visited_Большой 100×100.png new file mode 100644 index 0000000..edcb37c Binary files /dev/null and b/zaharoves/задание 2/visited_Большой 100×100.png differ diff --git a/zaharoves/задание 2/visited_Маленький 10×10.png b/zaharoves/задание 2/visited_Маленький 10×10.png new file mode 100644 index 0000000..249fbd9 Binary files /dev/null and b/zaharoves/задание 2/visited_Маленький 10×10.png differ diff --git a/zaharoves/задание 2/visited_Пустой 50×50.png b/zaharoves/задание 2/visited_Пустой 50×50.png new file mode 100644 index 0000000..aa7c867 Binary files /dev/null and b/zaharoves/задание 2/visited_Пустой 50×50.png differ diff --git a/zaharoves/задание 2/visited_Средний 50×50.png b/zaharoves/задание 2/visited_Средний 50×50.png new file mode 100644 index 0000000..b35591d Binary files /dev/null and b/zaharoves/задание 2/visited_Средний 50×50.png differ diff --git a/zaharoves/задание 2/Графики.docx b/zaharoves/задание 2/Графики.docx new file mode 100644 index 0000000..7bcb5f3 Binary files /dev/null and b/zaharoves/задание 2/Графики.docx differ diff --git a/zaharoves/задание 2/Отчёт.docx b/zaharoves/задание 2/Отчёт.docx new file mode 100644 index 0000000..4abdb82 Binary files /dev/null and b/zaharoves/задание 2/Отчёт.docx differ