commit 0e48e52f8a68052282d01e58c367604efcc3f313 Author: quirinecker Date: Mon Nov 3 09:16:40 2025 +0100 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0d7773c --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +# Created by https://www.toptal.com/developers/gitignore/api/jupyternotebooks +# Edit at https://www.toptal.com/developers/gitignore?templates=jupyternotebooks + +### JupyterNotebooks ### +# gitignore template for Jupyter Notebooks +# website: http://jupyter.org/ + +.ipynb_checkpoints +*/.ipynb_checkpoints/* + +# IPython +profile_default/ +ipython_config.py + +# Remove previous ipynb_checkpoints +# git rm -r .ipynb_checkpoints/ + +# End of https://www.toptal.com/developers/gitignore/api/jupyternotebooks + diff --git a/README.md b/README.md new file mode 100644 index 0000000..39232e3 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# JKU AI UE Exercise + +## How to use + +1. `nix-shell` +2. jupyter lab . + + + diff --git a/boards/tiny0.json b/boards/tiny0.json new file mode 100644 index 0000000..4d19827 --- /dev/null +++ b/boards/tiny0.json @@ -0,0 +1,17 @@ +{"type": "Simple2DProblem", +"board": [ + [0, 0, 0, 0, 0], + [0, 1, 1, 1, 0], + [0, 0, 0, 0, 0], + [0, 1, 0, 1, 0], + [0, 1, 0, 0, 0] +], +"costs": [ + [4, 4, 3, 1, 0], + [3, 4, 2, 2, 2], + [4, 3, 3, 4, 0], + [4, 4, 3, 3, 0], + [4, 3, 1, 1, 2] +], +"start_state": [1, 0], +"end_state": [4, 4]} diff --git a/boards/tiny1.json b/boards/tiny1.json new file mode 100644 index 0000000..93a99a6 --- /dev/null +++ b/boards/tiny1.json @@ -0,0 +1,19 @@ +{ + "type": "Simple2DProblem", + "board": [ + [0, 0, 0, 0, 0], + [0, 1, 1, 1, 0], + [0, 0, 0, 1, 0], + [0, 1, 0, 1, 0], + [0, 0, 0, 0, 0] + ], + "costs": [ + [1, 1, 10, 10, 1], + [1, 0, 0, 0, 2], + [2, 10, 10, 0, 2], + [2, 0, 1, 0, 2], + [1, 1, 10, 1, 1] + ], + "start_state": [0, 0], + "end_state": [4, 4] +} diff --git a/boards/tiny2.json b/boards/tiny2.json new file mode 100644 index 0000000..950e35f --- /dev/null +++ b/boards/tiny2.json @@ -0,0 +1,19 @@ +{ + "type": "Simple2DProblem", + "board": [ + [0, 0, 0, 1, 0], + [0, 1, 0, 1, 0], + [0, 0, 0, 0, 0], + [1, 0, 1, 0, 1], + [0, 0, 0, 0, 0] + ], + "costs": [ + [1, 1, 5, 0, 2], + [1, 0, 5, 0, 2], + [1, 1, 1, 1, 2], + [0, 1, 0, 1, 0], + [2, 2, 5, 1, 1] + ], + "start_state": [0, 0], + "end_state": [4, 4] +} diff --git a/boards/tiny3.json b/boards/tiny3.json new file mode 100644 index 0000000..287d053 --- /dev/null +++ b/boards/tiny3.json @@ -0,0 +1,19 @@ +{ + "type": "Simple2DProblem", + "board": [ + [0, 0, 0, 1, 0], + [0, 1, 0, 1, 0], + [0, 0, 0, 0, 0], + [0, 1, 0, 1, 0], + [0, 0, 0, 0, 0] + ], + "costs": [ + [1, 10, 10, 0, 1], + [1, 0, 10, 0, 1], + [1, 1, 5, 5, 1], + [10, 1, 1, 10, 1], + [2, 2, 1, 10, 1] + ], + "start_state": [0, 0], + "end_state": [4, 4] +} diff --git a/heuristic_search.ipynb b/heuristic_search.ipynb new file mode 100644 index 0000000..8442e1b --- /dev/null +++ b/heuristic_search.ipynb @@ -0,0 +1,842 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "markdown", + "checksum": "57e5ba00b7b45ec500d2f43583946ec4", + "grade": false, + "grade_id": "cell-fca4677f5235e400", + "locked": true, + "schema_version": 3, + "solution": false, + "task": false + }, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Artificial Intelligence UE\n", + "## Exercises 2 - Heuristic Search\n", + "\n", + "In this exercise you will implement two heuristic search algorithms: Greedy Best First Search and A* search. We also look at a few different heuristics to test out the algorithms. \n", + "\n", + "The algorithms have been explained in the lecture (VO) and we provide some additional hints for the different heuristics below. Please refer to the lecture slides (VO) for the pseudo algorithms.\n", + "\n", + "
\n", + "\n", + "

Practical hints:

\n", + "\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "9f781970aadce801f4f3db209b324590", + "grade": false, + "grade_id": "cell-a899a3e4e7642bba", + "locked": true, + "schema_version": 3, + "solution": false, + "task": false + } + }, + "outputs": [], + "source": [ + "# import stuff\n", + "from pig_lite.problem.base import Problem, Node\n", + "from pig_lite.datastructures.queue import Queue\n", + "from pig_lite.datastructures.stack import Stack\n", + "from pig_lite.datastructures.priority_queue import PriorityQueue\n", + "from pig_lite.instance_generation.problem_factory import ProblemFactory\n", + "\n", + "import math\n", + "import random\n", + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "d39d626778c6bc4602c99d614ce15f29", + "grade": false, + "grade_id": "cell-e5b8421256781208", + "locked": true, + "schema_version": 3, + "solution": false, + "task": false + } + }, + "outputs": [], + "source": [ + "# as a reminder, this way we can visualize a particular problem (here: a maze)\n", + "factory = ProblemFactory()\n", + "maze = factory.create_problem_from_json(json_path='boards/tiny0.json')\n", + "maze.visualize()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "Now it's your turn to implement some heuristics and search algorithms - all spots that need your attention are marked with # YOUR CODE HERE!\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "markdown", + "checksum": "eb30ea66fa5021f4fd86c85ca69c9a62", + "grade": false, + "grade_id": "cell-9f2c8647014ac9bb", + "locked": true, + "schema_version": 3, + "solution": false, + "task": false + } + }, + "source": [ + "## Implementing Heuristics\n", + "\n", + "Here, you first have to implement several heuristics:\n", + "- [Manhattan (City block) distance](https://en.wikipedia.org/wiki/Taxicab_geometry)\n", + "- [Euclidean distance](https://en.wikipedia.org/wiki/Euclidean_distance)\n", + "- [Chebyshev distance](https://en.wikipedia.org/wiki/Chebyshev_distance)\n", + "\n", + "For comparison, we also provide you with a random distance heuristic - feel free to use them for debugging your implementations if it helps! " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "859bbb736254964fe70b6c73998c7b9a", + "grade": false, + "grade_id": "cell-37c3f36c850cc52c", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + } + }, + "outputs": [], + "source": [ + "# this is a random heuristic - it returns a random number as the distance between two nodes\n", + "# we use it for testing - you can also use it for debbuging if you want\n", + "def random_heuristic(current: Node, goal: Node):\n", + " return random.random()\n", + "\n", + "def cityblock_heuristic(current: Node, goal: Node):\n", + " # YOUR CODE HERE\n", + " raise NotImplementedError()\n", + " return -1\n", + "\n", + "def euclidean_heuristic(current: Node, goal: Node):\n", + " # YOUR CODE HERE\n", + " raise NotImplementedError()\n", + " return -1\n", + "\n", + "def chebyshev_heuristic(current: Node, goal: Node):\n", + " # YOUR CODE HERE\n", + " raise NotImplementedError()\n", + " return -1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Check City Block Heuristic" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "b4bfd7b32d44d3bfe6f4511793e4fa2f", + "grade": true, + "grade_id": "cell-9bf0ab82cd12f045", + "locked": true, + "points": 1, + "schema_version": 3, + "solution": false, + "task": false + }, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# this is a testing cell, do not edit or delete\n", + "maze = ProblemFactory().create_problem_from_json(json_path='boards/tiny0.json')\n", + "maze.visualize()\n", + "\n", + "assert(cityblock_heuristic(maze.get_start_node(), maze.get_end_node()) != -1), \"it seems like you might not have implemented this heuristic yet, the distance is -1\"\n", + "assert(cityblock_heuristic(maze.get_start_node(), maze.get_end_node()) == 7.0), \"the city block heuristic returned the wrong distance between start and end node\"\n", + "assert(cityblock_heuristic(Node(None, [2, 3], None, 0, 0), maze.get_end_node()) == 3.0), \"the city block heuristic returned the wrong distance between arbitrary node and end\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Check Euclidean Heuristic" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "5cbac803847c6552e5948aa13664d4a7", + "grade": true, + "grade_id": "cell-30cd5ba142359b7e", + "locked": true, + "points": 1, + "schema_version": 3, + "solution": false, + "task": false + }, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# this is a testing cell, do not edit or delete\n", + "maze = ProblemFactory().create_problem_from_json(json_path='boards/tiny0.json')\n", + "\n", + "assert(euclidean_heuristic(maze.get_start_node(), maze.get_end_node()) != -1), \"it seems like you might not have implemented this heuristic yet, the distance is -1\"\n", + "assert(math.isclose(euclidean_heuristic(maze.get_start_node(), maze.get_end_node()), 5.0)), \"the euclidean heuristic returned the wrong distance between start and end node\"\n", + "assert(math.isclose(euclidean_heuristic(Node(None, [2, 3], None, 0, 0), maze.get_end_node()), 2.23606797749979)), \"the euclidean heuristic returned the wrong distance between arbitrary node and end\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Check Chebyshev Heuristic" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "ca7d173ebc842e01cf0ee94873621c2b", + "grade": true, + "grade_id": "cell-7d395cfb4952c216", + "locked": true, + "points": 1, + "schema_version": 3, + "solution": false, + "task": false + }, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# this is a testing cell, do not edit or delete\n", + "maze = ProblemFactory().create_problem_from_json(json_path='boards/tiny0.json')\n", + "\n", + "assert(chebyshev_heuristic(maze.get_start_node(), maze.get_end_node()) != -1), \"it seems like you might not have implemented this heuristic yet, the distance is -1\"\n", + "assert(chebyshev_heuristic(maze.get_start_node(), maze.get_end_node()) == 4.0), \"the chebyshev heuristic returned the wrong distance between start and end node\"\n", + "assert(chebyshev_heuristic(Node(None, [2, 3], None, 0, 0), maze.get_end_node()) == 2.0), \"the chebyshev heuristic returned the wrong distance between arbitrary node and end\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Implementing GBFS\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": true, + "nbgrader": { + "cell_type": "code", + "checksum": "51332bf82c052acd3d8f20d078acde5c", + "grade": false, + "grade_id": "cell-d09ad07d2e0d6517", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "class GBFS(object):\n", + " def __init__(self, heuristic):\n", + " \n", + " self.heuristic = heuristic\n", + " self.visited = None\n", + " self.fringe = None\n", + " \n", + " def solve(self, problem: Problem):\n", + " \n", + " # YOUR CODE HERE: make sure to initialise self.visited and self.fringe here! \n", + " \n", + " # YOUR CODE HERE\n", + " raise NotImplementedError()\n", + " return None\n", + "\n", + "\n", + "# reset maze before search\n", + "maze.reset()\n", + "gbfs_rand = GBFS(random_heuristic)\n", + "gbfs_rand_sol = gbfs_rand.solve(maze)\n", + "if gbfs_rand_sol is not None: \n", + " gbfs_rand_sol.pretty_print()\n", + " maze.visualize(sequences=[('gbfs rand', \"\".join(maze.get_action_sequence(gbfs_rand_sol)))])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "### Basic checks" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "da3db1e5026088e700feea53e49c52c3", + "grade": true, + "grade_id": "cell-33642543af658c78", + "locked": true, + "points": 1, + "schema_version": 3, + "solution": false, + "task": false + }, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# this is a testing cell, do not edit or delete\n", + "assert(gbfs_rand_sol is not None), \"GBFS did not return a solution\"\n", + "assert(gbfs_rand_sol.state == (4, 4)), \"GBFS did not return the expected solution\"\n", + "\n", + "assert(gbfs_rand.visited is not None), \"it seems you did not correctly initialize the visited set\"\n", + "assert(gbfs_rand.fringe is not None), \"it seems you did not correctly initialize the fringe\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "maze.reset()\n", + "gbfs_cb_sol = GBFS(cityblock_heuristic).solve(maze)\n", + "assert(gbfs_cb_sol.depth == 7), \"the solution found by city block-GBFS does not have the expected length\"\n", + "assert(gbfs_cb_sol.cost == 17), \"the solution found by city block-GBFS does not have the expected cost\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "### Check different mazes" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "c4a4cbe8458bcabe3abe68ddcfbe8d30", + "grade": true, + "grade_id": "cell-ae3066efbf1abd87", + "locked": true, + "points": 0.5, + "schema_version": 3, + "solution": false, + "task": false + }, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "tiny1 = factory.create_problem_from_json(json_path='boards/tiny1.json')\n", + "assert(GBFS(cityblock_heuristic).solve(tiny1).get_action_sequence_hash() == '0123d362bf2df8f84e7c41197827be005159724c07774ef32d9f15373a440091'), \"City block-GBFS did not return the expected solution path\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "bf20896a24cdbfb8c9017d689fb1f686", + "grade": true, + "grade_id": "cell-db152198f4515796", + "locked": true, + "points": 0.5, + "schema_version": 3, + "solution": false, + "task": false + } + }, + "outputs": [], + "source": [ + "tiny1 = factory.create_problem_from_json(json_path='boards/tiny1.json')\n", + "assert(GBFS(euclidean_heuristic).solve(tiny1).get_action_sequence_hash() == 'c283a9803562a0053fc1ea0c30d421e0b4a7a9f599c699d74477cbeeffec23bc'), \"Euclidean-GBFS did not return the expected solution path\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "a62d879a6138939e7cb466f60f56cfe0", + "grade": true, + "grade_id": "cell-8fdbf6cce29d0e2a", + "locked": true, + "points": 0.5, + "schema_version": 3, + "solution": false, + "task": false + } + }, + "outputs": [], + "source": [ + "tiny2 = factory.create_problem_from_json(json_path='boards/tiny2.json')\n", + "assert(GBFS(cityblock_heuristic).solve(tiny2).get_action_sequence_hash() == 'f5cdd7625f98bc258a52c4c332d534d9c2d9bfebc34ef4c26c11b85e15803363'), \"City block-GBFS did not return the expected solution path\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "c617df180e1c7f73e54718c88661e24d", + "grade": true, + "grade_id": "cell-1db11bbb4212e83d", + "locked": true, + "points": 0.5, + "schema_version": 3, + "solution": false, + "task": false + } + }, + "outputs": [], + "source": [ + "tiny2 = factory.create_problem_from_json(json_path='boards/tiny2.json')\n", + "assert(GBFS(chebyshev_heuristic).solve(tiny2).get_action_sequence_hash() == '919c8fb20a877be0b0da8aeda03a070febb5607348e0c7f733c2405fdb9b4f74'), \"Chebyshev-GBFS did not return the expected solution path\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "d5c02b3e9f7fc8522f91023cb92d8d73", + "grade": true, + "grade_id": "cell-0e8036184401604e", + "locked": true, + "points": 0.5, + "schema_version": 3, + "solution": false, + "task": false + } + }, + "outputs": [], + "source": [ + "tiny3 = factory.create_problem_from_json(json_path='boards/tiny3.json')\n", + "assert(GBFS(cityblock_heuristic).solve(tiny3).get_action_sequence_hash() == '0123d362bf2df8f84e7c41197827be005159724c07774ef32d9f15373a440091'), \"City block-GBFS did not return the expected solution path\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "ad55064773115aa4d3020f95be536dc9", + "grade": true, + "grade_id": "cell-900e396bd7fa8958", + "locked": true, + "points": 0.5, + "schema_version": 3, + "solution": false, + "task": false + } + }, + "outputs": [], + "source": [ + "tiny3 = factory.create_problem_from_json(json_path='boards/tiny3.json')\n", + "assert(GBFS(euclidean_heuristic).solve(tiny3).get_action_sequence_hash() == 'c283a9803562a0053fc1ea0c30d421e0b4a7a9f599c699d74477cbeeffec23bc'), \"Euclidean-GBFS did not return the expected solution path\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Implementing A*\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "9336ab8123003b4c601e75b88ab5c28b", + "grade": false, + "grade_id": "cell-d2df9b0e3d90cf00", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + } + }, + "outputs": [], + "source": [ + "class ASTAR(object):\n", + " def __init__(self, heuristic):\n", + " self.heuristic = heuristic\n", + " self.visited = None\n", + " self.fringe = None\n", + " \n", + " def solve(self, problem: Problem):\n", + " # YOUR CODE HERE: make sure to initialise self.visited and self.fringe here! \n", + " # YOUR CODE HERE\n", + " raise NotImplementedError()\n", + " return None\n", + "\n", + "# reset maze before search\n", + "maze.reset()\n", + "astar_rand = ASTAR(random_heuristic)\n", + "astar_rand_sol = astar_rand.solve(maze)\n", + "if astar_rand_sol is not None:\n", + " astar_rand_sol.pretty_print()\n", + " maze.visualize(sequences=[('astar rand', \"\".join(maze.get_action_sequence(astar_rand_sol)))])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Basic checks" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "f61060cb80e1b3fc067eeec7d8f39e54", + "grade": true, + "grade_id": "cell-a755d290a7174b17", + "locked": true, + "points": 1, + "schema_version": 3, + "solution": false, + "task": false + }, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# this is a testing cell, do not edit or delete\n", + "\n", + "assert(astar_rand_sol is not None), \"A* did not return a solution\"\n", + "assert(astar_rand_sol.state == (4, 4)), \"A* did not return the expected solution\"\n", + "assert(astar_rand.visited is not None), \"it seems you did not correctly initialize the visited set\"\n", + "assert(astar_rand.fringe is not None), \"it seems you did not correctly initialize the fringe\"\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "maze.reset()\n", + "astar_cb_sol = ASTAR(cityblock_heuristic).solve(maze)\n", + "assert(astar_cb_sol.depth == 7), \"the solution found by city block-A* does not have the expected length\"\n", + "assert(astar_cb_sol.cost == 16), \"the solution found by city block-A* does not have the expected cost\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Check different mazes" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "f4d306cb3c9cb1e6a4b650a38476bcc5", + "grade": true, + "grade_id": "cell-68702797ea5b6849", + "locked": true, + "points": 0.5, + "schema_version": 3, + "solution": false, + "task": false + }, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "tiny1 = factory.create_problem_from_json(json_path='boards/tiny1.json')\n", + "assert(ASTAR(cityblock_heuristic).solve(tiny1).get_action_sequence_hash() == '0123d362bf2df8f84e7c41197827be005159724c07774ef32d9f15373a440091'), \"City block-A* did not return the expected solution path\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "ce0da3488b52d208fad0a40ff0a4a55a", + "grade": true, + "grade_id": "cell-0de1bd74e742f9e0", + "locked": true, + "points": 0.5, + "schema_version": 3, + "solution": false, + "task": false + } + }, + "outputs": [], + "source": [ + "tiny1 = factory.create_problem_from_json(json_path='boards/tiny1.json')\n", + "assert(ASTAR(chebyshev_heuristic).solve(tiny1).get_action_sequence_hash() == '0123d362bf2df8f84e7c41197827be005159724c07774ef32d9f15373a440091'), \"Chebyshev-A* did not return the expected solution path\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "b44c62aad8ed48f02b7f9b5895adc43a", + "grade": true, + "grade_id": "cell-64c86a0262c4475d", + "locked": true, + "points": 0.5, + "schema_version": 3, + "solution": false, + "task": false + } + }, + "outputs": [], + "source": [ + "tiny2 = factory.create_problem_from_json(json_path='boards/tiny2.json')\n", + "assert(ASTAR(cityblock_heuristic).solve(tiny2).get_action_sequence_hash() == '919c8fb20a877be0b0da8aeda03a070febb5607348e0c7f733c2405fdb9b4f74'), \"City block-A* did not return the expected solution path\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "766452fa6f1d78aa6e32b0a7c50b3d49", + "grade": true, + "grade_id": "cell-2af20325ececdc6f", + "locked": true, + "points": 0.5, + "schema_version": 3, + "solution": false, + "task": false + } + }, + "outputs": [], + "source": [ + "tiny2 = factory.create_problem_from_json(json_path='boards/tiny2.json')\n", + "assert(ASTAR(euclidean_heuristic).solve(tiny2).get_action_sequence_hash() == '919c8fb20a877be0b0da8aeda03a070febb5607348e0c7f733c2405fdb9b4f74'), \"Euclidean-A* did not return the expected solution path\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "c22e6b33c93fc7256859a7dc0feab21a", + "grade": true, + "grade_id": "cell-f2ad770abd459722", + "locked": true, + "points": 0.5, + "schema_version": 3, + "solution": false, + "task": false + } + }, + "outputs": [], + "source": [ + "tiny3 = factory.create_problem_from_json(json_path='boards/tiny3.json')\n", + "assert(ASTAR(cityblock_heuristic).solve(tiny3).get_action_sequence_hash() == '061c3912f2db8f3b1418829bc321fea4dfddba01ad42d45cecf22aed99a74475'), \"City block-A* did not return the expected solution path\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "6c3c40282e5d9f28262454b2099dec72", + "grade": true, + "grade_id": "cell-c099857f831b0c3a", + "locked": true, + "points": 0.5, + "schema_version": 3, + "solution": false, + "task": false + } + }, + "outputs": [], + "source": [ + "tiny0 = factory.create_problem_from_json(json_path='boards/tiny0.json')\n", + "assert(ASTAR(chebyshev_heuristic).solve(tiny3).get_action_sequence_hash() == '061c3912f2db8f3b1418829bc321fea4dfddba01ad42d45cecf22aed99a74475'), \"Chebyshev-A* did not return the expected solution path\"" + ] + } + ], + "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.12.11" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/pig_lite b/pig_lite new file mode 160000 index 0000000..01ca762 --- /dev/null +++ b/pig_lite @@ -0,0 +1 @@ +Subproject commit 01ca762fe9a14080a38973f444fb9e77c6b52711 diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..af8ecd4 --- /dev/null +++ b/shell.nix @@ -0,0 +1,15 @@ +{ + pkgs ? import { }, +}: + +pkgs.mkShell { + buildInputs = with pkgs; [ + python3 + python3Packages.notebook + python3Packages.numpy + python3Packages.matplotlib + graphviz + python3Packages.networkx + python3Packages.pydot + ]; +}