From eea45a052c0b1cd370a017f30cae82a4a6296f3d Mon Sep 17 00:00:00 2001 From: littlefox5678901234 <106403084+littlefox5678901234@users.noreply.github.com> Date: Tue, 18 Apr 2023 15:27:08 +0530 Subject: [PATCH 1/2] Created using Colaboratory --- AI_Lab_Internal.ipynb | 702 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 702 insertions(+) create mode 100644 AI_Lab_Internal.ipynb diff --git a/AI_Lab_Internal.ipynb b/AI_Lab_Internal.ipynb new file mode 100644 index 0000000..6a8cc85 --- /dev/null +++ b/AI_Lab_Internal.ipynb @@ -0,0 +1,702 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "provenance": [], + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "source": [ + "The code uses the A* algorithm to find the shortest path between a start point and a goal point on a 2D grid with obstacles. Here are the steps in the code:\n", + "\n", + "1) Import the PriorityQueue class from the queue module.\n", + "\n", + "2) Define the heuristic function that estimates the distance from a given point to the goal point.\n", + "\n", + "3) Define the astar function that takes in the start point, goal point, and the obstacles on the grid as parameters.\n", + "\n", + "4) Initialize a set called visited to keep track of the points that have already been explored and a priority queue called frontier to keep track of the points to explore.\n", + "\n", + "5) Add the start point to the frontier with its f-value (the sum of the g-value and the heuristic value), an empty path, and a g-value of 0.\n", + "While the frontier is not empty:\n", + "\n", + "a. Get the point with the lowest f-value from the frontier.\n", + "\n", + "b. If this point is the goal point, return the path to reach it.\n", + "\n", + "c. If the point is an obstacle or has already been visited, skip it and continue with the next point.\n", + "\n", + "d. Mark the point as visited.\n", + "\n", + "e. Add the neighboring points to the frontier with updated path and g-values.\n", + "\n", + "6) Return None if no path is found." + ], + "metadata": { + "id": "MyxS0pi0-7ky" + } + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "pMYjb9mFRiDK", + "outputId": "00fadc9e-405e-48e1-f0f2-1d92c3fb32ae" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Shortest path: [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1, 4), (2, 4), (3, 4), (4, 4)]\n" + ] + } + ], + "source": [ + "#Implement the A* Algorithm to find the shortest path between 2 points on a 2D grid with obstacles\n", + "\n", + "from queue import PriorityQueue\n", + "def heuristic(point, goal):\n", + " return abs(point[0] - goal[0]) + abs(point[1] - goal[1])\n", + "def astar(start, goal, obstacles):\n", + " \"\"\"\n", + " Returns the shortest path between start and goal on a 2D grid with obstacles using the A* algorithm.\n", + " \"\"\"\n", + " # Define a heuristic function that estimates the distance from any point to the goal\n", + " \n", + "\n", + " # Initialize the set of visited points and the priority queue of points to explore\n", + " visited = set()\n", + " frontier = PriorityQueue()\n", + " frontier.put((heuristic(start, goal), start, [], 0))\n", + "\n", + " # Explore the frontier until the goal is reached or no more points can be explored\n", + " while not frontier.empty():\n", + " # Get the next point to explore\n", + " f_value, current, path, g_value = frontier.get()\n", + "\n", + " # Check if the goal has been reached\n", + " if current == goal:\n", + " return path + [current]\n", + "\n", + " # Check if the current point is an obstacle or has already been visited\n", + " if current in visited or current in obstacles:\n", + " continue\n", + "\n", + " # Mark the current point as visited\n", + " visited.add(current)\n", + "\n", + " # Add the neighbors of the current point to the frontier\n", + " for dx, dy in [(0, -1), (0, 1), (-1, 0), (1, 0)]:\n", + " neighbor = (current[0] + dx, current[1] + dy)\n", + " new_g_value = g_value + 1\n", + " if neighbor not in visited:\n", + " frontier.put((new_g_value + heuristic(neighbor, goal), neighbor, path + [current], new_g_value))\n", + "\n", + " # Return None if no path is found\n", + " return None\n", + "# Define the start and goal points and the set of obstacles\n", + "start = (0, 0)\n", + "goal = (4, 4)\n", + "obstacles = [(1, 2), (2, 2), (3, 2), (3, 3)]\n", + "\n", + "# Find the shortest path using the A* algorithm\n", + "path = astar(start, goal, obstacles)\n", + "\n", + "# Print the path\n", + "if path is None:\n", + " print(\"No path found.\")\n", + "else:\n", + " print(\"Shortest path:\", path)" + ] + }, + { + "cell_type": "code", + "source": [ + "#Dijkstra's Algorithm to find the shortest path between 2 points on a 2D grid with obstacles\n", + "from heapq import heappop, heappush\n", + "\n", + "def dijkstra(start, goal, obstacles, m, n):\n", + " grid = [(i, j) for i in range(m) for j in range(n)]\n", + " start_index = grid.index(start)\n", + " goal_indices = goal\n", + " \n", + " heap = [(0, start_index, [])]\n", + " visited = set()\n", + " distances = {start_index: 0}\n", + " \n", + " while heap:\n", + " (d, curr, path) = heappop(heap)\n", + " if curr in visited:\n", + " continue\n", + " visited.add(curr)\n", + " if (curr//m, curr%n) == goal:\n", + " return distances[curr], path + [(curr//m, curr%n)]\n", + " for neighbor in get_neighbors(curr, grid, obstacles, m, n):\n", + " if neighbor in visited:\n", + " continue\n", + " new_distance = distances[curr] + 1 # assuming all edges have weight 1\n", + " if neighbor not in distances.keys() or new_distance < distances[neighbor]:\n", + " distances[neighbor] = new_distance\n", + " heappush(heap, (new_distance, neighbor, path + [(curr//m, curr%n)]))\n", + " return None, None\n", + "\n", + "def get_neighbors(curr, grid, obstacles, m, n):\n", + " neighbors = []\n", + " for dx, dy in [(0, 1), (1, 0), (0, -1), (-1, 0)]:\n", + " x, y = grid[curr][0] + dx, grid[curr][1] + dy\n", + " if x < 0 or x >= m or y < 0 or y >= n:\n", + " continue\n", + " if (x, y) in obstacles:\n", + " continue\n", + " neighbors.append(grid.index((x, y)))\n", + " return neighbors\n", + "\n", + "# Define the start node, goal nodes, and obstacles\n", + "start = (0, 0)\n", + "goals = (3, 3)\n", + "obstacles = []\n", + "m = 4\n", + "n = 4\n", + "\n", + "# Run Dijkstra's algorithm\n", + "dist, path = dijkstra(start, goals, obstacles, m, n)\n", + "\n", + "# Print the result\n", + "if dist is not None:\n", + " print(f\"The shortest path from {start} to {goals} is {dist} steps. The path is {path}\")\n", + "else:\n", + " print(\"There is no path from the start node to any of the goal nodes.\")\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "O_hUB2pHWNQb", + "outputId": "6c26d56c-eca4-4420-8f8a-7abd1211869e" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "The shortest path from (0, 0) to (3, 3) is 6 steps. The path is [(0, 0), (0, 1), (0, 2), (0, 3), (1, 3), (2, 3), (3, 3)]\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "#Recording times taken to run A* on the 2D grid while uniformly varying grid size\n", + "import time\n", + "times=[]\n", + "for i in range(60):\n", + " start = time.time()\n", + " astar((0,0), (i,i), [])\n", + " end = time.time()\n", + " times.append(end-start)\n", + "print(times)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "Z3hRSN16amiZ", + "outputId": "aff73094-26cc-4835-ecb0-1842ffbde1eb" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "[7.104873657226562e-05, 9.560585021972656e-05, 0.00018548965454101562, 0.00032019615173339844, 0.0005145072937011719, 0.0007455348968505859, 0.000993490219116211, 0.002356290817260742, 0.0016820430755615234, 0.0020651817321777344, 0.006617546081542969, 0.0030014514923095703, 0.0035026073455810547, 0.008675336837768555, 0.004861116409301758, 0.005401134490966797, 0.0062634944915771484, 0.006893157958984375, 0.008358955383300781, 0.008827924728393555, 0.010068893432617188, 0.011027812957763672, 0.011646747589111328, 0.012610197067260742, 0.013443946838378906, 0.016542434692382812, 0.01647472381591797, 0.017716169357299805, 0.01840829849243164, 0.020115375518798828, 0.020951032638549805, 0.025582075119018555, 0.024633407592773438, 0.026372909545898438, 0.026763916015625, 0.028803110122680664, 0.030308246612548828, 0.0319976806640625, 0.03377032279968262, 0.03607988357543945, 0.03740119934082031, 0.04382491111755371, 0.04089665412902832, 0.04291820526123047, 0.04574084281921387, 0.049250125885009766, 0.052870750427246094, 0.05611896514892578, 0.059676170349121094, 0.061751365661621094, 0.061179399490356445, 0.06642675399780273, 0.06838607788085938, 0.07241106033325195, 0.07209444046020508, 0.08333635330200195, 0.08674979209899902, 0.07637786865234375, 0.07918739318847656, 0.08424735069274902]\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "#Recording times taken to run Dijkstra's Algorithm on the 2D grid while uniformly varying grid size\n", + "import time\n", + "times1=[]\n", + "for i in range(60):\n", + " start = time.time()\n", + " dijkstra((0,0), (i,i), [],i+1,i+1)\n", + " end = time.time()\n", + " times1.append(end-start)\n", + "print(times1)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "FDGTJYDAdHg_", + "outputId": "56b9e902-d20f-4a78-ec89-25dd336dc244" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "[1.811981201171875e-05, 3.218650817871094e-05, 6.628036499023438e-05, 0.00010704994201660156, 0.00018072128295898438, 0.0009953975677490234, 0.0003769397735595703, 0.0005831718444824219, 0.0009672641754150391, 0.024907588958740234, 0.0018062591552734375, 0.006893157958984375, 0.005394458770751953, 0.012332916259765625, 0.008365392684936523, 0.0061798095703125, 0.00972604751586914, 0.01140451431274414, 0.012651205062866211, 0.016077756881713867, 0.018657922744750977, 0.01715850830078125, 0.019794464111328125, 0.015165090560913086, 0.017676830291748047, 0.021033287048339844, 0.024349451065063477, 0.02770829200744629, 0.03122687339782715, 0.03521609306335449, 0.04042553901672363, 0.04510307312011719, 0.05338764190673828, 0.0573122501373291, 0.07101845741271973, 0.0719442367553711, 0.08297610282897949, 0.09609150886535645, 0.10378789901733398, 0.11063075065612793, 0.1382460594177246, 0.13142609596252441, 0.14563345909118652, 0.15976858139038086, 0.27063560485839844, 0.22902631759643555, 0.20594310760498047, 0.22767114639282227, 0.23844552040100098, 0.2747776508331299, 0.29952192306518555, 0.31092166900634766, 0.34259676933288574, 0.3677806854248047, 0.3935234546661377, 0.42641425132751465, 0.4452054500579834, 0.47357654571533203, 0.5131165981292725, 0.5543792247772217]\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "#Plotting and comparing the times taken by A* Algorithm and Dijkstra's Algorithm for uniformly varying grid sizes\n", + "import matplotlib.pyplot as plt\n", + "plt.plot(list(range(60)), times, color = \"blue\", label = \"A* Algorithm\")\n", + "plt.plot(list(range(60)), times1, color = \"red\", label = \"Dijkstra's Algorithm\")\n", + "plt.legend()\n", + "plt.xlabel(\"Size of the 2D grid\")\n", + "plt.ylabel(\"Time taken in seconds\")\n", + "plt.title(\"Perfomance of A* vs Dijsltra's Algorithm for searching in a 2D grid with obstacles.\")" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 489 + }, + "id": "SqID279rjgcW", + "outputId": "352e06fc-e700-4253-b120-b0ada5dd64d6" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "Text(0.5, 1.0, \"Perfomance of A* vs Dijsltra's Algorithm for searching in a 2D grid with obstacles.\")" + ] + }, + "metadata": {}, + "execution_count": 12 + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "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WIhyicElu3Z2doiIiEhTfvbsWZQoUUKGiIiIiAqAhw+Bv/+W1vv3lzcWolxkcMlut27d8O233yIyMhIKhQJqtRpHjx7F119/jZ49e8odHhERkX5avFhqs/vhh0DFinJHQ5RrDC7Z/emnn1ChQgW4ubkhLi4OlSpVQv369VG3bl388MMPcodHRESkf9Rqdkwjg2Ww4+zev38fFy9eRFxcHGrUqAEvLy+5Q8o2jtNHRET5avduoHlzwM4OePQIMDeXO6ICiddv/WRw0wVruLm5wc3NDSqVChcvXsSLFy9gb28vd1hERET6R9MxrWdPJrpkcAyuGcOwYcOwcOFCAIBKpUJAQABq1qwJNzc3HDp0SN7giIiI9E1EBLB1q7TOjmlkgAwu2V2/fj2qVasGANi2bRvu3LmDa9eu4auvvsL3338vc3RERER6ZskS4PVroG5doEoVuaMhynUGl+w+ffoUzs7OAIAdO3aga9euKFeuHPr27YuLFy/KHB0REZEeUauBBQukdXZMIwNlcMmuk5MTrly5ApVKhV27dqFJkyYAgISEBBgbG8scHRERkR7Zvx8ICwNsbYEuXeSOhihPGFwHtT59+qBr165wcXGBQqFAYGAgAODEiROoUKGCzNERERHpkblzpdtPPgEsLOSNhSiPGFyyO27cOFSpUgX3799Hly5doFQqAQDGxsYYOXKkzNERERHpASGAMWOAjRul++yYRgbMYMfZLcg4Th8REeWZ16+BL754M4nEpEnAd9/JG5OB4PVbPxlczS4RERFl4NUroFs3aagxIyOpGQNrdcnAGVwHtbwwa9YseHh4wMzMDH5+fjh58mSG227cuBG+vr6ws7ODpaUlqlevjmXLluVjtEREROl48QJo2lRKdM3MgA0bmOhSocBkNwtr1qxBcHAwxo4di9DQUFSrVg3NmjVDVFRUutsXLVoU33//PY4fP44LFy6gT58+6NOnD3bv3p3PkRMREf3fgwdAvXrAv/9KUwLv2QO0by93VET5gm12s+Dn54datWph5syZAAC1Wg03NzcMHjw42x3eatasiVatWmHixInZ2p5tfoiIKNdcvQo0awbcvw+4ugK7d3PyiDzC67d+Msg2u2q1Grdu3UJUVBTUarXOY/Xr18/2fpKTk3HmzBmMGjVKW2ZkZITAwEAcP348y+cLIXDgwAFcv34dkydPznC7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\n" + }, + "metadata": {} + } + ] + }, + { + "cell_type": "code", + "source": [ + "#Extending the A* Algorithm to a 3D version of the grid with obstacles\n", + "from queue import PriorityQueue\n", + "\n", + "def astar3D(start, goal, obstacles):\n", + " \"\"\"\n", + " Returns the shortest path between start and goal on a 2D grid with obstacles using the A* algorithm.\n", + " \"\"\"\n", + " # Define a heuristic function that estimates the distance from any point to the goal\n", + " def heuristic(point):\n", + " return abs(point[0] - goal[0]) + abs(point[1] - goal[1]) + abs(point[2] - goal[2])\n", + "\n", + " # Initialize the set of visited points and the priority queue of points to explore\n", + " visited = set()\n", + " frontier = PriorityQueue()\n", + " frontier.put((heuristic(start), start, [], 0))\n", + "\n", + " # Explore the frontier until the goal is reached or no more points can be explored\n", + " while not frontier.empty():\n", + " # Get the next point to explore\n", + " f_value, current, path, g_value = frontier.get()\n", + "\n", + " # Check if the goal has been reached\n", + " if current == goal:\n", + " return path + [current]\n", + "\n", + " # Check if the current point is an obstacle or has already been visited\n", + " if current in visited or current in obstacles:\n", + " continue\n", + "\n", + " # Mark the current point as visited\n", + " visited.add(current)\n", + "\n", + " # Add the neighbors of the current point to the frontier\n", + " for dx, dy, dz in [(0, 0, -1), (0, 0, 1), (0, -1, 0), (0, 1, 0),(1, 0, 0), (-1, 0, 0)]:\n", + " neighbor = (current[0] + dx, current[1] + dy, current[2] + dz)\n", + " new_g_value = g_value + 1\n", + " if neighbor not in visited:\n", + " frontier.put((new_g_value + heuristic(neighbor), neighbor, path + [current], new_g_value))\n", + "\n", + " # Return None if no path is found\n", + " return None\n", + "# Define the start and goal points and the set of obstacles\n", + "start = (0, 0, 0)\n", + "goal = (4, 4, 4)\n", + "obstacles = [(1, 2, 1), (2, 2, 2), (3, 2, 3), (3, 3, 1)]\n", + "\n", + "# Find the shortest path using the A* algorithm\n", + "path = astar3D(start, goal, obstacles)\n", + "\n", + "# Print the path\n", + "if path is None:\n", + " print(\"No path found.\")\n", + "else:\n", + " print(\"Shortest path:\", path)\n", + " print(\"length of shortest path\", len(path))\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "xWiG-h9sdeXp", + "outputId": "62ebaef0-4d2c-4a20-b493-af030f0043e2" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Shortest path: [(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 0, 3), (0, 0, 4), (0, 1, 4), (0, 2, 4), (0, 3, 4), (0, 4, 4), (1, 4, 4), (2, 4, 4), (3, 4, 4), (4, 4, 4)]\n", + "length of shortest path 13\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "# A* for 2D grid with multiple goals\n", + "from queue import PriorityQueue\n", + "\n", + "def heuristic(point, goals):\n", + " heuristic = abs(point[0] - goals[0][0]) + abs(point[1] - goals[0][1])\n", + " for i in goals:\n", + " heuristic = min(heuristic, abs(point[0] - i[0]) + abs(point[1] - i[1]))\n", + " return heuristic \n", + "def astar(start, goals, obstacles):\n", + " \"\"\"\n", + " Returns the shortest path between start and goal on a 2D grid with obstacles using the A* algorithm.\n", + " \"\"\"\n", + " # Define a heuristic function that estimates the distance from any point to the goal\n", + "\n", + " # Initialize the set of visited points and the priority queue of points to explore\n", + " visited = set()\n", + " frontier = PriorityQueue()\n", + " frontier.put((heuristic(start, goals), start, [], 0))\n", + "\n", + " # Explore the frontier until the goal is reached or no more points can be explored\n", + " while not frontier.empty():\n", + " # Get the next point to explore\n", + " g_value, current, path, f_value = frontier.get()\n", + "\n", + " # Check if the goal has been reached\n", + " if current in goals:\n", + " return path + [current]\n", + "\n", + " # Check if the current point is an obstacle or has already been visited\n", + " if current in visited or current in obstacles:\n", + " continue\n", + "\n", + " # Mark the current point as visited\n", + " visited.add(current)\n", + "\n", + " # Add the neighbors of the current point to the frontier\n", + " for dx, dy in [(0, -1), (0, 1), (-1, 0), (1, 0)]:\n", + " neighbor = (current[0] + dx, current[1] + dy)\n", + " new_g_value = g_value + 1\n", + " if neighbor not in visited:\n", + " frontier.put((new_g_value + heuristic(neighbor, goals), neighbor, path + [current], new_g_value))\n", + "\n", + " # Return None if no path is found\n", + " return None\n", + "# Define the start and goal points and the set of obstacles\n", + "start = (0, 0)\n", + "goals = [(4, 4), (2,3), (1,3)]\n", + "obstacles = [(1, 2), (2, 2), (3, 2), (3, 3)]\n", + "\n", + "# Find the shortest path using the A* algorithm\n", + "path = astar(start, goals, obstacles)\n", + "\n", + "# Print the path\n", + "if path is None:\n", + " print(\"No path found.\")\n", + "else:\n", + " print(\"Shortest path:\", path)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "i-OlKCOiK1nw", + "outputId": "351ed1fe-a2d5-4141-b2a5-3eaf382453cd" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Shortest path: [(0, 0), (0, 1), (0, 2), (0, 3), (1, 3)]\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "# A* for 8 puzzles problem\n", + "from heapq import heappop, heappush\n", + "\n", + "def solve(initial_state, goal_state):\n", + " heap = [(heuristic(initial_state), initial_state, [initial_state], 0)]\n", + " visited = set() \n", + " while heap:\n", + " f_value, current, path, g_value = heappop(heap)\n", + " if current == goal_state:\n", + " return g_value, current, path\n", + " if tuple(map(tuple,current)) in visited:\n", + " continue\n", + " visited.add(tuple(map(tuple,current)))\n", + " for neighbor in neighbors(current):\n", + " heappush(heap, (g_value + 1 + heuristic(neighbor), neighbor, path + [neighbor], g_value + 1))\n", + " return None, None, None # no solution found\n", + "\n", + "def neighbors(state):\n", + " neighbors = []\n", + " row, col = next((i, j) for i, row in enumerate(state) for j, val in enumerate(row) if val == 0)\n", + " for d_row, d_col in [(0, 1), (0, -1), (1, 0), (-1, 0)]:\n", + " new_row, new_col = row + d_row, col + d_col\n", + " if 0 <= new_row < 3 and 0 <= new_col < 3:\n", + " new_state = [row[:] for row in state]\n", + " new_state[row][col], new_state[new_row][new_col] = new_state[new_row][new_col], new_state[row][col]\n", + " neighbors.append(new_state)\n", + " return neighbors\n", + "\n", + "def heuristic(state):\n", + " distance = 0\n", + " for i in range(3):\n", + " for j in range(3):\n", + " if state[i][j] != 0:\n", + " x, y = divmod(state[i][j]-1, 3)\n", + " distance += abs(x-i) + abs(y-j)\n", + " return distance\n", + "\n", + "def path_to_moves(path):\n", + " moves = []\n", + " for i in range(len(path) - 1):\n", + " current, next = path[i], path[i+1]\n", + " for row in range(3):\n", + " for col in range(3):\n", + " if current[row][col] == 0:\n", + " row1, col1 = row, col\n", + " if next[row][col] == 0:\n", + " row2, col2 = row, col\n", + " if row1 > row2:\n", + " moves.append('up')\n", + " elif row1 < row2:\n", + " moves.append('down')\n", + " elif col1 > col2:\n", + " moves.append('left')\n", + " elif col1 < col2:\n", + " moves.append('right')\n", + " return moves\n", + "\n", + "goal_state = [[1, 2, 3], [4, 5, 6], [7, 8, 0]]\n", + "initial_state = [[6, 4, 7], [8, 5, 0], [3, 2, 1]]\n", + "length, state, path = solve(initial_state, goal_state)\n", + "if path is not None:\n", + " print(\"The number of steps required to reach goal state is: \", len(path)-1)\n", + " print(\"The required sequence of steps to reach goal state is: \", *path_to_moves(path))\n", + "\n", + " print(\"The sequence of puzzle states at each step is: \")\n", + " for i in path:\n", + " for j in range(3):\n", + " for k in range(3):\n", + " print(i[j][k], end = \" \")\n", + " print()\n", + " print()\n", + "else:\n", + " print(\"The goal state cannot be reached from this configuration.\")" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "CpbihGSHMsqb", + "outputId": "2d134bb7-fdaa-477f-94bc-d5dde0953a98" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "The number of steps required to reach goal state is: 31\n", + "The required sequence of steps to reach goal state is: down left left up right up left down right right up left down down left up up right down right down left up right up left down left down right right\n", + "The sequence of puzzle states at each step is: \n", + "6 4 7 \n", + "8 5 0 \n", + "3 2 1 \n", + "\n", + "6 4 7 \n", + "8 5 1 \n", + "3 2 0 \n", + "\n", + "6 4 7 \n", + "8 5 1 \n", + "3 0 2 \n", + "\n", + "6 4 7 \n", + "8 5 1 \n", + "0 3 2 \n", + "\n", + "6 4 7 \n", + "0 5 1 \n", + "8 3 2 \n", + "\n", + "6 4 7 \n", + "5 0 1 \n", + "8 3 2 \n", + "\n", + "6 0 7 \n", + "5 4 1 \n", + "8 3 2 \n", + "\n", + "0 6 7 \n", + "5 4 1 \n", + "8 3 2 \n", + "\n", + "5 6 7 \n", + "0 4 1 \n", + "8 3 2 \n", + "\n", + "5 6 7 \n", + "4 0 1 \n", + "8 3 2 \n", + "\n", + "5 6 7 \n", + "4 1 0 \n", + "8 3 2 \n", + "\n", + "5 6 0 \n", + "4 1 7 \n", + "8 3 2 \n", + "\n", + "5 0 6 \n", + "4 1 7 \n", + "8 3 2 \n", + "\n", + "5 1 6 \n", + "4 0 7 \n", + "8 3 2 \n", + "\n", + "5 1 6 \n", + "4 3 7 \n", + "8 0 2 \n", + "\n", + "5 1 6 \n", + "4 3 7 \n", + "0 8 2 \n", + "\n", + "5 1 6 \n", + "0 3 7 \n", + "4 8 2 \n", + "\n", + "0 1 6 \n", + "5 3 7 \n", + "4 8 2 \n", + "\n", + "1 0 6 \n", + "5 3 7 \n", + "4 8 2 \n", + "\n", + "1 3 6 \n", + "5 0 7 \n", + "4 8 2 \n", + "\n", + "1 3 6 \n", + "5 7 0 \n", + "4 8 2 \n", + "\n", + "1 3 6 \n", + "5 7 2 \n", + "4 8 0 \n", + "\n", + "1 3 6 \n", + "5 7 2 \n", + "4 0 8 \n", + "\n", + "1 3 6 \n", + "5 0 2 \n", + "4 7 8 \n", + "\n", + "1 3 6 \n", + "5 2 0 \n", + "4 7 8 \n", + "\n", + "1 3 0 \n", + "5 2 6 \n", + "4 7 8 \n", + "\n", + "1 0 3 \n", + "5 2 6 \n", + "4 7 8 \n", + "\n", + "1 2 3 \n", + "5 0 6 \n", + "4 7 8 \n", + "\n", + "1 2 3 \n", + "0 5 6 \n", + "4 7 8 \n", + "\n", + "1 2 3 \n", + "4 5 6 \n", + "0 7 8 \n", + "\n", + "1 2 3 \n", + "4 5 6 \n", + "7 0 8 \n", + "\n", + "1 2 3 \n", + "4 5 6 \n", + "7 8 0 \n", + "\n" + ] + } + ] + } + ] +} \ No newline at end of file From 672b3c82a74c27bc17939557b26066fd80360705 Mon Sep 17 00:00:00 2001 From: littlefox5678901234 <106403084+littlefox5678901234@users.noreply.github.com> Date: Tue, 18 Apr 2023 15:42:16 +0530 Subject: [PATCH 2/2] Created using Colaboratory