diff --git a/ProninVV/task-2-oop/AStarStrategy.py b/ProninVV/task-2-oop/AStarStrategy.py new file mode 100644 index 0000000..f3bcd8d --- /dev/null +++ b/ProninVV/task-2-oop/AStarStrategy.py @@ -0,0 +1,41 @@ +from Maze import Cell, Maze +from strategy import PathFindingStrategy + + +class AStarStrategy(PathFindingStrategy): + def findPath(self, maze, start, exit): + + def heuristik(cell): + return abs(cell.x - exit.x) + abs(cell.y - exit.y) + + parents = {start: None} + + queue = [start] + + if not start or not exit: + return [], 0 + + while len(queue) != 0: + best_cell = queue[0] + for cell in queue: + if heuristik(cell) < heuristik(best_cell): + best_cell = cell + + u = best_cell + queue.remove(u) + + if u == exit: + path = [] + current = exit + while current is not None: + path.append(current) + current = parents[current] + path.reverse() + return path, len(parents) + + childs = maze.getNeighbors(u) + for child in childs: + if child not in parents: + parents[child] = u + queue.append(child) + return [], len(parents) diff --git a/ProninVV/task-2-oop/BreadthFirstSearch.py b/ProninVV/task-2-oop/BreadthFirstSearch.py new file mode 100644 index 0000000..b2b0515 --- /dev/null +++ b/ProninVV/task-2-oop/BreadthFirstSearch.py @@ -0,0 +1,32 @@ +from strategy import PathFindingStrategy +from Maze import Maze, Cell + + +class BFSStrategy(PathFindingStrategy): + def findPath(self, maze: Maze, start: Cell, exit: Cell): + + # очерель: перывй вошел - первый вышел + queue = [start] + # будем хранить откуда в какую клетку пришли + parents = {start: None} + + if not start or not exit: + return [], 0 + + while (len(queue) != 0): + u = queue.pop(0) + if u == exit: + path = [] + current = exit + while current is not None: + path.append(current) + current = parents[current] + path.reverse() + return path, len(parents) + + childs = maze.getNeighbors(u) + for child in childs: + if child not in parents: + parents[child] = u + queue.append(child) + return [], len(parents) diff --git a/ProninVV/task-2-oop/Command.py b/ProninVV/task-2-oop/Command.py new file mode 100644 index 0000000..c9e391d --- /dev/null +++ b/ProninVV/task-2-oop/Command.py @@ -0,0 +1,45 @@ +from abc import ABC, abstractmethod + + +class Player: + def __init__(self, start_cell): + self.current_cell = start_cell + + +class Command(ABC): + @abstractmethod + def execute(self) -> bool: + """Выполняет действие. Возвращает True, если ход успешен.""" + pass + + @abstractmethod + def undo(self) -> None: + """Откатывает действие назад.""" + pass + + +class MoveCommand(Command): + def __init__(self, player: Player, maze, dx: int, dy: int): + self.player = player + self.maze = maze + self.dx = dx + self.dy = dy + self.previous_cell = None + + def execute(self) -> bool: + new_x = self.player.current_cell.x + self.dx + new_y = self.player.current_cell.y + self.dy + + next_cell = self.maze.getCell(new_x, new_y) + + if next_cell and next_cell.isPassable(): + self.previous_cell = self.player.current_cell + self.player.current_cell = next_cell + return True + + print("Ошибка: Там стена или край лабиринта!") + return False + + def undo(self) -> None: + if self.previous_cell: + self.player.current_cell = self.previous_cell diff --git a/ProninVV/task-2-oop/ConsoleView.py b/ProninVV/task-2-oop/ConsoleView.py new file mode 100644 index 0000000..c122c5e --- /dev/null +++ b/ProninVV/task-2-oop/ConsoleView.py @@ -0,0 +1,40 @@ +from Observer import Observer, Event + + +class ConsoleView(Observer): + def update(self, event: Event) -> None: + if event.type == "maze_loaded": + print("\n[Система] Лабиринт успешно загружен!") + self.render(event.data.get("maze")) + + elif event.type == "path_found": + print("\n[Система] Алгоритм нашёл решение!") + self.render(event.data.get("maze"), path=event.data.get("path")) + + elif event.type == "move": + print( + f"\n[Игрок] Переместился в точку: ({event.data.get('player_pos').x}, {event.data.get('player_pos').y})") + self.render(event.data.get("maze"), + player_position=event.data.get("player_pos")) + + def render(self, maze, player_position=None, path=None) -> None: + path_set = set(path) if path else set() + + for y in range(maze.height): + row_chars = [] + for x in range(maze.width): + cell = maze.getCell(x, y) + + if player_position and cell == player_position: + row_chars.append("P") + elif cell.isStart: + row_chars.append("S") + elif cell.isExit: + row_chars.append("E") + elif cell in path_set: + row_chars.append(".") + elif cell.isWall: + row_chars.append("#") + else: + row_chars.append(" ") + print("".join(row_chars)) diff --git a/ProninVV/task-2-oop/Deikstra.py b/ProninVV/task-2-oop/Deikstra.py new file mode 100644 index 0000000..d7547b2 --- /dev/null +++ b/ProninVV/task-2-oop/Deikstra.py @@ -0,0 +1,43 @@ +from strategy import PathFindingStrategy +from Maze import Maze, Cell + + +class DeikstraFind(PathFindingStrategy): + def findPath(self, maze, start, exit): + + if not start or not exit: + return [], len(parents) + + queue = [start] + + distances = {start: 0} + parents = {start: None} + + while len(queue) != 0: + best_cell = queue[0] + for cell in queue: + if distances[cell] < distances[best_cell]: + best_cell = cell + + u = best_cell + queue.remove(u) + + if u == exit: + path = [] + current = exit + while current is not None: + path.append(current) + current = parents[current] + path.reverse() + return path, len(parents) + + for child in maze.getNeighbors(u): + distance_through_u = distances[u] + 1 + + if distance_through_u < distances.get(child, float('inf')): + distances[child] = distance_through_u + parents[child] = u + if child not in queue: + queue.append(child) + + return [], len(parents) diff --git a/ProninVV/task-2-oop/DepthFirstSearch.py b/ProninVV/task-2-oop/DepthFirstSearch.py new file mode 100644 index 0000000..0f353ef --- /dev/null +++ b/ProninVV/task-2-oop/DepthFirstSearch.py @@ -0,0 +1,40 @@ +import sys + +from strategy import PathFindingStrategy +from Maze import Maze, Cell + +sys.setrecursionlimit(15000) + + +class DFSStrategy(PathFindingStrategy): + def findPath(self, maze: Maze, start, exit): + + if not start or not exit: + return [], 0 + + visited = set() + path = [] + + count_cell = 0 + + def dfs(root: Cell) -> bool: + visited.add(root) + path.append(root) + # count_cell += 1 + + if root == exit: + return True + + neighbors = maze.getNeighbors(root) + for neighbor in neighbors: + if neighbor not in visited: + if dfs(neighbor): + return True + + path.pop() + return False + + if dfs(start): + return path, len(visited) + + return [], len(visited) diff --git a/ProninVV/task-2-oop/Maze.py b/ProninVV/task-2-oop/Maze.py new file mode 100644 index 0000000..6140d80 --- /dev/null +++ b/ProninVV/task-2-oop/Maze.py @@ -0,0 +1,49 @@ +# модель клетки лабиринта + +class Cell: + def __init__(self, x, y, isWall=False, isStart=False, isExit=False): + self.x = x + self.y = y + self.isWall = isWall + self.isStart = isStart + self.isExit = isExit + + def isPassable(self): + return not self.isWall + + +# модель лабиринта + +class Maze: + + def __init__(self, height, width, start=None, exit=None): + self.height = height # строки + self.width = width # столбцы + self.__grid = [[Cell(x, y) for x in range(width)] + for y in range(height)] + self.start = start + self.exit = exit + + def getCell(self, x, y) -> Cell: + if (0 <= x < self.width) and (0 <= y < self.height): + return self.__grid[y][x] + return None + + def getNeighbors(self, cell): + dirs = {'left': (-1, 0), 'right': (1, 0), + 'up': (0, 1), 'down': (0, -1)} + neighbors = [] + for _, val in dirs.items(): + dx, dy = val + nx, ny = cell.x + dx, cell.y + dy + neighbor = self.getCell(nx, ny) + + if neighbor and isinstance(neighbor, Cell) and neighbor.isPassable(): + neighbors.append(neighbor) + return neighbors + + +if __name__ == "__main__": + maze1 = Maze(height=5, width=5, start=0, exit=4) + cell1 = maze1.getCell(2, 2) + print(maze1.getNeighbors(cell1)) diff --git a/ProninVV/task-2-oop/MazeBuilder.py b/ProninVV/task-2-oop/MazeBuilder.py new file mode 100644 index 0000000..c43a4b4 --- /dev/null +++ b/ProninVV/task-2-oop/MazeBuilder.py @@ -0,0 +1,47 @@ +from abc import ABC, abstractmethod +from Maze import Maze, Cell + + +class MazeBuilder(ABC): + @abstractmethod + def buildFromFile(self, filename): + pass + + +class TextFileMazeBuilder(MazeBuilder): + def __init__(self): + self._maze = None + + @property + def maze(self): + return self._maze + + def buildFromFile(self, filename: str): + + with open(filename, mode='r', encoding='utf-8') as file: + lines = file.read().splitlines() + + height = len(lines) + width = len(lines[0]) + self._maze = Maze(height, width) + + for y, line in enumerate(lines): + for x, char in enumerate(line): + cell = self._maze.getCell(x, y) + + if char == '#': + cell.isWall = True + elif char == 'S': + cell.isStart = True + self._maze.start = cell + elif char == 'E': + cell.isExit = True + self._maze.exit = cell + self._validate() + return self._maze + + def _validate(self): + if self._maze.start is None: + raise "в лабиринте нет старта" + if self._maze.exit is None: + raise "в лабиринте нет начала" diff --git a/ProninVV/task-2-oop/MazeSolver.py b/ProninVV/task-2-oop/MazeSolver.py new file mode 100644 index 0000000..b90ad4c --- /dev/null +++ b/ProninVV/task-2-oop/MazeSolver.py @@ -0,0 +1,57 @@ +import time +from Maze import Maze +from strategy import PathFindingStrategy + + +class SearchStats: + def __init__(self, execution_time, visited_count, path_length, path): + self.execution_time = execution_time + self.visited_count = visited_count + self.path_length = path_length + self.path = path + + def __str__(self): + return ("f == Статистика поиска == =\n" + f"Время выполнения: {self.execution_time_ms:.4f} мс\n" + f"Посещено клеток: {self.visited_count}\n" + f"Длина пути: {self.path_length} клеток\n") + + +class MazeSolver: + def __init__(self, maze: Maze, strategy: PathFindingStrategy): + self._maze = maze + self._strategy = strategy + self._observers = [] + + def addObserver(self, observer): + """Регистрация нового наблюдателя (например, ConsoleView)""" + self._observers.append(observer) + + def notify(self, event): + """Уведомление всех подписчиков о событии""" + for observer in self._observers: + observer.update(event) + + def setStrategy(self, strategy): + self._strategy = strategy + + def solve(self): + + if not self._maze or not self._strategy: + raise ValueError("Не задан лабиринт или стратегия поиска!") + + start_time = time.perf_counter() + + path, visited_count = self._strategy.findPath( + self._maze, self._maze.start, self._maze.exit) + + end_time = time.perf_counter() + + execution_time_ms = (end_time - start_time) * 1000 + + path_length = len(path) + + from ConsoleView import Event + self.notify(Event("path_found", {"maze": self._maze, "path": path})) + + return SearchStats(execution_time_ms, visited_count, path_length, path) diff --git a/ProninVV/task-2-oop/Observer.py b/ProninVV/task-2-oop/Observer.py new file mode 100644 index 0000000..ea1a1dd --- /dev/null +++ b/ProninVV/task-2-oop/Observer.py @@ -0,0 +1,13 @@ +from abc import ABC, abstractmethod + + +class Event: + def __init__(self, type: str, data: dict = None): + self.type = type # "maze_loaded", "move", "path_found" + self.data = data if data else {} + + +class Observer(ABC): + @abstractmethod + def update(self, event: Event) -> None: + pass diff --git a/ProninVV/task-2-oop/main.py b/ProninVV/task-2-oop/main.py new file mode 100644 index 0000000..bee4738 --- /dev/null +++ b/ProninVV/task-2-oop/main.py @@ -0,0 +1,8 @@ +from MazeBuilder import TextFileMazeBuilder +from BreadthFirstSearch import BFSStrategy +from Maze import Maze + + +maze1 = TextFileMazeBuilder().buildFromFile("text.txt") +pathh = BFSStrategy.findPath(maze1, maze1.start, maze1.exit) +print(pathh) diff --git a/ProninVV/task-2-oop/report/cells.eps b/ProninVV/task-2-oop/report/cells.eps new file mode 100644 index 0000000..c4c949d --- /dev/null +++ b/ProninVV/task-2-oop/report/cells.eps @@ -0,0 +1,2264 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%LanguageLevel: 3 +%%Title: benchmark_visited_cells.eps +%%Creator: Matplotlib v3.10.0, https://matplotlib.org/ +%%CreationDate: Wed May 20 20:35:42 2026 +%%Orientation: portrait +%%BoundingBox: 0 0 720 432 +%%HiResBoundingBox: 0.000000 0.000000 720.000000 432.000000 +%%EndComments +%%BeginProlog +/mpldict 9 dict def +mpldict begin +/_d { bind def } bind def +/m { moveto } _d +/l { lineto } _d +/r { rlineto } _d +/c { curveto } _d +/cl { closepath } _d +/ce { closepath eofill } _d +/sc { setcachedevice } _d +%!PS-Adobe-3.0 Resource-Font +%%Creator: Converted from TrueType to Type 3 by Matplotlib. +10 dict begin +/FontName /DejaVuSans def +/PaintType 0 def +/FontMatrix [0.00048828125 0 0 0.00048828125 0 0] def +/FontBBox [-2090 -948 3673 2524] def +/FontType 3 def +/Encoding [/uni0430 /uni0431 /uni041A /space /uni0421 /uni0434 /parenleft /parenright /asterisk /period /slash /zero /one /two /three /four /five /six /seven /uni0438 /uni0435 /uni0432 /uni043B /uni043A /uni043D /uni043E /uni043F /uni0440 /uni0441 /uni0442 /uni043C /uni0444 /uni0445 /equal /uni0447 /uni0448 /uni0449 /uni0443 /uni044B /uni044C /uni044D /B /F /A /S /D /underscore /a /d /e /g /i /l /m /n /o /p /r /s /t /u /x /y /z] def +/CharStrings 65 dict dup begin +/.notdef 0 def +/uni0430{1255 0 123 -29 1069 1147 sc +702 563 m +553 563 450 546 393 512 c +336 478 307 420 307 338 c +307 273 328 221 371 182 c +414 144 473 125 547 125 c +649 125 731 161 792 233 c +854 306 885 402 885 522 c +885 563 l +702 563 l + +1069 639 m +1069 0 l +885 0 l +885 170 l +843 102 791 52 728 19 c +665 -13 589 -29 498 -29 c +383 -29 292 3 224 67 c +157 132 123 218 123 326 c +123 452 165 547 249 611 c +334 675 460 707 627 707 c +885 707 l +885 725 l +885 810 857 875 801 921 c +746 968 668 991 567 991 c +503 991 441 983 380 968 c +319 953 261 930 205 899 c +205 1069 l +272 1095 338 1114 401 1127 c +464 1140 526 1147 586 1147 c +748 1147 869 1105 949 1021 c +1029 937 1069 810 1069 639 c + +ce} _d +/uni0431{1263 0 112 -29 1151 1591 sc +637 1147 m +797 1147 923 1095 1014 991 c +1105 887 1151 743 1151 559 c +1151 376 1105 232 1014 127 c +923 23 797 -29 637 -29 c +476 -29 352 22 263 123 c +174 224 128 370 123 559 c +117 788 l +114 867 112 921 112 948 c +112 1055 131 1147 170 1226 c +231 1349 313 1438 418 1491 c +523 1544 664 1572 840 1573 c +921 1574 980 1580 1016 1591 c +1067 1445 l +1034 1432 1003 1425 973 1424 c +723 1407 l +639 1401 572 1383 521 1354 c +388 1276 316 1186 303 1084 c +296 1028 l +383 1107 496 1147 637 1147 c + +637 991 m +538 991 460 952 403 875 c +346 798 317 693 317 559 c +317 425 345 319 402 242 c +459 165 538 127 637 127 c +735 127 813 166 870 243 c +927 320 956 426 956 559 c +956 692 927 797 870 874 c +813 952 735 991 637 991 c + +ce} _d +/uni041A{1454 0 201 0 1414 1493 sc +201 1493 m +403 1493 l +403 755 l +1125 1493 l +1384 1493 l +807 903 l +1414 0 l +1194 0 l +676 769 l +403 490 l +403 0 l +201 0 l +201 1493 l + +ce} _d +/space{651 0 0 0 0 0 sc +ce} _d +/uni0421{1430 0 115 -29 1319 1520 sc +1319 1378 m +1319 1165 l +1251 1228 1178 1276 1101 1307 c +1024 1338 943 1354 856 1354 c +685 1354 555 1302 464 1197 c +373 1093 328 942 328 745 c +328 548 373 398 464 293 c +555 189 685 137 856 137 c +943 137 1024 153 1101 184 c +1178 215 1251 263 1319 326 c +1319 115 l +1248 67 1173 31 1094 7 c +1015 -17 932 -29 844 -29 c +618 -29 440 40 310 178 c +180 317 115 506 115 745 c +115 985 180 1174 310 1312 c +440 1451 618 1520 844 1520 c +933 1520 1017 1508 1096 1484 c +1175 1461 1250 1425 1319 1378 c + +ce} _d +/uni0434{1416 0 107 -283 1309 1120 sc +443 147 m +977 147 l +977 973 l +590 973 l +590 833 l +590 558 551 348 472 201 c +443 147 l + +176 147 m +237 174 280 215 307 272 c +372 413 405 625 405 908 c +405 1120 l +1162 1120 l +1162 147 l +1309 147 l +1309 -283 l +1162 -283 l +1162 0 l +254 0 l +254 -283 l +107 -283 l +107 147 l +176 147 l + +ce} _d +/parenleft{799 0 176 -270 635 1554 sc +635 1554 m +546 1401 479 1249 436 1099 c +393 949 371 797 371 643 c +371 489 393 336 436 185 c +480 34 546 -117 635 -270 c +475 -270 l +375 -113 300 41 250 192 c +201 343 176 494 176 643 c +176 792 201 941 250 1092 c +299 1243 374 1397 475 1554 c +635 1554 l + +ce} _d +/parenright{799 0 164 -270 623 1554 sc +164 1554 m +324 1554 l +424 1397 499 1243 548 1092 c +598 941 623 792 623 643 c +623 494 598 343 548 192 c +499 41 424 -113 324 -270 c +164 -270 l +253 -117 319 34 362 185 c +406 336 428 489 428 643 c +428 797 406 949 362 1099 c +319 1249 253 1401 164 1554 c + +ce} _d +/asterisk{1024 0 61 586 963 1520 sc +963 1247 m +604 1053 l +963 858 l +905 760 l +569 963 l +569 586 l +455 586 l +455 963 l +119 760 l +61 858 l +420 1053 l +61 1247 l +119 1346 l +455 1143 l +455 1520 l +569 1520 l +569 1143 l +905 1346 l +963 1247 l + +ce} _d +/period{651 0 219 0 430 254 sc +219 254 m +430 254 l +430 0 l +219 0 l +219 254 l + +ce} _d +/slash{690 0 0 -190 690 1493 sc +520 1493 m +690 1493 l +170 -190 l +0 -190 l +520 1493 l + +ce} _d +/zero{1303 0 135 -29 1167 1520 sc +651 1360 m +547 1360 469 1309 416 1206 c +364 1104 338 950 338 745 c +338 540 364 387 416 284 c +469 182 547 131 651 131 c +756 131 834 182 886 284 c +939 387 965 540 965 745 c +965 950 939 1104 886 1206 c +834 1309 756 1360 651 1360 c + +651 1520 m +818 1520 946 1454 1034 1321 c +1123 1189 1167 997 1167 745 c +1167 494 1123 302 1034 169 c +946 37 818 -29 651 -29 c +484 -29 356 37 267 169 c +179 302 135 494 135 745 c +135 997 179 1189 267 1321 c +356 1454 484 1520 651 1520 c + +ce} _d +/one{1303 0 225 0 1114 1493 sc +254 170 m +584 170 l +584 1309 l +225 1237 l +225 1421 l +582 1493 l +784 1493 l +784 170 l +1114 170 l +1114 0 l +254 0 l +254 170 l + +ce} _d +/two{1303 0 150 0 1098 1520 sc +393 170 m +1098 170 l +1098 0 l +150 0 l +150 170 l +227 249 331 356 463 489 c +596 623 679 709 713 748 c +778 821 823 882 848 932 c +874 983 887 1032 887 1081 c +887 1160 859 1225 803 1275 c +748 1325 675 1350 586 1350 c +523 1350 456 1339 385 1317 c +315 1295 240 1262 160 1217 c +160 1421 l +241 1454 317 1478 388 1495 c +459 1512 523 1520 582 1520 c +737 1520 860 1481 952 1404 c +1044 1327 1090 1223 1090 1094 c +1090 1033 1078 974 1055 919 c +1032 864 991 800 930 725 c +913 706 860 650 771 557 c +682 465 556 336 393 170 c + +ce} _d +/three{1303 0 156 -29 1139 1520 sc +831 805 m +928 784 1003 741 1057 676 c +1112 611 1139 530 1139 434 c +1139 287 1088 173 987 92 c +886 11 742 -29 555 -29 c +492 -29 428 -23 361 -10 c +295 2 227 20 156 45 c +156 240 l +212 207 273 183 340 166 c +407 149 476 141 549 141 c +676 141 772 166 838 216 c +905 266 938 339 938 434 c +938 522 907 591 845 640 c +784 690 698 715 588 715 c +414 715 l +414 881 l +596 881 l +695 881 771 901 824 940 c +877 980 903 1037 903 1112 c +903 1189 876 1247 821 1288 c +767 1329 689 1350 588 1350 c +533 1350 473 1344 410 1332 c +347 1320 277 1301 201 1276 c +201 1456 l +278 1477 349 1493 416 1504 c +483 1515 547 1520 606 1520 c +759 1520 881 1485 970 1415 c +1059 1346 1104 1252 1104 1133 c +1104 1050 1080 980 1033 923 c +986 866 918 827 831 805 c + +ce} _d +/four{1303 0 100 0 1188 1493 sc +774 1317 m +264 520 l +774 520 l +774 1317 l + +721 1493 m +975 1493 l +975 520 l +1188 520 l +1188 352 l +975 352 l +975 0 l +774 0 l +774 352 l +100 352 l +100 547 l +721 1493 l + +ce} _d +/five{1303 0 158 -29 1124 1493 sc +221 1493 m +1014 1493 l +1014 1323 l +406 1323 l +406 957 l +435 967 465 974 494 979 c +523 984 553 987 582 987 c +749 987 881 941 978 850 c +1075 759 1124 635 1124 479 c +1124 318 1074 193 974 104 c +874 15 733 -29 551 -29 c +488 -29 424 -24 359 -13 c +294 -2 227 14 158 35 c +158 238 l +218 205 280 181 344 165 c +408 149 476 141 547 141 c +662 141 754 171 821 232 c +888 293 922 375 922 479 c +922 583 888 665 821 726 c +754 787 662 817 547 817 c +493 817 439 811 385 799 c +332 787 277 768 221 743 c +221 1493 l + +ce} _d +/six{1303 0 143 -29 1174 1520 sc +676 827 m +585 827 513 796 460 734 c +407 672 381 587 381 479 c +381 372 407 287 460 224 c +513 162 585 131 676 131 c +767 131 838 162 891 224 c +944 287 971 372 971 479 c +971 587 944 672 891 734 c +838 796 767 827 676 827 c + +1077 1460 m +1077 1276 l +1026 1300 975 1318 923 1331 c +872 1344 821 1350 770 1350 c +637 1350 535 1305 464 1215 c +394 1125 354 989 344 807 c +383 865 433 909 492 940 c +551 971 617 987 688 987 c +838 987 956 941 1043 850 c +1130 759 1174 636 1174 479 c +1174 326 1129 203 1038 110 c +947 17 827 -29 676 -29 c +503 -29 371 37 280 169 c +189 302 143 494 143 745 c +143 981 199 1169 311 1309 c +423 1450 573 1520 762 1520 c +813 1520 864 1515 915 1505 c +967 1495 1021 1480 1077 1460 c + +ce} _d +/seven{1303 0 168 0 1128 1493 sc +168 1493 m +1128 1493 l +1128 1407 l +586 0 l +375 0 l +885 1323 l +168 1323 l +168 1493 l + +ce} _d +/uni0438{1331 0 186 0 1145 1120 sc +1145 1120 m +1145 0 l +962 0 l +962 899 l +422 0 l +186 0 l +186 1120 l +369 1120 l +369 223 l +908 1120 l +1145 1120 l + +ce} _d +/uni0435{1260 0 113 -29 1151 1147 sc +1151 606 m +1151 516 l +305 516 l +313 389 351 293 419 226 c +488 160 583 127 705 127 c +776 127 844 136 910 153 c +977 170 1043 196 1108 231 c +1108 57 l +1042 29 974 8 905 -7 c +836 -22 765 -29 694 -29 c +515 -29 374 23 269 127 c +165 231 113 372 113 549 c +113 732 162 878 261 985 c +360 1093 494 1147 662 1147 c +813 1147 932 1098 1019 1001 c +1107 904 1151 773 1151 606 c + +967 660 m +966 761 937 841 882 901 c +827 961 755 991 664 991 c +561 991 479 962 417 904 c +356 846 320 764 311 659 c +967 660 l + +ce} _d +/uni0432{1207 0 186 0 1086 1120 sc +370 516 m +370 147 l +632 147 l +716 147 780 163 824 194 c +868 226 890 272 890 332 c +890 392 868 438 824 469 c +780 500 716 516 632 516 c +370 516 l + +370 973 m +370 663 l +612 663 l +681 663 738 677 782 704 c +826 732 848 771 848 820 c +848 869 826 907 782 933 c +738 960 681 973 612 973 c +370 973 l + +186 1120 m +624 1120 l +755 1120 856 1096 927 1048 c +998 1000 1033 932 1033 843 c +1033 774 1015 720 979 679 c +943 639 890 614 819 604 c +904 588 969 555 1016 504 c +1063 453 1086 390 1086 314 c +1086 214 1047 137 970 82 c +893 27 784 0 641 0 c +186 0 l +186 1120 l + +ce} _d +/uni043B{1309 0 76 0 1139 1120 sc +76 0 m +76 153 l +197 172 277 223 314 307 c +359 425 382 635 382 937 c +382 1120 l +1139 1120 l +1139 0 l +955 0 l +955 973 l +566 973 l +566 862 l +566 574 537 365 478 236 c +415 98 281 19 76 0 c + +ce} _d +/uni043A{1237 0 186 0 1169 1120 sc +186 1120 m +369 1120 l +369 594 l +888 1120 l +1114 1120 l +686 687 l +1169 0 l +963 0 l +566 565 l +369 365 l +369 0 l +186 0 l +186 1120 l + +ce} _d +/uni043D{1339 0 186 0 1153 1120 sc +186 1120 m +371 1120 l +371 663 l +968 663 l +968 1120 l +1153 1120 l +1153 0 l +968 0 l +968 516 l +371 516 l +371 0 l +186 0 l +186 1120 l + +ce} _d +/uni043E{1253 0 113 -29 1141 1147 sc +627 991 m +528 991 450 952 393 875 c +336 798 307 693 307 559 c +307 425 335 319 392 242 c +449 165 528 127 627 127 c +725 127 803 166 860 243 c +917 320 946 426 946 559 c +946 692 917 797 860 874 c +803 952 725 991 627 991 c + +627 1147 m +787 1147 913 1095 1004 991 c +1095 887 1141 743 1141 559 c +1141 376 1095 232 1004 127 c +913 23 787 -29 627 -29 c +466 -29 340 23 249 127 c +158 232 113 376 113 559 c +113 743 158 887 249 991 c +340 1095 466 1147 627 1147 c + +ce} _d +/uni043F{1339 0 186 0 1153 1120 sc +1153 1120 m +1153 0 l +968 0 l +968 973 l +371 973 l +371 0 l +186 0 l +186 1120 l +1153 1120 l + +ce} _d +/uni0440{1300 0 186 -426 1188 1147 sc +371 168 m +371 -426 l +186 -426 l +186 1120 l +371 1120 l +371 950 l +410 1017 458 1066 517 1098 c +576 1131 647 1147 729 1147 c +865 1147 975 1093 1060 985 c +1145 877 1188 735 1188 559 c +1188 383 1145 241 1060 133 c +975 25 865 -29 729 -29 c +647 -29 576 -13 517 19 c +458 52 410 101 371 168 c + +997 559 m +997 694 969 800 913 877 c +858 954 781 993 684 993 c +587 993 510 954 454 877 c +399 800 371 694 371 559 c +371 424 399 317 454 240 c +510 163 587 125 684 125 c +781 125 858 163 913 240 c +969 317 997 424 997 559 c + +ce} _d +/uni0441{1126 0 113 -29 999 1147 sc +999 1077 m +999 905 l +947 934 895 955 842 969 c +790 984 737 991 684 991 c +565 991 472 953 406 877 c +340 802 307 696 307 559 c +307 422 340 316 406 240 c +472 165 565 127 684 127 c +737 127 790 134 842 148 c +895 163 947 184 999 213 c +999 43 l +948 19 894 1 839 -11 c +784 -23 726 -29 664 -29 c +495 -29 361 24 262 130 c +163 236 113 379 113 559 c +113 742 163 885 263 990 c +364 1095 501 1147 676 1147 c +733 1147 788 1141 842 1129 c +896 1118 948 1100 999 1077 c + +ce} _d +/uni0442{1193 0 60 0 1133 1120 sc +60 1120 m +1133 1120 l +1133 973 l +687 973 l +687 0 l +506 0 l +506 973 l +60 973 l +60 1120 l + +ce} _d +/uni043C{1545 0 186 0 1359 1120 sc +186 1120 m +455 1120 l +773 370 l +1092 1120 l +1359 1120 l +1359 0 l +1174 0 l +1174 944 l +865 215 l +681 215 l +371 944 l +371 0 l +186 0 l +186 1120 l + +ce} _d +/uni0444{1751 0 112 -426 1639 1493 sc +303 559 m +303 402 327 291 375 224 c +424 158 489 125 571 125 c +636 125 707 181 783 293 c +783 825 l +707 937 636 993 571 993 c +489 993 424 960 375 893 c +327 827 303 716 303 559 c + +783 -426 m +783 143 l +745 80 704 36 660 10 c +617 -16 567 -29 512 -29 c +401 -29 306 22 228 125 c +151 228 112 372 112 555 c +112 738 151 883 228 988 c +306 1094 401 1147 512 1147 c +567 1147 617 1134 660 1109 c +704 1084 745 1040 783 977 c +783 1493 l +968 1493 l +968 977 l +1006 1040 1047 1084 1090 1109 c +1134 1134 1184 1147 1239 1147 c +1350 1147 1445 1094 1522 988 c +1600 883 1639 738 1639 555 c +1639 372 1600 228 1522 125 c +1445 22 1350 -29 1239 -29 c +1184 -29 1134 -16 1090 10 c +1047 36 1006 80 968 143 c +968 -426 l +783 -426 l + +1448 559 m +1448 716 1424 827 1375 893 c +1327 960 1262 993 1180 993 c +1115 993 1044 937 968 825 c +968 293 l +1044 181 1115 125 1180 125 c +1262 125 1327 158 1375 224 c +1424 291 1448 402 1448 559 c + +ce} _d +/uni0445{1212 0 59 0 1145 1120 sc +1124 1120 m +719 575 l +1145 0 l +928 0 l +602 440 l +276 0 l +59 0 l +494 586 l +96 1120 l +313 1120 l +610 721 l +907 1120 l +1124 1120 l + +ce} _d +/equal{1716 0 217 352 1499 930 sc +217 930 m +1499 930 l +1499 762 l +217 762 l +217 930 l + +217 522 m +1499 522 l +1499 352 l +217 352 l +217 522 l + +ce} _d +/uni0447{1210 0 150 0 1024 1120 sc +840 0 m +840 471 l +497 471 l +395 471 310 503 242 566 c +181 623 150 713 150 836 c +150 1120 l +334 1120 l +334 853 l +334 775 351 716 386 677 c +421 638 474 618 543 618 c +840 618 l +840 1120 l +1024 1120 l +1024 0 l +840 0 l + +ce} _d +/uni0448{1874 0 186 0 1688 1120 sc +1029 147 m +1503 147 l +1503 1120 l +1688 1120 l +1688 0 l +186 0 l +186 1120 l +371 1120 l +371 147 l +844 147 l +844 1120 l +1029 1120 l +1029 147 l + +ce} _d +/uni0449{1929 0 186 -283 1835 1120 sc +1688 0 m +186 0 l +186 1120 l +371 1120 l +371 147 l +844 147 l +844 1120 l +1029 1120 l +1029 147 l +1503 147 l +1503 1120 l +1688 1120 l +1688 147 l +1835 147 l +1835 -283 l +1688 -283 l +1688 0 l + +ce} _d +/uni0443{1212 0 61 -426 1151 1120 sc +659 -104 m +607 -237 556 -324 507 -365 c +458 -406 392 -426 309 -426 c +162 -426 l +162 -272 l +270 -272 l +321 -272 360 -260 388 -236 c +416 -212 447 -155 481 -66 c +514 18 l +61 1120 l +256 1120 l +606 244 l +956 1120 l +1151 1120 l +659 -104 l + +ce} _d +/uni044B{1617 0 186 0 1435 1147 sc +1251 1120 m +1435 1120 l +1435 0 l +1251 0 l +1251 1120 l + +1343 1147 m +1343 1147 l + +890 332 m +890 392 868 438 824 469 c +781 500 717 516 633 516 c +371 516 l +371 147 l +633 147 l +717 147 781 163 824 194 c +868 226 890 272 890 332 c + +186 1120 m +371 1120 l +371 663 l +641 663 l +784 663 893 636 970 581 c +1047 527 1086 444 1086 332 c +1086 220 1047 137 970 82 c +893 27 784 0 641 0 c +186 0 l +186 1120 l + +ce} _d +/uni044C{1207 0 186 0 1086 1120 sc +890 332 m +890 392 868 438 824 469 c +781 500 717 516 633 516 c +371 516 l +371 147 l +633 147 l +717 147 781 163 824 194 c +868 226 890 272 890 332 c + +186 1120 m +371 1120 l +371 663 l +641 663 l +784 663 893 636 970 581 c +1047 527 1086 444 1086 332 c +1086 220 1047 137 970 82 c +893 27 784 0 641 0 c +186 0 l +186 1120 l + +ce} _d +/uni044D{1124 0 113 -29 999 1147 sc +113 213 m +218 156 323 127 428 127 c +526 127 610 155 680 212 c +750 269 791 371 804 516 c +236 516 l +236 663 l +798 663 l +790 733 759 805 706 879 c +653 954 561 991 428 991 c +325 991 220 962 113 905 c +113 1077 l +218 1124 325 1147 436 1147 c +611 1147 748 1094 848 988 c +949 883 999 740 999 559 c +999 379 950 236 852 130 c +755 24 620 -29 449 -29 c +323 -29 211 -5 113 43 c +113 213 l + +ce} _d +/B{1405 0 201 0 1260 1493 sc +403 713 m +403 166 l +727 166 l +836 166 916 188 968 233 c +1021 278 1047 347 1047 440 c +1047 533 1021 602 968 646 c +916 691 836 713 727 713 c +403 713 l + +403 1327 m +403 877 l +702 877 l +801 877 874 895 922 932 c +971 969 995 1026 995 1102 c +995 1177 971 1234 922 1271 c +874 1308 801 1327 702 1327 c +403 1327 l + +201 1493 m +717 1493 l +871 1493 990 1461 1073 1397 c +1156 1333 1198 1242 1198 1124 c +1198 1033 1177 960 1134 906 c +1091 852 1029 818 946 805 c +1045 784 1122 739 1177 671 c +1232 604 1260 519 1260 418 c +1260 285 1215 182 1124 109 c +1033 36 904 0 737 0 c +201 0 l +201 1493 l + +ce} _d +/F{1178 0 201 0 1059 1493 sc +201 1493 m +1059 1493 l +1059 1323 l +403 1323 l +403 883 l +995 883 l +995 713 l +403 713 l +403 0 l +201 0 l +201 1493 l + +ce} _d +/A{1401 0 16 0 1384 1493 sc +700 1294 m +426 551 l +975 551 l +700 1294 l + +586 1493 m +815 1493 l +1384 0 l +1174 0 l +1038 383 l +365 383 l +229 0 l +16 0 l +586 1493 l + +ce} _d +/S{1300 0 135 -29 1186 1520 sc +1096 1444 m +1096 1247 l +1019 1284 947 1311 879 1329 c +811 1347 745 1356 682 1356 c +572 1356 487 1335 427 1292 c +368 1249 338 1189 338 1110 c +338 1044 358 994 397 960 c +437 927 512 900 623 879 c +745 854 l +896 825 1007 775 1078 702 c +1150 630 1186 533 1186 412 c +1186 267 1137 158 1040 83 c +943 8 801 -29 614 -29 c +543 -29 468 -21 388 -5 c +309 11 226 35 141 66 c +141 274 l +223 228 303 193 382 170 c +461 147 538 135 614 135 c +729 135 818 158 881 203 c +944 248 975 313 975 397 c +975 470 952 528 907 569 c +862 610 789 641 686 662 c +563 686 l +412 716 303 763 236 827 c +169 891 135 980 135 1094 c +135 1226 181 1330 274 1406 c +367 1482 496 1520 659 1520 c +729 1520 800 1514 873 1501 c +946 1488 1020 1469 1096 1444 c + +ce} _d +/D{1577 0 201 0 1456 1493 sc +403 1327 m +403 166 l +647 166 l +853 166 1004 213 1099 306 c +1195 399 1243 547 1243 748 c +1243 948 1195 1094 1099 1187 c +1004 1280 853 1327 647 1327 c +403 1327 l + +201 1493 m +616 1493 l +905 1493 1118 1433 1253 1312 c +1388 1192 1456 1004 1456 748 c +1456 491 1388 302 1252 181 c +1116 60 904 0 616 0 c +201 0 l +201 1493 l + +ce} _d +/underscore{1024 0 -20 -483 1044 -340 sc +1044 -340 m +1044 -483 l +-20 -483 l +-20 -340 l +1044 -340 l + +ce} _d +/a{1255 0 123 -29 1069 1147 sc +702 563 m +553 563 450 546 393 512 c +336 478 307 420 307 338 c +307 273 328 221 371 182 c +414 144 473 125 547 125 c +649 125 731 161 792 233 c +854 306 885 402 885 522 c +885 563 l +702 563 l + +1069 639 m +1069 0 l +885 0 l +885 170 l +843 102 791 52 728 19 c +665 -13 589 -29 498 -29 c +383 -29 292 3 224 67 c +157 132 123 218 123 326 c +123 452 165 547 249 611 c +334 675 460 707 627 707 c +885 707 l +885 725 l +885 810 857 875 801 921 c +746 968 668 991 567 991 c +503 991 441 983 380 968 c +319 953 261 930 205 899 c +205 1069 l +272 1095 338 1114 401 1127 c +464 1140 526 1147 586 1147 c +748 1147 869 1105 949 1021 c +1029 937 1069 810 1069 639 c + +ce} _d +/d{1300 0 113 -29 1114 1556 sc +930 950 m +930 1556 l +1114 1556 l +1114 0 l +930 0 l +930 168 l +891 101 842 52 783 19 c +724 -13 654 -29 571 -29 c +436 -29 325 25 240 133 c +155 241 113 383 113 559 c +113 735 155 877 240 985 c +325 1093 436 1147 571 1147 c +654 1147 724 1131 783 1098 c +842 1066 891 1017 930 950 c + +303 559 m +303 424 331 317 386 240 c +442 163 519 125 616 125 c +713 125 790 163 846 240 c +902 317 930 424 930 559 c +930 694 902 800 846 877 c +790 954 713 993 616 993 c +519 993 442 954 386 877 c +331 800 303 694 303 559 c + +ce} _d +/e{1260 0 113 -29 1151 1147 sc +1151 606 m +1151 516 l +305 516 l +313 389 351 293 419 226 c +488 160 583 127 705 127 c +776 127 844 136 910 153 c +977 170 1043 196 1108 231 c +1108 57 l +1042 29 974 8 905 -7 c +836 -22 765 -29 694 -29 c +515 -29 374 23 269 127 c +165 231 113 372 113 549 c +113 732 162 878 261 985 c +360 1093 494 1147 662 1147 c +813 1147 932 1098 1019 1001 c +1107 904 1151 773 1151 606 c + +967 660 m +966 761 937 841 882 901 c +827 961 755 991 664 991 c +561 991 479 962 417 904 c +356 846 320 764 311 659 c +967 660 l + +ce} _d +/g{1300 0 113 -426 1114 1147 sc +930 573 m +930 706 902 810 847 883 c +792 956 715 993 616 993 c +517 993 440 956 385 883 c +330 810 303 706 303 573 c +303 440 330 337 385 264 c +440 191 517 154 616 154 c +715 154 792 191 847 264 c +902 337 930 440 930 573 c + +1114 139 m +1114 -52 1072 -193 987 -286 c +902 -379 773 -426 598 -426 c +533 -426 472 -421 415 -411 c +358 -402 302 -387 248 -367 c +248 -188 l +302 -217 355 -239 408 -253 c +461 -267 514 -274 569 -274 c +690 -274 780 -242 840 -179 c +900 -116 930 -21 930 106 c +930 197 l +892 131 843 82 784 49 c +725 16 654 0 571 0 c +434 0 323 52 239 157 c +155 262 113 400 113 573 c +113 746 155 885 239 990 c +323 1095 434 1147 571 1147 c +654 1147 725 1131 784 1098 c +843 1065 892 1016 930 950 c +930 1120 l +1114 1120 l +1114 139 l + +ce} _d +/i{569 0 193 0 377 1556 sc +193 1120 m +377 1120 l +377 0 l +193 0 l +193 1120 l + +193 1556 m +377 1556 l +377 1323 l +193 1323 l +193 1556 l + +ce} _d +/l{569 0 193 0 377 1556 sc +193 1556 m +377 1556 l +377 0 l +193 0 l +193 1556 l + +ce} _d +/m{1995 0 186 0 1821 1147 sc +1065 905 m +1111 988 1166 1049 1230 1088 c +1294 1127 1369 1147 1456 1147 c +1573 1147 1663 1106 1726 1024 c +1789 943 1821 827 1821 676 c +1821 0 l +1636 0 l +1636 670 l +1636 777 1617 857 1579 909 c +1541 961 1483 987 1405 987 c +1310 987 1234 955 1179 892 c +1124 829 1096 742 1096 633 c +1096 0 l +911 0 l +911 670 l +911 778 892 858 854 909 c +816 961 757 987 678 987 c +584 987 509 955 454 891 c +399 828 371 742 371 633 c +371 0 l +186 0 l +186 1120 l +371 1120 l +371 946 l +413 1015 463 1065 522 1098 c +581 1131 650 1147 731 1147 c +812 1147 881 1126 938 1085 c +995 1044 1038 984 1065 905 c + +ce} _d +/n{1298 0 186 0 1124 1147 sc +1124 676 m +1124 0 l +940 0 l +940 670 l +940 776 919 855 878 908 c +837 961 775 987 692 987 c +593 987 514 955 457 892 c +400 829 371 742 371 633 c +371 0 l +186 0 l +186 1120 l +371 1120 l +371 946 l +415 1013 467 1064 526 1097 c +586 1130 655 1147 733 1147 c +862 1147 959 1107 1025 1027 c +1091 948 1124 831 1124 676 c + +ce} _d +/o{1253 0 113 -29 1141 1147 sc +627 991 m +528 991 450 952 393 875 c +336 798 307 693 307 559 c +307 425 335 319 392 242 c +449 165 528 127 627 127 c +725 127 803 166 860 243 c +917 320 946 426 946 559 c +946 692 917 797 860 874 c +803 952 725 991 627 991 c + +627 1147 m +787 1147 913 1095 1004 991 c +1095 887 1141 743 1141 559 c +1141 376 1095 232 1004 127 c +913 23 787 -29 627 -29 c +466 -29 340 23 249 127 c +158 232 113 376 113 559 c +113 743 158 887 249 991 c +340 1095 466 1147 627 1147 c + +ce} _d +/p{1300 0 186 -426 1188 1147 sc +371 168 m +371 -426 l +186 -426 l +186 1120 l +371 1120 l +371 950 l +410 1017 458 1066 517 1098 c +576 1131 647 1147 729 1147 c +865 1147 975 1093 1060 985 c +1145 877 1188 735 1188 559 c +1188 383 1145 241 1060 133 c +975 25 865 -29 729 -29 c +647 -29 576 -13 517 19 c +458 52 410 101 371 168 c + +997 559 m +997 694 969 800 913 877 c +858 954 781 993 684 993 c +587 993 510 954 454 877 c +399 800 371 694 371 559 c +371 424 399 317 454 240 c +510 163 587 125 684 125 c +781 125 858 163 913 240 c +969 317 997 424 997 559 c + +ce} _d +/r{842 0 186 0 842 1147 sc +842 948 m +821 960 799 969 774 974 c +750 980 723 983 694 983 c +590 983 510 949 454 881 c +399 814 371 717 371 590 c +371 0 l +186 0 l +186 1120 l +371 1120 l +371 946 l +410 1014 460 1064 522 1097 c +584 1130 659 1147 748 1147 c +761 1147 775 1146 790 1144 c +805 1143 822 1140 841 1137 c +842 948 l + +ce} _d +/s{1067 0 111 -29 967 1147 sc +907 1087 m +907 913 l +855 940 801 960 745 973 c +689 986 631 993 571 993 c +480 993 411 979 365 951 c +320 923 297 881 297 825 c +297 782 313 749 346 724 c +379 700 444 677 543 655 c +606 641 l +737 613 829 573 884 522 c +939 471 967 400 967 309 c +967 205 926 123 843 62 c +761 1 648 -29 504 -29 c +444 -29 381 -23 316 -11 c +251 0 183 18 111 41 c +111 231 l +179 196 246 169 312 151 c +378 134 443 125 508 125 c +595 125 661 140 708 169 c +755 199 778 241 778 295 c +778 345 761 383 727 410 c +694 437 620 462 506 487 c +442 502 l +328 526 246 563 195 612 c +144 662 119 730 119 817 c +119 922 156 1004 231 1061 c +306 1118 412 1147 549 1147 c +617 1147 681 1142 741 1132 c +801 1122 856 1107 907 1087 c + +ce} _d +/t{803 0 55 0 754 1438 sc +375 1438 m +375 1120 l +754 1120 l +754 977 l +375 977 l +375 369 l +375 278 387 219 412 193 c +437 167 488 154 565 154 c +754 154 l +754 0 l +565 0 l +423 0 325 26 271 79 c +217 132 190 229 190 369 c +190 977 l +55 977 l +55 1120 l +190 1120 l +190 1438 l +375 1438 l + +ce} _d +/u{1298 0 174 -29 1112 1147 sc +174 442 m +174 1120 l +358 1120 l +358 449 l +358 343 379 263 420 210 c +461 157 523 131 606 131 c +705 131 784 163 841 226 c +899 289 928 376 928 485 c +928 1120 l +1112 1120 l +1112 0 l +928 0 l +928 172 l +883 104 831 53 772 20 c +713 -13 645 -29 567 -29 c +438 -29 341 11 274 91 c +207 171 174 288 174 442 c + +637 1147 m +637 1147 l + +ce} _d +/x{1212 0 59 0 1145 1120 sc +1124 1120 m +719 575 l +1145 0 l +928 0 l +602 440 l +276 0 l +59 0 l +494 586 l +96 1120 l +313 1120 l +610 721 l +907 1120 l +1124 1120 l + +ce} _d +/y{1212 0 61 -426 1151 1120 sc +659 -104 m +607 -237 556 -324 507 -365 c +458 -406 392 -426 309 -426 c +162 -426 l +162 -272 l +270 -272 l +321 -272 360 -260 388 -236 c +416 -212 447 -155 481 -66 c +514 18 l +61 1120 l +256 1120 l +606 244 l +956 1120 l +1151 1120 l +659 -104 l + +ce} _d +/z{1075 0 88 0 987 1120 sc +113 1120 m +987 1120 l +987 952 l +295 147 l +987 147 l +987 0 l +88 0 l +88 168 l +780 973 l +113 973 l +113 1120 l + +ce} _d +end readonly def + +/BuildGlyph { + exch begin + CharStrings exch + 2 copy known not {pop /.notdef} if + true 3 1 roll get exec + end +} _d + +/BuildChar { + 1 index /Encoding get exch get + 1 index /BuildGlyph get exec +} _d + +FontName currentdict end definefont pop +end +%%EndProlog +mpldict begin +0 0 translate +0 0 720 432 rectclip +gsave +0 0 m +720 0 l +720 432 l +0 432 l +cl +1 setgray +fill +grestore +gsave +57.17 60.315413 m +709.2 60.315413 l +709.2 404.95125 l +57.17 404.95125 l +cl +1 setgray +fill +grestore +gsave +57.17 60.315 652.03 344.636 rectclip +86.807727 60.315413 m +118.005335 60.315413 l +118.005335 99.325715 l +86.807727 99.325715 l +cl +0.122 0.467 0.706 setrgbcolor +fill +grestore +gsave +57.17 60.315 652.03 344.636 rectclip +211.598158 60.315413 m +242.795766 60.315413 l +242.795766 388.54002 l +211.598158 388.54002 l +cl +0.122 0.467 0.706 setrgbcolor +fill +grestore +gsave +57.17 60.315 652.03 344.636 rectclip +336.388589 60.315413 m +367.586196 60.315413 l +367.586196 140.084754 l +336.388589 140.084754 l +cl +0.122 0.467 0.706 setrgbcolor +fill +grestore +gsave +57.17 60.315 652.03 344.636 rectclip +461.179019 60.315413 m +492.376627 60.315413 l +492.376627 67.489721 l +461.179019 67.489721 l +cl +0.122 0.467 0.706 setrgbcolor +fill +grestore +gsave +57.17 60.315 652.03 344.636 rectclip +585.96945 60.315413 m +617.167057 60.315413 l +617.167057 61.570917 l +585.96945 61.570917 l +cl +0.122 0.467 0.706 setrgbcolor +fill +grestore +gsave +57.17 60.315 652.03 344.636 rectclip +118.005335 60.315413 m +149.202943 60.315413 l +149.202943 98.070211 l +118.005335 98.070211 l +cl +1 0.498 0.055 setrgbcolor +fill +grestore +gsave +57.17 60.315 652.03 344.636 rectclip +242.795766 60.315413 m +273.993373 60.315413 l +273.993373 219.45054 l +242.795766 219.45054 l +cl +1 0.498 0.055 setrgbcolor +fill +grestore +gsave +57.17 60.315 652.03 344.636 rectclip +367.586196 60.315413 m +398.783804 60.315413 l +398.783804 99.460233 l +367.586196 99.460233 l +cl +1 0.498 0.055 setrgbcolor +fill +grestore +gsave +57.17 60.315 652.03 344.636 rectclip +492.376627 60.315413 m +523.574234 60.315413 l +523.574234 67.489721 l +492.376627 67.489721 l +cl +1 0.498 0.055 setrgbcolor +fill +grestore +gsave +57.17 60.315 652.03 344.636 rectclip +617.167057 60.315413 m +648.364665 60.315413 l +648.364665 60.988005 l +617.167057 60.988005 l +cl +1 0.498 0.055 setrgbcolor +fill +grestore +gsave +57.17 60.315 652.03 344.636 rectclip +149.202943 60.315413 m +180.40055 60.315413 l +180.40055 65.382268 l +149.202943 65.382268 l +cl +0.173 0.627 0.173 setrgbcolor +fill +grestore +gsave +57.17 60.315 652.03 344.636 rectclip +273.993373 60.315413 m +305.190981 60.315413 l +305.190981 75.022745 l +273.993373 75.022745 l +cl +0.173 0.627 0.173 setrgbcolor +fill +grestore +gsave +57.17 60.315 652.03 344.636 rectclip +398.783804 60.315413 m +429.981411 60.315413 l +429.981411 67.400043 l +398.783804 67.400043 l +cl +0.173 0.627 0.173 setrgbcolor +fill +grestore +gsave +57.17 60.315 652.03 344.636 rectclip +523.574234 60.315413 m +554.771842 60.315413 l +554.771842 67.489721 l +523.574234 67.489721 l +cl +0.173 0.627 0.173 setrgbcolor +fill +grestore +gsave +57.17 60.315 652.03 344.636 rectclip +648.364665 60.315413 m +679.562273 60.315413 l +679.562273 61.032844 l +648.364665 61.032844 l +cl +0.173 0.627 0.173 setrgbcolor +fill +grestore +0.8 setlinewidth +1 setlinejoin +0 setlinecap +[] 0 setdash +0 setgray +gsave +/o { +gsave +newpath +translate +0.8 setlinewidth +1 setlinejoin + +0 setlinecap + +0 0 m +0 -3.5 l + +gsave +0 setgray +fill +grestore +stroke +grestore +} bind def +133.604 60.3154 o +grestore +/DejaVuSans 10.000 selectfont +gsave + +78.3044 16.2736 translate +15 rotate +0 0 m /m glyphshow +9.74121 0 m /a glyphshow +15.8691 0 m /z glyphshow +21.1182 0 m /e glyphshow +27.2705 0 m /s glyphshow +32.4805 0 m /slash glyphshow +35.8496 0 m /m glyphshow +45.5908 0 m /a glyphshow +51.7188 0 m /z glyphshow +56.9678 0 m /e glyphshow +63.1201 0 m /underscore glyphshow +68.1201 0 m /e glyphshow +74.2725 0 m /m glyphshow +84.0137 0 m /p glyphshow +90.3613 0 m /t glyphshow +94.2822 0 m /y glyphshow +98.8252 0 m /period glyphshow +102.004 0 m /t glyphshow +105.925 0 m /x glyphshow +111.843 0 m /t glyphshow +grestore +gsave +/o { +gsave +newpath +translate +0.8 setlinewidth +1 setlinejoin + +0 setlinecap + +0 0 m +0 -3.5 l + +gsave +0 setgray +fill +grestore +stroke +grestore +} bind def +258.395 60.3154 o +grestore +/DejaVuSans 10.000 selectfont +gsave + +205.705 17.3809 translate +15 rotate +0 0 m /m glyphshow +9.74121 0 m /a glyphshow +15.8691 0 m /z glyphshow +21.1182 0 m /e glyphshow +27.2705 0 m /s glyphshow +32.4805 0 m /slash glyphshow +35.8496 0 m /m glyphshow +45.5908 0 m /a glyphshow +51.7188 0 m /z glyphshow +56.9678 0 m /e glyphshow +63.1201 0 m /underscore glyphshow +68.1201 0 m /l glyphshow +70.8984 0 m /a glyphshow +77.0264 0 m /r glyphshow +81.0127 0 m /g glyphshow +87.3604 0 m /e glyphshow +93.5127 0 m /period glyphshow +96.6914 0 m /t glyphshow +100.612 0 m /x glyphshow +106.53 0 m /t glyphshow +grestore +gsave +/o { +gsave +newpath +translate +0.8 setlinewidth +1 setlinejoin + +0 setlinecap + +0 0 m +0 -3.5 l + +gsave +0 setgray +fill +grestore +stroke +grestore +} bind def +383.185 60.3154 o +grestore +/DejaVuSans 10.000 selectfont +gsave + +322.896 13.3086 translate +15 rotate +0 0 m /m glyphshow +9.74121 0 m /a glyphshow +15.8691 0 m /z glyphshow +21.1182 0 m /e glyphshow +27.2705 0 m /s glyphshow +32.4805 0 m /slash glyphshow +35.8496 0 m /m glyphshow +45.5908 0 m /a glyphshow +51.7188 0 m /z glyphshow +56.9678 0 m /e glyphshow +63.1201 0 m /underscore glyphshow +68.1201 0 m /m glyphshow +77.8613 0 m /e glyphshow +84.0137 0 m /d glyphshow +90.3613 0 m /i glyphshow +93.1396 0 m /u glyphshow +99.4775 0 m /m glyphshow +109.219 0 m /period glyphshow +112.397 0 m /t glyphshow +116.318 0 m /x glyphshow +122.236 0 m /t glyphshow +grestore +gsave +/o { +gsave +newpath +translate +0.8 setlinewidth +1 setlinejoin + +0 setlinecap + +0 0 m +0 -3.5 l + +gsave +0 setgray +fill +grestore +stroke +grestore +} bind def +507.975 60.3154 o +grestore +/DejaVuSans 10.000 selectfont +gsave + +450.101 14.6026 translate +15 rotate +0 0 m /m glyphshow +9.74121 0 m /a glyphshow +15.8691 0 m /z glyphshow +21.1182 0 m /e glyphshow +27.2705 0 m /s glyphshow +32.4805 0 m /slash glyphshow +35.8496 0 m /m glyphshow +45.5908 0 m /a glyphshow +51.7188 0 m /z glyphshow +56.9678 0 m /e glyphshow +63.1201 0 m /underscore glyphshow +68.1201 0 m /n glyphshow +74.458 0 m /o glyphshow +80.5762 0 m /underscore glyphshow +85.5762 0 m /e glyphshow +91.6035 0 m /x glyphshow +97.5215 0 m /i glyphshow +100.3 0 m /t glyphshow +104.221 0 m /period glyphshow +107.399 0 m /t glyphshow +111.32 0 m /x glyphshow +117.238 0 m /t glyphshow +grestore +gsave +/o { +gsave +newpath +translate +0.8 setlinewidth +1 setlinejoin + +0 setlinecap + +0 0 m +0 -3.5 l + +gsave +0 setgray +fill +grestore +stroke +grestore +} bind def +632.766 60.3154 o +grestore +/DejaVuSans 10.000 selectfont +gsave + +579.465 17.0533 translate +15 rotate +0 0 m /m glyphshow +9.74121 0 m /a glyphshow +15.8691 0 m /z glyphshow +21.1182 0 m /e glyphshow +27.2705 0 m /s glyphshow +32.4805 0 m /slash glyphshow +35.8496 0 m /m glyphshow +45.5908 0 m /a glyphshow +51.7188 0 m /z glyphshow +56.9678 0 m /e glyphshow +63.1201 0 m /underscore glyphshow +68.1201 0 m /s glyphshow +73.3301 0 m /m glyphshow +83.0713 0 m /a glyphshow +89.1992 0 m /l glyphshow +91.9775 0 m /l glyphshow +94.7559 0 m /period glyphshow +97.9346 0 m /t glyphshow +101.855 0 m /x glyphshow +107.773 0 m /t glyphshow +grestore +gsave +/o { +gsave +newpath +translate +0.8 setlinewidth +1 setlinejoin + +0 setlinecap + +-0 0 m +-3.5 0 l + +gsave +0 setgray +fill +grestore +stroke +grestore +} bind def +57.17 60.3154 o +grestore +/DejaVuSans 10.000 selectfont +gsave + +43.8106 56.5185 translate +0 rotate +0 0 m /zero glyphshow +grestore +gsave +/o { +gsave +newpath +translate +0.8 setlinewidth +1 setlinejoin + +0 setlinecap + +-0 0 m +-3.5 0 l + +gsave +0 setgray +fill +grestore +stroke +grestore +} bind def +57.17 105.155 o +grestore +/DejaVuSans 10.000 selectfont +gsave + +24.7325 101.358 translate +0 rotate +0 0 m /one glyphshow +6.3623 0 m /zero glyphshow +12.7246 0 m /zero glyphshow +19.0869 0 m /zero glyphshow +grestore +gsave +/o { +gsave +newpath +translate +0.8 setlinewidth +1 setlinejoin + +0 setlinecap + +-0 0 m +-3.5 0 l + +gsave +0 setgray +fill +grestore +stroke +grestore +} bind def +57.17 149.994 o +grestore +/DejaVuSans 10.000 selectfont +gsave + +24.7325 146.197 translate +0 rotate +0 0 m /two glyphshow +6.3623 0 m /zero glyphshow +12.7246 0 m /zero glyphshow +19.0869 0 m /zero glyphshow +grestore +gsave +/o { +gsave +newpath +translate +0.8 setlinewidth +1 setlinejoin + +0 setlinecap + +-0 0 m +-3.5 0 l + +gsave +0 setgray +fill +grestore +stroke +grestore +} bind def +57.17 194.834 o +grestore +/DejaVuSans 10.000 selectfont +gsave + +24.7325 191.037 translate +0 rotate +0 0 m /three glyphshow +6.3623 0 m /zero glyphshow +12.7246 0 m /zero glyphshow +19.0869 0 m /zero glyphshow +grestore +gsave +/o { +gsave +newpath +translate +0.8 setlinewidth +1 setlinejoin + +0 setlinecap + +-0 0 m +-3.5 0 l + +gsave +0 setgray +fill +grestore +stroke +grestore +} bind def +57.17 239.673 o +grestore +/DejaVuSans 10.000 selectfont +gsave + +24.7325 235.876 translate +0 rotate +0 0 m /four glyphshow +6.3623 0 m /zero glyphshow +12.7246 0 m /zero glyphshow +19.0869 0 m /zero glyphshow +grestore +gsave +/o { +gsave +newpath +translate +0.8 setlinewidth +1 setlinejoin + +0 setlinecap + +-0 0 m +-3.5 0 l + +gsave +0 setgray +fill +grestore +stroke +grestore +} bind def +57.17 284.513 o +grestore +/DejaVuSans 10.000 selectfont +gsave + +24.7325 280.716 translate +0 rotate +0 0 m /five glyphshow +6.3623 0 m /zero glyphshow +12.7246 0 m /zero glyphshow +19.0869 0 m /zero glyphshow +grestore +gsave +/o { +gsave +newpath +translate +0.8 setlinewidth +1 setlinejoin + +0 setlinecap + +-0 0 m +-3.5 0 l + +gsave +0 setgray +fill +grestore +stroke +grestore +} bind def +57.17 329.352 o +grestore +/DejaVuSans 10.000 selectfont +gsave + +24.7325 325.555 translate +0 rotate +0 0 m /six glyphshow +6.3623 0 m /zero glyphshow +12.7246 0 m /zero glyphshow +19.0869 0 m /zero glyphshow +grestore +gsave +/o { +gsave +newpath +translate +0.8 setlinewidth +1 setlinejoin + +0 setlinecap + +-0 0 m +-3.5 0 l + +gsave +0 setgray +fill +grestore +stroke +grestore +} bind def +57.17 374.191 o +grestore +/DejaVuSans 10.000 selectfont +gsave + +24.7325 370.395 translate +0 rotate +0 0 m /seven glyphshow +6.3623 0 m /zero glyphshow +12.7246 0 m /zero glyphshow +19.0869 0 m /zero glyphshow +grestore +/DejaVuSans 10.000 selectfont +gsave + +18.6544 146.985 translate +90 rotate +0 0 m /uni041A glyphshow +7.09961 0 m /uni043E glyphshow +13.2178 0 m /uni043B glyphshow +19.6094 0 m /uni0438 glyphshow +26.1084 0 m /uni0447 glyphshow +32.0166 0 m /uni0435 glyphshow +38.1689 0 m /uni0441 glyphshow +43.667 0 m /uni0442 glyphshow +49.4922 0 m /uni0432 glyphshow +55.3857 0 m /uni043E glyphshow +61.5039 0 m /space glyphshow +64.6826 0 m /uni043F glyphshow +71.2207 0 m /uni043E glyphshow +77.3389 0 m /uni0441 glyphshow +82.8369 0 m /uni0435 glyphshow +88.9893 0 m /uni0449 glyphshow +98.4082 0 m /uni0435 glyphshow +104.561 0 m /uni043D glyphshow +111.099 0 m /uni043D glyphshow +117.637 0 m /uni044B glyphshow +125.532 0 m /uni0445 glyphshow +131.45 0 m /space glyphshow +134.629 0 m /uni043A glyphshow +140.669 0 m /uni043B glyphshow +147.061 0 m /uni0435 glyphshow +153.213 0 m /uni0442 glyphshow +159.038 0 m /uni043E glyphshow +165.156 0 m /uni043A glyphshow +grestore +0 setlinejoin +2 setlinecap +gsave +57.17 60.315413 m +57.17 404.95125 l +stroke +grestore +gsave +709.2 60.315413 m +709.2 404.95125 l +stroke +grestore +gsave +57.17 60.315413 m +709.2 60.315413 l +stroke +grestore +gsave +57.17 404.95125 m +709.2 404.95125 l +stroke +grestore +/DejaVuSans 12.000 selectfont +gsave + +172.708 410.951 translate +0 rotate +0 0 m /uni0421 glyphshow +8.37891 0 m /uni0440 glyphshow +15.9961 0 m /uni0430 glyphshow +23.3496 0 m /uni0432 glyphshow +30.4219 0 m /uni043D glyphshow +38.2676 0 m /uni0435 glyphshow +45.6504 0 m /uni043D glyphshow +53.4961 0 m /uni0438 glyphshow +61.2949 0 m /uni0435 glyphshow +68.6777 0 m /space glyphshow +72.4922 0 m /uni044D glyphshow +79.0781 0 m /uni0444 glyphshow +89.3379 0 m /uni0444 glyphshow +99.5977 0 m /uni0435 glyphshow +106.98 0 m /uni043A glyphshow +114.229 0 m /uni0442 glyphshow +121.219 0 m /uni0438 glyphshow +129.018 0 m /uni0432 glyphshow +136.09 0 m /uni043D glyphshow +143.936 0 m /uni043E glyphshow +151.277 0 m /uni0441 glyphshow +157.875 0 m /uni0442 glyphshow +164.865 0 m /uni0438 glyphshow +172.664 0 m /space glyphshow +176.479 0 m /uni043E glyphshow +183.82 0 m /uni0431 glyphshow +191.221 0 m /uni0445 glyphshow +198.322 0 m /uni043E glyphshow +205.664 0 m /uni0434 glyphshow +213.961 0 m /uni0430 glyphshow +221.314 0 m /space glyphshow +225.129 0 m /uni043B glyphshow +232.799 0 m /uni0430 glyphshow +240.152 0 m /uni0431 glyphshow +247.553 0 m /uni0438 glyphshow +255.352 0 m /uni0440 glyphshow +262.969 0 m /uni0438 glyphshow +270.768 0 m /uni043D glyphshow +278.613 0 m /uni0442 glyphshow +285.604 0 m /uni043E glyphshow +292.945 0 m /uni0432 glyphshow +300.018 0 m /space glyphshow +303.832 0 m /parenleft glyphshow +308.514 0 m /uni043C glyphshow +317.566 0 m /uni0435 glyphshow +324.949 0 m /uni043D glyphshow +332.795 0 m /uni044C glyphshow +339.867 0 m /uni0448 glyphshow +350.848 0 m /uni0435 glyphshow +358.23 0 m /space glyphshow +362.045 0 m /equal glyphshow +372.1 0 m /space glyphshow +375.914 0 m /uni043B glyphshow +383.584 0 m /uni0443 glyphshow +390.686 0 m /uni0447 glyphshow +397.775 0 m /uni0448 glyphshow +408.756 0 m /uni0435 glyphshow +416.139 0 m /parenright glyphshow +grestore +1 setlinewidth +0 setlinecap +0.8 setgray +gsave +650.528125 352.935625 m +702.2 352.935625 l +703.533333 352.935625 704.2 353.602292 704.2 354.935625 c +704.2 397.95125 l +704.2 399.284583 703.533333 399.95125 702.2 399.95125 c +650.528125 399.95125 l +649.194792 399.95125 648.528125 399.284583 648.528125 397.95125 c +648.528125 354.935625 l +648.528125 353.602292 649.194792 352.935625 650.528125 352.935625 c +cl +gsave +1 setgray +fill +grestore +stroke +grestore +gsave +652.528125 388.3575 m +672.528125 388.3575 l +672.528125 395.3575 l +652.528125 395.3575 l +cl +0.122 0.467 0.706 setrgbcolor +fill +grestore +0 setgray +/DejaVuSans 10.000 selectfont +gsave + +680.528 388.358 translate +0 rotate +0 0 m /B glyphshow +6.86035 0 m /F glyphshow +12.4873 0 m /S glyphshow +grestore +gsave +652.528125 373.685625 m +672.528125 373.685625 l +672.528125 380.685625 l +652.528125 380.685625 l +cl +1 0.498 0.055 setrgbcolor +fill +grestore +/DejaVuSans 10.000 selectfont +gsave + +680.528 373.686 translate +0 rotate +0 0 m /D glyphshow +7.7002 0 m /F glyphshow +13.3271 0 m /S glyphshow +grestore +gsave +652.528125 359.01375 m +672.528125 359.01375 l +672.528125 366.01375 l +652.528125 366.01375 l +cl +0.173 0.627 0.173 setrgbcolor +fill +grestore +/DejaVuSans 10.000 selectfont +gsave + +680.528 359.014 translate +0 rotate +0 0 m /A glyphshow +6.84082 0 m /asterisk glyphshow +grestore + +end +showpage diff --git a/ProninVV/task-2-oop/report/document.pdf b/ProninVV/task-2-oop/report/document.pdf new file mode 100644 index 0000000..b6504c9 Binary files /dev/null and b/ProninVV/task-2-oop/report/document.pdf differ diff --git a/ProninVV/task-2-oop/report/document.tex b/ProninVV/task-2-oop/report/document.tex new file mode 100644 index 0000000..00619d5 --- /dev/null +++ b/ProninVV/task-2-oop/report/document.tex @@ -0,0 +1,302 @@ +\input{preambule.tex} + + + +\begin{document} + + + + \thispagestyle{empty} + + \centerline{МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РФ} + \centerline{НАЦИОНАЛЬНЫЙ ИССЛЕДОВАТЕЛЬСКИЙ НИЖЕГОРОДСКИЙ} + \centerline{ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ИМ Н. И. ЛОБАЧЕВСКОГО} + \centerline{Радиофизический факультет} + + \vfill + + \centerline{\Large{Отчет к лабораторной работе}} + \centerline{\large{по Методам программирования}} + \centerline{\Large{Поиск выхода из лабиринта }} + \centerline{\Large{(объектно-ориентированная реализация с паттернами)}} + \vfill + + Студент группы 427 \hfill Пронин Владислав Владимирович + + Преподаватель \hfill Морозов Н. С. + + \vfill + + \centerline{Н. Новгород, 2026} + \clearpage + + \newpage + + \tableofcontents + + \newpage + + \section{Цель работы} + + Разработать гибкую, расширяемую программу для загрузки лабиринта из файла, поиска пути от старта до выхода с возможностью выбора алгоритма, визуализации процесса и экспериментального сравнения алгоритмов. В ходе работы необходимо применить минимум 3 паттерна проектирования из списка GoF, обосновать их выбор и продемонстрировать преимущества такой архитектуры. + + + \section{Описание задачи и выбранных паттернов} + + + Используемые Паттерны: + \begin{itemize} + + \item Strategy (Стратегия) \textemdash \ это поведенческий паттерн проектирования, который определяет семейство схожих алгоритмов и помещает каждый из них в собственный класс, после чего алгоритмы можно взаимозаменять прямо во время исполнения программы. Выбран, так как в данной лабораторной работе используются несколько алгоритмов, выполняющих одно и то же действие \ \textemdash \ обход графа. + + \item Builder (строитель) \textemdash \ абстрактный класс/интерфейс, который определяет все этапы, необходимые для производства сложного объекта-продукта. Позволяет отделить построение сложного объекта от его представления, создает сложные объекты, используя простые объекты и поэтапный подход. Выбран для изоляции сложного процесса парсинга текстовоо файла. + + \item Observer (Наблюдатель) \ \textemdash \ это поведенческий паттерн проектирования, который создаёт механизм подписки, позволяющий одним объектам следить и реагировать на события, происходящие в других объектах. Выбран для отделения логики приложения от вывода на экран (принцип MVC). Класс ConsoleView подписывается на события GameController и перерисовывает карту только тогда, когда игрок перемещается или путь найден. + + \end{itemize} + + + + \section{Диаграмма классов} + + \begin{figure}[H] + \centering + \includegraphics[scale=0.06]{plan.png} + \end{figure} + + + \section{Листиги Классов} + \subsection{Maze Solver} + + \begin{lstlisting} + import time + from Maze import Maze + from strategy import PathFindingStrategy + + class MazeSolver: + def __init__(self, maze: Maze, strategy: PathFindingStrategy): + self._maze = maze + self._strategy = strategy + self._observers = [] + + def addObserver(self, observer): + """Регистрация нового наблюдателя (например, ConsoleView)""" + self._observers.append(observer) + + def notify(self, event): + """Уведомление всех подписчиков о событии""" + for observer in self._observers: + observer.update(event) + + def setStrategy(self, strategy): + self._strategy = strategy + + def solve(self): + + if not self._maze or not self._strategy: + raise ValueError("Не задан лабиринт или стратегия поиска!") + + start_time = time.perf_counter() + + path, visited_count = self._strategy.findPath( + self._maze, self._maze.start, self._maze.exit) + + end_time = time.perf_counter() + + execution_time_ms = (end_time - start_time) * 1000 + + path_length = len(path) + + from ConsoleView import Event + self.notify(Event("path_found", {"maze": self._maze, "path": path})) + + return SearchStats(execution_time_ms, visited_count, path_length, path) + \end{lstlisting} + + \subsection{Maze Builder} + + \begin{lstlisting} + + from abc import ABC, abstractmethod + from Maze import Maze, Cell + + class MazeBuilder(ABC): + @abstractmethod + def buildFromFile(self, filename): + pass + + + class TextFileMazeBuilder(MazeBuilder): + def __init__(self): + self._maze = None + + @property + def maze(self): + return self._maze + + def buildFromFile(self, filename: str): + + with open(filename, mode='r', encoding='utf-8') as file: + lines = file.read().splitlines() + + height = len(lines) + width = len(lines[0]) + self._maze = Maze(height, width) + + for y, line in enumerate(lines): + for x, char in enumerate(line): + cell = self._maze.getCell(x, y) + + if char == '#': + cell.isWall = True + elif char == 'S': + cell.isStart = True + self._maze.start = cell + elif char == 'E': + cell.isExit = True + self._maze.exit = cell + self._validate() + return self._maze + + def _validate(self): + if self._maze.start is None: + raise "в лабиринте нет старта" + if self._maze.exit is None: + raise "в лабиринте нет начала" + + + \end{lstlisting} + + \subsection{OBserver} + + \begin{lstlisting} + + + from Observer import Observer, Event + + + class ConsoleView(Observer): + def update(self, event: Event) -> None: + if event.type == "maze_loaded": + print("\n[Система] Лабиринт успешно загружен!") + self.render(event.data.get("maze")) + + elif event.type == "path_found": + print("\n[Система] Алгоритм нашёл решение!") + self.render(event.data.get("maze"), path=event.data.get("path")) + + elif event.type == "move": + print( + f"\n[Игрок] Переместился в точку: ({event.data.get('player_pos').x}, {event.data.get('player_pos').y})") + self.render(event.data.get("maze"), + player_position=event.data.get("player_pos")) + + def render(self, maze, player_position=None, path=None) -> None: + path_set = set(path) if path else set() + + for y in range(maze.height): + row_chars = [] + for x in range(maze.width): + cell = maze.getCell(x, y) + + if player_position and cell == player_position: + row_chars.append("P") + elif cell.isStart: + row_chars.append("S") + elif cell.isExit: + row_chars.append("E") + elif cell in path_set: + row_chars.append(".") + elif cell.isWall: + row_chars.append("#") + else: + row_chars.append(" ") + print("".join(row_chars)) + + \end{lstlisting} + + \section{Результаты} + + Таблицы замеров времени и посещенных клеток: + + \begin{table}[H] + \centering + \caption{Результаты экспериментального сравнения алгоритмов поиска пути} + \label{tab:maze_benchmark} + \begin{tabular}{llccc} + \toprule + \textbf{Лабиринт} & \textbf{Стратегия} & \textbf{Время (мс)} & \textbf{Посещено клеток} & \textbf{Длина пути} \\ + \midrule + \multirow{4}{*}{Маленький (10×10)} + & BFS & 0.0516 & 28 & 15 \\ + & DFS & 0.0275 & 15 & 15 \\ + & A* & 0.0360 & 16 & 15 \\ + & Дейкстра & 0.0722 & 28 & 15 \\ + \midrule + \multirow{4}{*}{Пустой (30×30)} + & BFS & 1.1863 & 870 & 58 \\ + & DFS & 1.5568 & 842 & 842 \\ + & A* & 0.4405 & 113 & 58 \\ + & Дейкстра & 2.8607 & 870 & 58 \\ + \midrule + \multirow{4}{*}{Без выхода (15×15)} + & BFS & 0.2230 & 160 & 0 \\ + & DFS & 0.2959 & 160 & 0 \\ + & A* & 0.9378 & 160 & 0 \\ + & Дейкстра & 0.4148 & 160 & 0 \\ + \midrule + \multirow{4}{*}{Средний (50×50)} + & BFS & 3.2247 & 1779 & 95 \\ + & DFS & 1.6985 & 873 & 873 \\ + & A* & 0.7348 & 158 & 95 \\ + & Дейкстра & 6.1264 & 1779 & 95 \\ + \midrule + \multirow{4}{*}{Большой (100×100)} + & BFS & 10.1308 & 7320 & 195 \\ + & DFS & 6.1878 & 3549 & 3549 \\ + & A* & 2.8441 & 328 & 195 \\ + & Дейкстра & 35.2250 & 7320 & 195 \\ + \bottomrule + \end{tabular} + \end{table} + + + Графики: + + \begin{figure}[H] + \includegraphics[scale=0.6]{time.eps} + \end{figure} + + + \begin{figure}[H] + \includegraphics[scale=0.6]{cells.eps} + \end{figure} + + \section{Анализ эффективности} + + Так как в нашем лабиринте вес всех ребер равны 1, то Дейкстра выродился в Поиск в ширину. Также Дейкстра несколько медленнее из за дополнительных расчетов на сортировку стоимостей. + + Самым лучшим по скорости стал алгоритм А*. Он в среднем 3-4 раза быстрее поиска в ширину, так как на каждом шаге он выбирает самого оптимального соседа для каждого узла, а поиск в ширину проверяет всех соседей. + + В разработанной рекурсивной стратегии DFS метрика посещенных клеток совпадает с длиной пути, так как алгоритм фиксирует состояние успешно развернутого стека вызовов в момент достижения целевой точки. Все тупиковые ветви, из которых рекурсия вышла до момента нахождения exit, отсекаются архитектурой возврата флага True, что демонстрирует специфику работы рекурсивного бэктрекинга в Python + + + \section{Выводы по ООП} + + В ходе выполнения лабораторной работы была спроектирована и реализована объектно-ориентированная система поиска пути в лабиринтах. Применение принципов ООП и паттернов проектирования GoF позволило полностью разделить зоны ответственности классов (принцип Single Responsibility) и обеспечить высокий уровень гибкости и расширяемости приложения. + + 1. Как паттерны помогли сделать код гибким и расширяемым + \begin{itemize} + \item Разделение логики построения и представления (Паттерн Builder): + Процесс создания лабиринта инкапсулирован внутри класса TextFileMazeBuilder. Сам лабиринт (Maze) и алгоритмы поиска никак не завязаны на формат хранения данных. Если в будущем потребуется сменить текстовый формат .txt на структуру .json достаточно будет создать нового строителя, реализующего интерфейс MazeBuilder. + + \item Изоляция и динамическая смена алгоритмов (Паттерн Strategy): + Каждый алгоритм обхода графа вынесен в отдельный класс-стратегию с единым интерфейсом PathfindingStrategy. Класс-оркестратор MazeSolver работает исключительно с абстракцией. + + \item Использование Observer позволило отделить вычислительную составляющую от графической. Maze SOlver никак не учитывает где и как будут отображаться данные, он только отдает сигнал о событиях. Это позволяет если нужно изменить графический инт6ерфейс. + \end{itemize} + + + + +\end{document} \ No newline at end of file diff --git a/ProninVV/task-2-oop/report/plan.png b/ProninVV/task-2-oop/report/plan.png new file mode 100644 index 0000000..09a03f7 Binary files /dev/null and b/ProninVV/task-2-oop/report/plan.png differ diff --git a/ProninVV/task-2-oop/report/preambule.tex b/ProninVV/task-2-oop/report/preambule.tex new file mode 100644 index 0000000..f193c69 --- /dev/null +++ b/ProninVV/task-2-oop/report/preambule.tex @@ -0,0 +1,83 @@ +%\documentclass[a4paper, 12pt]{article} +\documentclass[a4paper, 14pt]{extarticle} + +\usepackage[english, russian]{babel} +\usepackage[T2A]{fontenc} +\usepackage[utf8]{inputenc} +\usepackage{comment} + + +\usepackage{fontspec} +\setmainfont{Times New Roman} + +\usepackage{amsmath} +\usepackage{amssymb} + +\usepackage{geometry} +\usepackage{titleps} +\usepackage{graphicx} +\DeclareGraphicsExtensions{.pdf, .jpg} +\usepackage{wrapfig} + + +\usepackage{indentfirst} + + +\geometry{top=20mm} +\geometry{bottom=25mm} +\geometry{left=30mm} +\geometry{right=10mm} + +\usepackage{float} +\usepackage{wrapfig} + +\newpagestyle{main}{ + \setheadrule{0.4pt} + \sethead{ННГУ им Н.И. Лобачесвкого}{}{В. В. Пронин} + + \setfoot{}{\thepage}{} +} +\pagestyle{main} +%\setcounter{page}{2} + +\linespread{1.5} +\setlength{\parindent}{10mm} +\setlength{\parskip}{1ex} + + +\usepackage{listings} +\usepackage{xcolor} + +% Настройка цветов для аккуратного кода +\definecolor{codegreen}{rgb}{0,0.5,0} +\definecolor{codegray}{rgb}{0.5,0.5,0.5} +\definecolor{codepurple}{rgb}{0.58,0,0.82} +\definecolor{backcolour}{rgb}{0.97,0.97,0.96} + +\lstset{ + backgroundcolor=\color{backcolour}, + commentstyle=\color{codegreen}, + keywordstyle=\color{blue}\bfseries, + numberstyle=\tiny\color{codegray}, + stringstyle=\color{codepurple}, + basicstyle=\ttfamily\small, % Моноширинный аккуратный шрифт + breakatwhitespace=false, + breaklines=true, % Автоперенос длинных строк + captionpos=b, % Подпись снизу + keepspaces=true, + numbers=left, % Нумерация строк слева + numbersep=8pt, + showspaces=false, + showstringspaces=false, + showtabs=false, + tabsize=4, + language=Python, + frame=single, % Тонкая рамка вокруг кода + rulecolor=\color{lightgray} +} + + +\usepackage{booktabs} % Для красивых горизонтальных линий +\usepackage{multirow} % Для объединения строк по вертикали +\usepackage{float} % Для точного позиционирования таблицы [H] + diff --git a/ProninVV/task-2-oop/report/time.eps b/ProninVV/task-2-oop/report/time.eps new file mode 100644 index 0000000..37ed032 --- /dev/null +++ b/ProninVV/task-2-oop/report/time.eps @@ -0,0 +1,1947 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%LanguageLevel: 3 +%%Title: benchmark_execution_time.eps +%%Creator: Matplotlib v3.10.0, https://matplotlib.org/ +%%CreationDate: Wed May 20 20:35:42 2026 +%%Orientation: portrait +%%BoundingBox: 0 0 720 432 +%%HiResBoundingBox: 0.000000 0.000000 720.000000 432.000000 +%%EndComments +%%BeginProlog +/mpldict 9 dict def +mpldict begin +/_d { bind def } bind def +/m { moveto } _d +/l { lineto } _d +/r { rlineto } _d +/c { curveto } _d +/cl { closepath } _d +/ce { closepath eofill } _d +/sc { setcachedevice } _d +%!PS-Adobe-3.0 Resource-Font +%%Creator: Converted from TrueType to Type 3 by Matplotlib. +10 dict begin +/FontName /DejaVuSans def +/PaintType 0 def +/FontMatrix [0.00048828125 0 0 0.00048828125 0 0] def +/FontBBox [-2090 -948 3673 2524] def +/FontType 3 def +/Encoding [/uni0412 /space /uni0421 /uni0433 /parenleft /parenright /asterisk /period /slash /zero /one /two /uni0432 /four /uni0435 /six /uni0430 /eight /uni0438 /uni0431 /uni043B /uni043C /uni043D /uni043E /uni043F /uni0440 /uni0441 /uni0442 /B /D /A /F /uni044B /uni044F /S /underscore /a /d /e /g /i /l /m /n /o /p /r /s /t /u /x /y /z] def +/CharStrings 54 dict dup begin +/.notdef 0 def +/uni0412{1405 0 201 0 1260 1493 sc +403 713 m +403 166 l +727 166 l +836 166 916 188 968 233 c +1021 278 1047 347 1047 440 c +1047 533 1021 602 968 646 c +916 691 836 713 727 713 c +403 713 l + +403 1327 m +403 877 l +702 877 l +801 877 874 895 922 932 c +971 969 995 1026 995 1102 c +995 1177 971 1234 922 1271 c +874 1308 801 1327 702 1327 c +403 1327 l + +201 1493 m +717 1493 l +871 1493 990 1461 1073 1397 c +1156 1333 1198 1242 1198 1124 c +1198 1033 1177 960 1134 906 c +1091 852 1029 818 946 805 c +1045 784 1122 739 1177 671 c +1232 604 1260 519 1260 418 c +1260 285 1215 182 1124 109 c +1033 36 904 0 737 0 c +201 0 l +201 1493 l + +ce} _d +/space{651 0 0 0 0 0 sc +ce} _d +/uni0421{1430 0 115 -29 1319 1520 sc +1319 1378 m +1319 1165 l +1251 1228 1178 1276 1101 1307 c +1024 1338 943 1354 856 1354 c +685 1354 555 1302 464 1197 c +373 1093 328 942 328 745 c +328 548 373 398 464 293 c +555 189 685 137 856 137 c +943 137 1024 153 1101 184 c +1178 215 1251 263 1319 326 c +1319 115 l +1248 67 1173 31 1094 7 c +1015 -17 932 -29 844 -29 c +618 -29 440 40 310 178 c +180 317 115 506 115 745 c +115 985 180 1174 310 1312 c +440 1451 618 1520 844 1520 c +933 1520 1017 1508 1096 1484 c +1175 1461 1250 1425 1319 1378 c + +ce} _d +/uni0433{1076 0 186 0 976 1120 sc +186 0 m +186 1120 l +976 1120 l +976 973 l +371 973 l +371 0 l +186 0 l + +ce} _d +/parenleft{799 0 176 -270 635 1554 sc +635 1554 m +546 1401 479 1249 436 1099 c +393 949 371 797 371 643 c +371 489 393 336 436 185 c +480 34 546 -117 635 -270 c +475 -270 l +375 -113 300 41 250 192 c +201 343 176 494 176 643 c +176 792 201 941 250 1092 c +299 1243 374 1397 475 1554 c +635 1554 l + +ce} _d +/parenright{799 0 164 -270 623 1554 sc +164 1554 m +324 1554 l +424 1397 499 1243 548 1092 c +598 941 623 792 623 643 c +623 494 598 343 548 192 c +499 41 424 -113 324 -270 c +164 -270 l +253 -117 319 34 362 185 c +406 336 428 489 428 643 c +428 797 406 949 362 1099 c +319 1249 253 1401 164 1554 c + +ce} _d +/asterisk{1024 0 61 586 963 1520 sc +963 1247 m +604 1053 l +963 858 l +905 760 l +569 963 l +569 586 l +455 586 l +455 963 l +119 760 l +61 858 l +420 1053 l +61 1247 l +119 1346 l +455 1143 l +455 1520 l +569 1520 l +569 1143 l +905 1346 l +963 1247 l + +ce} _d +/period{651 0 219 0 430 254 sc +219 254 m +430 254 l +430 0 l +219 0 l +219 254 l + +ce} _d +/slash{690 0 0 -190 690 1493 sc +520 1493 m +690 1493 l +170 -190 l +0 -190 l +520 1493 l + +ce} _d +/zero{1303 0 135 -29 1167 1520 sc +651 1360 m +547 1360 469 1309 416 1206 c +364 1104 338 950 338 745 c +338 540 364 387 416 284 c +469 182 547 131 651 131 c +756 131 834 182 886 284 c +939 387 965 540 965 745 c +965 950 939 1104 886 1206 c +834 1309 756 1360 651 1360 c + +651 1520 m +818 1520 946 1454 1034 1321 c +1123 1189 1167 997 1167 745 c +1167 494 1123 302 1034 169 c +946 37 818 -29 651 -29 c +484 -29 356 37 267 169 c +179 302 135 494 135 745 c +135 997 179 1189 267 1321 c +356 1454 484 1520 651 1520 c + +ce} _d +/one{1303 0 225 0 1114 1493 sc +254 170 m +584 170 l +584 1309 l +225 1237 l +225 1421 l +582 1493 l +784 1493 l +784 170 l +1114 170 l +1114 0 l +254 0 l +254 170 l + +ce} _d +/two{1303 0 150 0 1098 1520 sc +393 170 m +1098 170 l +1098 0 l +150 0 l +150 170 l +227 249 331 356 463 489 c +596 623 679 709 713 748 c +778 821 823 882 848 932 c +874 983 887 1032 887 1081 c +887 1160 859 1225 803 1275 c +748 1325 675 1350 586 1350 c +523 1350 456 1339 385 1317 c +315 1295 240 1262 160 1217 c +160 1421 l +241 1454 317 1478 388 1495 c +459 1512 523 1520 582 1520 c +737 1520 860 1481 952 1404 c +1044 1327 1090 1223 1090 1094 c +1090 1033 1078 974 1055 919 c +1032 864 991 800 930 725 c +913 706 860 650 771 557 c +682 465 556 336 393 170 c + +ce} _d +/uni0432{1207 0 186 0 1086 1120 sc +370 516 m +370 147 l +632 147 l +716 147 780 163 824 194 c +868 226 890 272 890 332 c +890 392 868 438 824 469 c +780 500 716 516 632 516 c +370 516 l + +370 973 m +370 663 l +612 663 l +681 663 738 677 782 704 c +826 732 848 771 848 820 c +848 869 826 907 782 933 c +738 960 681 973 612 973 c +370 973 l + +186 1120 m +624 1120 l +755 1120 856 1096 927 1048 c +998 1000 1033 932 1033 843 c +1033 774 1015 720 979 679 c +943 639 890 614 819 604 c +904 588 969 555 1016 504 c +1063 453 1086 390 1086 314 c +1086 214 1047 137 970 82 c +893 27 784 0 641 0 c +186 0 l +186 1120 l + +ce} _d +/four{1303 0 100 0 1188 1493 sc +774 1317 m +264 520 l +774 520 l +774 1317 l + +721 1493 m +975 1493 l +975 520 l +1188 520 l +1188 352 l +975 352 l +975 0 l +774 0 l +774 352 l +100 352 l +100 547 l +721 1493 l + +ce} _d +/uni0435{1260 0 113 -29 1151 1147 sc +1151 606 m +1151 516 l +305 516 l +313 389 351 293 419 226 c +488 160 583 127 705 127 c +776 127 844 136 910 153 c +977 170 1043 196 1108 231 c +1108 57 l +1042 29 974 8 905 -7 c +836 -22 765 -29 694 -29 c +515 -29 374 23 269 127 c +165 231 113 372 113 549 c +113 732 162 878 261 985 c +360 1093 494 1147 662 1147 c +813 1147 932 1098 1019 1001 c +1107 904 1151 773 1151 606 c + +967 660 m +966 761 937 841 882 901 c +827 961 755 991 664 991 c +561 991 479 962 417 904 c +356 846 320 764 311 659 c +967 660 l + +ce} _d +/six{1303 0 143 -29 1174 1520 sc +676 827 m +585 827 513 796 460 734 c +407 672 381 587 381 479 c +381 372 407 287 460 224 c +513 162 585 131 676 131 c +767 131 838 162 891 224 c +944 287 971 372 971 479 c +971 587 944 672 891 734 c +838 796 767 827 676 827 c + +1077 1460 m +1077 1276 l +1026 1300 975 1318 923 1331 c +872 1344 821 1350 770 1350 c +637 1350 535 1305 464 1215 c +394 1125 354 989 344 807 c +383 865 433 909 492 940 c +551 971 617 987 688 987 c +838 987 956 941 1043 850 c +1130 759 1174 636 1174 479 c +1174 326 1129 203 1038 110 c +947 17 827 -29 676 -29 c +503 -29 371 37 280 169 c +189 302 143 494 143 745 c +143 981 199 1169 311 1309 c +423 1450 573 1520 762 1520 c +813 1520 864 1515 915 1505 c +967 1495 1021 1480 1077 1460 c + +ce} _d +/uni0430{1255 0 123 -29 1069 1147 sc +702 563 m +553 563 450 546 393 512 c +336 478 307 420 307 338 c +307 273 328 221 371 182 c +414 144 473 125 547 125 c +649 125 731 161 792 233 c +854 306 885 402 885 522 c +885 563 l +702 563 l + +1069 639 m +1069 0 l +885 0 l +885 170 l +843 102 791 52 728 19 c +665 -13 589 -29 498 -29 c +383 -29 292 3 224 67 c +157 132 123 218 123 326 c +123 452 165 547 249 611 c +334 675 460 707 627 707 c +885 707 l +885 725 l +885 810 857 875 801 921 c +746 968 668 991 567 991 c +503 991 441 983 380 968 c +319 953 261 930 205 899 c +205 1069 l +272 1095 338 1114 401 1127 c +464 1140 526 1147 586 1147 c +748 1147 869 1105 949 1021 c +1029 937 1069 810 1069 639 c + +ce} _d +/eight{1303 0 139 -29 1163 1520 sc +651 709 m +555 709 479 683 424 632 c +369 581 342 510 342 420 c +342 330 369 259 424 208 c +479 157 555 131 651 131 c +747 131 823 157 878 208 c +933 260 961 331 961 420 c +961 510 933 581 878 632 c +823 683 748 709 651 709 c + +449 795 m +362 816 295 857 246 916 c +198 975 174 1048 174 1133 c +174 1252 216 1347 301 1416 c +386 1485 503 1520 651 1520 c +800 1520 916 1485 1001 1416 c +1086 1347 1128 1252 1128 1133 c +1128 1048 1104 975 1055 916 c +1007 857 940 816 854 795 c +951 772 1027 728 1081 662 c +1136 596 1163 515 1163 420 c +1163 275 1119 164 1030 87 c +942 10 816 -29 651 -29 c +486 -29 360 10 271 87 c +183 164 139 275 139 420 c +139 515 166 596 221 662 c +276 728 352 772 449 795 c + +375 1114 m +375 1037 399 976 447 933 c +496 890 564 868 651 868 c +738 868 805 890 854 933 c +903 976 928 1037 928 1114 c +928 1191 903 1252 854 1295 c +805 1338 738 1360 651 1360 c +564 1360 496 1338 447 1295 c +399 1252 375 1191 375 1114 c + +ce} _d +/uni0438{1331 0 186 0 1145 1120 sc +1145 1120 m +1145 0 l +962 0 l +962 899 l +422 0 l +186 0 l +186 1120 l +369 1120 l +369 223 l +908 1120 l +1145 1120 l + +ce} _d +/uni0431{1263 0 112 -29 1151 1591 sc +637 1147 m +797 1147 923 1095 1014 991 c +1105 887 1151 743 1151 559 c +1151 376 1105 232 1014 127 c +923 23 797 -29 637 -29 c +476 -29 352 22 263 123 c +174 224 128 370 123 559 c +117 788 l +114 867 112 921 112 948 c +112 1055 131 1147 170 1226 c +231 1349 313 1438 418 1491 c +523 1544 664 1572 840 1573 c +921 1574 980 1580 1016 1591 c +1067 1445 l +1034 1432 1003 1425 973 1424 c +723 1407 l +639 1401 572 1383 521 1354 c +388 1276 316 1186 303 1084 c +296 1028 l +383 1107 496 1147 637 1147 c + +637 991 m +538 991 460 952 403 875 c +346 798 317 693 317 559 c +317 425 345 319 402 242 c +459 165 538 127 637 127 c +735 127 813 166 870 243 c +927 320 956 426 956 559 c +956 692 927 797 870 874 c +813 952 735 991 637 991 c + +ce} _d +/uni043B{1309 0 76 0 1139 1120 sc +76 0 m +76 153 l +197 172 277 223 314 307 c +359 425 382 635 382 937 c +382 1120 l +1139 1120 l +1139 0 l +955 0 l +955 973 l +566 973 l +566 862 l +566 574 537 365 478 236 c +415 98 281 19 76 0 c + +ce} _d +/uni043C{1545 0 186 0 1359 1120 sc +186 1120 m +455 1120 l +773 370 l +1092 1120 l +1359 1120 l +1359 0 l +1174 0 l +1174 944 l +865 215 l +681 215 l +371 944 l +371 0 l +186 0 l +186 1120 l + +ce} _d +/uni043D{1339 0 186 0 1153 1120 sc +186 1120 m +371 1120 l +371 663 l +968 663 l +968 1120 l +1153 1120 l +1153 0 l +968 0 l +968 516 l +371 516 l +371 0 l +186 0 l +186 1120 l + +ce} _d +/uni043E{1253 0 113 -29 1141 1147 sc +627 991 m +528 991 450 952 393 875 c +336 798 307 693 307 559 c +307 425 335 319 392 242 c +449 165 528 127 627 127 c +725 127 803 166 860 243 c +917 320 946 426 946 559 c +946 692 917 797 860 874 c +803 952 725 991 627 991 c + +627 1147 m +787 1147 913 1095 1004 991 c +1095 887 1141 743 1141 559 c +1141 376 1095 232 1004 127 c +913 23 787 -29 627 -29 c +466 -29 340 23 249 127 c +158 232 113 376 113 559 c +113 743 158 887 249 991 c +340 1095 466 1147 627 1147 c + +ce} _d +/uni043F{1339 0 186 0 1153 1120 sc +1153 1120 m +1153 0 l +968 0 l +968 973 l +371 973 l +371 0 l +186 0 l +186 1120 l +1153 1120 l + +ce} _d +/uni0440{1300 0 186 -426 1188 1147 sc +371 168 m +371 -426 l +186 -426 l +186 1120 l +371 1120 l +371 950 l +410 1017 458 1066 517 1098 c +576 1131 647 1147 729 1147 c +865 1147 975 1093 1060 985 c +1145 877 1188 735 1188 559 c +1188 383 1145 241 1060 133 c +975 25 865 -29 729 -29 c +647 -29 576 -13 517 19 c +458 52 410 101 371 168 c + +997 559 m +997 694 969 800 913 877 c +858 954 781 993 684 993 c +587 993 510 954 454 877 c +399 800 371 694 371 559 c +371 424 399 317 454 240 c +510 163 587 125 684 125 c +781 125 858 163 913 240 c +969 317 997 424 997 559 c + +ce} _d +/uni0441{1126 0 113 -29 999 1147 sc +999 1077 m +999 905 l +947 934 895 955 842 969 c +790 984 737 991 684 991 c +565 991 472 953 406 877 c +340 802 307 696 307 559 c +307 422 340 316 406 240 c +472 165 565 127 684 127 c +737 127 790 134 842 148 c +895 163 947 184 999 213 c +999 43 l +948 19 894 1 839 -11 c +784 -23 726 -29 664 -29 c +495 -29 361 24 262 130 c +163 236 113 379 113 559 c +113 742 163 885 263 990 c +364 1095 501 1147 676 1147 c +733 1147 788 1141 842 1129 c +896 1118 948 1100 999 1077 c + +ce} _d +/uni0442{1193 0 60 0 1133 1120 sc +60 1120 m +1133 1120 l +1133 973 l +687 973 l +687 0 l +506 0 l +506 973 l +60 973 l +60 1120 l + +ce} _d +/B{1405 0 201 0 1260 1493 sc +403 713 m +403 166 l +727 166 l +836 166 916 188 968 233 c +1021 278 1047 347 1047 440 c +1047 533 1021 602 968 646 c +916 691 836 713 727 713 c +403 713 l + +403 1327 m +403 877 l +702 877 l +801 877 874 895 922 932 c +971 969 995 1026 995 1102 c +995 1177 971 1234 922 1271 c +874 1308 801 1327 702 1327 c +403 1327 l + +201 1493 m +717 1493 l +871 1493 990 1461 1073 1397 c +1156 1333 1198 1242 1198 1124 c +1198 1033 1177 960 1134 906 c +1091 852 1029 818 946 805 c +1045 784 1122 739 1177 671 c +1232 604 1260 519 1260 418 c +1260 285 1215 182 1124 109 c +1033 36 904 0 737 0 c +201 0 l +201 1493 l + +ce} _d +/D{1577 0 201 0 1456 1493 sc +403 1327 m +403 166 l +647 166 l +853 166 1004 213 1099 306 c +1195 399 1243 547 1243 748 c +1243 948 1195 1094 1099 1187 c +1004 1280 853 1327 647 1327 c +403 1327 l + +201 1493 m +616 1493 l +905 1493 1118 1433 1253 1312 c +1388 1192 1456 1004 1456 748 c +1456 491 1388 302 1252 181 c +1116 60 904 0 616 0 c +201 0 l +201 1493 l + +ce} _d +/A{1401 0 16 0 1384 1493 sc +700 1294 m +426 551 l +975 551 l +700 1294 l + +586 1493 m +815 1493 l +1384 0 l +1174 0 l +1038 383 l +365 383 l +229 0 l +16 0 l +586 1493 l + +ce} _d +/F{1178 0 201 0 1059 1493 sc +201 1493 m +1059 1493 l +1059 1323 l +403 1323 l +403 883 l +995 883 l +995 713 l +403 713 l +403 0 l +201 0 l +201 1493 l + +ce} _d +/uni044B{1617 0 186 0 1435 1147 sc +1251 1120 m +1435 1120 l +1435 0 l +1251 0 l +1251 1120 l + +1343 1147 m +1343 1147 l + +890 332 m +890 392 868 438 824 469 c +781 500 717 516 633 516 c +371 516 l +371 147 l +633 147 l +717 147 781 163 824 194 c +868 226 890 272 890 332 c + +186 1120 m +371 1120 l +371 663 l +641 663 l +784 663 893 636 970 581 c +1047 527 1086 444 1086 332 c +1086 220 1047 137 970 82 c +893 27 784 0 641 0 c +186 0 l +186 1120 l + +ce} _d +/uni044F{1232 0 116 0 1058 1120 sc +378 797 m +378 742 399 698 442 667 c +485 636 546 620 625 620 c +873 620 l +873 973 l +625 973 l +546 973 485 958 442 927 c +399 896 378 853 378 797 c + +116 0 m +458 491 l +381 508 316 540 265 585 c +214 631 188 702 188 797 c +188 905 224 986 295 1039 c +367 1093 475 1120 620 1120 c +1058 1120 l +1058 0 l +873 0 l +873 473 l +644 473 l +314 0 l +116 0 l + +ce} _d +/S{1300 0 135 -29 1186 1520 sc +1096 1444 m +1096 1247 l +1019 1284 947 1311 879 1329 c +811 1347 745 1356 682 1356 c +572 1356 487 1335 427 1292 c +368 1249 338 1189 338 1110 c +338 1044 358 994 397 960 c +437 927 512 900 623 879 c +745 854 l +896 825 1007 775 1078 702 c +1150 630 1186 533 1186 412 c +1186 267 1137 158 1040 83 c +943 8 801 -29 614 -29 c +543 -29 468 -21 388 -5 c +309 11 226 35 141 66 c +141 274 l +223 228 303 193 382 170 c +461 147 538 135 614 135 c +729 135 818 158 881 203 c +944 248 975 313 975 397 c +975 470 952 528 907 569 c +862 610 789 641 686 662 c +563 686 l +412 716 303 763 236 827 c +169 891 135 980 135 1094 c +135 1226 181 1330 274 1406 c +367 1482 496 1520 659 1520 c +729 1520 800 1514 873 1501 c +946 1488 1020 1469 1096 1444 c + +ce} _d +/underscore{1024 0 -20 -483 1044 -340 sc +1044 -340 m +1044 -483 l +-20 -483 l +-20 -340 l +1044 -340 l + +ce} _d +/a{1255 0 123 -29 1069 1147 sc +702 563 m +553 563 450 546 393 512 c +336 478 307 420 307 338 c +307 273 328 221 371 182 c +414 144 473 125 547 125 c +649 125 731 161 792 233 c +854 306 885 402 885 522 c +885 563 l +702 563 l + +1069 639 m +1069 0 l +885 0 l +885 170 l +843 102 791 52 728 19 c +665 -13 589 -29 498 -29 c +383 -29 292 3 224 67 c +157 132 123 218 123 326 c +123 452 165 547 249 611 c +334 675 460 707 627 707 c +885 707 l +885 725 l +885 810 857 875 801 921 c +746 968 668 991 567 991 c +503 991 441 983 380 968 c +319 953 261 930 205 899 c +205 1069 l +272 1095 338 1114 401 1127 c +464 1140 526 1147 586 1147 c +748 1147 869 1105 949 1021 c +1029 937 1069 810 1069 639 c + +ce} _d +/d{1300 0 113 -29 1114 1556 sc +930 950 m +930 1556 l +1114 1556 l +1114 0 l +930 0 l +930 168 l +891 101 842 52 783 19 c +724 -13 654 -29 571 -29 c +436 -29 325 25 240 133 c +155 241 113 383 113 559 c +113 735 155 877 240 985 c +325 1093 436 1147 571 1147 c +654 1147 724 1131 783 1098 c +842 1066 891 1017 930 950 c + +303 559 m +303 424 331 317 386 240 c +442 163 519 125 616 125 c +713 125 790 163 846 240 c +902 317 930 424 930 559 c +930 694 902 800 846 877 c +790 954 713 993 616 993 c +519 993 442 954 386 877 c +331 800 303 694 303 559 c + +ce} _d +/e{1260 0 113 -29 1151 1147 sc +1151 606 m +1151 516 l +305 516 l +313 389 351 293 419 226 c +488 160 583 127 705 127 c +776 127 844 136 910 153 c +977 170 1043 196 1108 231 c +1108 57 l +1042 29 974 8 905 -7 c +836 -22 765 -29 694 -29 c +515 -29 374 23 269 127 c +165 231 113 372 113 549 c +113 732 162 878 261 985 c +360 1093 494 1147 662 1147 c +813 1147 932 1098 1019 1001 c +1107 904 1151 773 1151 606 c + +967 660 m +966 761 937 841 882 901 c +827 961 755 991 664 991 c +561 991 479 962 417 904 c +356 846 320 764 311 659 c +967 660 l + +ce} _d +/g{1300 0 113 -426 1114 1147 sc +930 573 m +930 706 902 810 847 883 c +792 956 715 993 616 993 c +517 993 440 956 385 883 c +330 810 303 706 303 573 c +303 440 330 337 385 264 c +440 191 517 154 616 154 c +715 154 792 191 847 264 c +902 337 930 440 930 573 c + +1114 139 m +1114 -52 1072 -193 987 -286 c +902 -379 773 -426 598 -426 c +533 -426 472 -421 415 -411 c +358 -402 302 -387 248 -367 c +248 -188 l +302 -217 355 -239 408 -253 c +461 -267 514 -274 569 -274 c +690 -274 780 -242 840 -179 c +900 -116 930 -21 930 106 c +930 197 l +892 131 843 82 784 49 c +725 16 654 0 571 0 c +434 0 323 52 239 157 c +155 262 113 400 113 573 c +113 746 155 885 239 990 c +323 1095 434 1147 571 1147 c +654 1147 725 1131 784 1098 c +843 1065 892 1016 930 950 c +930 1120 l +1114 1120 l +1114 139 l + +ce} _d +/i{569 0 193 0 377 1556 sc +193 1120 m +377 1120 l +377 0 l +193 0 l +193 1120 l + +193 1556 m +377 1556 l +377 1323 l +193 1323 l +193 1556 l + +ce} _d +/l{569 0 193 0 377 1556 sc +193 1556 m +377 1556 l +377 0 l +193 0 l +193 1556 l + +ce} _d +/m{1995 0 186 0 1821 1147 sc +1065 905 m +1111 988 1166 1049 1230 1088 c +1294 1127 1369 1147 1456 1147 c +1573 1147 1663 1106 1726 1024 c +1789 943 1821 827 1821 676 c +1821 0 l +1636 0 l +1636 670 l +1636 777 1617 857 1579 909 c +1541 961 1483 987 1405 987 c +1310 987 1234 955 1179 892 c +1124 829 1096 742 1096 633 c +1096 0 l +911 0 l +911 670 l +911 778 892 858 854 909 c +816 961 757 987 678 987 c +584 987 509 955 454 891 c +399 828 371 742 371 633 c +371 0 l +186 0 l +186 1120 l +371 1120 l +371 946 l +413 1015 463 1065 522 1098 c +581 1131 650 1147 731 1147 c +812 1147 881 1126 938 1085 c +995 1044 1038 984 1065 905 c + +ce} _d +/n{1298 0 186 0 1124 1147 sc +1124 676 m +1124 0 l +940 0 l +940 670 l +940 776 919 855 878 908 c +837 961 775 987 692 987 c +593 987 514 955 457 892 c +400 829 371 742 371 633 c +371 0 l +186 0 l +186 1120 l +371 1120 l +371 946 l +415 1013 467 1064 526 1097 c +586 1130 655 1147 733 1147 c +862 1147 959 1107 1025 1027 c +1091 948 1124 831 1124 676 c + +ce} _d +/o{1253 0 113 -29 1141 1147 sc +627 991 m +528 991 450 952 393 875 c +336 798 307 693 307 559 c +307 425 335 319 392 242 c +449 165 528 127 627 127 c +725 127 803 166 860 243 c +917 320 946 426 946 559 c +946 692 917 797 860 874 c +803 952 725 991 627 991 c + +627 1147 m +787 1147 913 1095 1004 991 c +1095 887 1141 743 1141 559 c +1141 376 1095 232 1004 127 c +913 23 787 -29 627 -29 c +466 -29 340 23 249 127 c +158 232 113 376 113 559 c +113 743 158 887 249 991 c +340 1095 466 1147 627 1147 c + +ce} _d +/p{1300 0 186 -426 1188 1147 sc +371 168 m +371 -426 l +186 -426 l +186 1120 l +371 1120 l +371 950 l +410 1017 458 1066 517 1098 c +576 1131 647 1147 729 1147 c +865 1147 975 1093 1060 985 c +1145 877 1188 735 1188 559 c +1188 383 1145 241 1060 133 c +975 25 865 -29 729 -29 c +647 -29 576 -13 517 19 c +458 52 410 101 371 168 c + +997 559 m +997 694 969 800 913 877 c +858 954 781 993 684 993 c +587 993 510 954 454 877 c +399 800 371 694 371 559 c +371 424 399 317 454 240 c +510 163 587 125 684 125 c +781 125 858 163 913 240 c +969 317 997 424 997 559 c + +ce} _d +/r{842 0 186 0 842 1147 sc +842 948 m +821 960 799 969 774 974 c +750 980 723 983 694 983 c +590 983 510 949 454 881 c +399 814 371 717 371 590 c +371 0 l +186 0 l +186 1120 l +371 1120 l +371 946 l +410 1014 460 1064 522 1097 c +584 1130 659 1147 748 1147 c +761 1147 775 1146 790 1144 c +805 1143 822 1140 841 1137 c +842 948 l + +ce} _d +/s{1067 0 111 -29 967 1147 sc +907 1087 m +907 913 l +855 940 801 960 745 973 c +689 986 631 993 571 993 c +480 993 411 979 365 951 c +320 923 297 881 297 825 c +297 782 313 749 346 724 c +379 700 444 677 543 655 c +606 641 l +737 613 829 573 884 522 c +939 471 967 400 967 309 c +967 205 926 123 843 62 c +761 1 648 -29 504 -29 c +444 -29 381 -23 316 -11 c +251 0 183 18 111 41 c +111 231 l +179 196 246 169 312 151 c +378 134 443 125 508 125 c +595 125 661 140 708 169 c +755 199 778 241 778 295 c +778 345 761 383 727 410 c +694 437 620 462 506 487 c +442 502 l +328 526 246 563 195 612 c +144 662 119 730 119 817 c +119 922 156 1004 231 1061 c +306 1118 412 1147 549 1147 c +617 1147 681 1142 741 1132 c +801 1122 856 1107 907 1087 c + +ce} _d +/t{803 0 55 0 754 1438 sc +375 1438 m +375 1120 l +754 1120 l +754 977 l +375 977 l +375 369 l +375 278 387 219 412 193 c +437 167 488 154 565 154 c +754 154 l +754 0 l +565 0 l +423 0 325 26 271 79 c +217 132 190 229 190 369 c +190 977 l +55 977 l +55 1120 l +190 1120 l +190 1438 l +375 1438 l + +ce} _d +/u{1298 0 174 -29 1112 1147 sc +174 442 m +174 1120 l +358 1120 l +358 449 l +358 343 379 263 420 210 c +461 157 523 131 606 131 c +705 131 784 163 841 226 c +899 289 928 376 928 485 c +928 1120 l +1112 1120 l +1112 0 l +928 0 l +928 172 l +883 104 831 53 772 20 c +713 -13 645 -29 567 -29 c +438 -29 341 11 274 91 c +207 171 174 288 174 442 c + +637 1147 m +637 1147 l + +ce} _d +/x{1212 0 59 0 1145 1120 sc +1124 1120 m +719 575 l +1145 0 l +928 0 l +602 440 l +276 0 l +59 0 l +494 586 l +96 1120 l +313 1120 l +610 721 l +907 1120 l +1124 1120 l + +ce} _d +/y{1212 0 61 -426 1151 1120 sc +659 -104 m +607 -237 556 -324 507 -365 c +458 -406 392 -426 309 -426 c +162 -426 l +162 -272 l +270 -272 l +321 -272 360 -260 388 -236 c +416 -212 447 -155 481 -66 c +514 18 l +61 1120 l +256 1120 l +606 244 l +956 1120 l +1151 1120 l +659 -104 l + +ce} _d +/z{1075 0 88 0 987 1120 sc +113 1120 m +987 1120 l +987 952 l +295 147 l +987 147 l +987 0 l +88 0 l +88 168 l +780 973 l +113 973 l +113 1120 l + +ce} _d +end readonly def + +/BuildGlyph { + exch begin + CharStrings exch + 2 copy known not {pop /.notdef} if + true 3 1 roll get exec + end +} _d + +/BuildChar { + 1 index /Encoding get exch get + 1 index /BuildGlyph get exec +} _d + +FontName currentdict end definefont pop +end +%%EndProlog +mpldict begin +0 0 translate +0 0 720 432 rectclip +gsave +0 0 m +720 0 l +720 432 l +0 432 l +cl +1 setgray +fill +grestore +gsave +44.57 60.315413 m +709.2 60.315413 l +709.2 404.95125 l +44.57 404.95125 l +cl +1 setgray +fill +grestore +gsave +44.57 60.315 664.63 344.636 rectclip +74.780455 60.315413 m +106.580933 60.315413 l +106.580933 100.669994 l +74.780455 100.669994 l +cl +0.122 0.467 0.706 setrgbcolor +fill +grestore +gsave +44.57 60.315 664.63 344.636 rectclip +201.982368 60.315413 m +233.782847 60.315413 l +233.782847 388.54002 l +201.982368 388.54002 l +cl +0.122 0.467 0.706 setrgbcolor +fill +grestore +gsave +44.57 60.315 664.63 344.636 rectclip +329.184282 60.315413 m +360.984761 60.315413 l +360.984761 138.259275 l +329.184282 138.259275 l +cl +0.122 0.467 0.706 setrgbcolor +fill +grestore +gsave +44.57 60.315 664.63 344.636 rectclip +456.386196 60.315413 m +488.186675 60.315413 l +488.186675 67.55447 l +456.386196 67.55447 l +cl +0.122 0.467 0.706 setrgbcolor +fill +grestore +gsave +44.57 60.315 664.63 344.636 rectclip +583.58811 60.315413 m +615.388589 60.315413 l +615.388589 61.936339 l +583.58811 61.936339 l +cl +0.122 0.467 0.706 setrgbcolor +fill +grestore +gsave +44.57 60.315 664.63 344.636 rectclip +106.580933 60.315413 m +138.381411 60.315413 l +138.381411 110.369617 l +106.580933 110.369617 l +cl +1 0.498 0.055 setrgbcolor +fill +grestore +gsave +44.57 60.315 664.63 344.636 rectclip +233.782847 60.315413 m +265.583325 60.315413 l +265.583325 260.156174 l +233.782847 260.156174 l +cl +1 0.498 0.055 setrgbcolor +fill +grestore +gsave +44.57 60.315 664.63 344.636 rectclip +360.984761 60.315413 m +392.785239 60.315413 l +392.785239 108.978862 l +360.984761 108.978862 l +cl +1 0.498 0.055 setrgbcolor +fill +grestore +gsave +44.57 60.315 664.63 344.636 rectclip +488.186675 60.315413 m +519.987153 60.315413 l +519.987153 69.159187 l +488.186675 69.159187 l +cl +1 0.498 0.055 setrgbcolor +fill +grestore +gsave +44.57 60.315 664.63 344.636 rectclip +615.388589 60.315413 m +647.189067 60.315413 l +647.189067 62.425859 l +615.388589 62.425859 l +cl +1 0.498 0.055 setrgbcolor +fill +grestore +gsave +44.57 60.315 664.63 344.636 rectclip +138.381411 60.315413 m +170.18189 60.315413 l +170.18189 75.607232 l +138.381411 75.607232 l +cl +0.173 0.627 0.173 setrgbcolor +fill +grestore +gsave +44.57 60.315 664.63 344.636 rectclip +265.583325 60.315413 m +297.383804 60.315413 l +297.383804 151.852363 l +265.583325 151.852363 l +cl +0.173 0.627 0.173 setrgbcolor +fill +grestore +gsave +44.57 60.315 664.63 344.636 rectclip +392.785239 60.315413 m +424.585718 60.315413 l +424.585718 84.282429 l +392.785239 84.282429 l +cl +0.173 0.627 0.173 setrgbcolor +fill +grestore +gsave +44.57 60.315 664.63 344.636 rectclip +519.987153 60.315413 m +551.787632 60.315413 l +551.787632 90.351177 l +519.987153 90.351177 l +cl +0.173 0.627 0.173 setrgbcolor +fill +grestore +gsave +44.57 60.315 664.63 344.636 rectclip +647.189067 60.315413 m +678.989545 60.315413 l +678.989545 61.508415 l +647.189067 61.508415 l +cl +0.173 0.627 0.173 setrgbcolor +fill +grestore +0.8 setlinewidth +1 setlinejoin +0 setlinecap +[] 0 setdash +0 setgray +gsave +/o { +gsave +newpath +translate +0.8 setlinewidth +1 setlinejoin + +0 setlinecap + +0 0 m +0 -3.5 l + +gsave +0 setgray +fill +grestore +stroke +grestore +} bind def +122.481 60.3154 o +grestore +/DejaVuSans 10.000 selectfont +gsave + +67.1815 16.2736 translate +15 rotate +0 0 m /m glyphshow +9.74121 0 m /a glyphshow +15.8691 0 m /z glyphshow +21.1182 0 m /e glyphshow +27.2705 0 m /s glyphshow +32.4805 0 m /slash glyphshow +35.8496 0 m /m glyphshow +45.5908 0 m /a glyphshow +51.7188 0 m /z glyphshow +56.9678 0 m /e glyphshow +63.1201 0 m /underscore glyphshow +68.1201 0 m /e glyphshow +74.2725 0 m /m glyphshow +84.0137 0 m /p glyphshow +90.3613 0 m /t glyphshow +94.2822 0 m /y glyphshow +98.8252 0 m /period glyphshow +102.004 0 m /t glyphshow +105.925 0 m /x glyphshow +111.843 0 m /t glyphshow +grestore +gsave +/o { +gsave +newpath +translate +0.8 setlinewidth +1 setlinejoin + +0 setlinecap + +0 0 m +0 -3.5 l + +gsave +0 setgray +fill +grestore +stroke +grestore +} bind def +249.683 60.3154 o +grestore +/DejaVuSans 10.000 selectfont +gsave + +196.993 17.3809 translate +15 rotate +0 0 m /m glyphshow +9.74121 0 m /a glyphshow +15.8691 0 m /z glyphshow +21.1182 0 m /e glyphshow +27.2705 0 m /s glyphshow +32.4805 0 m /slash glyphshow +35.8496 0 m /m glyphshow +45.5908 0 m /a glyphshow +51.7188 0 m /z glyphshow +56.9678 0 m /e glyphshow +63.1201 0 m /underscore glyphshow +68.1201 0 m /l glyphshow +70.8984 0 m /a glyphshow +77.0264 0 m /r glyphshow +81.0127 0 m /g glyphshow +87.3604 0 m /e glyphshow +93.5127 0 m /period glyphshow +96.6914 0 m /t glyphshow +100.612 0 m /x glyphshow +106.53 0 m /t glyphshow +grestore +gsave +/o { +gsave +newpath +translate +0.8 setlinewidth +1 setlinejoin + +0 setlinecap + +0 0 m +0 -3.5 l + +gsave +0 setgray +fill +grestore +stroke +grestore +} bind def +376.885 60.3154 o +grestore +/DejaVuSans 10.000 selectfont +gsave + +316.596 13.3086 translate +15 rotate +0 0 m /m glyphshow +9.74121 0 m /a glyphshow +15.8691 0 m /z glyphshow +21.1182 0 m /e glyphshow +27.2705 0 m /s glyphshow +32.4805 0 m /slash glyphshow +35.8496 0 m /m glyphshow +45.5908 0 m /a glyphshow +51.7188 0 m /z glyphshow +56.9678 0 m /e glyphshow +63.1201 0 m /underscore glyphshow +68.1201 0 m /m glyphshow +77.8613 0 m /e glyphshow +84.0137 0 m /d glyphshow +90.3613 0 m /i glyphshow +93.1396 0 m /u glyphshow +99.4775 0 m /m glyphshow +109.219 0 m /period glyphshow +112.397 0 m /t glyphshow +116.318 0 m /x glyphshow +122.236 0 m /t glyphshow +grestore +gsave +/o { +gsave +newpath +translate +0.8 setlinewidth +1 setlinejoin + +0 setlinecap + +0 0 m +0 -3.5 l + +gsave +0 setgray +fill +grestore +stroke +grestore +} bind def +504.087 60.3154 o +grestore +/DejaVuSans 10.000 selectfont +gsave + +446.213 14.6026 translate +15 rotate +0 0 m /m glyphshow +9.74121 0 m /a glyphshow +15.8691 0 m /z glyphshow +21.1182 0 m /e glyphshow +27.2705 0 m /s glyphshow +32.4805 0 m /slash glyphshow +35.8496 0 m /m glyphshow +45.5908 0 m /a glyphshow +51.7188 0 m /z glyphshow +56.9678 0 m /e glyphshow +63.1201 0 m /underscore glyphshow +68.1201 0 m /n glyphshow +74.458 0 m /o glyphshow +80.5762 0 m /underscore glyphshow +85.5762 0 m /e glyphshow +91.6035 0 m /x glyphshow +97.5215 0 m /i glyphshow +100.3 0 m /t glyphshow +104.221 0 m /period glyphshow +107.399 0 m /t glyphshow +111.32 0 m /x glyphshow +117.238 0 m /t glyphshow +grestore +gsave +/o { +gsave +newpath +translate +0.8 setlinewidth +1 setlinejoin + +0 setlinecap + +0 0 m +0 -3.5 l + +gsave +0 setgray +fill +grestore +stroke +grestore +} bind def +631.289 60.3154 o +grestore +/DejaVuSans 10.000 selectfont +gsave + +577.988 17.0533 translate +15 rotate +0 0 m /m glyphshow +9.74121 0 m /a glyphshow +15.8691 0 m /z glyphshow +21.1182 0 m /e glyphshow +27.2705 0 m /s glyphshow +32.4805 0 m /slash glyphshow +35.8496 0 m /m glyphshow +45.5908 0 m /a glyphshow +51.7188 0 m /z glyphshow +56.9678 0 m /e glyphshow +63.1201 0 m /underscore glyphshow +68.1201 0 m /s glyphshow +73.3301 0 m /m glyphshow +83.0713 0 m /a glyphshow +89.1992 0 m /l glyphshow +91.9775 0 m /l glyphshow +94.7559 0 m /period glyphshow +97.9346 0 m /t glyphshow +101.855 0 m /x glyphshow +107.773 0 m /t glyphshow +grestore +gsave +/o { +gsave +newpath +translate +0.8 setlinewidth +1 setlinejoin + +0 setlinecap + +-0 0 m +-3.5 0 l + +gsave +0 setgray +fill +grestore +stroke +grestore +} bind def +44.57 60.3154 o +grestore +/DejaVuSans 10.000 selectfont +gsave + +31.2106 56.5185 translate +0 rotate +0 0 m /zero glyphshow +grestore +gsave +/o { +gsave +newpath +translate +0.8 setlinewidth +1 setlinejoin + +0 setlinecap + +-0 0 m +-3.5 0 l + +gsave +0 setgray +fill +grestore +stroke +grestore +} bind def +44.57 125.152 o +grestore +/DejaVuSans 10.000 selectfont +gsave + +31.2106 121.356 translate +0 rotate +0 0 m /two glyphshow +grestore +gsave +/o { +gsave +newpath +translate +0.8 setlinewidth +1 setlinejoin + +0 setlinecap + +-0 0 m +-3.5 0 l + +gsave +0 setgray +fill +grestore +stroke +grestore +} bind def +44.57 189.99 o +grestore +/DejaVuSans 10.000 selectfont +gsave + +31.2106 186.193 translate +0 rotate +0 0 m /four glyphshow +grestore +gsave +/o { +gsave +newpath +translate +0.8 setlinewidth +1 setlinejoin + +0 setlinecap + +-0 0 m +-3.5 0 l + +gsave +0 setgray +fill +grestore +stroke +grestore +} bind def +44.57 254.827 o +grestore +/DejaVuSans 10.000 selectfont +gsave + +31.2106 251.03 translate +0 rotate +0 0 m /six glyphshow +grestore +gsave +/o { +gsave +newpath +translate +0.8 setlinewidth +1 setlinejoin + +0 setlinecap + +-0 0 m +-3.5 0 l + +gsave +0 setgray +fill +grestore +stroke +grestore +} bind def +44.57 319.664 o +grestore +/DejaVuSans 10.000 selectfont +gsave + +31.2106 315.867 translate +0 rotate +0 0 m /eight glyphshow +grestore +gsave +/o { +gsave +newpath +translate +0.8 setlinewidth +1 setlinejoin + +0 setlinecap + +-0 0 m +-3.5 0 l + +gsave +0 setgray +fill +grestore +stroke +grestore +} bind def +44.57 384.501 o +grestore +/DejaVuSans 10.000 selectfont +gsave + +24.8513 380.704 translate +0 rotate +0 0 m /one glyphshow +6.3623 0 m /zero glyphshow +grestore +/DejaVuSans 10.000 selectfont +gsave + +18.7731 170.251 translate +90 rotate +0 0 m /uni0412 glyphshow +6.86035 0 m /uni0440 glyphshow +13.208 0 m /uni0435 glyphshow +19.3604 0 m /uni043C glyphshow +26.9043 0 m /uni044F glyphshow +32.9199 0 m /space glyphshow +36.0986 0 m /uni0432 glyphshow +41.9922 0 m /uni044B glyphshow +49.8877 0 m /uni043F glyphshow +56.4258 0 m /uni043E glyphshow +62.5439 0 m /uni043B glyphshow +68.9355 0 m /uni043D glyphshow +75.4736 0 m /uni0435 glyphshow +81.626 0 m /uni043D glyphshow +88.1641 0 m /uni0438 glyphshow +94.6631 0 m /uni044F glyphshow +100.679 0 m /space glyphshow +103.857 0 m /parenleft glyphshow +107.759 0 m /uni043C glyphshow +115.303 0 m /uni0441 glyphshow +120.801 0 m /parenright glyphshow +grestore +0 setlinejoin +2 setlinecap +gsave +44.57 60.315413 m +44.57 404.95125 l +stroke +grestore +gsave +709.2 60.315413 m +709.2 404.95125 l +stroke +grestore +gsave +44.57 60.315413 m +709.2 60.315413 l +stroke +grestore +gsave +44.57 404.95125 m +709.2 404.95125 l +stroke +grestore +/DejaVuSans 12.000 selectfont +gsave + +249.354 410.951 translate +0 rotate +0 0 m /uni0421 glyphshow +8.37891 0 m /uni0440 glyphshow +15.9961 0 m /uni0430 glyphshow +23.3496 0 m /uni0432 glyphshow +30.4219 0 m /uni043D glyphshow +38.2676 0 m /uni0435 glyphshow +45.6504 0 m /uni043D glyphshow +53.4961 0 m /uni0438 glyphshow +61.2949 0 m /uni0435 glyphshow +68.6777 0 m /space glyphshow +72.4922 0 m /uni0432 glyphshow +79.5645 0 m /uni0440 glyphshow +87.1816 0 m /uni0435 glyphshow +94.5645 0 m /uni043C glyphshow +103.617 0 m /uni0435 glyphshow +111 0 m /uni043D glyphshow +118.846 0 m /uni0438 glyphshow +126.645 0 m /space glyphshow +130.459 0 m /uni0440 glyphshow +138.076 0 m /uni0430 glyphshow +145.43 0 m /uni0431 glyphshow +152.83 0 m /uni043E glyphshow +160.172 0 m /uni0442 glyphshow +167.162 0 m /uni044B glyphshow +176.637 0 m /space glyphshow +180.451 0 m /uni0430 glyphshow +187.805 0 m /uni043B glyphshow +195.475 0 m /uni0433 glyphshow +201.779 0 m /uni043E glyphshow +209.121 0 m /uni0440 glyphshow +216.738 0 m /uni0438 glyphshow +224.537 0 m /uni0442 glyphshow +231.527 0 m /uni043C glyphshow +240.58 0 m /uni043E glyphshow +247.922 0 m /uni0432 glyphshow +grestore +1 setlinewidth +0 setlinecap +0.8 setgray +gsave +650.528125 352.935625 m +702.2 352.935625 l +703.533333 352.935625 704.2 353.602292 704.2 354.935625 c +704.2 397.95125 l +704.2 399.284583 703.533333 399.95125 702.2 399.95125 c +650.528125 399.95125 l +649.194792 399.95125 648.528125 399.284583 648.528125 397.95125 c +648.528125 354.935625 l +648.528125 353.602292 649.194792 352.935625 650.528125 352.935625 c +cl +gsave +1 setgray +fill +grestore +stroke +grestore +gsave +652.528125 388.3575 m +672.528125 388.3575 l +672.528125 395.3575 l +652.528125 395.3575 l +cl +0.122 0.467 0.706 setrgbcolor +fill +grestore +0 setgray +/DejaVuSans 10.000 selectfont +gsave + +680.528 388.358 translate +0 rotate +0 0 m /B glyphshow +6.86035 0 m /F glyphshow +12.4873 0 m /S glyphshow +grestore +gsave +652.528125 373.685625 m +672.528125 373.685625 l +672.528125 380.685625 l +652.528125 380.685625 l +cl +1 0.498 0.055 setrgbcolor +fill +grestore +/DejaVuSans 10.000 selectfont +gsave + +680.528 373.686 translate +0 rotate +0 0 m /D glyphshow +7.7002 0 m /F glyphshow +13.3271 0 m /S glyphshow +grestore +gsave +652.528125 359.01375 m +672.528125 359.01375 l +672.528125 366.01375 l +652.528125 366.01375 l +cl +0.173 0.627 0.173 setrgbcolor +fill +grestore +/DejaVuSans 10.000 selectfont +gsave + +680.528 359.014 translate +0 rotate +0 0 m /A glyphshow +6.84082 0 m /asterisk glyphshow +grestore + +end +showpage diff --git a/ProninVV/task-2-oop/strategy.py b/ProninVV/task-2-oop/strategy.py new file mode 100644 index 0000000..ffb6613 --- /dev/null +++ b/ProninVV/task-2-oop/strategy.py @@ -0,0 +1,12 @@ +from abc import ABC, abstractmethod +from typing import List +from Maze import Maze, Cell + +# интерфейс стратегий + + +class PathFindingStrategy(ABC): + @abstractmethod + def findPath(maze: Maze, start, exit) -> List[Cell]: + """ возвращает список клеток пути (от старта до выхода включительно) или пустой список, если пути нет """ + pass diff --git a/ProninVV/task-2-oop/test.py b/ProninVV/task-2-oop/test.py new file mode 100644 index 0000000..44bfb69 --- /dev/null +++ b/ProninVV/task-2-oop/test.py @@ -0,0 +1,134 @@ +import csv +import time +import os +import matplotlib.pyplot as plt +import numpy as np + +from MazeBuilder import TextFileMazeBuilder +from MazeSolver import MazeSolver, SearchStats +from DepthFirstSearch import DFSStrategy +from BreadthFirstSearch import BFSStrategy +from Deikstra import DeikstraFind +from AStarStrategy import AStarStrategy +from ConsoleView import ConsoleView + + +def run_benchmarks(): + + files = ["mazes/maze_small.txt", "mazes/maze_empty.txt", + "mazes/maze_no_exit.txt", "mazes/maze_medium.txt", "mazes/maze_large.txt"] + strategies = { + "BFS": BFSStrategy(), + "DFS": DFSStrategy(), + "A*": AStarStrategy(), + "Deikstra": DeikstraFind() + } + + view = ConsoleView() + + NUM_RUNS = 5 + results = [] + + print("Запуск экспериментов...") + + for file in files: + if not os.path.exists(file): + print(f"Файл {file} не найден. Пропуск.") + continue + + for name, strategy in strategies.items(): + total_time = 0.0 + visited_counts = [] + path_lengths = [] + + print(f" работает {name}") + for _ in range(NUM_RUNS): + # Пересоздаем лабиринт + builder = TextFileMazeBuilder() + builder.buildFromFile(file) + maze = builder.maze + + solver = MazeSolver(maze, strategy) + + solver.addObserver(view) + + stats = solver.solve() + + total_time += stats.execution_time + visited_counts.append(stats.visited_count) + path_lengths.append(stats.path_length) + + # средние значения + avg_time = total_time / NUM_RUNS + avg_visited = int(np.mean(visited_counts)) + avg_path = int(np.mean(path_lengths)) + + results.append({ + "лабиринт": file, + "стратегия": name, + "время_мс": round(avg_time, 4), + "посещено_клеток": avg_visited, + "длина_пути": avg_path + }) + + # Запись в CSV + csv_file = "results/maze_benchmark_results.csv" + with open(csv_file, mode="w", encoding="utf-8", newline="") as f: + writer = csv.DictWriter(f, fieldnames=[ + "лабиринт", "стратегия", "время_мс", "посещено_клеток", "длина_пути"]) + writer.writeheader() + writer.writerows(results) + + print(f"Результаты успешно сохранены в {csv_file}") + return results + +# Построение графиков + + +def plot_results(results): + print("Генерация графиков...") + mazes = sorted(list(set(r["лабиринт"] for r in results))) + strategies = ["BFS", "DFS", "A*"] + + # График Количество посещенных клеток + fig, ax = plt.subplots(figsize=(10, 6)) + x = np.arange(len(mazes)) + width = 0.25 + + for i, strat in enumerate(strategies): + visited = [next(r["посещено_клеток"] for r in results if r["лабиринт"] + == m and r["стратегия"] == strat) for m in mazes] + ax.bar(x + i*width, visited, width, label=strat) + + ax.set_ylabel('Количество посещенных клеток') + ax.set_title('Сравнение эффективности обхода лабиринтов (меньше = лучше)') + ax.set_xticks(x + width) + ax.set_xticklabels(mazes, rotation=15) + ax.legend() + plt.tight_layout() + plt.savefig("results/benchmark_visited_cells.png", dpi=200) + plt.savefig("results/benchmark_visited_cells.eps", dpi=200) + plt.close() + + # График Время выполнения + fig, ax = plt.subplots(figsize=(10, 6)) + for i, strat in enumerate(strategies): + times = [next(r["время_мс"] for r in results if r["лабиринт"] + == m and r["стратегия"] == strat) for m in mazes] + ax.bar(x + i*width, times, width, label=strat) + + ax.set_ylabel('Время выполнения (мс)') + ax.set_title('Сравнение времени работы алгоритмов') + ax.set_xticks(x + width) + ax.set_xticklabels(mazes, rotation=15) + ax.legend() + plt.tight_layout() + plt.savefig("results/benchmark_execution_time.png", dpi=200) + plt.savefig("results/benchmark_execution_time.eps", dpi=200) + plt.close() + print("Графики сохранены в текущую директорию.") + + +if __name__ == "__main__": + data = run_benchmarks() + plot_results(data)