From cd00c3238393a7ee352a6d4bffa8bafc316fc062 Mon Sep 17 00:00:00 2001 From: Anthony Marakis Date: Mon, 12 Feb 2018 18:15:10 +0200 Subject: [PATCH] Update search.ipynb --- search.ipynb | 255 +++++++++++++++++++++++---------------------------- 1 file changed, 117 insertions(+), 138 deletions(-) diff --git a/search.ipynb b/search.ipynb index 6da1d0ef5..52eb39c0e 100644 --- a/search.ipynb +++ b/search.ipynb @@ -17,23 +17,7 @@ "metadata": { "scrolled": true }, - "outputs": [ - { - "ename": "FileNotFoundError", - "evalue": "[Errno 2] No such file or directory: '/home/apurv/aima-python/aima-data/orings.csv'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mFileNotFoundError\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;32mfrom\u001b[0m \u001b[0msearch\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;32mfrom\u001b[0m \u001b[0mnotebook\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mpsource\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# Needed to hide warnings in the matplotlib sections\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mwarnings\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/aima-python/notebook.py\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mgames\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mTicTacToe\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0malphabeta_player\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrandom_player\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mFig52Extended\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0minfinity\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mlogic\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mparse_definite_clause\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstandardize_variables\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0munify\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubst\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0;32mfrom\u001b[0m \u001b[0mlearning\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mDataSet\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 7\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mIPython\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdisplay\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mHTML\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdisplay\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mcollections\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mCounter\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdefaultdict\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/aima-python/learning.py\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1105\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1106\u001b[0m orings = DataSet(name='orings', target='Distressed',\n\u001b[0;32m-> 1107\u001b[0;31m attrnames=\"Rings Distressed Temp Pressure Flightnum\")\n\u001b[0m\u001b[1;32m 1108\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1109\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/aima-python/learning.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, examples, attrs, attrnames, target, inputs, values, distance, name, source, exclude)\u001b[0m\n\u001b[1;32m 96\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexamples\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mparse_csv\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mexamples\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 97\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mexamples\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 98\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexamples\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mparse_csv\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mopen_data\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mname\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m'.csv'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread\u001b[0m\u001b[0;34m(\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 99\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 100\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexamples\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mexamples\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/aima-python/utils.py\u001b[0m in \u001b[0;36mopen_data\u001b[0;34m(name, mode)\u001b[0m\n\u001b[1;32m 414\u001b[0m \u001b[0maima_file\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mos\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mjoin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0maima_root\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'aima-data'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 415\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 416\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0maima_file\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 417\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 418\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mFileNotFoundError\u001b[0m: [Errno 2] No such file or directory: '/home/apurv/aima-python/aima-data/orings.csv'" - ] - } - ], + "outputs": [], "source": [ "from search import *\n", "from notebook import psource\n", @@ -158,10 +142,8 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, + "execution_count": 2, + "metadata": {}, "outputs": [], "source": [ "romania_map = UndirectedGraph(dict(\n", @@ -205,10 +187,8 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, + "execution_count": 3, + "metadata": {}, "outputs": [], "source": [ "romania_problem = GraphProblem('Arad', 'Bucharest', romania_map)" @@ -232,11 +212,17 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'Arad': (91, 492), 'Bucharest': (400, 327), 'Craiova': (253, 288), 'Drobeta': (165, 299), 'Eforie': (562, 293), 'Fagaras': (305, 449), 'Giurgiu': (375, 270), 'Hirsova': (534, 350), 'Iasi': (473, 506), 'Lugoj': (165, 379), 'Mehadia': (168, 339), 'Neamt': (406, 537), 'Oradea': (131, 571), 'Pitesti': (320, 368), 'Rimnicu': (233, 410), 'Sibiu': (207, 457), 'Timisoara': (94, 410), 'Urziceni': (456, 350), 'Vaslui': (509, 444), 'Zerind': (108, 531)}\n" + ] + } + ], "source": [ "romania_locations = romania_map.locations\n", "print(romania_locations)" @@ -251,10 +237,8 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, + "execution_count": 5, + "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", @@ -277,10 +261,8 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, + "execution_count": 6, + "metadata": {}, "outputs": [], "source": [ "# initialise a graph\n", @@ -323,10 +305,8 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, + "execution_count": 7, + "metadata": {}, "outputs": [], "source": [ "# initialise a graph\n", @@ -442,7 +422,7 @@ "source": [ "## SIMPLE PROBLEM SOLVING AGENT PROGRAM\n", "\n", - "Let us now define a Simple Problem Solving Agent Program. Run the next cell to see how the abstract class SimpleProblemSolvingAgentProgram is defined in the search module." + "Let us now define a Simple Problem Solving Agent Program. Run the next cell to see how the abstract class `SimpleProblemSolvingAgentProgram` is defined in the search module." ] }, { @@ -462,21 +442,16 @@ "source": [ "The SimpleProblemSolvingAgentProgram class has six methods: \n", "\n", - "* `__init__(self, intial_state=None)`: This is the `contructor` of the class and is the first method to be called when the class is instantiated. It takes in a keyword argument, `initial_state` which is initially `None`. The argument `intial_state` represents the state from which the agent starts. \n", - "\n", + "* `__init__(self, intial_state=None)`: This is the `contructor` of the class and is the first method to be called when the class is instantiated. It takes in a keyword argument, `initial_state` which is initially `None`. The argument `intial_state` represents the state from which the agent starts.\n", "\n", "* `__call__(self, percept)`: This method updates the `state` of the agent based on its `percept` using the `update_state` method. It then formulates a `goal` with the help of `formulate_goal` method and a `problem` using the `formulate_problem` method and returns a sequence of actions to solve it (using the `search` method).\n", "\n", - "\n", - "* `update_state(self, percept)`: This method updates the `state` of the agent based on its `percept`. \n", - "\n", + "* `update_state(self, percept)`: This method updates the `state` of the agent based on its `percept`.\n", "\n", "* `formulate_goal(self, state)`: Given a `state` of the agent, this method formulates the `goal` for it.\n", "\n", - "\n", "* `formulate_problem(self, state, goal)`: It is used in problem formulation given a `state` and a `goal` for the `agent`.\n", "\n", - "\n", "* `search(self, problem)`: This method is used to search a sequence of `actions` to solve a `problem`." ] }, @@ -695,8 +670,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Now, we use ipywidgets to display a slider, a button and our romania map. By sliding the slider we can have a look at all the intermediate steps of a particular search algorithm. By pressing the button **Visualize**, you can see all the steps without interacting with the slider. These two helper functions are the callback functions which are called when we interact with the slider and the button.\n", - "\n" + "Now, we use `ipywidgets` to display a slider, a button and our romania map. By sliding the slider we can have a look at all the intermediate steps of a particular search algorithm. By pressing the button **Visualize**, you can see all the steps without interacting with the slider. These two helper functions are the callback functions which are called when we interact with the slider and the button." ] }, { @@ -791,7 +765,7 @@ "source": [ "## BREADTH-FIRST SEARCH\n", "\n", - "Let's change all the node_colors to starting position and define a different problem statement." + "Let's change all the `node_colors` to starting position and define a different problem statement." ] }, { @@ -997,7 +971,8 @@ "metadata": {}, "source": [ "## BEST FIRST SEARCH\n", - "Let's change all the node_colors to starting position and define a different problem statement." + "\n", + "Let's change all the `node_colors` to starting position and define a different problem statement." ] }, { @@ -1084,7 +1059,7 @@ "source": [ "## UNIFORM COST SEARCH\n", "\n", - "Let's change all the node_colors to starting position and define a different problem statement." + "Let's change all the `node_colors` to starting position and define a different problem statement." ] }, { @@ -1193,7 +1168,7 @@ "source": [ "## A\\* SEARCH\n", "\n", - "Let's change all the node_colors to starting position and define a different problem statement." + "Let's change all the `node_colors` to starting position and define a different problem statement." ] }, { @@ -1321,69 +1296,73 @@ " | 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 the initial configuration is not solvable which means that only 9!/2 initial states lead to a solution.\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", - "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", + "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:- The heuristic calculates the number of misplaced tiles between the current state and goal 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:- It calculates the square root of Manhattan distance.\n", + "3) Sqrt of Manhattan Distance:- It calculates the square root of Manhattan distance.\n", "\n", - "4.) Max Heuristic:- It assign the score as max of Manhattan Distance and No. of misplaced tiles. " + "4) Max Heuristic:- It assign the score as the maximum between \"Manhattan Distance\" and \"No. of Misplaced Tiles\". " ] }, { "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": true - }, + "execution_count": 11, + "metadata": {}, "outputs": [], "source": [ - "# heuristics for 8 Puzzle Problem\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", - "\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", + " 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, y = 0, 0\n", + " \n", + " for i in range(len(state)):\n", + " index_state[state[i]] = index[i]\n", + " \n", + " mhd = 0\n", + " \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", + " \n", + " return mhd\n", "\n", "def sqrt_manhanttan(state,goal):\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", + " 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, y = 0, 0\n", + " \n", + " for i in range(len(state)):\n", + " index_state[state[i]] = index[i]\n", + " \n", + " mhd = 0\n", + " \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", + " \n", + " return math.sqrt(mhd)\n", "\n", "def max_heuristic(state,goal):\n", - "\tscore1 = manhanttan(state, goal)\n", - "\tscore2 = linear(state, goal)\n", - "\treturn max(score1, score2)\t\t\n" + " score1 = manhanttan(state, goal)\n", + " score2 = linear(state, goal)\n", + " return max(score1, score2)" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -1391,45 +1370,45 @@ "output_type": "stream", "text": [ "True\n", - "Number of explored nodes by the following heuristic are: 126\n", + "Number of explored nodes by the following heuristic are: 145\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", + "[2, 4, 3, 1, 5, 6, 7, 0, 8]\n", + "[2, 4, 3, 1, 0, 6, 7, 5, 8]\n", + "[2, 0, 3, 1, 4, 6, 7, 5, 8]\n", + "[0, 2, 3, 1, 4, 6, 7, 5, 8]\n", + "[1, 2, 3, 0, 4, 6, 7, 5, 8]\n", + "[1, 2, 3, 4, 0, 6, 7, 5, 8]\n", + "[1, 2, 3, 4, 5, 6, 7, 0, 8]\n", "[1, 2, 3, 4, 5, 6, 7, 8, 0]\n", - "Number of explored nodes by the following heuristic are: 129\n", + "Number of explored nodes by the following heuristic are: 153\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", + "[2, 4, 3, 1, 5, 6, 7, 0, 8]\n", + "[2, 4, 3, 1, 0, 6, 7, 5, 8]\n", + "[2, 0, 3, 1, 4, 6, 7, 5, 8]\n", + "[0, 2, 3, 1, 4, 6, 7, 5, 8]\n", + "[1, 2, 3, 0, 4, 6, 7, 5, 8]\n", + "[1, 2, 3, 4, 0, 6, 7, 5, 8]\n", + "[1, 2, 3, 4, 5, 6, 7, 0, 8]\n", "[1, 2, 3, 4, 5, 6, 7, 8, 0]\n", - "Number of explored nodes by the following heuristic are: 126\n", + "Number of explored nodes by the following heuristic are: 145\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", + "[2, 4, 3, 1, 5, 6, 7, 0, 8]\n", + "[2, 4, 3, 1, 0, 6, 7, 5, 8]\n", + "[2, 0, 3, 1, 4, 6, 7, 5, 8]\n", + "[0, 2, 3, 1, 4, 6, 7, 5, 8]\n", + "[1, 2, 3, 0, 4, 6, 7, 5, 8]\n", + "[1, 2, 3, 4, 0, 6, 7, 5, 8]\n", + "[1, 2, 3, 4, 5, 6, 7, 0, 8]\n", "[1, 2, 3, 4, 5, 6, 7, 8, 0]\n", - "Number of explored nodes by the following heuristic are: 139\n", + "Number of explored nodes by the following heuristic are: 169\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", + "[2, 4, 3, 1, 5, 6, 7, 0, 8]\n", + "[2, 4, 3, 1, 0, 6, 7, 5, 8]\n", + "[2, 0, 3, 1, 4, 6, 7, 5, 8]\n", + "[0, 2, 3, 1, 4, 6, 7, 5, 8]\n", + "[1, 2, 3, 0, 4, 6, 7, 5, 8]\n", + "[1, 2, 3, 4, 0, 6, 7, 5, 8]\n", + "[1, 2, 3, 4, 5, 6, 7, 0, 8]\n", "[1, 2, 3, 4, 5, 6, 7, 8, 0]\n" ] } @@ -1438,10 +1417,10 @@ "# 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" + "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" ] }, { @@ -2105,14 +2084,14 @@ "\n", "If we wanted to include punctuations and numerals into the sample space, we would have further complicated an already impossible problem. Hence, brute forcing is not an option. Now we'll apply the genetic algorithm and see how it significantly reduces the search space. We essentially want to *evolve* our population of random strings so that they better approximate the target phrase as the number of generations increase. Genetic algorithms work on the principle of Darwinian Natural Selection according to which, there are three key concepts that need to be in place for evolution to happen. They are:\n", "\n", - "1. Heredity : There must be a process in place by which children receive the properties of their parents.
\n", + "* **Heredity**: There must be a process in place by which children receive the properties of their parents.
\n", "For this particular problem, two strings from the population will be chosen as parents and will be split at a random index and recombined as described in the `recombine` function to create a child. This child string will then be added to the new generation.\n", - "
\n",
-    "
\n", - "2. Variation : There must be a variety of traits present in the population or a means with which to introduce variation.
If there is no variation in the sample space, we might never reach the global optimum. To ensure that there is enough variation, we can initialize a large population, but this gets computationally expensive as the population gets larger. Hence, we often use another method called mutation. In this method, we randomly change one or more characters of some strings in the population based on a predefined probability value called the mutation rate or mutation probability as described in the `mutate` function. The mutation rate is usually kept quite low. A mutation rate of zero fails to introduce variation in the population and a high mutation rate (say 50%) is as good as a coin flip and the population fails to benefit from the previous recombinations. An optimum balance has to be maintained between population size and mutation rate so as to reduce the computational cost as well as have sufficient variation in the population.\n", - "
\n",
-    "
\n", - "3. Selection : There must be some mechanism by which some members of the population have the opportunity to be parents and pass down their genetic information and some do not. This is typically referred to as \"survival of the fittest\".
\n", + "\n", + "\n", + "* **Variation**: There must be a variety of traits present in the population or a means with which to introduce variation.
If there is no variation in the sample space, we might never reach the global optimum. To ensure that there is enough variation, we can initialize a large population, but this gets computationally expensive as the population gets larger. Hence, we often use another method called mutation. In this method, we randomly change one or more characters of some strings in the population based on a predefined probability value called the mutation rate or mutation probability as described in the `mutate` function. The mutation rate is usually kept quite low. A mutation rate of zero fails to introduce variation in the population and a high mutation rate (say 50%) is as good as a coin flip and the population fails to benefit from the previous recombinations. An optimum balance has to be maintained between population size and mutation rate so as to reduce the computational cost as well as have sufficient variation in the population.\n", + "\n", + "\n", + "* **Selection**: There must be some mechanism by which some members of the population have the opportunity to be parents and pass down their genetic information and some do not. This is typically referred to as \"survival of the fittest\".
\n", "There has to be some way of determining which phrases in our population have a better chance of eventually evolving into the target phrase. This is done by introducing a fitness function that calculates how close the generated phrase is to the target phrase. The function will simply return a scalar value corresponding to the number of matching characters between the generated phrase and the target phrase." ] }, @@ -2881,7 +2860,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.5.2" + "version": "3.6.3" } }, "nbformat": 4,