{ "cells": [ { "cell_type": "markdown", "id": "16f8fedb-ac10-450c-b5c7-f820a985902d", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "# Pathfinding demo\n", "\n", "## List of methods\n", "\n", "Non-exhaustive list of methods follows.\n", "\n", "$V$ is the set of all vertices; $E$ is the set of all edges; $|V|$ is the size of the set\n", "\n", "1. Depth-first search\n", " - s\n", "1. [Bellman-Ford algorithm](https://en.wikipedia.org/wiki/Bellman%E2%80%93Ford_algorithm)\n", " - exhaustive method\n", " - $O(|V|*|E|)$\n", "2. Dijkstra\n", "3. A*" ] }, { "cell_type": "code", "execution_count": 85, "id": "fbdf9d2c-d050-4744-b559-abc71e550725", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "#\n", "# Imports\n", "#\n", "\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "from typing import Protocol, Optional" ] }, { "cell_type": "code", "execution_count": 86, "id": "c704cf15-95fa-49c1-af1b-c99f7b5c8b95", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "#\n", "# Type and interfaces definition\n", "#\n", "\n", "type Point2D = tuple[int, int] # tuple(x, y)\n", "type Path = list[Point2D]\n", "type ElapsedTime_ns = float # nanoseconds\n", "type VisitedNodeCount = int\n", "\n", "class Map:\n", " \"\"\"\n", " 2D map consisting of cells with given cost\n", " \"\"\"\n", " array: np.array\n", "\n", " def __init__(self, width: int, height: int) -> None:\n", " assert width > 0\n", " assert height > 0\n", " self.array = np.zeros((width, height), dtype=np.float64)\n", "\n", " def Randomize(self, low: float = 0.0, high: float = 1.0) -> None:\n", " self.array = np.random.uniform(low, high, self.array.shape)\n", "\n", " def GetCost(self, point: Point2D) -> float:\n", " return self.array[point]\n", " \n", " def IsPointValid(self, point: Point2D) -> bool:\n", " ...\n", " \n", " def GetNeighbours(self) -> list[Point2D]:\n", " ...\n", "\n", " \n", "\n", "class PathFinder(Protocol):\n", " def SetMap(m: Map) -> None:\n", " ...\n", "\n", " def CalculatePath(start: Point2D, end: Point2D) -> Path:\n", " \"\"\"\n", " Calculate path on a given map.\n", " Note: map must be set first using SetMap (or using constructor)\n", " \"\"\"\n", "\n", " def GetStats() -> (ElapsedTime_ns, VisitedNodeCount):\n", " \"\"\"\n", " Return performance stats for the last calculation:\n", " - elapsed time in nanoseconds,\n", " - number of visited nodes during search\n", " \"\"\"\n" ] }, { "cell_type": "code", "execution_count": 87, "id": "043a1f1c-a7a7-4f24-b69c-c6c809830111", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [ "#\n", "# Drawing utilities\n", "#\n", "\n", "class Visualizer:\n", " _axes: Optional[plt.Axes]\n", " _cmap: plt.Colormap\n", " _cmap_counter: int\n", " \n", " def __init__(self):\n", " self._axes = None\n", " self._cmap = plt.get_cmap('tab10')\n", " self._cmap_counter = 0\n", " \n", " def DrawMap(self, m: Map):\n", " M, N = m.array.shape\n", " _, ax = plt.subplots()\n", " ax.imshow(m.array, cmap='terrain', origin='lower', interpolation='none')\n", " self._axes = ax\n", "\n", " def DrawPath(self, path: Path, label: str = \"Path\"):\n", " \"\"\"\n", " Draw path on a map. Note that DrawMap has to be called first\n", " \"\"\"\n", " assert self._axes is not None, \"DrawMap must be called first\"\n", " xs, ys = zip(*path)\n", " color = self._cmap(self._cmap_counter)\n", " self._cmap_counter += 1\n", " self._axes.plot(xs, ys, 'o-', color=color, label=label)\n", " self._axes.plot(xs[0], ys[0], 'o', color='lime', markersize=8) # starting point\n", " self._axes.plot(xs[-1], ys[-1], 'o', color='magenta', markersize=8) # end point\n", " " ] }, { "cell_type": "code", "execution_count": 88, "id": "859c64f4-e65c-4905-a775-c6f17542eac8", "metadata": {}, "outputs": [], "source": [ "#\n", "# Method: depth-first search\n", "#\n", "\n", "class DFS:\n", "\n", " name = \"Depth First Search\"\n", " _map: Optional[Map]\n", " \n", " def __init__(self) -> None:\n", " self._map = None\n", " \n", " def SetMap(self, m: Map) -> None:\n", " self._map = m\n", " \n", " def CalculatePath(self, start: Point2D, end: Point2D) -> Path:\n", " assert m is not None, \"SetMap must be called first\"\n", " return [(0,0), (5,5), (6,6), (1,9)]\n", "\n", " def GetStats(self) -> (ElapsedTime_ns, VisitedNodeCount):\n", " return 150.0, 42\n", "\n", "\n", "class BFS:\n", "\n", " name = \"Breadth First Search\"\n", " _map: Optional[Map]\n", " \n", " def __init__(self) -> None:\n", " self._map = None\n", " \n", " def SetMap(self, m: Map) -> None:\n", " self._map = m\n", " \n", " def CalculatePath(self, start: Point2D, end: Point2D) -> Path:\n", " assert m is not None, \"SetMap must be called first\"\n", " return [(0,0), (1,0), (2,0), (3,0)]\n", "\n", " def GetStats(self) -> (ElapsedTime_ns, VisitedNodeCount):\n", " return 300.0, 21" ] }, { "cell_type": "code", "execution_count": 89, "id": "ece3a6c8-aa1d-49a8-9f4c-06ebff72f991", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Breadth First Search : took 300.0 ns, visited 21 nodes\n", "Depth First Search : took 150.0 ns, visited 42 nodes\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZgAAAGdCAYAAAAv9mXmAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjUsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvWftoOwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAJ4xJREFUeJzt3Xl8VPW9//H3zCSZbJMARhBkCwIFWS4QqBVwoVC8bi2PWlxKtVfrVS+gIr1epLbXyq+QupZfRbHg8nNDaatWsKLiAggWQUBFUVBRiSwimn2ZJDPn90dIhEwSZpI58z0z83o+HvPgZjzDfO6E5pXzPWfOuCzLsgQAQJS5TQ8AAEhMBAYAYAsCAwCwBYEBANiCwAAAbEFgAAC2IDAAAFsQGACALVJi/YTBYFD79u2Tz+eTy+WK9dMDADrAsiyVl5erR48ecrvb3keJeWD27dunXr16xfppAQBRVFRUpJ49e7a5TcwD4/P5JEkrl12nrExvrJ++Vf2HH2d6hBDvrMszPUKIn+8Ya3qEEBUnOe9qRx9f8ILpEUJ0sf7D9Agh7vzmLtMjhPhZ586mRwix4U9fmR6hSbXfrzl/urfpZ3lbYh6YxmWxrEyvsrOcE5gcX7rpEUJkZWaaHiGEy3vsf1Qxl+G8wPhyMkyPECLHyjE9Qoj0Wuf8DGiUneO8nwUZXue9TuEc4uAgPwDAFgQGAGALAgMAsAWBAQDYgsAAAGxBYAAAtiAwAABbEBgAgC0IDADAFjF/J39CqvEodcUApb5wklzF6bI616junE9V9+OPpfSA6ekAwAgC00EpL+YrY+ZkuUvTZbmDcgXdstxBpf6zv4K/OUPV976s+rM+Mz0mAMQcS2QdkPJivjIvO1+usjRJkivoPvrPsjRlXnq+Ul7MNzYjAJhCYNqrxqOMmZMlWXJZLb+MDfdbDdvVeGI6HgCYRmDaKXXFALlL01uNSyOX5Za7NF2pK/vHaDIAcAYC006pL5wkyx0Ma9vGYzIAkEwITDu5itObjrUcc9ugW65i532eAwDYicC0k9W5JqI9GKuz3+aJAMBZCEw71Z3zaUR7MPWnvW3zRADgLASmnep+/LGCuTWyXG3vxVgKSunFSi+/Xulrn5dqqmM0IQCYRWDaKz2g6ntfluRqNTKWKyi5XKqb/ke5Umrk3b5Jvif+rNQdWyUrvOU1AIhXBKYD6s/6TFWPrpSVUytJTcdkmv7MqVXVYytVNbeHKqb8hwKdj5e7ulKZr/1DWU8/KPfX+43NDgB241IxHVT/75+p/P0HlLqyv1L/2V+uYq+szn7VnfuJ6s7/pOlaZIGe/VRx8XSlvbdR6ZteV8qBImX/9X7VDh2jmlMmSukZhv8/AYDoIjDRkB5Q3dSdqpu6s+3tPB7VjhynugHDlL7hJaV9vF3e7ZuU+skHqjn1R6obPEJysVMJIDHw08wAKztH1WdNZdkMQEIjMAY1LptVjztLVmpa07IZZ5sBSAQExrTDy2bl065T7YBhcllW09lm3Yvf5GwzAHGLwDhES8tmg/c9qoLP7lR29R7T4wFAxAiMwxy5bFbv9iq3erfG7C7UwP1PKiVQaXo8AAgbgXGiw8tmG/v/Xgdyx8glSz2/XasffPx7ls0AxA0C42C1qZ21o+evtLXvDar0nqC0QDnLZgDiBoGJAyVZ39Omk36nj7tdwLIZgLhBYOKE5fKoKO9HLJsBiBsEJs6wbAYgXrgsy7Ji+YRlZWXKzc3Vvi+LlJOTE8unbtM769aYHiHE+LIBbf73FKte1xUv1+8PPSifVaWA3Frc6af6Xd5VKvHY89oePH2VLX9vRyz/83umRwhxfI+hpkcI8eXH20yPECLTl2Z6hBB3fXyJ6RFCzF+y1fQITarKanRF/q0qLS095s9w9mDiWL0rRXd3maZB+U9pmW+yPApqZsnftfOzi/Qfpc/LxbIZAIMITALYl9pV03rM04Re92pHWl91DRTr4QN/0Po9V2tEzTEuwAkANiEwCWRNZoH+re/j+vXx16rclamxNdv19heX656v7lSnQJnp8QAkGQKTYFg2A+AUBCZBsWwGwDQCk+BYNgNgCoFJAiybATCBwCSR1pbNNuy5SiNrPjI9HoAEQ2CSUPNls1Nr3tfmL65g2QxAVBGYJMWyGQC7EZgkx7IZALsQGEhi2QxA9BEYNGHZDEA0ERiEaGvZLOXQftPjAYgTEQWmvr5ev/3tb5Wfn6+MjAz169dP8+bNUzDIb7aJqKVls07/WKrsDS/I5a82PR4Ah4soMLfddpvuv/9+LVq0SB9++KFuv/123XHHHbrnnnvsmg+GNV82c1mWMnZsVpe/LpJ35zYpth8nBCCOpESy8b/+9S/95Cc/0bnnnitJ6tu3r5588km9/fbbtgwH52hcNjun/wnK3vCCUkoOKWfdCtV9tFUV485RfV530yMCcJiI9mDGjx+vV199Vbt27ZIkvfvuu1q/fr3OOeecVh/j9/tVVlZ21A3xq65HvoovuEYVp/xIwdQ0pR78kmUzAC2KaA9mzpw5Ki0t1aBBg+TxeBQIBDR//nxdcknrHzFaWFioW2+9tcODwkHcHlUPHyv/SUOV9dZqpX/6vjJ2bJZ39weq+P4k+QeOkFwu01MCMCyiPZjly5fr8ccf17Jly7R161Y98sgjuvPOO/XII4+0+pi5c+eqtLS06VZUVNThoeEMwawclf/wApWce5nqO+XJXVOlnHUr1GnFQ5xtBiCyPZgbb7xRN910ky6++GJJ0rBhw/TFF1+osLBQv/zlL1t8jNfrldfr7fikcKzGZbOM999S5ta1TctmNYNHq3L0BFneDNMjAjAgoj2Yqqoqud1HP8Tj8XCaMpqWzYqnzlDNSUM52wxAZHsw559/vubPn6/evXtryJAh2rZtm+6++25dccUVds2HONO4bFYzaBRnmwFJLqLA3HPPPfrd736n6dOn6+DBg+rRo4euvvpq/e///q9d8yFOsWwGIKLA+Hw+LVy4UAsXLrRpHCQUzjYDkhrXIoPtONsMSE4EBjHDmzSB5EJgEFucbQYkDQIDI1g2AxIfgYFRLJsBiYvAwDyWzYCERGDgGCybAYmFwMBxWDYDEgOBgTOxbAbEPQIDR2PZDIhfBAZxofVls3/Kq1rT4wFoQUTXIoum9Iy/KT3DORc8HHO26QlCdX7vRdMjhPj7ItPHQHzK0kSdmrJdAzxfKmPH25rWOUNrfnC6tn9viGOubWbdud30CCFSUj2mRwhRuPdXpkcIUfTrlaZHCNFn02mmR2hSWVkV9rbswSDuVCpDr9R/X8/VnqZvgz5l1lTrnDUv6Rf/eFLdvv7K9HgADiMwiFv7rOP1t7qJeu3UM+RPTdWJX+3XZc88oR+98Yq8/hrT4wFJj8AgrgXl1uZ/G60HLrpcO/p/T27L0qgP3tVVTz6kYR+9z9lmgEEEBgmhItunlZPO05PnT9Whzl1YNgMcgMAgoew5sbce/tllLJsBDkBgkHCCHg/LZoADEBgkLJbNALMIDBIey2aAGQQGSYFlMyD2CAySCstmQOwQGCQlls0A+xEYJC2WzQB7ERgkPZbNAHsQGOAwls2A6CIwwBFYNgOih8AALWDZDOg4AgO0gWUzoP0IDHAMLJsB7UNggDCxbAZEhsAAEWpcNnv9B6ezbAa0IcX0AEA8Cno82jRijHb0H6QJG9fq5E92atQH72rQp7u05gen61OlS3KZHhMwij0YoANaWzb7WcY6He8uMT0eYBSBAaKg+bJZd0+xLsxYozPS3pVXtabHA4wgMECUNC6bPXDR5dpVd6LcLml42me6NOsVDU75QhJnmyG5EBggyiqyfXrJP0bPVI/Tt0GfMly1mpS+jWUzJB0CA9hkb+B4PVk1Qev9Q1RrpbBshqRDYAAbBeXWtroBerxqIstmSDoEBoiBSiuDZTMkHQIDxBDLZkgmBAaIMZbNkCwIDGAIy2ZIdAQGMIxlMyQqAgM4AMtmSEQEBnAQls2QSAgM4EAsmyEREBjAoVg2Q7wz9nkwf/z6oLw1XlNPHyJr3hemRwix6qcXmh4hxEVFWaZHCPGOZ5DpEUJ06dcl6n/nmbVvaFH5/+jkwC5NSt+mrBSPZvpu17bUfwvr8fvP+79Rn6mjnqh82vQIIfYM/pPpEULsqvmz6RGapJWF/6F67MEAcWJN2mka0WWdbsy+VeWuLJ1a/7Y2FU/SovIb1SlYYno8IASBAeJIvStVd2XO1OAuG/Wk96fyKKjp1Q9p5zff1+XVT8hlBU2PCDQhMEAc2ufpoWm5S/XDTv/QDs9AHW99owfLr9P64rM1su5d0+MBkggMENdYNoOTERggzrFsBqciMECCYNkMTkNggATT2rKZ780X5PJXmx4PSYTAAAmopWWzzI/eVt7T9yp91zbJ4k2asB+BARLYkctm9Z3y5K6pUu76ler8/ENKObTf9HhIcAQGSAJr0k7TN1OuVvmYSQqmpCnt673qsvIBls1gKwIDJAu3R1XDxuqbC6arJn+IXJbFshlsRWCAJBPMylHphAv07dmXsmwGWxEYIEnVdc9n2Qy2MnY1ZQAOcHjZrKbfUPk2rVb6Zx8o86O3lf75DpWPnqiaASMkl6th22BQqV/tkaeqQoHMbNV16y25+R0VrYs4MHv37tWcOXO0atUqVVdXa+DAgXrwwQdVUFBgx3wAYqBx2axq0Cjl/GuVUkoOKXf9SmXs3KryU8+Rp6JEvo0vyVNV1vSYQGaOyn9wlvx9BxucHE4WUWCKi4s1btw4TZgwQatWrVLXrl316aefqlOnTjaNByCWGpfNMj94S1nb1jUsm61Y2uK27qoy5b72N5X+cCqRQYsiCsxtt92mXr166eGHH266r2/fvtGeCYBJRy6bvfWy0j/f0eJmLjV8pqbvrZfk7/09lssQIqJ/EStWrNDo0aM1depUde3aVSNHjtTSpS3/dtPI7/errKzsqBsA5wtm5ahq8Og2t3FJ8lSWKfWrPbEZCnElosDs3r1bixcv1oABA/TSSy/pmmuu0XXXXadHH3201ccUFhYqNze36darV68ODw0gNjxVFVHdDsklosAEg0GNGjVKCxYs0MiRI3X11VfrP//zP7V48eJWHzN37lyVlpY23YqKijo8NIDYCGRmR3U7JJeIAtO9e3edfPLJR903ePBg7dnT+u6x1+tVTk7OUTcA8cFK86qt9/dbkgJZOQ2nLAPNRBSYcePGaefOnUfdt2vXLvXp0yeqQwEwL+Xbr9T5xcebDuY3D03j1+WnnMUBfrQoon8VN9xwgzZu3KgFCxbok08+0bJly7RkyRLNmDHDrvkAGJDy7VfqvOpRuf3VqsvrobLTpiiYefTqQzArh1OU0aaITlMeM2aMnn32Wc2dO1fz5s1Tfn6+Fi5cqGnTptk1H4AYax6X4rN+IcubrpqThvJOfkQk4nfyn3feeTrvvPPsmAWAYa3FRZLkdquue1/VmR0RcYRfPwBIOkZcgHYgMACIC2xBYIAkR1xgFwIDJDHiAjsRGCBJERfYjcAASYi4IBYIDJBkiAtihcAASYS4IJYIDJAkiAtijcAASWBY/QfEBTEX8aViAMSXYfUf6NXiKXJbxAWxZSwwI14sVmaG19TThyjrm2Z6hBDX9nrZ9AghrkzbZ3qEEC89kWd6hBB3XnKC6REkSXnffK2pK/6qDKta2+oG66Kdd6nsI5/psZrktPFZUqb89E9zTI8Q4rdFPzI9QpOKysqwt2WJDEhQTXGpqdaBrifoorK7VGY5Jy5IfAQGSEDN4/L0eT8jLog5AgMkmJbi4ueYCwwgMEACIS5wEgIDJAjiAqchMEACIC5wIgIDxDniAqciMEAcIy5wMgIDxCniAqcjMEAcIi6IBwQGiDPEBfGCwABxhLggnhAYIE4QF8QbLtcPOJArGNSJ+79UVlWlKjOz5E/z6mfP/524IK4QGMBh+u/epQnrX5OvsqLpvqAalhuIC+IJgQEcpP/uXTr/pRUh97slWZK2DR1JXBA3OAYDOIQrGNSE9a81/N+tbDNu03q5gsHYDQV0AIEBHOLE/V/KV1nRalxcknIqynXi/i9jORbQbgQGcIisqvA+ijbc7QDTCAzgEJWZWVHdDjCNwAAO4U/zqq2jK5aksmyf9nbvGauRgA4hMIAD5H3ztX72/N+bzhazmv33xq/XjJsgy83/bBEf+JcKGNb8Hfov/vBsVWRlH7VNebZPK8/6sT7pN9DQlEDkeB8MYFBrl3/5aMDgo97Jv7d7T/ZcEHcIDGBIW9cWs9xufXlib8MTAh3Dr0SAAVy4EsmAwAAxRlyQLAgMEEPEBcmEwAAxQlyQbAgMEAPEBcmIwAA2Iy5IVgQGsBFxQTIjMIBNiAuSHYEBbEBcAN7JD0RdbqBYZ6x4jbgg6REYIIpyA8WaUPGKvJafuCDpGQtMpq9AWZkZpp4+xKSLSkyPEOLS3JmmRwjRe5bzZnq+f3/TI0iS0g8eUL/lzyjF8qvS100HB07R2M9SJNWbHk2S9P5/P2V6hBB/7nSj6RFCvPrX1aZHCFGW963pEZpUVlWFvS17MEAUNMTlEaVUV6nqhBP1af/zFUhlzwXJjYP8QAc1j8vuCy8lLoAIDNAhLcUlmO6cpV/AJAIDtBNxAdpGYIB2IC7AsREYIELEBQgPgQEiQFyA8BEYIEzEBYgMgQHCQFyAyBEY4BiIC9A+BAZoA3EB2o/AAK0gLkDHEBigBcQF6DgCAzRDXIDo6FBgCgsL5XK5NGvWrCiNA5hFXIDoaXdgNm/erCVLlmj48OHRnAcwhrgA0dWuwFRUVGjatGlaunSpOnfuHO2ZgJgjLkD0tSswM2bM0LnnnqtJkyYdc1u/36+ysrKjboCTEBfAHhF/ouVTTz2lrVu3avPmzWFtX1hYqFtvvTXiwYBYIC6AfSLagykqKtL111+vxx9/XOnp4X1i39y5c1VaWtp0KyoqategQLQRF8BeEe3BbNmyRQcPHlRBQUHTfYFAQOvWrdOiRYvk9/vl8XiOeozX65XX643OtECUEBfAfhEFZuLEidq+fftR911++eUaNGiQ5syZExIXwImICxAbEQXG5/Np6NChR92XlZWl4447LuR+wImICxA7vJMfSYO4ALEV8Vlkza1ZsyYKYwD2Ii5A7LEHg4RHXAAzCAwSGnEBzCEwSFjEBTCLwCAhERfAPAKDhENcAGcgMEgoxAVwDgKDhEFcAGchMEgIxAVwHgKDuEdcAGfq8Dv5AZMGlRar36qniQvgQAQGcWtQabGeemO1Umr9xAVwIGOBuXDv2XKl55h6+hD31S0yPUKI289bYXqEEM/c8GPTI0iSMiq/0MD3blVqvV/vl/bWf716jSoeyTQ9VpO3NoT3gXyxdNXLPU2PEOKJ9b82PUKIhZf4TI8Q4qOPTjQ9wnesyrA35RgM4s53cSlXZfZJ+q+3r1FFvXPiAqABgUFcaR6XXcN+R1wAhyIwiBstxSWQkmV6LACtIDCIC8QFiD8EBo5HXID4RGDgaMQFiF8EBo5FXID4RmDgSMQFiH8EBo5DXIDEQGDgKMQFSBwEBo5BXIDEQmDgCMQFSDwEBsYRFyAxERgYRVyAxEVgYAxxARIbgYERxAVIfAQGMUdcgORAYBBTxAVIHgQGMUNcgORCYBATxAVIPgQGtiMuQHIiMLAVcQGSF4GBbYgLkNwIDGxBXAAQGEQdcQEgERhEGXEB0IjAIGqIC4AjERhEBXEB0ByBQYcRFwAtITDoEOICoDUEBu1GXAC0hcCgXYgLgGMhMIgYcQEQDgKDiBAXAOFKMT0A4sfAjD0a+N4fiQuAsBAYhGVgxh49MrBQqfUVxAVAWFyWZVmxfMKysjLl5uZq+Kg/y+PJiOVTt+nOV0pMjxDipH0B0yNIklJLDqrba0/IU1utg1Zn/TMwXrVKMz1Wk+NOGGZ6hBBTTxxheoRQJSNMTxBi7uSFpkcIcVXZhaZHCJGR7TM9QpPy8nINGDJUpaWlysnJaXNbjsGgTUfGxd+lu+PiAsC5CAxa1TwuX515CXEBEDYCgxa1FBcrLd30WADiCIFBCOICIBoIDI5CXABEC4FBE+ICIJoIDCQRFwDRR2BAXADYgsAkOeICwC4EJokRFwB2IjBJirgAsBuBSULEBUAsEJgkQ1wAxAqBSSLEBUAsRRSYwsJCjRkzRj6fT127dtWUKVO0c+dOu2ZDFBEXALEWUWDWrl2rGTNmaOPGjVq9erXq6+s1efJkVVZW2jUfooC4ADAhok+0fPHFF4/6+uGHH1bXrl21ZcsWnX766VEdDNFBXACY0qGPTC4tLZUkdenSpdVt/H6//H5/09dlZWUdeUpEgLgAMKndB/kty9Ls2bM1fvx4DR06tNXtCgsLlZub23Tr1atXe58SESAuAExrd2Bmzpyp9957T08++WSb282dO1elpaVNt6KiovY+JcJEXAA4QbuWyK699lqtWLFC69atU8+ePdvc1uv1yuv1tms4RI64AHCKiAJjWZauvfZaPfvss1qzZo3y8/PtmgvtQFwAOElEgZkxY4aWLVum5557Tj6fTwcOHJAk5ebmKiMjw5YBER7iAsBpIjoGs3jxYpWWlurMM89U9+7dm27Lly+3az6EgbgAcKKIl8jgLMQFgFNxLbI4RlwAOBmBiVPEBYDTEZg4RFwAxAMCE2eIC4B4QWDiCHEBEE8ITJwgLgDiDYGJA8QFQDwiMA5HXADEKwLjYMQFQDwjMA6V9fVXxAVAXCMwDpT19Vca+bfHiAuAuNahj0zuiKUvVCk7J2jq6UNc+cU+0yNIkk4q+Vb3vPaC0mr9qsrppk+HTlGw1JJUbXo0SdI1E4eZHiFExehfmR4hxL3zbzE9Qoj/yR5ieoQQuf9nj+kRQgwY3M/0CCF6bdhgeoQmwbrKsLc1FhiEaoxLp1q/dnTJU2DoTxVMZc8FQHxiicwhmsdl1pn/TlwAxDUC4wAtxaUijY+ZBhDfCIxhxAVAoiIwBhEXAImMwBhCXAAkOgJjAHEBkAwITIwRFwDJgsDEEHEBkEwITIwQFwDJhsDEAHEBkIwIjM2IC4BkRWBsRFwAJDMCYxPiAiDZERgbEBcAIDBRR1wAoAGBiSLiAgDfITBRQlwA4GgEJgqICwCEIjAdRFwAoGUEpgOICwC0jsC0E3EBgLYRmHYgLgBwbAQmQsQFAMJDYCJAXAAgfAQmTMQFACJDYMJAXAAgcgTmGIgLALQPgWkDcQGA9iMwrSAuANAxBKYFxAUAOo7ANENcACA6CMwRiAsARA+BOYy4AEB0ERhJ3oMHiAsARFmK6QFM8x48oD5P/T+lEBcAiCpjgfnm1e6qycw09fSSpKzqIg345FGlBKpUlTtQroIF+lNNtlRjdKwmU+4uMT1CiIKiItMjhPA/X2l6hBApv84zPUKIFd5HTY8QoqB2hOkRQkz3LDU9QoickzNMj/CdymrpH+FtmrR7MFnVRRr+yZ1KDVSoLDNfe7+/QMHUbNNjAUDCSMpjMM3jsr3fbOICAFGWdIFpKS6BFLNLdQCQiJIqMMQFAGInaQJDXAAgtpIiMMQFAGIv4QNDXADAjIQODHEBAHMSNjDEBQDMSsjAEBcAMC/hAkNcAMAZEiowxAUAnCPurkVWnlKhvwx5Qv86YYtqPH6lB7w69UCBZm8+U8M/uY+4OFha0KNJxf10Zklf5dR7VZbi15pOn+uVzrtV6w6YHg9AlMVVYB4YvEyPDXxWckmyJLmkCqtKK/Nf0boTXtFj9Rk648uBRuISsCx9cKhe39YE1SXdrSF5KfK4XDGdoTlLlqwMNXyX6yVXteSSmZlOL+mj339+pnICXgUUlEduBRTUD0vy9d9FY3VL39f1Rqc9RmYDYI92LZHdd999ys/PV3p6ugoKCvTGG29Ee64QTXFp5Dr6z7J06SeXVGvWub1jHpcNe2t1xYslmvtGue7YXKm5b5TrihdLtGFvbUznOFIw21J9P0uB3pYCPRr+rO9nKZhtxXyW00v66M5PJys7kCZJ8hz+Z9f4Z3YgTXd9epZOL+kT89kA2CfiwCxfvlyzZs3SzTffrG3btum0007T2WefrT177Pvtszyl4ru4tPILuOVq2Kl5+OSVKk+psG2W5jbsrdWCtyp0qProH9yHqi0teKvCSGSC2Q1RCdk/TZECPWIbmbSgR7///ExJkruVb17j/b///EylBT2xGg2AzSIOzN13361f/epXuvLKKzV48GAtXLhQvXr10uLFi+2YT5L0lyFPNITlWKs7h7dZPHiZ/AFFdKuptyK+VdYF9Zd32/6wq7+8W6nKumC7/n7LFfkt6Aoq0NX67vVo/vpICnRt2K49f7/ldkV0m1jSTzkBb6txaeSWSzkBryYW5x/jmwwgXkR0DKa2tlZbtmzRTTfddNT9kydP1ptvvtniY/x+v/x+f9PXZWVlEQ/5rxO2NB1zOSZLejFvi97fHOknwBVHPFc4vqmxdOHKkvY9eGBUR2ngkpQqBQZKDS9qZL4Z2COi7cc+O0gBlyWPdexvXkBBTSjJ16rjPol4LgDOE9EezKFDhxQIBNStW7ej7u/WrZsOHDjQ4mMKCwuVm5vbdOvVq1fEQ9Z4/OHFRZJcUjDNf+ztEBOdqlPDiovUcEwmp95r80QAYqVdZ5G5mp0dZVlWyH2N5s6dq9mzZzd9XVZWFnFk0gNeVVhVYe/BdFGalo6pjug5unSP7DdzSXr/UJ1uefPYx3tuHZutoXmpEf/9F91ZEvFjghmWgmG8vO4iyV0d+RlluV/ujWj7qopyBdSl6YB+WwIKqiyFXw6ARBFRYPLy8uTxeEL2Vg4ePBiyV9PI6/XK6+3Yb6WnHijQyvxXwtvYJY3bP1reCI8Vp6dE/sN2ZLdU5WW4Qg7wHykvw6WR3VLbdcqyK8zf/I/krpKCdYcP8Lf0cEtSveSucrXrlGVXMLJltbW5n4d9XMUjt17v9FnEMwFwpoiWyNLS0lRQUKDVq1cfdf/q1as1duzYqA52pKs/mNbwg/FYP9sOb3PVjp/bNsuRPC6Xrhqe1eY2Vw3Piun7YVxyyXPw8PM1f70Of+052L64tMcrnXerzONX8BjfvKAslXn8erUzgQESRcRnkc2ePVsPPPCAHnroIX344Ye64YYbtGfPHl1zzTV2zCdJ8tVn69KdFzR80drPqcP3X7rzAvnqs22bpblxJ6bpN6dkKy/j6B/YeRku/eaUbI07MS1mszRyV7jk2eeS6pv9h3rJs88ld0XsglfrDuiWvq9LUquRabz/lr6v845+IIFEfAzmoosu0jfffKN58+Zp//79Gjp0qF544QX16WPvm+Su/OhiyRX87v0wjWeVHXF22aU7L2jYLsbGnZimH/RIddQ7+d0VLrkq5Ih38r/RaY/++6SXW3wnv0duVXhqeSc/kIDadZB/+vTpmj59erRnOaYrP/y5Lvr4x1py8jK92f3tpmuRjd0/Wlft+HlM91ya87hcGn585Afy7eSSS67IznWwzbpOX+jfhz+uicX5mlCS33Qtstc7faZXO3/GnguQgOLqWmRSw3LZr9+7Sr9+7yrToyBCte6AVh33Ce9zAZJEQl2uHwDgHAQGAGALAgMAsAWBAQDYgsAAAGxBYAAAtiAwAABbEBgAgC0IDADAFjF/J79lNVzYsKrKIdcwOcxb0fZHH5sQrKsyPUKIQMBZ3zdJKisvNz1CiGpPjekRQlT6I/8EU7uV1TnvEkFut7lrCLbKST+eqhr+bTf+LG+Lywpnqyj68ssv2/WplgAA5ygqKlLPnj3b3CbmgQkGg9q3b598Pl+rn4IZjsZPxiwqKlJOTk4UJ0wsvE7h4XUKD69TeBL5dbIsS+Xl5erRo4fc7raPssR8icztdh+zepHIyclJuG+gHXidwsPrFB5ep/Ak6uuUm5sb1nYc5AcA2ILAAABsEbeB8Xq9uuWWW+T1ek2P4mi8TuHhdQoPr1N4eJ0axPwgPwAgOcTtHgwAwNkIDADAFgQGAGALAgMAsEXcBua+++5Tfn6+0tPTVVBQoDfeeMP0SI5SWFioMWPGyOfzqWvXrpoyZYp27txpeixHKywslMvl0qxZs0yP4jh79+7VL37xCx133HHKzMzUiBEjtGXLFtNjOUp9fb1++9vfKj8/XxkZGerXr5/mzZunYDBoejRj4jIwy5cv16xZs3TzzTdr27ZtOu2003T22Wdrz549pkdzjLVr12rGjBnauHGjVq9erfr6ek2ePFmVlU66ap5zbN68WUuWLNHw4cNNj+I4xcXFGjdunFJTU7Vq1Srt2LFDd911lzp16mR6NEe57bbbdP/992vRokX68MMPdfvtt+uOO+7QPffcY3o0Y+LyNOVTTjlFo0aN0uLFi5vuGzx4sKZMmaLCwkKDkznX119/ra5du2rt2rU6/fTTTY/jKBUVFRo1apTuu+8+/eEPf9CIESO0cOFC02M5xk033aQNGzawSnAM5513nrp166YHH3yw6b4LLrhAmZmZeuyxxwxOZk7c7cHU1tZqy5Ytmjx58lH3T548WW+++aahqZyvtLRUktSlSxfDkzjPjBkzdO6552rSpEmmR3GkFStWaPTo0Zo6daq6du2qkSNHaunSpabHcpzx48fr1Vdf1a5duyRJ7777rtavX69zzjnH8GTmxPxilx116NAhBQIBdevW7aj7u3XrpgMHDhiaytksy9Ls2bM1fvx4DR061PQ4jvLUU09p69at2rx5s+lRHGv37t1avHixZs+erd/85jfatGmTrrvuOnm9Xl122WWmx3OMOXPmqLS0VIMGDZLH41EgEND8+fN1ySWXmB7NmLgLTKPml/q3LKtDl/9PZDNnztR7772n9evXmx7FUYqKinT99dfr5ZdfVnp6uulxHCsYDGr06NFasGCBJGnkyJH64IMPtHjxYgJzhOXLl+vxxx/XsmXLNGTIEL3zzjuaNWuWevTooV/+8pemxzMi7gKTl5cnj8cTsrdy8ODBkL0aSNdee61WrFihdevWRfVjEhLBli1bdPDgQRUUFDTdFwgEtG7dOi1atEh+v18ej8fghM7QvXt3nXzyyUfdN3jwYD399NOGJnKmG2+8UTfddJMuvvhiSdKwYcP0xRdfqLCwMGkDE3fHYNLS0lRQUKDVq1cfdf/q1as1duxYQ1M5j2VZmjlzpp555hm99tprys/PNz2S40ycOFHbt2/XO++803QbPXq0pk2bpnfeeYe4HDZu3LiQU9x37dqlPn36GJrImaqqqkI+gMvj8ST1acpxtwcjSbNnz9all16q0aNH69RTT9WSJUu0Z88eXXPNNaZHc4wZM2Zo2bJleu655+Tz+Zr2+HJzc5WRkWF4Omfw+Xwhx6SysrJ03HHHcazqCDfccIPGjh2rBQsW6MILL9SmTZu0ZMkSLVmyxPRojnL++edr/vz56t27t4YMGaJt27bp7rvv1hVXXGF6NHOsOHXvvfdaffr0sdLS0qxRo0ZZa9euNT2So0hq8fbwww+bHs3RzjjjDOv66683PYbjrFy50ho6dKjl9XqtQYMGWUuWLDE9kuOUlZVZ119/vdW7d28rPT3d6tevn3XzzTdbfr/f9GjGxOX7YAAAzhd3x2AAAPGBwAAAbEFgAAC2IDAAAFsQGACALQgMAMAWBAYAYAsCAwCwBYEBANiCwAAAbEFgAAC2IDAAAFv8f7RJTV2VBKRxAAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Define the map and start/stop points\n", "m = Map(10, 10)\n", "m.Randomize()\n", "starting_point: Point2D = (0,0)\n", "end_point: Point2D = (9,9)\n", "\n", "#\n", "# Calculate paths using various methods and visualize them\n", "#\n", "\n", "path_finder_classes: list[PathFinder] = {\n", " DFS, BFS\n", "}\n", "\n", "v = Visualizer()\n", "v.DrawMap(m)\n", "\n", "for pt in path_finder_classes:\n", " path_finder = pt()\n", " path_finder.SetMap(m)\n", " path = path_finder.CalculatePath(starting_point, end_point)\n", " elapsed_time, visited_nodes = path_finder.GetStats()\n", " print(f\"{path_finder.name:22}: took {elapsed_time} ns, visited {visited_nodes} nodes\")\n", " v.DrawPath(path)\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "id": "2ec9fb78-089d-4d51-9f16-087a04b4e8a4", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "b050caaa-d9b5-4a22-8e6d-aaccfaa4fb1b", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.7" } }, "nbformat": 4, "nbformat_minor": 5 }