From b1b22678a2605410407310349e516a5abc92cbdd Mon Sep 17 00:00:00 2001 From: 4eker <423785z@gmail.com> Date: Mon, 25 May 2026 13:45:18 +0300 Subject: [PATCH] BagFix and add main file --- pomelovsd/ExitMaze/Builder/Builder.py | 4 +- pomelovsd/ExitMaze/Core/Maze.py | 4 +- pomelovsd/ExitMaze/Strategies/AStar.py | 20 +- pomelovsd/ExitMaze/Strategies/BFS.py | 6 +- pomelovsd/ExitMaze/Strategies/DFS.py | 8 +- pomelovsd/ExitMaze/Strategies/path.py | 2 +- pomelovsd/ExitMaze/analysis.png | Bin 0 -> 2396 bytes pomelovsd/ExitMaze/main.ipynb | 427 +++++++++++++------------ pomelovsd/ExitMaze/results.csv | 16 + 9 files changed, 261 insertions(+), 226 deletions(-) create mode 100644 pomelovsd/ExitMaze/analysis.png create mode 100644 pomelovsd/ExitMaze/results.csv diff --git a/pomelovsd/ExitMaze/Builder/Builder.py b/pomelovsd/ExitMaze/Builder/Builder.py index 69eec1a..789443c 100644 --- a/pomelovsd/ExitMaze/Builder/Builder.py +++ b/pomelovsd/ExitMaze/Builder/Builder.py @@ -15,9 +15,7 @@ class TextFileMazeBuilder(MazeBuilders): for y, line in enumerate(lines): row = [] for x, ch in enumerate(line): - - cell = Cell(x, y, is_wall = (ch == "#"), is_start = (ch == "S"), is_exit = (ch == "E")) - + cell = Cell(x, y, isWall = (ch == "#"), isStart = (ch == "S"), isExit = (ch == "E")) if (ch == "S"): start = cell if (ch == "E"): diff --git a/pomelovsd/ExitMaze/Core/Maze.py b/pomelovsd/ExitMaze/Core/Maze.py index 6429468..16fe36f 100644 --- a/pomelovsd/ExitMaze/Core/Maze.py +++ b/pomelovsd/ExitMaze/Core/Maze.py @@ -8,7 +8,7 @@ class Maze: # Создание новой ячейки def getCell(self, x, y): - if 0 <= y < self.height and 0 <= x < self.width: + if 0 <= x < self.height and 0 <= y < self.width: return self.grid[x][y] return None @@ -19,7 +19,7 @@ class Maze: for dx, dy in directions: nx, ny = cell.x + dx, cell.y + dy - neighbor = self.getСell(nx, ny) + neighbor = self.getCell(nx, ny) if neighbor and neighbor.isPassable(): result.append(neighbor) diff --git a/pomelovsd/ExitMaze/Strategies/AStar.py b/pomelovsd/ExitMaze/Strategies/AStar.py index 3382d61..12ded7a 100644 --- a/pomelovsd/ExitMaze/Strategies/AStar.py +++ b/pomelovsd/ExitMaze/Strategies/AStar.py @@ -1,34 +1,38 @@ from Strategies.strat import PathFindingStrategy -from path import restore +from Strategies.path import restore import heapq class AStar(PathFindingStrategy): def heuristic(self, a, b): - return abs(a.x - b.x)+ abs(a.y - b.y) + return abs(a.x - b.x) + abs(a.y - b.y) def findPath(self, maze, start, exit): - heap = [(0, start)] + heap = [] + counter = 0 + heapq.heappush(heap, (0, counter, start)) + counter += 1 + parent = {} g = {start: 0} visited = set() while heap: - _, current = heapq.heappop(heap) + _, _, current = heapq.heappop(heap) # распаковка трёх элементов if current == exit: break visited.add(current) - for n in maze.get_neigbors(current): + for n in maze.getNeighbors(current): tentative = g[current] + 1 if n not in g or tentative < g[n]: g[n] = tentative priority = tentative + self.heuristic(n, exit) - heapq.heappush(heap, (priority, n)) + heapq.heappush(heap, (priority, counter, n)) + counter += 1 parent[n] = current - return self.restore(parent, start, exit), len(visited) - \ No newline at end of file + return restore(parent, start, exit), len(visited) \ No newline at end of file diff --git a/pomelovsd/ExitMaze/Strategies/BFS.py b/pomelovsd/ExitMaze/Strategies/BFS.py index 4fadd8d..3aa876a 100644 --- a/pomelovsd/ExitMaze/Strategies/BFS.py +++ b/pomelovsd/ExitMaze/Strategies/BFS.py @@ -1,5 +1,5 @@ from Strategies.strat import PathFindingStrategy -from path import restore +from Strategies.path import restore from collections import deque class BFS(PathFindingStrategy): @@ -14,10 +14,10 @@ class BFS(PathFindingStrategy): if current == exit: break - for n in maze.get_neigbors(current): + for n in maze.getNeighbors(current): if n not in visited: visited.add(n) parent[n] = current queue.append(n) - return self.restore(parent, start, exit), len(visited) \ No newline at end of file + return restore(parent, start, exit), len(visited) \ No newline at end of file diff --git a/pomelovsd/ExitMaze/Strategies/DFS.py b/pomelovsd/ExitMaze/Strategies/DFS.py index f49998e..d523b9b 100644 --- a/pomelovsd/ExitMaze/Strategies/DFS.py +++ b/pomelovsd/ExitMaze/Strategies/DFS.py @@ -1,5 +1,5 @@ from Strategies.strat import PathFindingStrategy -from path import restore +from Strategies.path import restore class DFS(PathFindingStrategy): @@ -8,16 +8,16 @@ class DFS(PathFindingStrategy): visited = {start} parent = {} - while start: + while stack: current = stack.pop() if current == exit: break - for n in maze.get_neighbors(current): + for n in maze.getNeighbors(current): if n not in visited: visited.add(n) parent[n] = current stack.append(n) - return self.restore(parent, start, exit), len(visited) \ No newline at end of file + return restore(parent, start, exit), len(visited) \ No newline at end of file diff --git a/pomelovsd/ExitMaze/Strategies/path.py b/pomelovsd/ExitMaze/Strategies/path.py index edef25c..ba7f3bf 100644 --- a/pomelovsd/ExitMaze/Strategies/path.py +++ b/pomelovsd/ExitMaze/Strategies/path.py @@ -1,4 +1,4 @@ -def restore(self, parent, start, exit): +def restore(parent, start, exit): if exit not in parent and start != exit: return[] diff --git a/pomelovsd/ExitMaze/analysis.png b/pomelovsd/ExitMaze/analysis.png new file mode 100644 index 0000000000000000000000000000000000000000..17b4ea042846cd00588f8a30da94b471d0edae25 GIT binary patch literal 2396 zcmeAS@N?(olHy`uVBq!ia0y~yU}|7sV0^&A1{5*9c;^X_vMh0pC<)F_D=AMbN@eg( zEGfvzFUiSFQYcF;D$dN$GuAWHGuBbaC@Co@w$j(ng)7j@FG|-x|8?J2pdp+E9+AZi z4E%{8%(%jSc_sq`$4O5Y$B>FSZ?73LGAQsIFgURP`9r2YHLj|%^JjDz7>v%n2kN|M z)WE=C$R@y`aEyV8;fRC-LxTh}2ZKN|10zEcj{<{34 5\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mStrategies\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mBFS\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m BFS\n\u001b[1;32m 6\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mStrategies\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mDFS\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m DFS\n\u001b[1;32m 7\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mStrategies\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mAStar\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m AStar\n", - "File \u001b[0;32m~/2026-rff_mp/pomelovsd/ExitMaze/Strategies/BFS.py:2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mstrat\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m PathFindingStrategy\n\u001b[0;32m----> 2\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mpath\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m restore\n\u001b[1;32m 3\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mcollections\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m deque\n\u001b[1;32m 5\u001b[0m \u001b[38;5;28;01mclass\u001b[39;00m \u001b[38;5;21;01mBFS\u001b[39;00m(PathFindingStrategy):\n", - "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'path'" - ] - } - ], + "outputs": [], "source": [ "from Builder.Builder import TextFileMazeBuilder\n", "from Core.Benchmark import RunBenchmark\n", @@ -43,55 +32,11 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 82, "id": "50c7010d", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n" - ] - } - ], + "outputs": [], "source": [ - "print(TextFileMazeBuilder)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6ed7f922", - "metadata": {}, - "outputs": [ - { - "ename": "ImportError", - "evalue": "cannot import name 'BFS' from 'Strategies.BFS' (/home/i4eker/2026-rff_mp/pomelovsd/ExitMaze/Strategies/BFS.py)", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mImportError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[13], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mBuilder\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mBuilder\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m TextFileMazeBuilder\n\u001b[0;32m----> 3\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mStrategies\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mBFS\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m BFS\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mStrategies\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mDFS\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m DFS\n\u001b[1;32m 5\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mStrategies\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mAStar\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m AStar\n", - "\u001b[0;31mImportError\u001b[0m: cannot import name 'BFS' from 'Strategies.BFS' (/home/i4eker/2026-rff_mp/pomelovsd/ExitMaze/Strategies/BFS.py)" - ] - } - ], - "source": [ - "\n", - "from Builder.Builder import TextFileMazeBuilder\n", - "\n", - "from Strategies.BFS import BFS\n", - "from Strategies.DFS import DFS\n", - "from Strategies.AStar import AStar\n", - "\n", - "from MazeSolver.Solver import MazeSolver\n", - "\n", - "\n", - "# ============================================\n", - "# ЗАГРУЗКА ЛАБИРИНТОВ\n", - "# ============================================\n", - "\n", "builder = TextFileMazeBuilder()\n", "\n", "mazes = {\n", @@ -100,46 +45,88 @@ " \"large\": builder.build_from_file(\"Mazes/large.txt\"),\n", " \"empty\": builder.build_from_file(\"Mazes/empty.txt\"),\n", " \"no_exit\": builder.build_from_file(\"Mazes/no_exit.txt\"),\n", - "}\n", - "\n", - "\n", - "# ============================================\n", - "# СТРАТЕГИИ\n", - "# ============================================\n", - "\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "id": "7326fe7d", + "metadata": {}, + "outputs": [], + "source": [ "strategies = {\n", " \"BFS\": BFS(),\n", " \"DFS\": DFS(),\n", " \"A*\": AStar()\n", - "}\n", - "\n", - "\n", - "# ============================================\n", - "# РЕЗУЛЬТАТЫ\n", - "# ============================================\n", - "\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "id": "8d47b4cf", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Лабиринт: small\n", + "Testing BFS\n", + "BFS: time=0.05052728504649297 ms | visited=8.0 \n", + "Testing DFS\n", + "DFS: time=0.02667414290564401 ms | visited=8.0 \n", + "Testing A*\n", + "A*: time=0.04907028570804479 ms | visited=8.0 \n", + "Лабиринт: medium\n", + "Testing BFS\n", + "BFS: time=0.03876400062706255 ms | visited=10.0 \n", + "Testing DFS\n", + "DFS: time=0.03143985668430105 ms | visited=10.0 \n", + "Testing A*\n", + "A*: time=0.042394856791361235 ms | visited=10.0 \n", + "Лабиринт: large\n", + "Testing BFS\n", + "BFS: time=0.9620827144577301 ms | visited=197.0 \n", + "Testing DFS\n", + "DFS: time=0.8404238573608122 ms | visited=197.0 \n", + "Testing A*\n", + "A*: time=1.04237128575083 ms | visited=197.0 \n", + "Лабиринт: empty\n", + "Testing BFS\n", + "BFS: time=0.010339713948529347 ms | visited=2.0 \n", + "Testing DFS\n", + "DFS: time=0.007900571810231278 ms | visited=2.0 \n", + "Testing A*\n", + "A*: time=0.009533572145820861 ms | visited=2.0 \n", + "Лабиринт: no_exit\n", + "Testing BFS\n", + "BFS: time=0.00666371410521346 ms | visited=1.0 \n", + "Testing DFS\n", + "DFS: time=0.005225571450344952 ms | visited=1.0 \n", + "Testing A*\n", + "A*: time=0.006098571507858911 ms | visited=1.0 \n" + ] + } + ], + "source": [ "results = []\n", "\n", - "\n", - "# ============================================\n", - "# BENCHMARK\n", - "# ============================================\n", - "\n", - "REPEATS = 5\n", + "N = 7\n", "\n", "for maze_name, maze in mazes.items():\n", "\n", - " print(f\"\\n===== LABYRINTH: {maze_name} =====\")\n", + " print(f\"Лабиринт: {maze_name}\")\n", "\n", " for strategy_name, strategy in strategies.items():\n", "\n", " total_time = 0\n", " total_visited = 0\n", - " total_path = 0\n", "\n", - " print(f\"Testing {strategy_name}...\")\n", + " print(f\"Testing {strategy_name}\")\n", "\n", - " for _ in range(REPEATS):\n", + " for _ in range(N):\n", "\n", " solver = MazeSolver(maze, strategy)\n", "\n", @@ -153,33 +140,42 @@ "\n", " total_time += elapsed_ms\n", " total_visited += stats.visited_cells\n", - " total_path += stats.path_length\n", "\n", - " avg_time = total_time / REPEATS\n", - " avg_visited = total_visited / REPEATS\n", - " avg_path = total_path / REPEATS\n", + "\n", + " avg_time = total_time / N\n", + " avg_visited = total_visited / N\n", "\n", " results.append({\n", " \"maze\": maze_name,\n", " \"strategy\": strategy_name,\n", " \"time_ms\": round(avg_time, 3),\n", " \"visited_cells\": int(avg_visited),\n", - " \"path_length\": int(avg_path)\n", " })\n", "\n", " print(\n", " f\"{strategy_name}: \"\n", - " f\"time={avg_time:.3f} ms | \"\n", - " f\"visited={avg_visited:.0f} | \"\n", - " f\"path={avg_path:.0f}\"\n", - " )\n", - "\n", - "\n", - "# ============================================\n", - "# СОХРАНЕНИЕ CSV\n", - "# ============================================\n", - "\n", - "csv_file = \"benchmark_results.csv\"\n", + " f\"time={avg_time} ms | \"\n", + " f\"visited={avg_visited} \"\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "id": "347cb7be", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "CSV saved: results.csv\n" + ] + } + ], + "source": [ + "csv_file = \"results.csv\"\n", "\n", "with open(csv_file, \"w\", newline=\"\", encoding=\"utf-8\") as file:\n", "\n", @@ -190,7 +186,6 @@ " \"strategy\",\n", " \"time_ms\",\n", " \"visited_cells\",\n", - " \"path_length\"\n", " ])\n", "\n", " for row in results:\n", @@ -199,125 +194,147 @@ " row[\"strategy\"],\n", " row[\"time_ms\"],\n", " row[\"visited_cells\"],\n", - " row[\"path_length\"]\n", " ])\n", "\n", - "print(f\"\\nCSV saved: {csv_file}\")\n", + "print(f\"\\nCSV saved: {csv_file}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "id": "4b6fb0b0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Результаты:\n", + "small | BFS | 0.051 ms | 8 visited \n", + "small | DFS | 0.027 ms | 8 visited \n", + "small | A* | 0.049 ms | 8 visited \n", + "medium | BFS | 0.039 ms | 10 visited \n", + "medium | DFS | 0.031 ms | 10 visited \n", + "medium | A* | 0.042 ms | 10 visited \n", + "large | BFS | 0.962 ms | 197 visited \n", + "large | DFS | 0.84 ms | 197 visited \n", + "large | A* | 1.042 ms | 197 visited \n", + "empty | BFS | 0.01 ms | 2 visited \n", + "empty | DFS | 0.008 ms | 2 visited \n", + "empty | A* | 0.01 ms | 2 visited \n", + "no_exit | BFS | 0.007 ms | 1 visited \n", + "no_exit | DFS | 0.005 ms | 1 visited \n", + "no_exit | A* | 0.006 ms | 1 visited \n" + ] + } + ], + "source": [ "\n", - "\n", - "# ============================================\n", - "# ВЫВОД ТАБЛИЦЫ\n", - "# ============================================\n", - "\n", - "print(\"\\nRESULTS:\\n\")\n", + "print(\"Результаты:\")\n", "\n", "for row in results:\n", "\n", " print(\n", - " f\"{row['maze']:10} | \"\n", - " f\"{row['strategy']:5} | \"\n", - " f\"{row['time_ms']:10} ms | \"\n", - " f\"{row['visited_cells']:10} visited | \"\n", - " f\"{row['path_length']:5} path\"\n", - " )\n", - "\n", - "\n", - "# ============================================\n", - "# ГРАФИК ВРЕМЕНИ\n", - "# ============================================\n", - "\n", - "for maze_name in mazes.keys():\n", - "\n", - " strategy_names = []\n", - " times = []\n", - "\n", - " for row in results:\n", - "\n", - " if row[\"maze\"] == maze_name:\n", - "\n", - " strategy_names.append(row[\"strategy\"])\n", - " times.append(row[\"time_ms\"])\n", - "\n", - " plt.figure(figsize=(8, 5))\n", - "\n", - " plt.bar(strategy_names, times)\n", - "\n", - " plt.title(f\"Execution Time — {maze_name}\")\n", - " plt.xlabel(\"Strategy\")\n", - " plt.ylabel(\"Time (ms)\")\n", - "\n", - " plt.show()\n", - "\n", - "\n", - "# ============================================\n", - "# ГРАФИК ПОСЕЩЁННЫХ КЛЕТОК\n", - "# ============================================\n", - "\n", - "for maze_name in mazes.keys():\n", - "\n", - " strategy_names = []\n", - " visited = []\n", - "\n", - " for row in results:\n", - "\n", - " if row[\"maze\"] == maze_name:\n", - "\n", - " strategy_names.append(row[\"strategy\"])\n", - " visited.append(row[\"visited_cells\"])\n", - "\n", - " plt.figure(figsize=(8, 5))\n", - "\n", - " plt.bar(strategy_names, visited)\n", - "\n", - " plt.title(f\"Visited Cells — {maze_name}\")\n", - " plt.xlabel(\"Strategy\")\n", - " plt.ylabel(\"Visited Cells\")\n", - "\n", - " plt.show()\n", - "\n", - "\n", - "# ============================================\n", - "# ГРАФИК ДЛИНЫ ПУТИ\n", - "# ============================================\n", - "\n", - "for maze_name in mazes.keys():\n", - "\n", - " strategy_names = []\n", - " path_lengths = []\n", - "\n", - " for row in results:\n", - "\n", - " if row[\"maze\"] == maze_name:\n", - "\n", - " strategy_names.append(row[\"strategy\"])\n", - " path_lengths.append(row[\"path_length\"])\n", - "\n", - " plt.figure(figsize=(8, 5))\n", - "\n", - " plt.bar(strategy_names, path_lengths)\n", - "\n", - " plt.title(f\"Path Length — {maze_name}\")\n", - " plt.xlabel(\"Strategy\")\n", - " plt.ylabel(\"Path Length\")\n", - "\n", - " plt.show()\n", - "\n", - "\n", - "print(\"\\nBenchmark completed.\")" + " f\"{row['maze']} | \"\n", + " f\"{row['strategy']} | \"\n", + " f\"{row['time_ms']} ms | \"\n", + " f\"{row['visited_cells']} visited \"\n", + " )\n" ] }, { "cell_type": "code", "execution_count": null, - "id": "b001bee8", + "id": "95a41c2e", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABKUAAAPdCAYAAABba9tpAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/P9b71AAAACXBIWXMAAA9hAAAPYQGoP6dpAACLX0lEQVR4nOzdd3hUBdrG4edMOglJIIEUQglVihRBBBQBpYvYwUpZcGVBaYrAotIUBAuICopSVuFTFhZZCwsGkCIoKhILsK7EYCgJkAAJBNJmzvcHZpJhEkwgnIHwu68rl847p7zvZGZInpxzxjBN0xQAAAAAAABgIZunGwAAAAAAAMDVh1AKAAAAAAAAliOUAgAAAAAAgOUIpQAAAAAAAGA5QikAAAAAAABYjlAKAAAAAAAAliOUAgAAAAAAgOUIpQAAAAAAAGA5QikAAAAAAABYjlAKAOBxP/74owYOHKjY2Fj5+/srKChI1113nWbOnKljx455uj0AAAAAl4Bhmqbp6SYAAFevd955R0OHDlWDBg00dOhQNWrUSLm5ufruu+/0zjvvqFmzZvroo4883SYAAACAMkYoBQDwmK+++krt27dXly5dtGrVKvn5+bncn5OTozVr1qh3794e6hAAAADApcLpewAAj5k2bZoMw9D8+fPdAilJ8vX1dQmkatWqpV69eumjjz5S06ZN5e/vr9q1a2vOnDku62VlZenJJ59U8+bNFRISosqVK6tt27b697//7bYPwzCcX15eXoqOjlb//v11+PBh5zL79u2TYRh6+eWX3dZv0qSJOnbs6FLLyMjQU089pdjYWPn6+qpatWoaOXKkMjMz3fb9+OOPu22zV69eqlWrltv+Fy9e7LLcoEGDZBiGBgwY4FJPSUnRY489ppiYGPn6+io2NlaTJ09WXl6e277OVatWLefjYbPZVLVqVd1111369ddfi+z97bffVv369eXn56dGjRrpww8/dNtmSfrJn9EwDC1fvtxl/VOnTikkJKTI78Gvv/6qBx98UFWrVpWfn58aNmyoN99802WZjRs3yjAMrVixwq23oKAgl8dv8eLFMgxD+/btc9Zyc3PVsGHDIr8H58pfP/8rICBAjRo10muvveay3KRJk2QYhlJTU4vdVq1atYrsrbivSZMmuaz/5Zdf6tZbb1XFihVVoUIFtWvXTp999lmR++rYsWOR2yw8b8eOHdWkSRO3dV9++WW3x0ySli1bprZt2yowMFBBQUHq1q2bdu7c6bLMgAEDFBQU5LbNFStWyDAMbdy40WX/577WtmzZ4uy1sJSUFP3lL39R9erV5e3t7TLTuX2eKy4uTnfccYdiYmLk7++vunXr6rHHHiv2e1X4NVP4q3DvxS1T+PublZWl8ePHu7xvDBs2TCdOnHDbX0neB/Of94X7kKTOnTu7PF/yn4vn+8rfRv7z5LbbbnN7HAYOHCjDMNyeI8eOHdPQoUNVrVo1+fr6qnbt2powYYKys7NdlivJezEAoPzx9nQDAICrk91u14YNG9SyZUtVr169xOvFx8dr5MiRmjRpkiIjI7V06VKNGDFCOTk5euqppyRJ2dnZOnbsmJ566ilVq1ZNOTk5Wrdune6++24tWrRI/fr1c9nmoEGDNHjwYOXl5enbb7/V+PHjdfToUa1evbrUc50+fVodOnTQgQMH9Pe//11NmzbVrl279Nxzz+mnn37SunXr3H6BvhDbt2/XokWL5OXl5VJPSUlR69atZbPZ9Nxzz6lOnTr66quv9Pzzz2vfvn1atGjRn267Z8+eevbZZ+VwOLR7926NHTtWd9xxh3bv3u2y3Mcff6wvvvhCU6ZMUWBgoObOnasHHnhA3t7euvfeey+on8qVK+v111/Xfffd56z94x//kI+Pj1ufu3fvVrt27VSjRg298sorioyM1Nq1azV8+HClpqZq4sSJJX48z2fWrFluodyfWblypaKionTy5EnNnz9fI0eOVFRUlPr06XPR/SxatEjXXHON83Z6erq6d+/ussymTZvUpUsXNW3aVAsWLJCfn5/mzp2r22+/XR988IH69u3rtt0WLVpo7ty5kqTk5GTdfffdF9zjtGnT9Mwzz2jgwIF65plnlJOTo5deeknt27fXN998o0aNGl3wtvPZ7XYNGzZMXl5estvtLvf1799fW7du1YwZM9SsWTN5e3vr//7v//T666//6XYTEhLUtm1bDR48WCEhIdq3b59effVV3XTTTfrpp5+KfC7mv2Yk6fvvv9ewYcPclrnxxhvdQtUqVapIkkzT1J133qn169dr/Pjxat++vX788UdNnDhRX331lb766iuX4L4k74NF+ec//+kWUg0ePNjl+XPXXXfpuuuuc84jyeX7ValSJa1du1YJCQmqU6eOJCktLU0ffvihKleu7LLtrKwsderUSQkJCZo8ebKaNm2qLVu2aPr06YqPj3cLScvyvRgAcIUwAQDwgJSUFFOSef/995d4nZo1a5qGYZjx8fEu9S5dupjBwcFmZmZmkevl5eWZubm55qBBg8wWLVq43CfJnDhxokvtzjvvNKtWreq8nZiYaEoyX3rpJbdtN27c2OzQoYPz9vTp002bzWZ+++23LsutWLHClGSuXr3aZd/Dhg1z2+Ztt91m1qxZ023/ixYtMk3TNO12u9myZUuzd+/eZs2aNc3+/fs7l33sscfMoKAg8/fff3fZ5ssvv2xKMnft2uW2v8LO3Z5pmubIkSNNSebp06ddeg8ICDBTUlKctby8PPOaa64x69atW+p+8mccNWqU6ePjY/7www/OZRs2bGg+/fTTbt+Dbt26mTExMWZ6errLth9//HHT39/fPHbsmGmapvnFF1+Ykszly5e7zRsYGOgy76JFi0xJZmJiommapnngwAEzKCjIHD58uMv3oDjnrm+apnnixAlTkvn00087axMnTjQlmUePHi12W+d+L/K3fe5z6+jRo27P4zZt2phVq1Y1T5486azl5eWZTZo0MWNiYkyHw+GyjbZt25q33nqr8/a5zznTNM0OHTqYjRs3duvzpZdecpk5KSnJ9Pb2Np944gmX5U6ePGlGRkaaffr0cdb69+9vBgYGum1z+fLlpiTziy++cNl/4dfa7NmzzcDAQPMvf/mLee6PtIGBgeYjjzxy3j5LwuFwmLm5uebvv/9uSjL//e9/uy0TFRVlDho0yHk7//lWuPeaNWuat912W7H7WbNmjSnJnDlzpkt92bJlpiRz/vz5LtsqyfvguX2cOnXKjImJcT6Xz33fK7z9c98D8uU/B3r06GGOGjXKWX/xxRfN1q1buz1H3nrrLVOS+c9//tNlOzNmzDAlmZ9//rmzVpL3YgBA+cPpewCAK0rjxo3VrFkzl9qDDz6ojIwMff/9987a8uXLdeONNyooKEje3t7y8fHRggULtGfPHrdtOhwO5eXlKTs7W1u2bHGe9lTccoW/zvXpp5+qSZMmat68ucty3bp1K/JUGtM03bZp/snlHt9++23t3r1bs2fPLnL/nTp1UnR0tMs2e/ToIensETR/Jr+nnJwcxcfH69NPP1Xbtm0VEBDgstytt96qiIgI520vLy/17dtXe/fu1YEDBy6on+joaN11113OI1rWrVungwcP6pFHHnFZLisrS+vXr9ddd92lChUquGy7Z8+eysrK0tdff+2yTkm+f+caPXq0atWqpSeeeOJPly3MbrcrLy9Px48f12uvvSbDMNSpU6dil/uz73lpZGZmavv27br33ntdTo3z8vLSI488ogMHDuiXX35xWefMmTPy9/cv0fbPfQwdDofL/WvXrlVeXp769evnspy/v786dOjg9hooyTbPdfjwYU2cOFHPPvtskUda1q1bVxs2bND27duVlZVVom3mO3LkiIYMGeI89c/Hx0c1a9aUpCLfP0rz2BVnw4YNkuR2Ku59992nwMBArV+/3qVe0vfBwqZMmaLc3FxNmTLlonqVpCeeeEKLFi1SZmam7Ha75s2bV+TRYRs2bFBgYKDzyMl8+XOeO1dJ34sBAOUHp+8BADwiPDxcFSpUUGJiYqnWi4yMLLaWlpYm6eypU3369NF9992nMWPGKDIyUt7e3po3b54WLlzotv7UqVM1depU5+02bdoUGfiMHTtWY8eOdat36NDB+f+HDx/W3r17izzFR5LbdWnmzp3rPGWqsPxfgota/5lnntG4ceMUGxvrdv/hw4f1ySeflHj/RXnvvff03nvvOW9fc801RZ7292ffi5iYmAvq54knnlC3bt00c+ZMvfHGG+rfv7/bdYfS0tKUl5en119/vdhTss7ddlGnrJ3Phg0btHz5cn3xxRfy9i7dj0x169Z1/r+3t7eeeeYZt1PspILHy9vbW9WqVdO9996r559//qJCjuPHj8s0TUVFRbndFx0dLangtZIvNTXVLeQoyq5du4r9XubLvwbQ9ddfX+T9Npvr30QzMzP/dJvnyn9djxo1StOmTXO7/x//+IceffRRtWnTplTbdTgc6tq1qw4dOqRnn31W1157rQIDA+VwONSmTRudOXPGZfnc3Fylp6crPDy8VPs5V1pamry9vZ2n8+UzDEORkZFu36+SvA8W9ssvv2jWrFl69913FRISclG9SlL37t1VpUoVLVmyRBERETp9+rT69u3r9v6alpamyMhIt1OWq1atKm9vb7deS/peDAAoPwilAAAe4eXlpVtvvVX/+c9/dODAAcXExJRovZSUlGJrYWFhkqQlS5YoNjZWy5Ytc/ll6NwL6+Z79NFH9de//lWmaerQoUOaNm2a2rZtq/j4eFWsWNG53IgRI/Twww+7rHv//fe73A4PD1dAQECR4Vf+/YX16dNHY8aMcamNGjVK+/fvL3L98ePHKzQ0VE8//XSx22/atKleeOGFIu/PDyXOp1evXs7rMR09elRz5sxRu3btFB8f73JUSkm+FxfSz0033aT69etr4sSJ+uyzz/Tzzz+7LVOpUiXnkT9FHaEhyS20mzFjhm655RaX2s0331zkurm5uXr88cf14IMPqkOHDn96cexzffzxx4qKilJOTo6+//57jRs3TllZWZo5c6bLcuvWrVNISIiysrK0ceNGTZo0SXl5eRf1i3ilSpVks9mUnJzsdt+hQ4ckuT4PT58+rYMHD7oEacWpU6eO28XslyxZ4nIh9/xtr1ixothwtbCAgABt3rzZpbZhw4YiA2Dp7AXclyxZorVr18rX17fIZZo1a6alS5eqefPmGjJkiB544AG3Povy888/64cfftDixYvVv39/Z33v3r1FLp+QkCDTNEv02J1PWFiY8vLydPToUZdgyjRNpaSkuAV8JXntFfbEE0/ohhtucLue3oUyDENDhw7VG2+8oYiICA0ePLjID6sICwvT9u3bZZqmy3vxkSNHlJeX5/Z+WNL3YgBA+UEoBQDwmPHjx2v16tV69NFH9e9//9vtF8zc3FytWbNGt99+u7O2a9cu/fDDDy5Hdfzf//2fKlasqOuuu07S2V+YfH19XX4JSklJKfLT96SzwUirVq2ct03T1F133aWvvvpKXbt2ddZjYmJclpPkdkRLr169NG3aNIWFhRV5JNO5qlSp4rbNkJCQIkOpb775RgsWLNAnn3xS7JE0vXr10urVq1WnTh1VqlTpT/dflLCwMJeeoqKi1KJFC/3nP//RX//6V2d9/fr1Onz4sPMUPrvdrmXLlqlOnTrOkPFC+3n88cc1ePBgdenSRQ0aNHALhSpUqKBOnTpp586datq0abHhRGG1a9d2e6zPPWon32uvvaYDBw64nV5UUtdee63zExTbtWundevWacmSJW6hVLNmzZy/mN90003617/+pW+++eaC9pkvMDBQN9xwg1auXKmXX37Zedqlw+HQkiVLFBMTo/r16zuX//jjj2WaZrEBXWH+/v5uj+G5p+N169ZN3t7eSkhI0D333POn27TZbG7bLC4EtNvtevzxx3XPPfeoS5cuxW4zLy9PDz30kJo0aaIZM2bI29u7yNMGz5X/nnFuwPL2228XufyqVaskSe3bt//TbZ/PrbfeqpkzZ2rJkiUaNWqUs/6vf/1LmZmZbqewleR9MN+KFSu0YcMG7dix46J6PFf+Rez37NlTbAh/66236p///KdWrVqlu+66y1nPPxLz3LlK+l4MACg/CKUAAB7Ttm1bzZs3T0OHDlXLli31t7/9TY0bN1Zubq527typ+fPnq0mTJi6hVHR0tHr37q1JkyYpKipKS5YsUVxcnGbMmKEKFSpIOhuErFy5UkOHDtW9996r/fv3a+rUqYqKiiryU9QOHDigr7/+2vnX+enTp8vPz08NGzYs9UwjR47Uv/71L918880aNWqUmjZtKofDoaSkJH3++ed68skndcMNN1zQ4zV//nzdfvvtRX4ce74pU6YoLi5O7dq10/Dhw9WgQQNlZWVp3759Wr16td56660/PSrt6NGjzusxpaamas6cOTIMw+30rvDwcN1yyy169tlnnZ++99///tflSJoL7eehhx5SzZo1Va9evWL7fO2113TTTTepffv2+tvf/qZatWrp5MmT2rt3rz755BPndXouxFtvvaWXXnqpyFPgSmLnzp1KSUlRTk6Odu7cqbi4OHXs2NFtub179yo1NVXZ2dnavHmzfv75Zz3++OMX3He+6dOnq0uXLurUqZOeeuop+fr6au7cufr555/1wQcfyDAMpaena968eZo2bZrzcSwLtWrV0pQpUzRhwgT99ttv6t69uypVqqTDhw/rm2++UWBgoCZPnnxB2/7qq6/k7++vTz755LzLTZo0Sbt379bOnTtLderlNddcozp16mjcuHEyTVOVK1fWJ598ori4OJflkpOT9cYbb2jmzJl68MEHS3RE2Pl06dJF3bp109ixY5WRkaEbb7zR+el7LVq0cLumWkneB/O99dZbGjZsWIlOzyyNkJAQbd68WTk5OapRo0aRy/Tr109vvvmm+vfvr3379unaa6/Vl19+qWnTpqlnz57q3Lmzy/Jl+V4MALgyEEoBADzq0UcfVevWrTVr1izNmDFDKSkp8vHxUf369fXggw+6/YLevHlzDRw4UBMnTtSvv/6q6Ohovfrqqy5HFwwcOFBHjhzRW2+9pYULF6p27doaN26cDhw4UOQvwwsWLNCCBQtkGIYqV66sZs2a6T//+U+RF1D+M4GBgdqyZYtefPFFzZ8/X4mJiQoICFCNGjXUuXNn59EzF8LHx+dPT+uKiorSd999p6lTp+qll17SgQMHVLFiRcXGxjrDgT+zevVq50ewh4aGqmHDhlq+fLlbmNa7d281btxYzzzzjJKSklSnTh0tXbrU5dpNF9qPv7+/2y+s52rUqJG+//57TZ06Vc8884yOHDmi0NBQ1atXTz179vzTOc/nmmuuKfXFzQu7++67JZ39nkVGRurhhx8u8tpHbdu2lXT2yJxq1app5MiRLtfUuVAdOnTQhg0bNHHiRA0YMEAOh0PNmjXTxx9/rF69ekk6e7TN/Pnz9de//lUTJ050u+7PxRg/frwaNWqk1157TR988IGys7MVGRmp66+/XkOGDLng7drtdj3zzDPnfW1++eWXevHFFzV37tzzhppF8fHx0SeffKIRI0bosccek7e3tzp37qx169a5BC8bN27UypUrNXHixGJPMywNwzC0atUqTZo0SYsWLdILL7yg8PBwPfLII5o2bZrbkVsleR/MFxYWViYXNy/KuUdlncvf319ffPGFJkyYoJdeeklHjx5VtWrV9NRTTzlPES6sLN+LAQBXBsMsy497AQDgEqpVq5aaNGmiTz/91NOtXPUMw9CwYcP0xhtveLoV4KrC+yAAoDwp+kIKAAAAAAAAwCVEKAUAAAAAAADLcfoeAAAAAAAALMeRUgAAAAAAALAcoRQAAAAAAAAs5+3pBqzmcDh06NAhVaxYsUw/+hgAAAAAAKC8Mk1TJ0+eVHR0tGy2sjnG6aoLpQ4dOqTq1at7ug0AAAAAAIArzv79+xUTE1Mm27rqQqmKFStKOvsgBgcHe7gbAAAAAACAy19GRoaqV6/uzFXKwlUXSuWfshccHEwoBQAAAAAAUApleSkkLnQOAAAAAAAAyxFKAQAAAAAAwHKEUgAAAAAAALDcVXdNKQAAAAAAcHWx2+3Kzc31dBuXNR8fH3l5eVm6T0IpAAAAAABQLpmmqZSUFJ04ccLTrVwRQkNDFRkZWaYXMz8fQikAAAAAAFAu5QdSVatWVYUKFSwLW640pmnq9OnTOnLkiCQpKirKkv0SSgEAAAAAgHLHbrc7A6mwsDBPt3PZCwgIkCQdOXJEVatWteRUPi50DgAAAAAAyp38a0hVqFDBw51cOfIfK6uuv0UoBQAAAAAAyi1O2Ss5qx8rQikAAAAAAABYjlAKAAAAAAAAluNC5wAAAAAA4KpxPGGqpfurVOdZS/d3JeFIKQAAAAAAgMvIgAEDZBiG8yssLEzdu3fXjz/+6Fym8P35XzfddJPz/rffflvNmjVTYGCgQkND1aJFC82YMcMT4xSLUAoAAAAAAOAy0717dyUnJys5OVnr16+Xt7e3evXq5bLMokWLnMskJyfr448/liQtWLBAo0eP1vDhw/XDDz9o69atevrpp3Xq1ClPjFIsTt8DAAAAAAC4zPj5+SkyMlKSFBkZqbFjx+rmm2/W0aNHVaVKFUlSaGioc5nCPvnkE/Xp00eDBg1y1ho3bmxN46XAkVIAAAAAAACXsVOnTmnp0qWqW7euwsLC/nT5yMhIff311/r9998t6O7CEUoBAAAAAABcZj799FMFBQUpKChIFStW1Mcff6xly5bJZiuIch544AHnMkFBQVq1apUkaeLEiQoNDVWtWrXUoEEDDRgwQP/85z/lcDg8NE3RCKUAAAAAAAAuM506dVJ8fLzi4+O1fft2de3aVT169HA5+mnWrFnOZeLj49WlSxdJUlRUlL766iv99NNPGj58uHJzc9W/f3917979sgqmuKYUAADA1arzUk93UPbWPeTpDgAAKBOBgYGqW7eu83bLli0VEhKid955R88//7yks6fpFV7mXE2aNFGTJk00bNgwffnll2rfvr02bdqkTp06XfL+S4IjpQAAAAAAAC5zhmHIZrPpzJkzF7R+o0aNJEmZmZll2dZF4UgpAAAAAACAy0x2drZSUlIkScePH9cbb7yhU6dO6fbbb//Tdf/2t78pOjpat9xyi2JiYpScnKznn39eVapUUdu2bS916yVGKAUAAAAAAK4aleo86+kWSmTNmjWKioqSJFWsWFHXXHONli9fro4dO/7pup07d9bChQs1b948paWlKTw8XG3bttX69etL9Ol9ViGUAgAAAAAAuIwsXrxYixcvPu8ypmkWe98999yje+65p4y7KntcUwoAAAAAAACWI5QCAAAAAACA5QilAAAAAAAAYDlCKQAAAAAAAFiOUAoAAAAAAACWI5QCAAAAAACA5QilAAAAAAAAYDlCKQAAAAAAAFiOUAoAAAAAAACW8/bkzjdv3qyXXnpJO3bsUHJysj766CPdeeed511n06ZNGj16tHbt2qXo6Gg9/fTTGjJkiDUNAwAAAACAK9qM/91u6f7G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Zoy++OILffTRR/r888+1ceNG7dixo0x6nTRpkt544w1t27ZN+/fvV58+fTR79mz93//9nz777DPFxcXp9ddfL5N9AVbJycnR1KlT9cMPP2jVqlVKTEzUgAED3JZ7+umnNX36dO3Zs0dNmzbV6NGjtXXrVn388ceKi4vTli1b9P3337usM3DgQG3dulUffvihfvzxR913333q3r27fv31V4umA8reM888o0WLFmnevHnatWuXRo0apYcfflibNm1yLnMh/1784x//kLe3t7Zv3645c+Zo1qxZevfddyVJK1euVExMjKZMmaLk5GQlJycrMDBQ999/vxYtWuSynUWLFunee+9VxYoVL/2DAVyAf/zjHwoMDNT27ds1c+ZMTZkyRXFxcTJNU3feeaeOHTumTZs2KS4uTgkJCerbt2+Jtrt27Vo9/PDDGj58uHbv3q23335bixcv1gsvvCBJmjBhgmrVqqXBgwdLkt566y1t3rxZ77//vmw299jhm2++kSStW7dOycnJWrlyZRk9ArjimMAVZseOHaYkc9++fW739e/f36xZs6Zpt9udtQYNGpjt27d33s7LyzMDAwPNDz74oNh9zJw502zZsqXz9sSJE81mzZq57OeOO+64uEGAS6xDhw7mTTfd5Lyd/9x/5JFHnLXk5GRTkvnVV1+Zzz77rNm1a1eXbezfv9+UZP7yyy/myZMnTV9fX/PDDz903p+WlmYGBASYI0aMcNZq1qxpzpo1yzRN00xMTDQlmTt37nTef/z4cVOS+cUXX5imaZpffPGFKclct26dc5np06ebksyEhARn7bHHHjO7det2MQ8JYIkOHTq4vCYK++abb0xJ5smTJ03TLHj+r1q1yrlMRkaG6ePjYy5fvtxZO3HihFmhQgXndvfu3WsahmEePHjQZfu33nqrOX78+LIdCLDIqVOnTH9/f3Pbtm0u9UGDBpkPPPDABf970aFDB7Nhw4amw+Fw1saOHWs2bNjQebvwv135tm/fbnp5eTlfZ0ePHjV9fHzMjRs3lsm8QFk792c/0zTN66+/3hw7dqz5+eefm15eXmZSUpLzvl27dpmSzG+++eZPt92+fXtz2rRpLrX333/fjIqKct5OSEgwK1asaI4dO9asUKGCuWTJEpflJZkfffSRaZpF/4yIqxMXLMAVp1mzZrr11lt17bXXqlu3buratavuvfdeVapUSZLUuHFjlzQ+IiJCTZo0cd728vJSWFiYy+kTK1as0OzZs7V3716dOnVKeXl5Cg4Otm4o4BJp2rSp8//zn/vXXnutsxYRESFJOnLkiHbs2KEvvvhCQUFBbttJSEjQmTNnlJOTo7Zt2zrrlStXVoMGDcq814iICOfptIVr+X9VA64UO3fu1KRJkxQfH69jx445T2FISkpSo0aNnMu1atXK+f+//fabcnNz1bp1a2ctJCTE5bX2/fffyzRN1a9f32V/2dnZCgsLu1TjAJfU7t27lZWVpS5durjUc3Jy1KJFC+ftC/n3ok2bNjIMw3m7bdu2euWVV2S32+Xl5VVkP61bt1bjxo313nvvady4cXr//fdVo0YN3XzzzRc1J3ApFX59SFJUVJSOHDmiPXv2qHr16qpevbrzvkaNGik0NFR79uzR9ddff97t7tixQ99++63zyChJstvtysrK0unTp52vw5dfflmPPfaY+vbtq4ceeqhsh0O5RCiFK46Xl5fi4uK0bds2ff7553r99dc1YcIEbd++XZLk4+PjsrxhGEXW8n8x+Prrr3X//fdr8uTJ6tatm0JCQvThhx8Wea0c4ErzZ6+H/B/QHQ6HHA6Hbr/9ds2YMcNtO1FRURd0SlB+QGz+cXqtpGKv13ZuX+d73QJXgszMTHXt2lVdu3bVkiVLVKVKFSUlJalbt27KyclxWTYwMND5//mvl8K/QBeuS2dfs15eXtqxY4fbL9RFBcvAlSD/Pf6zzz5TtWrVXO7z8/NTQkKCJGv/vRg8eLDeeOMNjRs3TosWLdLAgQPdXpvA5aS414NpmkU+d4urn8vhcGjy5Mm6++673e7z9/d3/v/mzZvl5eWlffv2KS8vjw/uwJ/imlK4IhmGoRtvvFGTJ0/Wzp075evrq48++uiCtrV161bVrFlTEyZMUKtWrVSvXj39/vvvZdwxcPm77rrrtGvXLtWqVUt169Z1+QoMDFTdunXl4+Ojr7/+2rnO8ePH9b///a/YbeZ/El9ycrKzxkf/4mrx3//+V6mpqXrxxRfVvn17XXPNNS5H6RanTp068vHxcTnSIyMjwyUYbtGihex2u44cOeL2euXTjXClatSokfz8/JSUlOT2vC58dMeFKPxvV/7tevXqOUNdX19f2e12t/UefvhhJSUlac6cOdq1a5f69+9/UX0AntKoUSMlJSW5XFd39+7dSk9PV8OGDf90/euuu06//PKL22uzbt26zj9CLlu2TCtXrtTGjRu1f/9+TZ06tdjt+fr6SlKRrztcXYgtccXZvn271q9fr65du6pq1aravn27jh49qoYNG+rHH38s9fbq1q2rpKQkffjhh7r++uv12WefXXDABVzJhg0bpnfeeUcPPPCAxowZo/DwcO3du1cffvih3nnnHQUFBWnQoEEaM2aMwsLCFBERoQkTJhR58cp8AQEBatOmjV588UXVqlVLqampeuaZZyycCvCcGjVqyNfXV6+//rqGDBmin3/++bw/oOerWLGi+vfv7/zU2KpVq2rixImy2WzOv2bXr19fDz30kPr166dXXnlFLVq0UGpqqjZs2KBrr71WPXv2vNTjAWWuYsWKeuqppzRq1Cg5HA7ddNNNysjI0LZt2xQUFKSaNWte8Lb379+v0aNH67HHHtP333+v119/3eWo+Fq1amnz5s26//775efnp/DwcElSpUqVdPfdd2vMmDHq2rWrYmJiLnpOwBM6d+6spk2b6qGHHtLs2bOVl5enoUOHqkOHDi6nkBfnueeeU69evVS9enXdd999stls+vHHH/XTTz/p+eef14EDB/S3v/1NM2bM0E033aTFixfrtttuU48ePdSmTRu37VWtWlUBAQFas2aNYmJi5O/vr5CQkEsxOi5zHCmFK05wcLA2b96snj17qn79+nrmmWf0yiuvqEePHhe0vTvuuEOjRo3S448/rubNm2vbtm169tlny7hr4PIXHR2trVu3ym63q1u3bmrSpIlGjBihkJAQZ/D00ksv6eabb1bv3r3VuXNn3XTTTWrZsuV5t7tw4ULl5uaqVatWGjFihJ5//nkrxgE8rkqVKlq8eLGWL1+uRo0a6cUXX9TLL79conVfffVVtW3bVr169VLnzp114403qmHDhi6nSCxatEj9+vXTk08+qQYNGqh3797avn37RR9RAnjS1KlT9dxzz2n69Olq2LChunXrpk8++cT58fEXql+/fjpz5oxat26tYcOG6YknntBf//pX5/1TpkzRvn37VKdOHedRvvkGDRqknJwc/eUvf7moHgBPMgxDq1atUqVKlXTzzTerc+fOql27tpYtW1ai9bt166ZPP/1UcXFxuv7669WmTRu9+uqrqlmzpkzT1IABA9S6dWs9/vjjkqQuXbro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3Jx4chia+nrmTmpvb48lS5bEtddem2hSGD76c+4WLlwY//znP2Pt2rXxn//8JzZs2BA///nPE04NQ1dfz9z27dtjyZIlcfvtt8d7770XL774Yvz73/+OO+64I/HkMDR99dVXcfnll8ff/va309o/UC0lL8uyrD8D/1jNmDEjpk+fHvX19V1rU6dOjQULFkRtbW2P/ffff39s3Lgx9uzZ07VWXV0d77zzTuzcuTPJzDDU9fXc9eayyy6LRYsWxYMPPjhYY8Kw0d8zt3jx4pg8eXLk5+fHa6+9Frt27UowLQwPfT13r7/+eixevDj27dsXo0ePTjkqDAt9PXN/+tOfor6+Pvbu3du19vjjj8eaNWti//79SWaG4SIvLy9effXVWLBgwSn3DFRLGVZ3Sh09ejSampqiqqqq23pVVVXs2LGj12t27tzZY//1118fb7/9dnz77beDNisMF/05d9934sSJOHLkiH9ph9PQ3zP37LPPxt69e2PVqlWDPSIMO/05dxs3bozKyspYs2ZNjB8/PqZMmRL33ntvfPPNNylGhiGtP2du1qxZceDAgdi0aVNkWRafffZZvPTSS3HDDTekGBnOOgPVUgoGerBcamtri+PHj0dZWVm39bKysjh48GCv1xw8eLDX/ceOHYu2trYYN27coM0Lw0F/zt33Pfroo/HVV1/FwoULB2NEGFb6c+Y++OCDWL58eWzbti0KCobVr35Ioj/nbt++fbF9+/YoLi6OV199Ndra2uLOO++Mzz//3PdKwf/QnzM3a9asWL9+fSxatCj++9//xrFjx+K3v/1tPP744ylGhrPOQLWUYXWn1El5eXndnmdZ1mPtf+3vbR04tb6eu5M2bNgQDz30UDQ0NMT5558/WOPBsHO6Z+748eNx0003xerVq2PKlCmpxoNhqS+/606cOBF5eXmxfv36uPLKK2P+/Pnx2GOPxXPPPeduKThNfTlzu3fvjnvuuScefPDBaGpqitdffz0+/PDDqK6uTjEqnJUGoqUMq/9cOnbs2MjPz+9Rzw8dOtSj4J10wQUX9Lq/oKAgxowZM2izwnDRn3N3UkNDQ9x+++3x4osvxnXXXTeYY8Kw0dczd+TIkXj77bejubk57r777oj47g/LWZZFQUFBbN68Oa655poks8NQ1Z/fdePGjYvx48dHaWlp19rUqVMjy7I4cOBATJ48eVBnhqGsP2eutrY2Zs+eHffdd19ERPzyl7+Mc889N+bMmROPPPKIT8DAABuoljKs7pQqLCyMioqKaGxs7Lbe2NgYs2bN6vWamTNn9ti/efPmqKysjJEjRw7arDBc9OfcRXx3h9Stt94aL7zwgs/6Qx/09cyVlJTEu+++G7t27ep6VFdXx6WXXhq7du2KGTNmpBodhqz+/K6bPXt2fPrpp/Hll192rb3//vsxYsSImDBhwqDOC0Ndf87c119/HSNGdP/jbX5+fkT8v7s3gIEzYC0lG2b+/ve/ZyNHjszWrl2b7d69O1u6dGl27rnnZh999FGWZVm2fPny7Oabb+7av2/fvuycc87Jli1blu3evTtbu3ZtNnLkyOyll17K1VuAIaev5+6FF17ICgoKsieeeCJrbW3tenzxxRe5egswpPT1zH3fqlWrsssvvzzRtDA89PXcHTlyJJswYUL2u9/9LnvvvfeyLVu2ZJMnT87uuOOOXL0FGFL6euaeffbZrKCgIKurq8v27t2bbd++PausrMyuvPLKXL0FGFKOHDmSNTc3Z83NzVlEZI899ljW3Nycffzxx1mWDV5LGXZRKsuy7IknnsjKy8uzwsLCbPr06dmWLVu6/tott9ySXXXVVd32v/nmm9mvfvWrrLCwMPvpT3+a1dfXJ54Yhr6+nLurrroqi4gej1tuuSX94DBE9fV33f9PlIL+6eu527NnT3bddddlo0aNyiZMmJDV1NRkX3/9deKpYejq65n761//mv3iF7/IRo0alY0bNy77/e9/nx04cCDx1DA0/etf//rBP6MNVkvJyzL3MgIAAACQ1rD6TikAAAAAhgZRCgAAAIDkRCkAAAAAkhOlAAAAAEhOlAIAAAAgOVEKAAAAgOREKQAAAACSE6UAAAAASE6UAgAAACA5UQoAAACA5EQpAAAAAJL7P8cE6SApUT+RAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Список лабиринтов в том же порядке, что и в results (уникальные)\n", + "maze_names = [\"small\", \"medium\", \"large\", \"empty\", \"no_exit\"]\n", + "strategies = [\"BFS\", \"DFS\", \"A*\"]\n", + "\n", + "# Цвета для стратегий (можно взять из вашего примера или задать свои)\n", + "colors = {\"BFS\": \"#EEDC82\", \"DFS\": \"#88D94C\", \"A*\": \"#FF43A4\"}\n", + "\n", + "# Подготовим данные для графиков\n", + "time_data = {maze: {s: None for s in strategies} for maze in maze_names}\n", + "visited_data = {maze: {s: None for s in strategies} for maze in maze_names}\n", + "\n", + "for row in results:\n", + " maze = row[\"maze\"]\n", + " strat = row[\"strategy\"]\n", + " time_data[maze][strat] = row[\"time_ms\"]\n", + " visited_data[maze][strat] = row[\"visited_cells\"]\n", + "\n", + "fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 10))\n", + "\n", + "x = np.arange(len(maze_names))\n", + "width = 0.25 \n", + "multiplier = 0\n", + "\n", + "for strategy in strategies:\n", + " values = [time_data[maze][strategy] for maze in maze_names]\n", + " offset = width * multiplier\n", + " bars = ax1.bar(x + offset, values, width, label=strategy, color=colors[strategy])\n", + " multiplier += 1\n", + "\n", + "ax1.set_xticks(x + width, maze_names)\n", + "ax1.set_ylabel(\"Время (мс)\")\n", + "ax1.set_title(\"Сравнение времени выполнения алгоритмов\")\n", + "ax1.legend()\n", + "ax1.grid(axis='y', alpha=0.5, linestyle='--')\n", + "\n", + "\n", + "multiplier = 0\n", + "for strategy in strategies:\n", + " values = [visited_data[maze][strategy] for maze in maze_names]\n", + " offset = width * multiplier\n", + " ax2.bar(x + offset, values, width, label=strategy, color=colors[strategy])\n", + " multiplier += 1\n", + "\n", + "ax2.set_xticks(x + width, maze_names)\n", + "ax2.set_ylabel(\"Количество посещённых клеток\")\n", + "ax2.set_title(\"Сравнение количества посещённых клеток\")\n", + "ax2.legend()\n", + "ax2.grid(axis='y', alpha=0.5, linestyle='--')\n", + "\n", + "plt.tight_layout()\n", + "plt.show()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f71359e0", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [] }, { "cell_type": "code", "execution_count": null, - "id": "083b0af8", + "id": "671b32d2", "metadata": {}, "outputs": [], "source": [] diff --git a/pomelovsd/ExitMaze/results.csv b/pomelovsd/ExitMaze/results.csv new file mode 100644 index 0000000..55e8ac7 --- /dev/null +++ b/pomelovsd/ExitMaze/results.csv @@ -0,0 +1,16 @@ +maze,strategy,time_ms,visited_cells +small,BFS,0.051,8 +small,DFS,0.027,8 +small,A*,0.049,8 +medium,BFS,0.039,10 +medium,DFS,0.031,10 +medium,A*,0.042,10 +large,BFS,0.962,197 +large,DFS,0.84,197 +large,A*,1.042,197 +empty,BFS,0.01,2 +empty,DFS,0.008,2 +empty,A*,0.01,2 +no_exit,BFS,0.007,1 +no_exit,DFS,0.005,1 +no_exit,A*,0.006,1