From 86d0f8d8674f565fbec646d7e661bfe6b53749c7 Mon Sep 17 00:00:00 2001 From: Dragneel7 Date: Sat, 13 Jan 2018 03:21:00 +0530 Subject: [PATCH 1/5] rebase with master --- search.ipynb | 366 +++++++++++++++++++-------------------------------- search.py | 90 +++++++++++++ 2 files changed, 227 insertions(+), 229 deletions(-) diff --git a/search.ipynb b/search.ipynb index 019ea8eb4..eff00283c 100644 --- a/search.ipynb +++ b/search.ipynb @@ -80,7 +80,9 @@ { "cell_type": "code", "execution_count": 2, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "%psource Problem" @@ -120,7 +122,9 @@ { "cell_type": "code", "execution_count": 3, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "%psource GraphProblem" @@ -136,7 +140,9 @@ { "cell_type": "code", "execution_count": 4, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "romania_map = UndirectedGraph(dict(\n", @@ -181,7 +187,9 @@ { "cell_type": "code", "execution_count": 5, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "romania_problem = GraphProblem('Arad', 'Bucharest', romania_map)" @@ -212,11 +220,7 @@ "name": "stdout", "output_type": "stream", "text": [ -<<<<<<< HEAD - "{'Rimnicu': (233, 410), 'Timisoara': (94, 410), 'Iasi': (473, 506), 'Neamt': (406, 537), 'Fagaras': (305, 449), 'Giurgiu': (375, 270), 'Urziceni': (456, 350), 'Mehadia': (168, 339), 'Lugoj': (165, 379), 'Sibiu': (207, 457), 'Oradea': (131, 571), 'Zerind': (108, 531), 'Craiova': (253, 288), 'Hirsova': (534, 350), 'Arad': (91, 492), 'Vaslui': (509, 444), 'Drobeta': (165, 299), 'Bucharest': (400, 327), 'Eforie': (562, 293), 'Pitesti': (320, 368)}\n" -======= "{'Oradea': (131, 571), 'Eforie': (562, 293), 'Timisoara': (94, 410), 'Hirsova': (534, 350), 'Bucharest': (400, 327), 'Rimnicu': (233, 410), 'Fagaras': (305, 449), 'Lugoj': (165, 379), 'Giurgiu': (375, 270), 'Mehadia': (168, 339), 'Pitesti': (320, 368), 'Drobeta': (165, 299), 'Craiova': (253, 288), 'Sibiu': (207, 457), 'Iasi': (473, 506), 'Urziceni': (456, 350), 'Vaslui': (509, 444), 'Neamt': (406, 537), 'Zerind': (108, 531), 'Arad': (91, 492)}\n" ->>>>>>> 8561c52d63fcaef4c0f99d997073aeb93e926e56 ] } ], @@ -235,26 +239,10 @@ { "cell_type": "code", "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "ename": "ImportError", - "evalue": "No module named 'matplotlib'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mImportError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mget_ipython\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrun_line_magic\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'matplotlib'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'inline'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mnetworkx\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mnx\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mmatplotlib\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpyplot\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mmatplotlib\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mlines\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/.local/lib/python3.5/site-packages/IPython/core/interactiveshell.py\u001b[0m in \u001b[0;36mrun_line_magic\u001b[0;34m(self, magic_name, line, _stack_depth)\u001b[0m\n\u001b[1;32m 2093\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'local_ns'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msys\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_getframe\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstack_depth\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mf_locals\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2094\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbuiltin_trap\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2095\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2096\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2097\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m\u001b[0m in \u001b[0;36mmatplotlib\u001b[0;34m(self, line)\u001b[0m\n", - "\u001b[0;32m~/.local/lib/python3.5/site-packages/IPython/core/magic.py\u001b[0m in \u001b[0;36m\u001b[0;34m(f, *a, **k)\u001b[0m\n\u001b[1;32m 185\u001b[0m \u001b[0;31m# but it's overkill for just that one bit of state.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 186\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mmagic_deco\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 187\u001b[0;31m \u001b[0mcall\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mlambda\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mk\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mk\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 188\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 189\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mcallable\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/.local/lib/python3.5/site-packages/IPython/core/magics/pylab.py\u001b[0m in \u001b[0;36mmatplotlib\u001b[0;34m(self, line)\u001b[0m\n\u001b[1;32m 97\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Available matplotlib backends: %s\"\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0mbackends_list\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 98\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 99\u001b[0;31m \u001b[0mgui\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbackend\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshell\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0menable_matplotlib\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgui\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 100\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_show_matplotlib_backend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgui\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbackend\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 101\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/.local/lib/python3.5/site-packages/IPython/core/interactiveshell.py\u001b[0m in \u001b[0;36menable_matplotlib\u001b[0;34m(self, gui)\u001b[0m\n\u001b[1;32m 2964\u001b[0m \"\"\"\n\u001b[1;32m 2965\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mIPython\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcore\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mpylabtools\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mpt\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2966\u001b[0;31m \u001b[0mgui\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbackend\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfind_gui_and_backend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgui\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpylab_gui_select\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2967\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2968\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mgui\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0;34m'inline'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/.local/lib/python3.5/site-packages/IPython/core/pylabtools.py\u001b[0m in \u001b[0;36mfind_gui_and_backend\u001b[0;34m(gui, gui_select)\u001b[0m\n\u001b[1;32m 268\u001b[0m \"\"\"\n\u001b[1;32m 269\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 270\u001b[0;31m \u001b[0;32mimport\u001b[0m \u001b[0mmatplotlib\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 271\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 272\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mgui\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mgui\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0;34m'auto'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mImportError\u001b[0m: No module named 'matplotlib'" - ] - } - ], + "metadata": { + "collapsed": true + }, + "outputs": [], "source": [ "%matplotlib inline\n", "import networkx as nx\n", @@ -277,20 +265,10 @@ { "cell_type": "code", "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'nx' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# initialise a graph\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mG\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mGraph\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;31m# use this while labeling nodes in the map\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mnode_labels\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdict\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mNameError\u001b[0m: name 'nx' is not defined" - ] - } - ], + "metadata": { + "collapsed": true + }, + "outputs": [], "source": [ "# initialise a graph\n", "G = nx.Graph()\n", @@ -1275,51 +1253,32 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## A* Search Heuristics Comparison\n", - "\n", - "Different Heuristics have different efficiency in solving a particular problem via A* search which is generally defined by the node of explored nodes as well as the branching factor. With the help of the Classic 8* Puzzle we can effectively visualize the difference in performance of these heuristics. \n", + "## A* Heuristics\n", "\n", - "### 8-Puzzle Problem\n", + "Different heuristics provide different have different efficiency in solving A* problems which are generally defined by the number of explored nodes as well as the branching factor. With the classic 8 puzzle we can show the efficiency of different heuristics through the number of explored nodes.\n", "\n", - "*8-Puzzle Problem* is another problem that is classified as NP hard for which genetic algorithms provide a better solution than any pre-existing ones.\n", + "### 8 Puzzle Problem\n", "\n", - "The *8-Puzzle Problem* consists of a *3x3 tray* in which 8 tiles numbered 1-8 are placed and the 9th tile is uncovered. The aim of the game is that given a initial placement of the tiles, we have to reach the goal state on the constraint that a tile adjacent to be the blank space can be slid into that space.\n", + "The *8 Puzzle Problem* consists of a 3x3 tray in which the goal is to get the initial configuration to the goal state by shifting the numbered tiles into the blank space.\n", "\n", - "*example:*\n", - " Initial State Goal State\n", + "example:- \n", "\n", - " | 7 | 2 | 4 | | | 1 | 2 |\n", - " | 5 | | 6 | ----> | 3 | 4 | 5 |\n", - " | 8 | 3 | 1 | | 6 | 7 | 8 |\n", - "\n", - "We have a total of 8+1(blank) tiles giving us total of 9! initial configurations but of all these configurations only 9!/2 can lead to a solution.The solvability can be checked by calculating the *Permutation Inversion* of each tile and then summing it up.\n", - "Inversion is defined as when a tile preceeds another tile with lower number.\n", - "Let's calculate the Permutation Inversion of the example shown above -\n", - " \n", - " Tile 7 -> 6 Inversions (for tile 2, 4, 5, 6, 3, 1)\n", - " Tile 2 -> 1 Inversions\n", - " Tile 4 -> 2 Inversions\n", - " Tile 5 -> 2 Inversions\n", - " Tile 6 -> 2 Inversions\n", - " Tile 8 -> 2 Inversions\n", - " Tile 3 -> 1 Inversions\n", - " Tile 1 -> 0 Inversions\n", - "Total Inversions = 16 Inversions, \n", - "Is total Inversions are even then the initial configuration is solvable else the configuration is impossible to solve.\n", + " Initial State Goal State\n", + " | 7 | 2 | 4 | | 0 | 1 | 2 |\n", + " | 5 | 0 | 6 | | 3 | 4 | 5 |\n", + " | 8 | 3 | 1 | | 6 | 7 | 8 |\n", + " \n", + "We have a total of 9 blank tiles giving us a total of 9! initial configuration but not all of these are solvable, the solvability of a configuration can be checked by calculating the Inversion Permutation.\n", "\n", - "For example we can have a state \"724506831\" where 0 represents the empty tile.\n", + "#### Heuristics :-\n", "\n", - "#### Heuristics:-\n", - "1.) Manhattan Distance:- For the 8 Puzzle problem \"Manhattan distance is defined as the distance of a tile from its \n", - " goal. In the example shown above the manhattan distance for the 'numbered tile 1' is 4\n", - " (2 unit left and 2 unit up).\n", + "1.) Manhattan Distance:- For the 8 puzzle problem Manhattan distance is defined as the distance of a tile from its goal state( for the tile numbered '1' in the initial configuration Manhattan distance is 4 \"2 for left and 2 for upward displacement\").\n", "\n", - "2.) No. of Misplaced Tiles:- This heuristics calculates the number of misplaced tile in the state from the goal \n", - " state.\n", + "2.) No. of Misplaced Tiles:- The heuristic calculates the number of misplaced tiles between the current state and goal state.\n", "\n", - "3.) Sqrt of Manhattan Distance:- Uses the sqaure root of the Manhattan distance\n", + "3.) Sqrt of Manhattan Distance:- It calculates the square root of Manhattan distance.\n", "\n", - "4.) Max Heuristic :- Score on the basis of max of Manhattan Distance and No. of Misplced tiles." + "4.) Max Heuristic:- It assign the score as max of Manhattan Distance and No. of misplaced tiles. " ] }, { @@ -1328,128 +1287,43 @@ "metadata": {}, "outputs": [], "source": [ - "# define heuristics\n", + "# heuristics for 8 Puzzle Problem\n", + "\n", "def linear(state,goal):\n", " return sum([1 if state[i] != goal[i] else 0 for i in range(8)])\n", "\n", "def manhanttan(state,goal):\n", - " index_goal = {0:[2,2], 1:[0,0], 2:[0,1], 3:[0,2], 4:[1,0], 5:[1,1], 6:[1,2], 7:[2,0], 8:[2,1]}\n", - " index_state = {}\n", - " index = [[0,0], [0,1], [0,2], [1,0], [1,1], [1,2], [2,0], [2,1], [2,2]]\n", - " x=0\n", - " y=0\n", - " for i in range(len(state)):\n", - " index_state[state[i]] = index[i]\n", - " mhd = 0\n", - " for i in range(8):\n", - " for j in range(2):\n", - " mhd = abs(index_goal[i][j] - index_state[i][j]) + mhd\n", - " return mhd\n", + "\tindex_goal = {0:[2,2], 1:[0,0], 2:[0,1], 3:[0,2], 4:[1,0], 5:[1,1], 6:[1,2], 7:[2,0], 8:[2,1]}\n", + "\tindex_state = {}\n", + "\tindex = [[0,0], [0,1], [0,2], [1,0], [1,1], [1,2], [2,0], [2,1], [2,2]]\n", + "\tx=0\n", + "\ty=0\n", + "\tfor i in range(len(state)):\n", + "\t\tindex_state[state[i]] = index[i]\n", + "\tmhd = 0\n", + "\tfor i in range(8):\n", + "\t\tfor j in range(2):\n", + "\t\t\tmhd = abs(index_goal[i][j] - index_state[i][j]) + mhd\n", + "\treturn mhd\n", "\n", "def sqrt_manhanttan(state,goal):\n", - " index_goal = {0:[2,2], 1:[0,0], 2:[0,1], 3:[0,2], 4:[1,0], 5:[1,1], 6:[1,2], 7:[2,0], 8:[2,1]}\n", - " index_state = {}\n", - " index = [[0,0], [0,1], [0,2], [1,0], [1,1], [1,2], [2,0], [2,1], [2,2]]\n", - " x=0\n", - " y=0\n", - " for i in range(len(state)):\n", - " index_state[state[i]] = index[i]\n", - " mhd = 0\n", - " for i in range(8):\n", - " for j in range(2):\n", - " mhd = (index_goal[i][j] - index_state[i][j])**2 + mhd\n", - " return math.sqrt(mhd)\n", + "\tindex_goal = {0:[2,2], 1:[0,0], 2:[0,1], 3:[0,2], 4:[1,0], 5:[1,1], 6:[1,2], 7:[2,0], 8:[2,1]}\n", + "\tindex_state = {}\n", + "\tindex = [[0,0], [0,1], [0,2], [1,0], [1,1], [1,2], [2,0], [2,1], [2,2]]\n", + "\tx=0\n", + "\ty=0\n", + "\tfor i in range(len(state)):\n", + "\t\tindex_state[state[i]] = index[i]\n", + "\tmhd = 0\n", + "\tfor i in range(8):\n", + "\t\tfor j in range(2):\n", + "\t\t\tmhd = (index_goal[i][j] - index_state[i][j])**2 + mhd\n", + "\treturn math.sqrt(mhd)\n", "\n", "def max_heuristic(state,goal):\n", - " score1 = manhanttan(state, goal)\n", - " score2 = linear(state, goal)\n", - " return max(score1, score2)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "# Algorithm for 8 Puzzle problem\n", - "\n", - "def checkSolvability(state):\n", - " inversion = 0\n", - " for i in range(len(state)):\n", - " for j in range(i,len(state)):\n", - " if (state[i]>state[j] and state[j]!=0):\n", - " inversion += 1\n", - " check = True\n", - " if inversion%2 != 0:\n", - " check = False\n", - " print(check)\n", - " return check\n", - "\n", - "def getPossibleMoves(state,heuristic,goal,moves):\n", - " move = {0:[1,3], 1:[0,2,4], 2:[1,5], 3:[0,6,4], 4:[1,3,5,7], 5:[2,4,8], 6:[3,7], 7:[6,8], 8:[7,5]} # create a dictionary of moves\n", - " index = state[0].index(0)\n", - " possible_moves = []\n", - " for i in range(len(move[index])):\n", - " conf = list(state[0][:])\n", - " a = conf[index]\n", - " b = conf[move[index][i]]\n", - " conf[move[index][i]] = a\n", - " conf[index] = b\n", - " possible_moves.append(conf)\n", - " scores = []\n", - " for i in possible_moves:\n", - " scores.append(heuristic(i,goal))\n", - " scores = [x+moves for x in scores]\n", - " allowed_state = []\n", - " for i in range(len(possible_moves)):\n", - " node = []\n", - " node.append(possible_moves[i])\n", - " node.append(scores[i])\n", - " node.append(state[0])\n", - " allowed_state.append(node) \n", - " return allowed_state\n", - "\n", - "path = []\n", - "final = []\n", - "def create_path(goal,initial):\n", - " node = goal[0]\n", - " final.append(goal[0])\n", - " if goal[2] == initial:\n", - " return reversed(final)\n", - " else:\n", - " parent = goal[2]\n", - " for i in path:\n", - " if i[0] == parent:\n", - " parent = i\n", - " create_path(parent,initial)\t\n", - "\n", - "def show_path(initial):\n", - " move = []\n", - " for i in range(0,len(path)):\n", - " move.append(''.join(str(x) for x in path[i][0]))\n", - " print(\"Number of explored nodes by the following heuristic are: \", len(set(move)))\t\n", - " print(initial)\n", - " for i in reversed(final):\n", - " print(i)\n", - " return\n", - "\n", - "def solve(initial,goal,heuristic):\n", - " root = [initial,heuristic(initial,goal),'']\n", - " nodes = [] # nodes is a priority Queue based on the state score \n", - " nodes.append(root)\n", - " moves = 0\n", - " while len(nodes) != 0:\n", - " node = nodes[0]\n", - " del nodes[0]\n", - " path.append(node)\n", - " if node[0] == goal:\n", - " soln = create_path(path[-1],initial )\n", - " show_path(initial)\n", - " return \n", - " moves +=1\n", - " opened_nodes = getPossibleMoves(node,heuristic,goal,moves)\n", - " nodes = sorted(opened_nodes+nodes, key=itemgetter(1))\n" + "\tscore1 = manhanttan(state, goal)\n", + "\tscore2 = linear(state, goal)\n", + "\treturn max(score1, score2)\t\t\n" ] }, { @@ -1461,7 +1335,6 @@ "name": "stdout", "output_type": "stream", "text": [ - "Heuristics is max_heuristic\n", "True\n", "Number of explored nodes by the following heuristic are: 126\n", "[2, 4, 3, 1, 5, 6, 7, 8, 0]\n", @@ -1472,16 +1345,48 @@ "[1, 2, 3, 0, 4, 5, 7, 8, 6]\n", "[1, 2, 3, 4, 0, 5, 7, 8, 6]\n", "[1, 2, 3, 4, 5, 0, 7, 8, 6]\n", + "[1, 2, 3, 4, 5, 6, 7, 8, 0]\n", + "Number of explored nodes by the following heuristic are: 129\n", + "[2, 4, 3, 1, 5, 6, 7, 8, 0]\n", + "[2, 4, 3, 1, 5, 0, 7, 8, 6]\n", + "[2, 4, 3, 1, 0, 5, 7, 8, 6]\n", + "[2, 0, 3, 1, 4, 5, 7, 8, 6]\n", + "[0, 2, 3, 1, 4, 5, 7, 8, 6]\n", + "[1, 2, 3, 0, 4, 5, 7, 8, 6]\n", + "[1, 2, 3, 4, 0, 5, 7, 8, 6]\n", + "[1, 2, 3, 4, 5, 0, 7, 8, 6]\n", + "[1, 2, 3, 4, 5, 6, 7, 8, 0]\n", + "Number of explored nodes by the following heuristic are: 126\n", + "[2, 4, 3, 1, 5, 6, 7, 8, 0]\n", + "[2, 4, 3, 1, 5, 0, 7, 8, 6]\n", + "[2, 4, 3, 1, 0, 5, 7, 8, 6]\n", + "[2, 0, 3, 1, 4, 5, 7, 8, 6]\n", + "[0, 2, 3, 1, 4, 5, 7, 8, 6]\n", + "[1, 2, 3, 0, 4, 5, 7, 8, 6]\n", + "[1, 2, 3, 4, 0, 5, 7, 8, 6]\n", + "[1, 2, 3, 4, 5, 0, 7, 8, 6]\n", + "[1, 2, 3, 4, 5, 6, 7, 8, 0]\n", + "Number of explored nodes by the following heuristic are: 139\n", + "[2, 4, 3, 1, 5, 6, 7, 8, 0]\n", + "[2, 4, 3, 1, 5, 0, 7, 8, 6]\n", + "[2, 4, 3, 1, 0, 5, 7, 8, 6]\n", + "[2, 0, 3, 1, 4, 5, 7, 8, 6]\n", + "[0, 2, 3, 1, 4, 5, 7, 8, 6]\n", + "[1, 2, 3, 0, 4, 5, 7, 8, 6]\n", + "[1, 2, 3, 4, 0, 5, 7, 8, 6]\n", + "[1, 2, 3, 4, 5, 0, 7, 8, 6]\n", "[1, 2, 3, 4, 5, 6, 7, 8, 0]\n" ] } ], "source": [ - "goal_state = [1,2,3,4,5,6,7,8,0] # define the goal state\n", - "initial_state = [2,4,3,1,5,6,7,8,0] # define the initial state\n", - "print(\"Heuristics is max_heuristic\")\n", - "checkSolvability(initial_state)\n", - "solve(initial_state,goal_state,max_heuristic) # to check the different heuristics change the function name in solve" + "# Solving the puzzle \n", + "puzzle = EightPuzzle()\n", + "puzzle.checkSolvability([2,4,3,1,5,6,7,8,0]) # checks whether the initialized configuration is solvable or not\n", + "puzzle.solve([2,4,3,1,5,6,7,8,0],[1,2,3,4,5,6,7,8,0],max_heuristic) # Max_heuristic\n", + "puzzle.solve([2,4,3,1,5,6,7,8,0],[1,2,3,4,5,6,7,8,0],linear) # Linear\n", + "puzzle.solve([2,4,3,1,5,6,7,8,0],[1,2,3,4,5,6,7,8,0],manhanttan) # Manhattan\n", + "puzzle.solve([2,4,3,1,5,6,7,8,0],[1,2,3,4,5,6,7,8,0],sqrt_manhanttan) # Sqrt_manhattan" ] }, { @@ -1594,7 +1499,9 @@ { "cell_type": "code", "execution_count": 2, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "%psource genetic_algorithm" @@ -1633,7 +1540,9 @@ { "cell_type": "code", "execution_count": 3, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "%psource reproduce" @@ -1651,7 +1560,9 @@ { "cell_type": "code", "execution_count": 4, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "%psource mutate" @@ -1669,7 +1580,9 @@ { "cell_type": "code", "execution_count": 5, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "%psource init_population" @@ -1710,8 +1623,10 @@ }, { "cell_type": "code", - "execution_count": 12, - "metadata": {}, + "execution_count": 6, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "edges = {\n", @@ -1733,14 +1648,14 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "[['R', 'G', 'G', 'R'], ['G', 'R', 'G', 'G'], ['G', 'G', 'G', 'G'], ['R', 'G', 'G', 'G'], ['R', 'G', 'G', 'R'], ['G', 'R', 'G', 'R'], ['G', 'G', 'G', 'R'], ['G', 'R', 'G', 'R']]\n" + "[['R', 'G', 'G', 'R'], ['R', 'G', 'R', 'R'], ['G', 'R', 'G', 'R'], ['R', 'G', 'R', 'G'], ['G', 'R', 'R', 'G'], ['G', 'R', 'G', 'R'], ['G', 'R', 'R', 'R'], ['R', 'G', 'G', 'G']]\n" ] } ], @@ -1760,8 +1675,10 @@ }, { "cell_type": "code", - "execution_count": 14, - "metadata": {}, + "execution_count": 8, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "def fitness(c):\n", @@ -1777,14 +1694,14 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "['G', 'R', 'G', 'R']\n" + "['R', 'G', 'R', 'G']\n" ] } ], @@ -1802,7 +1719,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -1847,14 +1764,14 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "[[6, 7, 3, 6, 3, 0, 1, 4], [7, 1, 4, 1, 5, 2, 0, 0], [1, 4, 7, 0, 0, 2, 5, 2], [2, 0, 3, 7, 5, 7, 0, 0], [6, 3, 1, 7, 5, 6, 3, 0]]\n" + "[[0, 2, 7, 1, 7, 3, 2, 4], [2, 7, 5, 4, 4, 5, 2, 0], [7, 1, 6, 0, 1, 3, 0, 2], [0, 3, 6, 1, 3, 0, 5, 4], [0, 4, 6, 4, 7, 4, 1, 6]]\n" ] } ], @@ -1878,8 +1795,10 @@ }, { "cell_type": "code", - "execution_count": 7, - "metadata": {}, + "execution_count": 12, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "def fitness(q):\n", @@ -1908,20 +1827,20 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "[3, 5, 7, 2, 0, 6, 4, 1]\n", - "28\n" + "[5, 0, 6, 3, 7, 4, 1, 3]\n", + "26\n" ] } ], "source": [ - "solution = genetic_algorithm(population, fitness, f_thres=28, gene_pool=range(8))\n", + "solution = genetic_algorithm(population, fitness, f_thres=25, gene_pool=range(8))\n", "print(solution)\n", "print(fitness(solution))" ] @@ -1939,13 +1858,6 @@ "source": [ "With that this tutorial on the genetic algorithm comes to an end. Hope you found this guide helpful!" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { @@ -1964,11 +1876,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", -<<<<<<< HEAD "version": "3.5.4rc1" -======= - "version": "3.5.2" ->>>>>>> 8561c52d63fcaef4c0f99d997073aeb93e926e56 }, "widgets": { "state": { diff --git a/search.py b/search.py index ea58d18f1..d0a029319 100644 --- a/search.py +++ b/search.py @@ -17,6 +17,7 @@ import bisect from operator import itemgetter + infinity = float('inf') # ______________________________________________________________________________ @@ -400,6 +401,95 @@ def astar_search(problem, h=None): h = memoize(h or problem.h, 'h') return best_first_graph_search(problem, lambda n: n.path_cost + h(n)) +# ______________________________________________________________________________ +# A* heuristics + +class EightPuzzle(): + + def __init__(self): + self.path = [] + self.final = [] + + def checkSolvability(self, state): + inversion = 0 + for i in range(len(state)): + for j in range(i,len(state)): + if (state[i]>state[j] and state[j]!=0): + inversion += 1 + check = True + if inversion%2 != 0: + check = False + print(check) + + def getPossibleMoves(self,state,heuristic,goal,moves): + move = {0:[1,3], 1:[0,2,4], 2:[1,5], 3:[0,6,4], 4:[1,3,5,7], 5:[2,4,8], 6:[3,7], 7:[6,8], 8:[7,5]} # create a dictionary of moves + index = state[0].index(0) + possible_moves = [] + for i in range(len(move[index])): + conf = list(state[0][:]) + a = conf[index] + b = conf[move[index][i]] + conf[move[index][i]] = a + conf[index] = b + possible_moves.append(conf) + scores = [] + for i in possible_moves: + scores.append(heuristic(i,goal)) + scores = [x+moves for x in scores] + allowed_state = [] + for i in range(len(possible_moves)): + node = [] + node.append(possible_moves[i]) + node.append(scores[i]) + node.append(state[0]) + allowed_state.append(node) + return allowed_state + + + def create_path(self,goal,initial): + node = goal[0] + self.final.append(goal[0]) + if goal[2] == initial: + return reversed(self.final) + else: + parent = goal[2] + for i in self.path: + if i[0] == parent: + parent = i + self.create_path(parent,initial) + + def show_path(self,initial): + move = [] + for i in range(0,len(self.path)): + move.append(''.join(str(x) for x in self.path[i][0])) + print("Number of explored nodes by the following heuristic are: ", len(set(move))) + print(initial) + for i in reversed(self.final): + print(i) + #self.path.clear() + #self.final.clear() + del self.path[:] + del self.final[:] + return + + def solve(self,initial,goal,heuristic): + root = [initial,heuristic(initial,goal),''] + nodes = [] # nodes is a priority Queue based on the state score + nodes.append(root) + moves = 0 + while len(nodes) != 0: + node = nodes[0] + del nodes[0] + self.path.append(node) + if node[0] == goal: + soln = self.create_path(self.path[-1],initial ) + self.show_path(initial) + return + moves +=1 + opened_nodes = self.getPossibleMoves(node,heuristic,goal,moves) + nodes = sorted(opened_nodes+nodes, key=itemgetter(1)) + + # ______________________________________________________________________________ # Other search algorithms From f6e3985a1c047ccbba23645509afc89b70a1877d Mon Sep 17 00:00:00 2001 From: Dragneel7 Date: Fri, 12 Jan 2018 22:39:40 +0530 Subject: [PATCH 2/5] solve error --- search.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/search.ipynb b/search.ipynb index eff00283c..15f60a442 100644 --- a/search.ipynb +++ b/search.ipynb @@ -1268,7 +1268,7 @@ " | 5 | 0 | 6 | | 3 | 4 | 5 |\n", " | 8 | 3 | 1 | | 6 | 7 | 8 |\n", " \n", - "We have a total of 9 blank tiles giving us a total of 9! initial configuration but not all of these are solvable, the solvability of a configuration can be checked by calculating the Inversion Permutation.\n", + "We have a total of 9 blank tiles giving us a total of 9! initial configuration but not all of these are solvable, the solvability of a configuration can be checked by calculating the Inversion Permutation. If the total Inversion Permutation is even then the initial configuration is solvable else not.\n", "\n", "#### Heuristics :-\n", "\n", From cbf56f5613fecaa513bf7f6623a3378900de7ab8 Mon Sep 17 00:00:00 2001 From: Dragneel7 Date: Fri, 12 Jan 2018 23:04:28 +0530 Subject: [PATCH 3/5] solve error --- search.ipynb | 4 +++- search.py | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/search.ipynb b/search.ipynb index 15f60a442..6f9919783 100644 --- a/search.ipynb +++ b/search.ipynb @@ -407,7 +407,9 @@ { "cell_type": "code", "execution_count": 11, - "metadata": {}, + "metadata": { + "scrolled": true + }, "outputs": [ { "data": { diff --git a/search.py b/search.py index d0a029319..46bef1557 100644 --- a/search.py +++ b/search.py @@ -462,12 +462,12 @@ def show_path(self,initial): move = [] for i in range(0,len(self.path)): move.append(''.join(str(x) for x in self.path[i][0])) - print("Number of explored nodes by the following heuristic are: ", len(set(move))) + + print("Number of explored nodes by the following heuristic are: ", len(set(move))) print(initial) for i in reversed(self.final): print(i) - #self.path.clear() - #self.final.clear() + del self.path[:] del self.final[:] return From 12030b8d9226dfe3f804fb5da49fd78866aec5f6 Mon Sep 17 00:00:00 2001 From: Dragneel7 Date: Sat, 13 Jan 2018 02:04:12 +0530 Subject: [PATCH 4/5] solve error --- search.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/search.ipynb b/search.ipynb index 6f9919783..7003a355f 100644 --- a/search.ipynb +++ b/search.ipynb @@ -1270,7 +1270,7 @@ " | 5 | 0 | 6 | | 3 | 4 | 5 |\n", " | 8 | 3 | 1 | | 6 | 7 | 8 |\n", " \n", - "We have a total of 9 blank tiles giving us a total of 9! initial configuration but not all of these are solvable, the solvability of a configuration can be checked by calculating the Inversion Permutation. If the total Inversion Permutation is even then the initial configuration is solvable else not.\n", + "We have a total of 9 blank tiles giving us a total of 9! initial configuration but not all of these are solvable, the solvability of a configuration can be checked by calculating the Inversion Permutation. If the total Inversion Permutation is even then the initial configuration is solvable else the initial configuration is not solvable which means that only 9!/2 initial states lead to a solution.\n", "\n", "#### Heuristics :-\n", "\n", From 8b371c6617a27e2302aa87b90574feee59646d9d Mon Sep 17 00:00:00 2001 From: surya saini Date: Sat, 13 Jan 2018 20:24:40 +0530 Subject: [PATCH 5/5] Update search.ipynb --- search.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/search.ipynb b/search.ipynb index 7003a355f..d537bd6c0 100644 --- a/search.ipynb +++ b/search.ipynb @@ -1257,7 +1257,7 @@ "source": [ "## A* Heuristics\n", "\n", - "Different heuristics provide different have different efficiency in solving A* problems which are generally defined by the number of explored nodes as well as the branching factor. With the classic 8 puzzle we can show the efficiency of different heuristics through the number of explored nodes.\n", + "Different heuristics provide different efficiency in solving A* problems which are generally defined by the number of explored nodes as well as the branching factor. With the classic 8 puzzle we can show the efficiency of different heuristics through the number of explored nodes.\n", "\n", "### 8 Puzzle Problem\n", "\n", pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy