diff --git a/lecture_material/09-Graph-Search-1/solution.ipynb b/lecture_material/09-Graph-Search-1/solution.ipynb index 1868202cd51d007b4cbd8b484ed2d3d06722d0db..8b53eb9cc198a5cab6fbb78e62c916b883c98c18 100644 --- a/lecture_material/09-Graph-Search-1/solution.ipynb +++ b/lecture_material/09-Graph-Search-1/solution.ipynb @@ -304,107 +304,107 @@ "name": "stdout", "output_type": "stream", "text": [ - "15\n", - " 3 (ROOT)\n", - "\t 0 (LEFT)\n", - "\t\t 1 (RIGHT)\n", - "\t\t\t 2 (RIGHT)\n", - "\t 96 (RIGHT)\n", - "\t\t 78 (LEFT)\n", - "\t\t\t 9 (LEFT)\n", - "\t\t\t\t 5 (LEFT)\n", - "\t\t\t\t\t 4 (LEFT)\n", - "\t\t\t\t\t 8 (RIGHT)\n", + "17\n", + " 13 (ROOT)\n", + "\t 1 (LEFT)\n", + "\t\t 0 (LEFT)\n", + "\t\t 10 (RIGHT)\n", + "\t\t\t 6 (LEFT)\n", + "\t\t\t\t 3 (LEFT)\n", + "\t\t\t\t\t 2 (LEFT)\n", + "\t\t\t\t\t 4 (RIGHT)\n", + "\t\t\t\t\t\t 5 (RIGHT)\n", + "\t\t\t\t 9 (RIGHT)\n", + "\t\t\t\t\t 8 (LEFT)\n", "\t\t\t\t\t\t 7 (LEFT)\n", - "\t\t\t\t\t\t\t 6 (LEFT)\n", - "\t\t\t\t 64 (RIGHT)\n", - "\t\t\t\t\t 46 (LEFT)\n", - "\t\t\t\t\t\t 29 (LEFT)\n", - "\t\t\t\t\t\t\t 25 (LEFT)\n", - "\t\t\t\t\t\t\t\t 14 (LEFT)\n", - "\t\t\t\t\t\t\t\t\t 12 (LEFT)\n", - "\t\t\t\t\t\t\t\t\t\t 10 (LEFT)\n", - "\t\t\t\t\t\t\t\t\t\t\t 11 (RIGHT)\n", - "\t\t\t\t\t\t\t\t\t\t 13 (RIGHT)\n", - "\t\t\t\t\t\t\t\t\t 20 (RIGHT)\n", - "\t\t\t\t\t\t\t\t\t\t 16 (LEFT)\n", - "\t\t\t\t\t\t\t\t\t\t\t 15 (LEFT)\n", - "\t\t\t\t\t\t\t\t\t\t\t 18 (RIGHT)\n", - "\t\t\t\t\t\t\t\t\t\t\t\t 17 (LEFT)\n", - "\t\t\t\t\t\t\t\t\t\t\t\t 19 (RIGHT)\n", - "\t\t\t\t\t\t\t\t\t\t 21 (RIGHT)\n", - "\t\t\t\t\t\t\t\t\t\t\t 23 (RIGHT)\n", - "\t\t\t\t\t\t\t\t\t\t\t\t 22 (LEFT)\n", - "\t\t\t\t\t\t\t\t\t\t\t\t 24 (RIGHT)\n", - "\t\t\t\t\t\t\t\t 27 (RIGHT)\n", - "\t\t\t\t\t\t\t\t\t 26 (LEFT)\n", - "\t\t\t\t\t\t\t\t\t 28 (RIGHT)\n", - "\t\t\t\t\t\t\t 44 (RIGHT)\n", - "\t\t\t\t\t\t\t\t 38 (LEFT)\n", - "\t\t\t\t\t\t\t\t\t 30 (LEFT)\n", - "\t\t\t\t\t\t\t\t\t\t 37 (RIGHT)\n", - "\t\t\t\t\t\t\t\t\t\t\t 32 (LEFT)\n", - "\t\t\t\t\t\t\t\t\t\t\t\t 31 (LEFT)\n", + "\t\t\t 12 (RIGHT)\n", + "\t\t\t\t 11 (LEFT)\n", + "\t 67 (RIGHT)\n", + "\t\t 52 (LEFT)\n", + "\t\t\t 50 (LEFT)\n", + "\t\t\t\t 18 (LEFT)\n", + "\t\t\t\t\t 16 (LEFT)\n", + "\t\t\t\t\t\t 15 (LEFT)\n", + "\t\t\t\t\t\t\t 14 (LEFT)\n", + "\t\t\t\t\t\t 17 (RIGHT)\n", + "\t\t\t\t\t 22 (RIGHT)\n", + "\t\t\t\t\t\t 21 (LEFT)\n", + "\t\t\t\t\t\t\t 20 (LEFT)\n", + "\t\t\t\t\t\t\t\t 19 (LEFT)\n", + "\t\t\t\t\t\t 49 (RIGHT)\n", + "\t\t\t\t\t\t\t 23 (LEFT)\n", + "\t\t\t\t\t\t\t\t 39 (RIGHT)\n", + "\t\t\t\t\t\t\t\t\t 35 (LEFT)\n", + "\t\t\t\t\t\t\t\t\t\t 31 (LEFT)\n", + "\t\t\t\t\t\t\t\t\t\t\t 24 (LEFT)\n", + "\t\t\t\t\t\t\t\t\t\t\t\t 25 (RIGHT)\n", + "\t\t\t\t\t\t\t\t\t\t\t\t\t 27 (RIGHT)\n", + "\t\t\t\t\t\t\t\t\t\t\t\t\t\t 26 (LEFT)\n", + "\t\t\t\t\t\t\t\t\t\t\t\t\t\t 28 (RIGHT)\n", + "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t 30 (RIGHT)\n", + "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t 29 (LEFT)\n", + "\t\t\t\t\t\t\t\t\t\t\t 32 (RIGHT)\n", "\t\t\t\t\t\t\t\t\t\t\t\t 33 (RIGHT)\n", - "\t\t\t\t\t\t\t\t\t\t\t\t\t 35 (RIGHT)\n", - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t 34 (LEFT)\n", - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t 36 (RIGHT)\n", - "\t\t\t\t\t\t\t\t\t 39 (RIGHT)\n", - "\t\t\t\t\t\t\t\t\t\t 40 (RIGHT)\n", - "\t\t\t\t\t\t\t\t\t\t\t 41 (RIGHT)\n", - "\t\t\t\t\t\t\t\t\t\t\t\t 42 (RIGHT)\n", - "\t\t\t\t\t\t\t\t\t\t\t\t\t 43 (RIGHT)\n", - "\t\t\t\t\t\t\t\t 45 (RIGHT)\n", - "\t\t\t\t\t\t 48 (RIGHT)\n", - "\t\t\t\t\t\t\t 47 (LEFT)\n", - "\t\t\t\t\t\t\t 53 (RIGHT)\n", - "\t\t\t\t\t\t\t\t 51 (LEFT)\n", - "\t\t\t\t\t\t\t\t\t 49 (LEFT)\n", - "\t\t\t\t\t\t\t\t\t\t 50 (RIGHT)\n", - "\t\t\t\t\t\t\t\t\t 52 (RIGHT)\n", - "\t\t\t\t\t\t\t\t 60 (RIGHT)\n", - "\t\t\t\t\t\t\t\t\t 56 (LEFT)\n", - "\t\t\t\t\t\t\t\t\t\t 54 (LEFT)\n", - "\t\t\t\t\t\t\t\t\t\t\t 55 (RIGHT)\n", - "\t\t\t\t\t\t\t\t\t\t 59 (RIGHT)\n", - "\t\t\t\t\t\t\t\t\t\t\t 58 (LEFT)\n", - "\t\t\t\t\t\t\t\t\t\t\t\t 57 (LEFT)\n", - "\t\t\t\t\t\t\t\t\t 62 (RIGHT)\n", - "\t\t\t\t\t\t\t\t\t\t 61 (LEFT)\n", - "\t\t\t\t\t\t\t\t\t\t 63 (RIGHT)\n", - "\t\t\t\t\t 65 (RIGHT)\n", - "\t\t\t\t\t\t 69 (RIGHT)\n", - "\t\t\t\t\t\t\t 68 (LEFT)\n", - "\t\t\t\t\t\t\t\t 66 (LEFT)\n", - "\t\t\t\t\t\t\t\t\t 67 (RIGHT)\n", - "\t\t\t\t\t\t\t 73 (RIGHT)\n", - "\t\t\t\t\t\t\t\t 70 (LEFT)\n", + "\t\t\t\t\t\t\t\t\t\t\t\t\t 34 (RIGHT)\n", + "\t\t\t\t\t\t\t\t\t\t 37 (RIGHT)\n", + "\t\t\t\t\t\t\t\t\t\t\t 36 (LEFT)\n", + "\t\t\t\t\t\t\t\t\t\t\t 38 (RIGHT)\n", + "\t\t\t\t\t\t\t\t\t 41 (RIGHT)\n", + "\t\t\t\t\t\t\t\t\t\t 40 (LEFT)\n", + "\t\t\t\t\t\t\t\t\t\t 44 (RIGHT)\n", + "\t\t\t\t\t\t\t\t\t\t\t 43 (LEFT)\n", + "\t\t\t\t\t\t\t\t\t\t\t\t 42 (LEFT)\n", + "\t\t\t\t\t\t\t\t\t\t\t 47 (RIGHT)\n", + "\t\t\t\t\t\t\t\t\t\t\t\t 46 (LEFT)\n", + "\t\t\t\t\t\t\t\t\t\t\t\t\t 45 (LEFT)\n", + "\t\t\t\t\t\t\t\t\t\t\t\t 48 (RIGHT)\n", + "\t\t\t\t 51 (RIGHT)\n", + "\t\t\t 55 (RIGHT)\n", + "\t\t\t\t 54 (LEFT)\n", + "\t\t\t\t\t 53 (LEFT)\n", + "\t\t\t\t 58 (RIGHT)\n", + "\t\t\t\t\t 56 (LEFT)\n", + "\t\t\t\t\t\t 57 (RIGHT)\n", + "\t\t\t\t\t 60 (RIGHT)\n", + "\t\t\t\t\t\t 59 (LEFT)\n", + "\t\t\t\t\t\t 62 (RIGHT)\n", + "\t\t\t\t\t\t\t 61 (LEFT)\n", + "\t\t\t\t\t\t\t 63 (RIGHT)\n", + "\t\t\t\t\t\t\t\t 66 (RIGHT)\n", + "\t\t\t\t\t\t\t\t\t 64 (LEFT)\n", + "\t\t\t\t\t\t\t\t\t\t 65 (RIGHT)\n", + "\t\t 82 (RIGHT)\n", + "\t\t\t 80 (LEFT)\n", + "\t\t\t\t 69 (LEFT)\n", + "\t\t\t\t\t 68 (LEFT)\n", + "\t\t\t\t\t 79 (RIGHT)\n", + "\t\t\t\t\t\t 74 (LEFT)\n", + "\t\t\t\t\t\t\t 73 (LEFT)\n", + "\t\t\t\t\t\t\t\t 71 (LEFT)\n", + "\t\t\t\t\t\t\t\t\t 70 (LEFT)\n", "\t\t\t\t\t\t\t\t\t 72 (RIGHT)\n", - "\t\t\t\t\t\t\t\t\t\t 71 (LEFT)\n", - "\t\t\t\t\t\t\t\t 75 (RIGHT)\n", - "\t\t\t\t\t\t\t\t\t 74 (LEFT)\n", - "\t\t\t\t\t\t\t\t\t 77 (RIGHT)\n", - "\t\t\t\t\t\t\t\t\t\t 76 (LEFT)\n", - "\t\t\t 87 (RIGHT)\n", - "\t\t\t\t 85 (LEFT)\n", - "\t\t\t\t\t 81 (LEFT)\n", - "\t\t\t\t\t\t 79 (LEFT)\n", - "\t\t\t\t\t\t\t 80 (RIGHT)\n", - "\t\t\t\t\t\t 84 (RIGHT)\n", - "\t\t\t\t\t\t\t 82 (LEFT)\n", - "\t\t\t\t\t\t\t\t 83 (RIGHT)\n", - "\t\t\t\t\t 86 (RIGHT)\n", - "\t\t\t\t 92 (RIGHT)\n", - "\t\t\t\t\t 89 (LEFT)\n", - "\t\t\t\t\t\t 88 (LEFT)\n", + "\t\t\t\t\t\t\t 75 (RIGHT)\n", + "\t\t\t\t\t\t\t\t 77 (RIGHT)\n", + "\t\t\t\t\t\t\t\t\t 76 (LEFT)\n", + "\t\t\t\t\t\t\t\t\t 78 (RIGHT)\n", + "\t\t\t\t 81 (RIGHT)\n", + "\t\t\t 94 (RIGHT)\n", + "\t\t\t\t 83 (LEFT)\n", + "\t\t\t\t\t 88 (RIGHT)\n", + "\t\t\t\t\t\t 85 (LEFT)\n", + "\t\t\t\t\t\t\t 84 (LEFT)\n", + "\t\t\t\t\t\t\t 86 (RIGHT)\n", + "\t\t\t\t\t\t\t\t 87 (RIGHT)\n", "\t\t\t\t\t\t 91 (RIGHT)\n", "\t\t\t\t\t\t\t 90 (LEFT)\n", - "\t\t\t\t\t 95 (RIGHT)\n", - "\t\t\t\t\t\t 93 (LEFT)\n", - "\t\t\t\t\t\t\t 94 (RIGHT)\n", - "\t\t 97 (RIGHT)\n", - "\t\t\t 98 (RIGHT)\n", - "\t\t\t\t 99 (RIGHT)\n" + "\t\t\t\t\t\t\t\t 89 (LEFT)\n", + "\t\t\t\t\t\t\t 92 (RIGHT)\n", + "\t\t\t\t\t\t\t\t 93 (RIGHT)\n", + "\t\t\t\t 97 (RIGHT)\n", + "\t\t\t\t\t 95 (LEFT)\n", + "\t\t\t\t\t\t 96 (RIGHT)\n", + "\t\t\t\t\t 99 (RIGHT)\n", + "\t\t\t\t\t\t 98 (LEFT)\n" ] } ], @@ -703,7 +703,7 @@ "</svg>\n" ], "text/plain": [ - "<__main__.Graph at 0x7f58e025b490>" + "<__main__.Graph at 0x7f875c333b80>" ] }, "execution_count": 14, @@ -762,14 +762,14 @@ " self.name = name\n", " self.children = []\n", " self.graph = None # back reference\n", - " self.finder = None # who found me during BFS\n", " \n", " def __repr__(self):\n", " return self.name\n", " \n", - " def dfs_search(self, dst):\n", + " def dfs_search_v1(self, dst):\n", " \"\"\"\n", " Returns True / False when path to dst is found / not found.\n", + " Try using this method by commenting out the dfs_search method below.\n", " \"\"\"\n", " # TODO: what is the simplest case? current node is the dst\n", " if self in self.graph.visited:\n", @@ -785,6 +785,25 @@ " \n", " return False\n", "\n", + " def dfs_search(self, dst):\n", + " \"\"\"\n", + " Returns the actual path to the dst as a tuple or None otherwise\n", + " \"\"\"\n", + " # TODO: what is the simplest case? current node is the dst\n", + " if self in self.graph.visited:\n", + " return None\n", + " self.graph.visited.add(self)\n", + "\n", + " if self == dst:\n", + " return (self,)\n", + " \n", + " for child in self.children:\n", + " child_path = child.dfs_search(dst)\n", + " if child_path != None:\n", + " return (self,) + child_path\n", + " \n", + " return None\n", + "\n", "\n", "g = example(1)\n", "g" @@ -795,7 +814,7 @@ "id": "c83e9993-765c-42a0-97f6-6277627acf95", "metadata": {}, "source": [ - "### Testcases for DFS with True or False" + "### Testcases for DFS" ] }, { @@ -805,16 +824,11 @@ "metadata": {}, "outputs": [ { - "ename": "AttributeError", - "evalue": "'Node' object has no attribute 'dfs_search_v1'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[15], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[43mg\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdfs_search\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mB\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mA\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m) \u001b[38;5;66;03m# should return False\u001b[39;00m\n\u001b[1;32m 2\u001b[0m \u001b[38;5;28mprint\u001b[39m(g\u001b[38;5;241m.\u001b[39mdfs_search(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mB\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mD\u001b[39m\u001b[38;5;124m\"\u001b[39m)) \u001b[38;5;66;03m# should return True\u001b[39;00m\n", - "Cell \u001b[0;32mIn[14], line 43\u001b[0m, in \u001b[0;36mGraph.dfs_search\u001b[0;34m(self, src_name, dst_name)\u001b[0m\n\u001b[1;32m 38\u001b[0m \u001b[38;5;66;03m# Q: is this method recursive?\u001b[39;00m\n\u001b[1;32m 39\u001b[0m \u001b[38;5;66;03m# A: no, it is just invoking dfs_search method for Node object instance\u001b[39;00m\n\u001b[1;32m 40\u001b[0m \u001b[38;5;66;03m# dfs_search method in Node class is recursive\u001b[39;00m\n\u001b[1;32m 41\u001b[0m \u001b[38;5;66;03m# These methods in two different classes just happen to share the same name\u001b[39;00m\n\u001b[1;32m 42\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mvisited\u001b[38;5;241m.\u001b[39mclear()\n\u001b[0;32m---> 43\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnodes\u001b[49m\u001b[43m[\u001b[49m\u001b[43msrc_name\u001b[49m\u001b[43m]\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdfs_search\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnodes\u001b[49m\u001b[43m[\u001b[49m\u001b[43mdst_name\u001b[49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\n", - "Cell \u001b[0;32mIn[14], line 69\u001b[0m, in \u001b[0;36mNode.dfs_search\u001b[0;34m(self, dst)\u001b[0m\n\u001b[1;32m 66\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[1;32m 68\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m child \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mchildren:\n\u001b[0;32m---> 69\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[43mchild\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdfs_search_v1\u001b[49m(dst):\n\u001b[1;32m 70\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[1;32m 72\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mFalse\u001b[39;00m\n", - "\u001b[0;31mAttributeError\u001b[0m: 'Node' object has no attribute 'dfs_search_v1'" + "name": "stdout", + "output_type": "stream", + "text": [ + "None\n", + "(B, C, D)\n" ] } ], @@ -835,187 +849,6 @@ "# TODO: use a different algorithm to find the shortest path" ] }, - { - "cell_type": "markdown", - "id": "ac4d6c30", - "metadata": {}, - "source": [ - "#### **IMPORTANT**: it is not recommended to re-define same `class`. This is shown only for example purposes. You must always go back to the original cell and update the definition there." - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "44fda5f1", - "metadata": {}, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n", - "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n", - " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n", - "<!-- Generated by graphviz version 2.43.0 (0)\n", - " -->\n", - "<!-- Title: %3 Pages: 1 -->\n", - "<svg width=\"134pt\" height=\"188pt\"\n", - " viewBox=\"0.00 0.00 134.00 188.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n", - "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 184)\">\n", - "<title>%3</title>\n", - "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-184 130,-184 130,4 -4,4\"/>\n", - "<!-- A -->\n", - "<g id=\"node1\" class=\"node\">\n", - "<title>A</title>\n", - "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\n", - "<text text-anchor=\"middle\" x=\"27\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">A</text>\n", - "</g>\n", - "<!-- B -->\n", - "<g id=\"node2\" class=\"node\">\n", - "<title>B</title>\n", - "<ellipse fill=\"none\" stroke=\"black\" cx=\"99\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\n", - "<text text-anchor=\"middle\" x=\"99\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">B</text>\n", - "</g>\n", - "<!-- C -->\n", - "<g id=\"node3\" class=\"node\">\n", - "<title>C</title>\n", - "<ellipse fill=\"none\" stroke=\"black\" cx=\"71\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\n", - "<text text-anchor=\"middle\" x=\"71\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">C</text>\n", - "</g>\n", - "<!-- B->C -->\n", - "<g id=\"edge1\" class=\"edge\">\n", - "<title>B->C</title>\n", - "<path fill=\"none\" stroke=\"black\" d=\"M92.36,-144.41C89.09,-136.22 85.06,-126.14 81.38,-116.95\"/>\n", - "<polygon fill=\"black\" stroke=\"black\" points=\"84.55,-115.45 77.59,-107.47 78.05,-118.05 84.55,-115.45\"/>\n", - "</g>\n", - "<!-- D -->\n", - "<g id=\"node4\" class=\"node\">\n", - "<title>D</title>\n", - "<ellipse fill=\"none\" stroke=\"black\" cx=\"98\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\n", - "<text text-anchor=\"middle\" x=\"98\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">D</text>\n", - "</g>\n", - "<!-- C->D -->\n", - "<g id=\"edge2\" class=\"edge\">\n", - "<title>C->D</title>\n", - "<path fill=\"none\" stroke=\"black\" d=\"M77.4,-72.41C80.51,-64.34 84.33,-54.43 87.83,-45.35\"/>\n", - "<polygon fill=\"black\" stroke=\"black\" points=\"91.13,-46.55 91.46,-35.96 84.6,-44.03 91.13,-46.55\"/>\n", - "</g>\n", - "<!-- D->B -->\n", - "<g id=\"edge3\" class=\"edge\">\n", - "<title>D->B</title>\n", - "<path fill=\"none\" stroke=\"black\" d=\"M101.65,-36.09C103.68,-46.43 105.98,-59.91 107,-72 108.34,-87.94 108.2,-92.04 107,-108 106.36,-116.48 105.16,-125.66 103.88,-133.96\"/>\n", - "<polygon fill=\"black\" stroke=\"black\" points=\"100.42,-133.45 102.25,-143.89 107.32,-134.59 100.42,-133.45\"/>\n", - "</g>\n", - "</g>\n", - "</svg>\n" - ], - "text/plain": [ - "<__main__.Graph at 0x7f58d164b430>" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "class Graph:\n", - " def __init__(self):\n", - " # name => Node\n", - " self.nodes = {}\n", - " # to keep track which nodes have already been visited\n", - " self.visited = set()\n", - "\n", - " def node(self, name):\n", - " node = Node(name)\n", - " self.nodes[name] = node\n", - " node.graph = self\n", - " \n", - " def edge(self, src, dst):\n", - " \"\"\"\n", - " Automatically adds missing nodes.\n", - " \"\"\"\n", - " for name in [src, dst]:\n", - " if not name in self.nodes:\n", - " self.node(name)\n", - " self.nodes[src].children.append(self.nodes[dst])\n", - "\n", - " def _repr_svg_(self):\n", - " \"\"\"\n", - " Draws the graph nodes and edges iteratively.\n", - " \"\"\"\n", - " g = Digraph()\n", - " for n in self.nodes:\n", - " g.node(n)\n", - " for child in self.nodes[n].children:\n", - " g.edge(n, child.name)\n", - " return g._repr_image_svg_xml()\n", - " \n", - " def dfs_search(self, src_name, dst_name):\n", - " \"\"\"\n", - " Clears the visited set and invokes dfs_search using Node object instance\n", - " with name src_name.\n", - " \"\"\"\n", - " # Q: is this method recursive?\n", - " # A: no, it is just invoking dfs_search method for Node object instance\n", - " # dfs_search method in Node class is recursive\n", - " # These methods in two different classes just happen to share the same name\n", - " self.visited.clear()\n", - " return self.nodes[src_name].dfs_search(self.nodes[dst_name])\n", - " \n", - "\n", - "class Node:\n", - " def __init__(self, name):\n", - " self.name = name\n", - " self.children = []\n", - " self.graph = None # back reference\n", - " self.finder = None # who found me during BFS\n", - " \n", - " def __repr__(self):\n", - " return self.name\n", - " \n", - " def dfs_search_v1(self, dst):\n", - " \"\"\"\n", - " Returns True / False when path to dst is found / not found.\n", - " Try using this method by commenting out the dfs_search method below.\n", - " \"\"\"\n", - " # TODO: what is the simplest case? current node is the dst\n", - " if self in self.graph.visited:\n", - " return False\n", - " self.graph.visited.add(self)\n", - "\n", - " if self == dst:\n", - " return True\n", - " \n", - " for child in self.children:\n", - " if child.dfs_search_v1(dst):\n", - " return True\n", - " \n", - " return False\n", - "\n", - " def dfs_search(self, dst):\n", - " \"\"\"\n", - " Returns the actual path to the dst as a tuple or None otherwise\n", - " \"\"\"\n", - " # TODO: what is the simplest case? current node is the dst\n", - " if self in self.graph.visited:\n", - " return None\n", - " self.graph.visited.add(self)\n", - "\n", - " if self == dst:\n", - " return (self,)\n", - " \n", - " for child in self.children:\n", - " child_path = child.dfs_search(dst)\n", - " if child_path != None:\n", - " return (self,) + child_path\n", - " \n", - " return None\n", - "\n", - "\n", - "g = example(1)\n", - "g" - ] - }, { "cell_type": "markdown", "id": "59aee028", @@ -1026,7 +859,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 17, "id": "6de4c8b1", "metadata": {}, "outputs": [ @@ -1071,7 +904,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 18, "id": "4480be3c", "metadata": {}, "outputs": [ @@ -1153,10 +986,10 @@ "</svg>\n" ], "text/plain": [ - "<__main__.Graph at 0x7f58d16a22c0>" + "<__main__.Graph at 0x7f87581aead0>" ] }, - "execution_count": 19, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -1168,7 +1001,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 19, "id": "9467f6cf", "metadata": {}, "outputs": [ @@ -1201,7 +1034,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 20, "id": "7da7bccc", "metadata": {}, "outputs": [ @@ -1211,7 +1044,7 @@ "(5,)" ] }, - "execution_count": 21, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } @@ -1222,7 +1055,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 21, "id": "b05a563a", "metadata": {}, "outputs": [ @@ -1232,7 +1065,7 @@ "5" ] }, - "execution_count": 22, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" } @@ -1243,7 +1076,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 22, "id": "778a76d7", "metadata": {}, "outputs": [ @@ -1253,7 +1086,7 @@ "(5, 5, 5)" ] }, - "execution_count": 23, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -1265,7 +1098,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 23, "id": "b8cc1b36", "metadata": {}, "outputs": [ @@ -1275,7 +1108,7 @@ "15" ] }, - "execution_count": 24, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } @@ -1286,7 +1119,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 24, "id": "a9e31d22", "metadata": {}, "outputs": [ @@ -1296,7 +1129,7 @@ "(3, 5)" ] }, - "execution_count": 25, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" }