diff --git a/search.ipynb b/search.ipynb index b8edde1e9..019ea8eb4 100644 --- a/search.ipynb +++ b/search.ipynb @@ -15,7 +15,6 @@ "cell_type": "code", "execution_count": 1, "metadata": { - "collapsed": true, "scrolled": true }, "outputs": [], @@ -81,9 +80,7 @@ { "cell_type": "code", "execution_count": 2, - "metadata": { - "collapsed": true - }, + "metadata": {}, "outputs": [], "source": [ "%psource Problem" @@ -123,9 +120,7 @@ { "cell_type": "code", "execution_count": 3, - "metadata": { - "collapsed": true - }, + "metadata": {}, "outputs": [], "source": [ "%psource GraphProblem" @@ -141,9 +136,7 @@ { "cell_type": "code", "execution_count": 4, - "metadata": { - "collapsed": true - }, + "metadata": {}, "outputs": [], "source": [ "romania_map = UndirectedGraph(dict(\n", @@ -188,9 +181,7 @@ { "cell_type": "code", "execution_count": 5, - "metadata": { - "collapsed": true - }, + "metadata": {}, "outputs": [], "source": [ "romania_problem = GraphProblem('Arad', 'Bucharest', romania_map)" @@ -221,7 +212,11 @@ "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 ] } ], @@ -240,10 +235,26 @@ { "cell_type": "code", "execution_count": 7, - "metadata": { - "collapsed": true - }, - "outputs": [], + "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'" + ] + } + ], "source": [ "%matplotlib inline\n", "import networkx as nx\n", @@ -266,10 +277,20 @@ { "cell_type": "code", "execution_count": 8, - "metadata": { - "collapsed": true - }, - "outputs": [], + "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" + ] + } + ], "source": [ "# initialise a graph\n", "G = nx.Graph()\n", @@ -1250,6 +1271,219 @@ "display_visual(user_input = True)" ] }, + { + "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", + "\n", + "### 8-Puzzle Problem\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", + "\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", + "\n", + "*example:*\n", + " Initial State Goal State\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", + "\n", + "For example we can have a state \"724506831\" where 0 represents the empty tile.\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", + "\n", + "2.) No. of Misplaced Tiles:- This heuristics calculates the number of misplaced tile in the state from the goal \n", + " state.\n", + "\n", + "3.) Sqrt of Manhattan Distance:- Uses the sqaure root of the Manhattan distance\n", + "\n", + "4.) Max Heuristic :- Score on the basis of max of Manhattan Distance and No. of Misplced tiles." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# define heuristics\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", + "\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", + "\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" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "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", + "[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" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -1360,9 +1594,7 @@ { "cell_type": "code", "execution_count": 2, - "metadata": { - "collapsed": true - }, + "metadata": {}, "outputs": [], "source": [ "%psource genetic_algorithm" @@ -1401,9 +1633,7 @@ { "cell_type": "code", "execution_count": 3, - "metadata": { - "collapsed": true - }, + "metadata": {}, "outputs": [], "source": [ "%psource reproduce" @@ -1421,9 +1651,7 @@ { "cell_type": "code", "execution_count": 4, - "metadata": { - "collapsed": true - }, + "metadata": {}, "outputs": [], "source": [ "%psource mutate" @@ -1441,9 +1669,7 @@ { "cell_type": "code", "execution_count": 5, - "metadata": { - "collapsed": true - }, + "metadata": {}, "outputs": [], "source": [ "%psource init_population" @@ -1484,10 +1710,8 @@ }, { "cell_type": "code", - "execution_count": 6, - "metadata": { - "collapsed": true - }, + "execution_count": 12, + "metadata": {}, "outputs": [], "source": [ "edges = {\n", @@ -1509,14 +1733,14 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "[['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" + "[['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" ] } ], @@ -1536,10 +1760,8 @@ }, { "cell_type": "code", - "execution_count": 8, - "metadata": { - "collapsed": true - }, + "execution_count": 14, + "metadata": {}, "outputs": [], "source": [ "def fitness(c):\n", @@ -1555,14 +1777,14 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "['R', 'G', 'R', 'G']\n" + "['G', 'R', 'G', 'R']\n" ] } ], @@ -1580,7 +1802,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 18, "metadata": {}, "outputs": [ { @@ -1625,14 +1847,14 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "[[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" + "[[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" ] } ], @@ -1656,10 +1878,8 @@ }, { "cell_type": "code", - "execution_count": 12, - "metadata": { - "collapsed": true - }, + "execution_count": 7, + "metadata": {}, "outputs": [], "source": [ "def fitness(q):\n", @@ -1688,20 +1908,20 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "[5, 0, 6, 3, 7, 4, 1, 3]\n", - "26\n" + "[3, 5, 7, 2, 0, 6, 4, 1]\n", + "28\n" ] } ], "source": [ - "solution = genetic_algorithm(population, fitness, f_thres=25, gene_pool=range(8))\n", + "solution = genetic_algorithm(population, fitness, f_thres=28, gene_pool=range(8))\n", "print(solution)\n", "print(fitness(solution))" ] @@ -1719,6 +1939,13 @@ "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": { @@ -1737,7 +1964,11 @@ "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 19481ea31..ea58d18f1 100644 --- a/search.py +++ b/search.py @@ -15,6 +15,7 @@ import random import sys import bisect +from operator import itemgetter infinity = float('inf')