324 lines
22 KiB
Plaintext
324 lines
22 KiB
Plaintext
{
|
|
"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": 11,
|
|
"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": 58,
|
|
"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": 71,
|
|
"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": 79,
|
|
"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": 84,
|
|
"id": "ece3a6c8-aa1d-49a8-9f4c-06ebff72f991",
|
|
"metadata": {
|
|
"editable": true,
|
|
"slideshow": {
|
|
"slide_type": ""
|
|
},
|
|
"tags": []
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Depth First Search : took 150.0 ns, visited 42 nodes\n",
|
|
"Breadth First Search : took 300.0 ns, visited 21 nodes\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "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",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 1 Axes>"
|
|
]
|
|
},
|
|
"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
|
|
}
|