2055 lines
214 KiB
Plaintext
2055 lines
214 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Artificial Intelligence UE\n",
|
|
"## Exercises 1 - Uninformed Search\n",
|
|
"\n",
|
|
"In this series of exercises you can implement a few different **uninformed** search algorithms: \n",
|
|
"- Breadth First Search\n",
|
|
"- Uniform Cost Search\n",
|
|
"- Depth First Search\n",
|
|
"- Depth Limited Depth First Search\n",
|
|
"- Iterative Deepening Search\n",
|
|
"\n",
|
|
"The algorithms have been explained in the lecture (VO) and we gave you some additional information in the exercise (UE). Please refer to the lecture slides (VO) for the pseudo algorithms and the exercise slides (UE) for additional hints. \n",
|
|
"Before implementing the algorithms make sure to check out the introductory notebook \"introducing_pig.ipynb\" and read the following instructions carefully.\n",
|
|
"\n",
|
|
"<div class=\"alert alert-warning\">\n",
|
|
"\n",
|
|
"<p><strong>Practical hints:</strong></p>\n",
|
|
"<ul>\n",
|
|
"<li>Replace the placeholders <code># YOUR CODE HERE</code>, <code>raise NotImplementedError()</code> with your code.</li>\n",
|
|
"<li>Do not rename any of the already existing variables (this might lead to some tests failing / not working).</li>\n",
|
|
"<li><code>solve()</code> should return the found solution node or <code>None</code> if no solution is found. You do not need to store the path, the function <code>node.get_action_sequence()</code> can be used to retrieve it later via backtracking.</li>\n",
|
|
"<li>Use a <code>set()</code> to store already visited nodes (when needed).</li>\n",
|
|
"<li>Use the imported data structures <code>Queue</code>, <code>Stack</code>, and <code>PriorityQueue</code> as the fringe / frontier (choose the right datatype depending on the algorithm)</li>\n",
|
|
"</ul>\n",
|
|
"</div>\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "e8c3c2892151630ce3b9132174833fd7",
|
|
"grade": false,
|
|
"grade_id": "cell-c5c2d34ef5fe1e7d",
|
|
"locked": true,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"from pig_lite.problem.base import Problem\n",
|
|
"from pig_lite.datastructures.queue import Queue\n",
|
|
"from pig_lite.datastructures.stack import Stack\n",
|
|
"from pig_lite.datastructures.priority_queue import PriorityQueue\n",
|
|
"from pig_lite.instance_generation.problem_factory import ProblemFactory"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"<div class=\"alert alert-warning\">\n",
|
|
"<strong>Hint:</strong> Here we load and visualize a problem instance that is used for some basic tests, please do not change it. You can use the printed output after each algorithm (i.e., position of the end node, action sequence) to compare whether your algorithm behaves as expected).\n",
|
|
"</div>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "b9b312c546887a10a22564e421213312",
|
|
"grade": false,
|
|
"grade_id": "cell-6f2cca86b47722a9",
|
|
"locked": true,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA94AAAIcCAYAAAAAOnYgAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjUsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvWftoOwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAPYBJREFUeJzt3XucVXW9N/Dv5jYDzgwc0OEmDVChEoi3LNEUDt4Q0a6WqYGWz3MUz5OWz6OlBerpkFQeO4lYnfKSF0Q92IXyxPFeiuKtDMqOiWIKQnIQxVCYvZ4/ppnjCAyzcW02a6/3+/Var9qLtX/rt9ce/PGdz2/9ViFJkiQAAACAsuhS6Q4AAABANVN4AwAAQBkpvAEAAKCMFN4AAABQRgpvAAAAKCOFNwAAAJSRwhsAAADKSOENAAAAZaTwBgAAgDJSeENEFAqFTm333HNP3HPPPVEoFOLWW28te78ef/zxOOyww6J3795RKBTi8ssvbzv/PffcU3J7pbx36tSpMXTo0JLPAVBtdtYxYkd68cUXY8aMGfHEE0+k3vZpp50WRx99dLt9Wxr/Kmnp0qUxY8aMePbZZyvaj7d79tlno1AoxDXXXFPpruy0rrzyyi1eny1du2uuuSYKhcJ2fc8/+MEPYvDgwbF+/frt7yxVrVulOwA7gwcffLDd60suuSTuvvvuuOuuu9rtHzlyZDz22GM7rF+nnXZarF+/PubOnRt/93d/F0OHDo1evXrFgw8+GCNHjtxh/QDIs511jNiRXnzxxbjoooti6NChsc8++6TW7uOPPx7XXnttPPTQQ+32b2n8q6SlS5fGRRddFOPGjat4X95q4MCB8eCDD8a73/3uSndlp3XllVfGrrvuGlOnTm23P+1rN2XKlLj00ktj1qxZcdFFF6XSJtVF4Q0R8cEPfrDd69122y26dOmy2f4d7Xe/+12cfvrpMXHixHb7K90vgDzZWceIavD1r389DjzwwDjggAPa7d/a+Le9Nm7cGIVCIbp1q65/+tbU1Pg53E5pX7tu3brF//7f/zsuueSSOO+886JXr16ptU11MNUcttPGjRvjggsuiEGDBkVDQ0Mcfvjh8dRTT2123H/+53/GhAkToqGhIXr16hUHH3xw3HnnnR223TrVadOmTTFnzpy2aYwRW58u/sgjj8Rxxx0Xffv2jdra2th3331j3rx5nfos11xzTeyxxx5RU1MTe+21V1x33XWduwgAbFE5x4hWa9eujS9+8YsxfPjwqKmpicbGxjjmmGPiD3/4Q9sxa9asiTPPPDMGDx4cPXr0iOHDh8cFF1wQb7zxRru2brnllvjABz4QvXv3jl69esXw4cPjtNNOi4iWcef9739/RESceuqpbWPSjBkzIiLimWeeiU996lMxaNCgqKmpif79+8eECRO2OS39pZdeivnz58cpp5zStq+j8S+ipSA//vjj4+/+7u+itrY29tlnn7j22mvbtds6Tv7oRz+KL37xizF48OCoqamJp59+eqt9mTNnTowZMybq6uqivr4+9txzz/jyl7/c1qdPfOITERExfvz4tj69dYpyZ77HGTNmRKFQiMcffzw++tGPRkNDQ/Tu3TtOPvnkWL16dbtjhw4dGscee2zMnz8/9t5776itrY3hw4fHv/7rv7Y7bkvTpVvPs2TJkjjxxBOjd+/e0b9//zjttNPilVdeaff+tWvXxmc/+9no27dv1NXVxaRJk+KZZ55p9/12ZPny5XHyySdHY2Nj278hvvWtb0WxWNysj9/85jfjsssui2HDhkVdXV0cdNBBsWjRom2eY/Xq1XHmmWfGyJEjo66uLhobG+Pv//7v4/7779/me4cOHRpLliyJe++9t+17a52xUMo0/c7+PT3ppJNi3bp1MXfu3G22Sf4ovGE7ffnLX47nnnsu/u3f/i2+973vxX/913/F5MmTo7m5ue2Y66+/Po488shoaGiIa6+9NubNmxd9+/aNo446qsN/WE2aNKltauPHP/7xePDBBzeb6vhWd999dxx88MGxdu3auOqqq+LHP/5x7LPPPvHJT35ymwPKNddcE6eeemrstddecdttt8WFF14Yl1xyyWZTKAHovHKOERERr776ahxyyCHx3e9+N0499dT46U9/GldddVWMGDEiVqxYERERGzZsiPHjx8d1110XX/jCF2LBggVx8sknx6xZs+KjH/1oW1sPPvhgfPKTn4zhw4fH3LlzY8GCBfHVr341Nm3aFBER++23X1x99dUREXHhhRe2jUmf+9znIiLimGOOiUcffTRmzZoVCxcujDlz5sS+++4ba9eu7fAz/PKXv4yNGzfG+PHj2/Z1NP499dRTMXbs2FiyZEn867/+a/z7v/97jBw5MqZOnRqzZs3arP0vfelLsXz58rjqqqvipz/9aTQ2Nm6xH3Pnzo0zzzwzDjvssJg/f37cfvvtcc4557Tdqztp0qT453/+54iImD17dlufJk2aFBGlf48f+chH4j3veU/ceuutMWPGjLj99tvjqKOOio0bN7Y77oknnoizzz47zjnnnJg/f36MHTs2Pv/5z8c3v/nNDq9rq4997GMxYsSIuO222+L888+PG2+8Mc4555y2Py8WizF58uS48cYb47zzzov58+fHBz7wgc3ut9+a1atXx9ixY+OXv/xlXHLJJfGTn/wkDj/88Dj33HPjrLPO2uz42bNnx8KFC+Pyyy+PG264IdavXx/HHHPMZr8MeLs1a9ZERMT06dNjwYIFcfXVV8fw4cNj3Lhx21yzZv78+TF8+PDYd9992763+fPnd+rztSrl+x0wYEDsueeesWDBgpLOQU4kwGamTJmS7LLLLlv8s7vvvjuJiOSYY45pt3/evHlJRCQPPvhgkiRJsn79+qRv377J5MmT2x3X3NycjBkzJjnwwAO32Y+ISKZNm7bF8999991t+/bcc89k3333TTZu3Nju2GOPPTYZOHBg0tzcvMX3Njc3J4MGDUr222+/pFgstr3v2WefTbp37540NTVts48AebMzjBEXX3xxEhHJwoULt3rMVVddlUREMm/evHb7L7300iQikl/+8pdJkiTJN7/5zSQikrVr1261rcWLFycRkVx99dXt9v/lL39JIiK5/PLLO+zvlpxxxhlJz549240/rbY0/n3qU59KampqkuXLl7fbP3HixKRXr15t/W/9Dg499NBO9eOss85K+vTp0+Ext9xyy2Zjb5KU9j1Onz49iYjknHPOaXfsDTfckEREcv3117fta2pqSgqFQvLEE0+0O/aII45IGhoakvXr1ydJkiTLli3b7HtpPc+sWbPavffMM89Mamtr2673ggULkohI5syZ0+64mTNnJhGRTJ8+vcNrcv755ycRkTz00EPt9p9xxhlJoVBInnrqqXZ9HD16dLJp06a24x5++OEkIpKbbrqpw/O83aZNm5KNGzcmEyZMSD7ykY9s8/j3ve99yWGHHbbZ/i1du6uvvjqJiGTZsmVJkmzf39OTTjop6d+/f0mfiXyQeMN2Ou6449q93nvvvSMi4rnnnouIiAceeCDWrFkTU6ZMiU2bNrVtxWIxjj766Fi8eHEqK18+/fTT8Yc//CFOOumkiIh25zrmmGNixYoVW5zeGNGSHrz44ovx6U9/ut1Uvqamphg7duw77htAXpV7jPjFL34RI0aMiMMPP3yrx9x1112xyy67xMc//vF2+1sXmWpN61qnkZ9wwgkxb968eOGFFzr9Ofv27Rvvfve74xvf+EZcdtll8fjjj7ebZtyRF198MXbbbbd2409H7rrrrpgwYUIMGTKk3f6pU6fG66+/vtnMsI997GOdavfAAw+MtWvXxoknnhg//vGP4y9/+Uun3hexfd9j63jd6oQTTohu3brF3Xff3W7/+973vhgzZky7fZ/+9Kdj3bp1nVrEb0s/gxs2bIhVq1ZFRMS9997bdv63OvHEE7fZdkTL9zFy5Mg48MAD2+2fOnVqJEmy2cy5SZMmRdeuXdv1J+J//k505Kqrror99tsvamtro1u3btG9e/e488474/e//32n+rq9tuf7bWxsjFWrVrXNGIFWCm/YTv369Wv3uqamJiIi/vrXv0ZEy71rES1T5bp3795uu/TSSyNJkrbpU+9E63nOPffczc5z5plnRkRs9R8RL7/8ckS0TI16uy3tA6Bzyj1GrF69OnbfffcO+/Dyyy/HgAEDNitsGxsbo1u3bm1jwKGHHhq33357bNq0KT7zmc/E7rvvHqNGjYqbbrppm5+zUCjEnXfeGUcddVTMmjUr9ttvv9htt93i//yf/xOvvvpqh+/961//GrW1tds8x1s/z8CBAzfbP2jQoLY/f6stHbslp5xySvzwhz+M5557Lj72sY9FY2NjfOADH4iFCxdu873b8z2+fXzt1q1b9OvXb7P+dzQ2v/3YLdnWz+DLL78c3bp1i759+7Y7rn///ttsu/X9pXwf2+rP1lx22WVxxhlnxAc+8IG47bbbYtGiRbF48eI4+uijt/ned2p7vt/a2tpIkiQ2bNhQ1r6RPdW1tCPsRHbdddeIiPjOd76z1VUzOzu4deY8X/rSl9rds/dWe+yxxxb3tw6CK1eu3OzPtrQPgHS80zFit912iz//+c8dnqNfv37x0EMPRZIk7Yrv1jSutQ8REccff3wcf/zx8cYbb8SiRYti5syZ8elPfzqGDh0aBx10UIfnaWpqih/84AcREfHHP/4x5s2bFzNmzIg333wzrrrqqq2+b9dddy3p8Wv9+vVru3/9rV588cW29t6qs0l6RMuicaeeemqsX78+7rvvvpg+fXoce+yx8cc//jGampq2+r7t+R5XrlwZgwcPbnu9adOmePnllzcrTDsam99+7Pbo169fbNq0KdasWdOu+O7s+F/q97G9rr/++hg3blzMmTOn3f5t/WInDdvz/a5ZsyZqamqirq6u7P0jWyTeUCYHH3xw9OnTJ5YuXRoHHHDAFrcePXq84/Psscce8d73vjd+85vfbPU89fX1W33vwIED46abbookSdr2P/fcc/HAAw+8474BsGXvdIyYOHFi/PGPf+xwIcwJEybEa6+9Frfffnu7/a1PrpgwYcJm76mpqYnDDjssLr300ohoec526/6IbaeTI0aMiAsvvDBGjx69zaJ6zz33jJdffnmbi2u99fPcddddbYXdWz9Pr169Unk01C677BITJ06MCy64IN58881YsmRJRGz982/P93jDDTe0ez1v3rzYtGlTjBs3rt3+JUuWxG9+85t2+2688caor6+P/fbb7x1/1sMOOywiIm6++eZ2+zu7IveECRNi6dKlm33P1113XRQKhXaL5r0ThUKh7fq3+u1vf9vhorNvVVNTs93J+PZ8v88880yMHDlyu85HdZN4Q5nU1dXFd77znZgyZUqsWbMmPv7xj0djY2OsXr06fvOb38Tq1as3++3t9vrud78bEydOjKOOOiqmTp0agwcPjjVr1sTvf//7eOyxx+KWW27Z4vu6dOkSl1xySXzuc5+Lj3zkI3H66afH2rVrY8aMGaaaA5TROx0jzj777Lj55pvj+OOPj/PPPz8OPPDA+Otf/xr33ntvHHvssTF+/Pj4zGc+E7Nnz44pU6bEs88+G6NHj45f/epX8c///M9xzDHHtN0f/tWvfjX+/Oc/x4QJE2L33XePtWvXxre//e3o3r17W3H27ne/O3r27Bk33HBD7LXXXlFXVxeDBg2Kv/zlL3HWWWfFJz7xiXjve98bPXr0iLvuuit++9vfxvnnn9/hNRg3blwkSRIPPfRQHHnkkdu8ZtOnT4+f/exnMX78+PjqV78affv2jRtuuCEWLFgQs2bNit69e5fwDfyP008/PXr27BkHH3xwDBw4MFauXBkzZ86M3r17t93/PmrUqIiI+N73vhf19fVRW1sbw4YNi379+pX8Pf77v/97dOvWLY444ohYsmRJfOUrX4kxY8Zsdq/1oEGD4rjjjosZM2bEwIED4/rrr4+FCxfGpZdemsozoo8++ug4+OCD44tf/GKsW7cu9t9//3jwwQfbfjHTpUvH+dw555wT1113XUyaNCkuvvjiaGpqigULFsSVV14ZZ5xxRowYMeId9zEi4thjj41LLrkkpk+fHocddlg89dRTcfHFF8ewYcM6dR/16NGjY+7cuXHzzTfH8OHDo7a2NkaPHt2pc5f697RYLMbDDz8cn/3sZ7f781LFKrasG+zEOrNi7S233NJu/5ZWx0ySJLn33nuTSZMmJX379k26d++eDB48OJk0adJm79+S6OSq5kmSJL/5zW+SE044IWlsbEy6d++eDBgwIPn7v//75Kqrrtrme//t3/4tee9735v06NEjGTFiRPLDH/4wmTJlilXNAbZgZxkj/vu//zv5/Oc/n7zrXe9KunfvnjQ2NiaTJk1K/vCHP7Qd8/LLLyf/8A//kAwcODDp1q1b0tTUlHzpS19KNmzY0HbMz372s2TixInJ4MGDkx49eiSNjY3JMccck9x///3tznfTTTcle+65Z9K9e/e2Va9feumlZOrUqcmee+6Z7LLLLkldXV2y9957J//yL//SbgXrLWlubk6GDh2anHnmmZv92ZbGvyRJkieffDKZPHly0rt376RHjx7JmDFjNrumW/sOtubaa69Nxo8fn/Tv3z/p0aNHMmjQoOSEE05Ifvvb37Y77vLLL0+GDRuWdO3adbPvsjPfY+tq448++mgyefLkpK6uLqmvr09OPPHE5KWXXmp3rqampmTSpEnJrbfemrzvfe9LevTokQwdOjS57LLL2h3X0armq1evbnfs21fsTpIkWbNmTXLqqacmffr0SXr16pUcccQRyaJFi5KISL797W9v89o999xzyac//emkX79+Sffu3ZM99tgj+cY3vtH2NJW39vEb3/jGZu+PTqye/sYbbyTnnntuMnjw4KS2tjbZb7/9kttvv73T/0559tlnkyOPPDKpr69PIqLtPZ1Z1bxVZ/+e3nnnnW3fMbxdIUneMr8UAAB2kG9961vxta99LV544YXo2bNnpbtTVjNmzIiLLrooVq9evc37n4cOHRqjRo2Kn/3sZzuod//jxhtvjJNOOil+/etfe8JJiU455ZR45pln4te//nWlu8JOyFRzAAAqYtq0aXHFFVfE7Nmz49xzz610d3LnpptuihdeeCFGjx4dXbp0iUWLFsU3vvGN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LbobGxujV69eiscSJEkSr7/+eqxatSoiIgYOHFjhHgEAwM5P4U2uNDc3txXd/fr1q3R3Mqlnz54REbFq1apobGw07RwAALbB4mrkSus93b169apwT7Kt9fq5Rx4AALZN4U0umV7+zrh+AADQeQpvAAAAKCOFNwAAAJSRwhsyburUqfHhD384tfbGjRsXZ599dmrtAQBA3lnVHLZDczGJh5etiVWvbojG+to4cFjf6Nol2/c9b9y4Mbp3717pbgAAQNWReEOJ7vjdijjk0rvixO8vis/PfSJO/P6iOOTSu+KO360o63lvvfXWGD16dPTs2TP69esXhx9+ePzf//t/49prr40f//jHUSgUolAoxD333BMREeedd16MGDEievXqFcOHD4+vfOUr7VYhnzFjRuyzzz7xwx/+MIYPHx41NTUxZcqUuPfee+Pb3/52W3vPPvtsWT8XAABUO4k3lOCO362IM65/LJK37V/5yoY44/rHYs7J+8XRowamft4VK1bEiSeeGLNmzYqPfOQj8eqrr8b9998fn/nMZ2L58uWxbt26uPrqqyMiom/fvhERUV9fH9dcc00MGjQonnzyyTj99NOjvr4+/t//+39t7T799NMxb968uO2226Jr167R1NQU//Vf/xWjRo2Kiy++OCIidtttt9Q/DwAA5InCGzqpuZjERT9dulnRHRGRREQhIi766dI4YuSA1Kedr1ixIjZt2hQf/ehHo6mpKSIiRo8eHRERPXv2jDfeeCMGDBjQ7j0XXnhh2/8fOnRofPGLX4ybb765XeH95ptvxo9+9KN2xXWPHj2iV69em7UHAABsH1PNoZMeXrYmVryyYat/nkTEilc2xMPL1qR+7jFjxsSECRNi9OjR8YlPfCK+//3vx3//9393+J5bb701DjnkkBgwYEDU1dXFV77ylVi+fHm7Y5qamiTaAABQZgpv6KRVr2696N6e40rRtWvXWLhwYfziF7+IkSNHxne+853YY489YtmyZVs8ftGiRfGpT30qJk6cGD/72c/i8ccfjwsuuCDefPPNdsftsssuqfcVAABoz1Rz6KTG+tpUjytVoVCIgw8+OA4++OD46le/Gk1NTTF//vzo0aNHNDc3tzv217/+dTQ1NcUFF1zQtu+5557r1Hm21B4AALD9FN7QSQcO6xsDe9fGylc2bPE+70JEDOjd8mixtD300ENx5513xpFHHhmNjY3x0EMPxerVq2OvvfaKDRs2xH/8x3/EU089Ff369YvevXvHe97znli+fHnMnTs33v/+98eCBQti/vz5nTrX0KFD46GHHopnn3026urqom/fvtGli8kxAACwvfxrGjqpa5dCTJ88MiJaiuy3an09ffLIsjzPu6GhIe6777445phjYsSIEXHhhRfGt771rZg4cWKcfvrpsccee8QBBxwQu+22W/z617+O448/Ps4555w466yzYp999okHHnggvvKVr3TqXOeee2507do1Ro4cGbvttttm94UDAAClKSRJsqXwDqrShg0bYtmyZTFs2LCord2+KeF3/G5FXPTTpe0WWhvYuzamTx5ZlkeJ7YzSuI4AAJAXpppDiY4eNTCOGDkgHl62Jla9uiEa61uml5cj6QYAALJP4Q3boWuXQhz07n6V7gYAAJAB7vEGAACAMlJ4AwAAQBkpvAEAAKCMFN4AAABQRgpvAAAAKCOFNwAAAJSRwhsAAADKSOENOTZjxozYZ599Kt0NAACoagpvAAAAKKNule4AZFKxOeK5ByJeeymirn9E09iILl0r3SsAAGAnJPGGUi39ScTloyKuPTbits+2/O/lo1r2l1GSJDFr1qwYPnx49OzZM8aMGRO33nprRETcc889USgU4s4774wDDjggevXqFWPHjo2nnnqqXRtf//rXo3///lFfXx+f/exnY8OGDWXtMwAAoPCG0iz9ScS8z0Sse7H9/nUrWvaXsfi+8MIL4+qrr445c+bEkiVL4pxzzomTTz457r333rZjLrjggvjWt74VjzzySHTr1i1OO+20tj+bN29eTJ8+Pb72ta/FI488EgMHDowrr7yybP0FAABaFJIkSSrdCdhRNmzYEMuWLYthw4ZFbW1taW8uNrck228vutsUIhoGRZz9ZOrTztevXx+77rpr3HXXXXHQQQe17f/c5z4Xr7/+evyv//W/Yvz48fGf//mfMWHChIiI+PnPfx6TJk2Kv/71r1FbWxtjx46NMWPGxJw5c9re/8EPfjA2bNgQTzzxREn9eUfXEQAAckbiDZ313AMdFN0REUnEuhdajkvZ0qVLY8OGDXHEEUdEXV1d23bdddfFn/70p7bj9t5777b/P3DgwIiIWLVqVURE/P73v29XtEfEZq8BAID0WVwNOuu1l9I9rgTFYjEiIhYsWBCDBw9u92c1NTVtxXf37t3b9hcKhXbvBQAAKkPiDZ1V1z/d40owcuTIqKmpieXLl8d73vOedtuQIUM61cZee+0VixYtarfv7a8BAID0Sbyhs5rGttzDvW5FRGxpaYS/3ePdNDb1U9fX18e5554b55xzThSLxTjkkENi3bp18cADD0RdXV00NTVts43Pf/7zMWXKlDjggAPikEMOiRtuuCGWLFkSw4cPT72/AADA/1B4Q2d16Rpx9KUtq5dHIdoX3y3TuuPor5fted6XXHJJNDY2xsyZM+OZZ56JPn36xH777Rdf/vKXOzWd/JOf/GT86U9/ivPOOy82bNgQH/vYx+KMM86I//iP/yhLfwEAgBZWNSdXUlmNe+lPIu44r/1Caw2DW4rukcel09GdnFXNAQCg8yTeUKqRx0XsOall9fLXXmq5p7tpbNmSbgAAINsU3rA9unSNGPahSvcCAADIAKuaAwAAQBkpvAEAAKCMFN7kkjUF3xnXDwAAOk/hTa507949IiJef/31Cvck21qvX+v1BAAAts7iauRK165do0+fPrFq1aqIiOjVq1cUCoUK9yo7kiSJ119/PVatWhV9+vSJrl2t5A4AANviOd7kTpIksXLlyli7dm2lu5JZffr0iQEDBvilBQAAdILCm9xqbm6OjRs3VrobmdO9e3dJNwAAlEDhDQAAAGVkcTUAAAAoI4U3AAAAlJHCGwAAAMpI4Q0AAABlpPAGAACAMlJ4AwAAQBkpvAEAAKCM/j9Sg0LHBUDMTgAAAABJRU5ErkJggg==",
|
|
"text/plain": [
|
|
"<Figure size 1000x700 with 4 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"factory = ProblemFactory()\n",
|
|
"maze = factory.create_problem_from_json(json_path='boards/tiny0.json')\n",
|
|
"maze.visualize()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"<div class=\"alert alert-warning\">\n",
|
|
"Now it's your turn to implement 5 different uninformed search algorithms - all spots that need your attention are marked with <code># YOUR CODE HERE</code>!\n",
|
|
"</div>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Implementing BFS"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "716c2661a31500af4a81eb11f7c180ca",
|
|
"grade": false,
|
|
"grade_id": "cell-d2df9b0e3d90cf00",
|
|
"locked": false,
|
|
"schema_version": 3,
|
|
"solution": true,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Queue [Node(id:139993320429904, parent:139994341380400, state:(0, 0), action:None, cost:0, depth:0)]\n",
|
|
"state (4, 4) was reached following the sequence ['R', 'R', 'D', 'D', 'R', 'R', 'D', 'D'] (cost: 20, depth: 8)\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA94AAAIxCAYAAAC7CGDIAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjUsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvWftoOwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAS1xJREFUeJzt3XucVHX9P/D37AK7XHYhkIUFcYEUFVHUzPKS4hdviGRmN7MELfulWKnZV1ML1PqalpcsxK5e0rykYZblV1NRS1G8lUFhKoopCEJcBFdg5/z+oN2vK7DswAyzZ+b5fDzOA+bsmc/5zMzCZ9/7+pzPySRJkgQAAABQEBXF7gAAAACUMoU3AAAAFJDCGwAAAApI4Q0AAAAFpPAGAACAAlJ4AwAAQAEpvAEAAKCAFN4AAABQQApvAAAAKCCFN0REJpNp1zZ9+vSYPn16ZDKZuO222wrer6effjoOPPDA6NmzZ2Qymbjiiitazj99+vSc28vluRMmTIjBgwfnfA6AUtNRx4it6bXXXovJkyfHM888k/e2TzzxxDj88MNb7dvQ+FdMs2fPjsmTJ8dLL71U1H6820svvRSZTCauvfbaYnelw7rqqqs2+P5s6L279tprI5PJbNbn/LOf/SwGDhwYK1eu3PzOUtI6FbsD0BE8+uijrR5feOGF8cADD8T999/fav/w4cPjqaee2mr9OvHEE2PlypVx8803x3ve854YPHhwdOvWLR599NEYPnz4VusHQDnrqGPE1vTaa6/F+eefH4MHD47dd989b+0+/fTTcd1118Vjjz3Wav+Gxr9imj17dpx//vkxatSoovflnerr6+PRRx+N9773vcXuSod11VVXxTbbbBMTJkxotT/f79348ePj4osvjksuuSTOP//8vLRJaVF4Q0R88IMfbPW4b9++UVFRsd7+re1vf/tbnHTSSTFmzJhW+4vdL4By0lHHiFLwne98J/bee+/Ya6+9Wu3f2Pi3udasWROZTCY6dSqtH32rqqp8H26mfL93nTp1iv/3//5fXHjhhXHWWWdFt27d8tY2pcFUc9hMa9asiXPPPTcGDBgQtbW1cfDBB8ecOXPWO+6Pf/xjjB49Ompra6Nbt26x3377xX333ddm281TndauXRtTp05tmcYYsfHp4k888UR8+MMfjt69e0d1dXXsscceceutt7brtVx77bWx4447RlVVVey8885x/fXXt+9NAGCDCjlGNFu6dGl89atfjaFDh0ZVVVXU1dXFEUccEf/4xz9ajlmyZEmccsopMXDgwOjSpUsMHTo0zj333Hj77bdbtfWrX/0qPvCBD0TPnj2jW7duMXTo0DjxxBMjYt248/73vz8iIk444YSWMWny5MkREfHiiy/Gpz71qRgwYEBUVVVFv379YvTo0Zuclv7666/HtGnT4rOf/WzLvrbGv4h1BflRRx0V73nPe6K6ujp23333uO6661q12zxO/uIXv4ivfvWrMXDgwKiqqornn39+o32ZOnVqjBw5Mnr06BE1NTWx0047xTnnnNPSp49//OMREXHQQQe19OmdU5Tb8zlOnjw5MplMPP300/HRj340amtro2fPnvGZz3wmFi1a1OrYwYMHx5FHHhnTpk2L3XbbLaqrq2Po0KFx5ZVXtjpuQ9Olm88za9asOPbYY6Nnz57Rr1+/OPHEE2PZsmWtnr906dL43Oc+F717944ePXrE2LFj48UXX2z1+bZl3rx58ZnPfCbq6upafoa49NJLI5vNrtfH733ve3HZZZfFkCFDokePHrHPPvvEjBkzNnmORYsWxSmnnBLDhw+PHj16RF1dXfzXf/1XPPzww5t87uDBg2PWrFnx4IMPtnxuzTMWcpmm395/p8cdd1wsX748br755k22SflReMNmOuecc+Lll1+On/70p/HjH/84/vnPf8a4ceOiqamp5ZgbbrghDj300KitrY3rrrsubr311ujdu3ccdthhbf5gNXbs2JapjR/72Mfi0UcfXW+q4zs98MADsd9++8XSpUvj6quvjt/85jex++67xyc/+clNDijXXnttnHDCCbHzzjvH7bffHuedd15ceOGF602hBKD9CjlGRESsWLEi9t9///jRj34UJ5xwQvz2t7+Nq6++OoYNGxbz58+PiIjGxsY46KCD4vrrr48zzjgj7rrrrvjMZz4Tl1xySXz0ox9taevRRx+NT37ykzF06NC4+eab46677opvfvObsXbt2oiI2HPPPeOaa66JiIjzzjuvZUz6/Oc/HxERRxxxRDz55JNxySWXxL333htTp06NPfbYI5YuXdrma7jnnntizZo1cdBBB7Xsa2v8mzNnTuy7774xa9asuPLKK+PXv/51DB8+PCZMmBCXXHLJeu1//etfj3nz5sXVV18dv/3tb6Ourm6D/bj55pvjlFNOiQMPPDCmTZsWd9xxR5x++ukt1+qOHTs2/ud//iciIqZMmdLSp7Fjx0ZE7p/j0UcfHdtvv33cdtttMXny5LjjjjvisMMOizVr1rQ67plnnonTTjstTj/99Jg2bVrsu+++8ZWvfCW+973vtfm+NjvmmGNi2LBhcfvtt8fZZ58dv/zlL+P0009v+Xo2m41x48bFL3/5yzjrrLNi2rRp8YEPfGC96+03ZtGiRbHvvvvGPffcExdeeGHceeedcfDBB8eZZ54Zp5566nrHT5kyJe6999644oor4sYbb4yVK1fGEUccsd4vA95tyZIlERExadKkuOuuu+Kaa66JoUOHxqhRoza5Zs20adNi6NChsccee7R8btOmTWvX62uWy+fbv3//2GmnneKuu+7K6RyUiQRYz/jx45Pu3btv8GsPPPBAEhHJEUcc0Wr/rbfemkRE8uijjyZJkiQrV65MevfunYwbN67VcU1NTcnIkSOTvffee5P9iIhk4sSJGzz/Aw880LJvp512SvbYY49kzZo1rY498sgjk/r6+qSpqWmDz21qakoGDBiQ7Lnnnkk2m2153ksvvZR07tw5aWho2GQfAcpNRxgjLrjggiQiknvvvXejx1x99dVJRCS33nprq/0XX3xxEhHJPffckyRJknzve99LIiJZunTpRtuaOXNmEhHJNddc02r/G2+8kUREcsUVV7TZ3w05+eSTk65du7Yaf5ptaPz71Kc+lVRVVSXz5s1rtX/MmDFJt27dWvrf/BkccMAB7erHqaeemvTq1avNY371q1+tN/YmSW6f46RJk5KISE4//fRWx954441JRCQ33HBDy76GhoYkk8kkzzzzTKtjDznkkKS2tjZZuXJlkiRJMnfu3PU+l+bzXHLJJa2ee8oppyTV1dUt7/ddd92VREQyderUVsdddNFFSUQkkyZNavM9Ofvss5OISB577LFW+08++eQkk8kkc+bMadXHXXfdNVm7dm3LcY8//ngSEclNN93U5nnebe3atcmaNWuS0aNHJ0cfffQmj99ll12SAw88cL39G3rvrrnmmiQikrlz5yZJsnn/To877rikX79+Ob0myoPEGzbThz/84VaPd9ttt4iIePnllyMi4pFHHoklS5bE+PHjY+3atS1bNpuNww8/PGbOnJmXlS+ff/75+Mc//hHHHXdcRESrcx1xxBExf/78DU5vjFiXHrz22mvx6U9/utVUvoaGhth33323uG8A5arQY8Qf/vCHGDZsWBx88MEbPeb++++P7t27x8c+9rFW+5sXmWpO65qnkX/iE5+IW2+9NV599dV2v87evXvHe9/73vjud78bl112WTz99NOtphm35bXXXou+ffu2Gn/acv/998fo0aNj0KBBrfZPmDAhVq1atd7MsGOOOaZd7e69996xdOnSOPbYY+M3v/lNvPHGG+16XsTmfY7N43WzT3ziE9GpU6d44IEHWu3fZZddYuTIka32ffrTn47ly5e3axG/DX0PNjY2xsKFCyMi4sEHH2w5/zsde+yxm2w7Yt3nMXz48Nh7771b7Z8wYUIkSbLezLmxY8dGZWVlq/5E/N+/ibZcffXVseeee0Z1dXV06tQpOnfuHPfdd1/8/e9/b1dfN9fmfL51dXWxcOHClhkj0EzhDZupT58+rR5XVVVFRMRbb70VEeuuXYtYN1Wuc+fOrbaLL744kiRpmT61JZrPc+aZZ653nlNOOSUiYqM/RCxevDgi1k2NercN7QOgfQo9RixatCi23XbbNvuwePHi6N+//3qFbV1dXXTq1KllDDjggAPijjvuiLVr18bxxx8f2267bYwYMSJuuummTb7OTCYT9913Xxx22GFxySWXxJ577hl9+/aNL3/5y7FixYo2n/vWW29FdXX1Js/xztdTX1+/3v4BAwa0fP2dNnTshnz2s5+Nn//85/Hyyy/HMcccE3V1dfGBD3wg7r333k0+d3M+x3ePr506dYo+ffqs1/+2xuZ3H7shm/oeXLx4cXTq1Cl69+7d6rh+/fptsu3m5+fyeWyqPxtz2WWXxcknnxwf+MAH4vbbb48ZM2bEzJkz4/DDD9/kc7fU5ny+1dXVkSRJNDY2FrRvpE9pLe0IHcg222wTERE/+MEPNrpqZnsHt/ac5+tf/3qra/beaccdd9zg/uZBcMGCBet9bUP7AMiPLR0j+vbtG//617/aPEefPn3iscceiyRJWhXfzWlccx8iIo466qg46qij4u23344ZM2bERRddFJ/+9Kdj8ODBsc8++7R5noaGhvjZz34WERHPPfdc3HrrrTF58uRYvXp1XH311Rt93jbbbJPT7df69OnTcv36O7322mst7b1Te5P0iHWLxp1wwgmxcuXKeOihh2LSpElx5JFHxnPPPRcNDQ0bfd7mfI4LFiyIgQMHtjxeu3ZtLF68eL3CtK2x+d3Hbo4+ffrE2rVrY8mSJa2K7/aO/7l+HpvrhhtuiFGjRsXUqVNb7d/UL3byYXM+3yVLlkRVVVX06NGj4P0jXSTeUCD77bdf9OrVK2bPnh177bXXBrcuXbps8Xl23HHH2GGHHeIvf/nLRs9TU1Oz0efW19fHTTfdFEmStOx/+eWX45FHHtnivgGwYVs6RowZMyaee+65NhfCHD16dLz55ptxxx13tNrffOeK0aNHr/ecqqqqOPDAA+Piiy+OiHX32W7eH7HpdHLYsGFx3nnnxa677rrJonqnnXaKxYsXb3JxrXe+nvvvv7+lsHvn6+nWrVtebg3VvXv3GDNmTJx77rmxevXqmDVrVkRs/PVvzud44403tnp86623xtq1a2PUqFGt9s+aNSv+8pe/tNr3y1/+MmpqamLPPffc4td64IEHRkTELbfc0mp/e1fkHj16dMyePXu9z/n666+PTCbTatG8LZHJZFre/2Z//etf21x09p2qqqo2OxnfnM/3xRdfjOHDh2/W+ShtEm8okB49esQPfvCDGD9+fCxZsiQ+9rGPRV1dXSxatCj+8pe/xKJFi9b77e3m+tGPfhRjxoyJww47LCZMmBADBw6MJUuWxN///vd46qmn4le/+tUGn1dRUREXXnhhfP7zn4+jjz46TjrppFi6dGlMnjzZVHOAAtrSMeK0006LW265JY466qg4++yzY++994633norHnzwwTjyyCPjoIMOiuOPPz6mTJkS48ePj5deeil23XXX+NOf/hT/8z//E0cccUTL9eHf/OY341//+leMHj06tt1221i6dGl8//vfj86dO7cUZ+9973uja9euceONN8bOO+8cPXr0iAEDBsQbb7wRp556anz84x+PHXbYIbp06RL3339//PWvf42zzz67zfdg1KhRkSRJPPbYY3HooYdu8j2bNGlS/O53v4uDDjoovvnNb0bv3r3jxhtvjLvuuisuueSS6NmzZw6fwP856aSTomvXrrHffvtFfX19LFiwIC666KLo2bNny/XvI0aMiIiIH//4x1FTUxPV1dUxZMiQ6NOnT86f469//evo1KlTHHLIITFr1qz4xje+ESNHjlzvWusBAwbEhz/84Zg8eXLU19fHDTfcEPfee29cfPHFeblH9OGHHx777bdffPWrX43ly5fH+973vnj00UdbfjFTUdF2Pnf66afH9ddfH2PHjo0LLrggGhoa4q677oqrrroqTj755Bg2bNgW9zEi4sgjj4wLL7wwJk2aFAceeGDMmTMnLrjgghgyZEi7rqPedddd4+abb45bbrklhg4dGtXV1bHrrru269y5/jvNZrPx+OOPx+c+97nNfr2UsKIt6wYdWHtWrP3Vr37Vav+GVsdMkiR58MEHk7Fjxya9e/dOOnfunAwcODAZO3bses/fkGjnquZJkiR/+ctfkk984hNJXV1d0rlz56R///7Jf/3XfyVXX331Jp/705/+NNlhhx2SLl26JMOGDUt+/vOfJ+PHj7eqOcAGdJQx4t///nfyla98Jdluu+2Szp07J3V1dcnYsWOTf/zjHy3HLF68OPniF7+Y1NfXJ506dUoaGhqSr3/960ljY2PLMb/73e+SMWPGJAMHDky6dOmS1NXVJUcccUTy8MMPtzrfTTfdlOy0005J586dW1a9fv3115MJEyYkO+20U9K9e/ekR48eyW677ZZcfvnlrVaw3pCmpqZk8ODBySmnnLLe1zY0/iVJkjz77LPJuHHjkp49eyZdunRJRo4cud57urHPYGOuu+665KCDDkr69euXdOnSJRkwYEDyiU98IvnrX//a6rgrrrgiGTJkSFJZWbneZ9mez7F5tfEnn3wyGTduXNKjR4+kpqYmOfbYY5PXX3+91bkaGhqSsWPHJrfddluyyy67JF26dEkGDx6cXHbZZa2Oa2tV80WLFrU69t0rdidJkixZsiQ54YQTkl69eiXdunVLDjnkkGTGjBlJRCTf//73N/nevfzyy8mnP/3ppE+fPknnzp2THXfcMfnud7/bcjeVd/bxu9/97nrPj3asnv72228nZ555ZjJw4MCkuro62XPPPZM77rij3T+nvPTSS8mhhx6a1NTUJBHR8pz2rGrerL3/Tu+7776WzxjeLZMk75hfCgAAW8mll14a3/72t+PVV1+Nrl27Frs7BTV58uQ4//zzY9GiRZu8/nnw4MExYsSI+N3vfreVevd/fvnLX8Zxxx0Xf/7zn93hJEef/exn48UXX4w///nPxe4KHZCp5gAAFMXEiRPjhz/8YUyZMiXOPPPMYnen7Nx0003x6quvxq677hoVFRUxY8aM+O53vxsHHHCAojtH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z7yf480334yzzz477rjjjli8eHEMHjw4vvzlL8fJJ5+ct3NMnz49Lr/88nj88cdj+fLlscMOO8TXvva1OO6441od9+CDD8YZZ5wRs2bNigEDBsR///d/xxe/+MW89QOAjsd43T7GaygfCm/Yyl544YXYeeedY8SIEQU7x+mnnx4PPPBA3HDDDTF48OC455574pRTTokBAwbEUUcdlZdzPPLII7HbbrvFWWedFf369Yu77rorjj/++KitrY1x48ZFRMTcuXPjiCOOiJNOOiluuOGG+POf/xynnHJK9O3bN4455pi89AMACsF4bbyGfDLVHPJs7dq1ceqpp0avXr2iT58+cd5550WSJBGxbmrbpZdeGg899FBkMpkYNWpURERcddVVscMOO0R1dXX069cvPvaxj21RHx599NEYP358jBo1KgYPHhxf+MIXYuTIkfHEE0+0+byf//znscsuu0RVVVXU19fHqaeeutFjzznnnLjwwgtj3333jfe+973x5S9/OQ4//PCYNm1ayzFXX311bLfddnHFFVfEzjvvHJ///OfjxBNPjO9973tb9PoAYEsZr43XsDUpvCHPrrvuuujUqVM89thjceWVV8bll18eP/3pTyMi4te//nWcdNJJsc8++8T8+fPj17/+dTzxxBPx5S9/OS644IKYM2dO3H333XHAAQe0+3wvvfRSZDKZmD59esu+/fffP+6888549dVXI0mSeOCBB+K5556Lww47bKPtTJ06NSZOnBhf+MIX4tlnn40777wztt9++5avT5gwoeUHj41ZtmxZ9O7du+Xxo48+GoceemirYw477LB44okn3H4EgKIyXhuvYWsy1RzybNCgQXH55ZdHJpOJHXfcMZ599tm4/PLL46STTorevXtHt27dokuXLtG/f/+IWHftVffu3ePII4+MmpqaaGhoiD322KPd5+vcuXPsuOOOre6heuWVV8ZJJ50U2267bXTq1CkqKiripz/9aey///4bbedb3/pWfPWrX42vfOUrLfve//73t/y9vr4+stnsRp9/2223xcyZM+NHP/pRy74FCxZEv379Wh3Xr1+/WLt2bbzxxhtRX1/f7tcJAPlkvDZew9ak8IY8++AHP9jq3pb77LNPXHrppdHU1BSVlZXrHX/IIYdEQ0NDDB06NA4//PA4/PDD4+ijj241MLdl4MCB8Y9//KPVviuvvDJmzJgRd955ZzQ0NMRDDz0Up5xyStTX18fBBx+8XhsLFy6M1157LUaPHr3R81x00UUb/dr06dNjwoQJ8ZOf/CR22WWXVl97930+m6fxuf8nAMVkvDZew9ZkqjkUWU1NTTz11FNx0003RX19fXzzm9+MkSNH5nzbkmZvvfVWnHPOOXHZZZfFuHHjYrfddotTTz01PvnJT270Wq2uXbtudv8ffPDBGDduXFx22WVx/PHHt/pa//79Y8GCBa32LVy4MDp16hR9+vTZ7HMCwNZmvAa2hMIb8mzGjBnrPd5hhx02+NvzZp06dYqDDz44LrnkkvjrX/8aL730Utx///2bdf41a9bEmjVroqKi9T/vysrKjU49q6mpicGDB8d9992X07mmT58eY8eOje985zvxhS98Yb2v77PPPnHvvfe22nfPPffEXnvtFZ07d87pXACQT8br/2O8hsJTeEOevfLKK3HGGWfEnDlz4qabboof/OAHra7Derff/e53ceWVV8YzzzwTL7/8clx//fWRzWZjxx13bNf5Xn311dhpp53i8ccfj4iI2traOPDAA+NrX/taTJ8+PebOnRvXXnttXH/99XH00UdvtJ3JkyfHpZdeGldeeWX885//jKeeeip+8IMftHz961//eqvfkDcP4l/+8pfjmGOOiQULFsSCBQtiyZIlLcd88YtfjJdffjnOOOOM+Pvf/x4///nP42c/+1mceeaZ7XptAFAoxmvjNWxNrvGGPDv++OPjrbfeir333jsqKyvjS1/60gZ/u9ysV69e8etf/zomT54cjY2NscMOO8RNN9203rVXG7NmzZqYM2dOrFq1qmXfzTffHF//+tfjuOOOiyVLlkRDQ0N8+9vfji9+8YsbbWf8+PHR2NgYl19+eZx55pmxzTbbtLpNyvz582PevHktj6+99tpYtWpVXHTRRa2uJzvwwANbVmwdMmRI/P73v4/TTz89pkyZEgMGDIgrr7zSPUEBKDrjtfEatqZM0rxyAnQQjY2NMXfu3BgyZEhUV1cXuztsZT5/gPTwf3b58tlDbkw1BwAAgAJSeAMAAEABKbwBAACggBTeAAAAUEAKbwAAtoi1esuPzxxyo/AGAGCzdO7cOSKi1S2yKA/Nn3nz9wDQNvfxBgBgs1RWVkavXr1i4cKFERHRrVu3yGQyRe4VhZQkSaxatSoWLlwYvXr1isrKymJ3CVJB4Q0AwGbr379/RERL8U156NWrV8tnD2yawhsAgM2WyWSivr4+6urqYs2aNcXuDltB586dJd2QI4U3AABbrLKyUjEGsBEWV4OtZMKECfGRj3wkb+2NGjUqTjvttLy1BwAAFIbEm5LWlE3i8blLYuGKxqirqY69h/SOyop0L/qyZs0aK4gCAECKSLwpWXf/bX7sf/H9cexPZsRXbn4mjv3JjNj/4vvj7r/NL+h5b7vttth1112ja9eu0adPnzj44IPja1/7Wlx33XXxm9/8JjKZTGQymZg+fXpERJx11lkxbNiw6NatWwwdOjS+8Y1vtLpGbvLkybH77rvHz3/+8xg6dGhUVVXF+PHj48EHH4zvf//7Le299NJLBX1dAADA5pF4U5Lu/tv8OPmGpyJ51/4Fyxrj5Bueiqmf2TMOH1Gf9/POnz8/jj322Ljkkkvi6KOPjhUrVsTDDz8cxx9/fMybNy+WL18e11xzTURE9O7dOyIiampq4tprr40BAwbEs88+GyeddFLU1NTEf//3f7e0+/zzz8ett94at99+e1RWVkZDQ0P885//jBEjRsQFF1wQERF9+/bN++sBAAC2nMKbktOUTeL8385er+iOiEgiIhMR5/92dhwyvH/ep53Pnz8/1q5dGx/96EejoaEhIiJ23XXXiIjo2rVrvP322+vdeuO8885r+fvgwYPjq1/9atxyyy2tCu/Vq1fHL37xi1bFdZcuXaJbt25u5QEAAB2cqeaUnMfnLon5yxo3+vUkIuYva4zH5y7J+7lHjhwZo0ePjl133TU+/vGPx09+8pP497//3eZzbrvttth///2jf//+0aNHj/jGN74R8+bNa3VMQ0ODRBsAAFJK4U3JWbhi40X35hyXi8rKyrj33nvjD3/4QwwfPjx+8IMfxI477hhz587d4PEzZsyIT33qUzFmzJj43e9+F08//XSce+65sXr16lbHde/ePe99BQAAtg5TzSk5dTXVeT0uV5lMJvbbb7/Yb7/94pvf/GY0NDTEtGnTokuXLtHU1NTq2D//+c/R0NAQ5557bsu+l19+uV3n2VB7AABAx6PwpuTsPaR31PesjgXLGjd4nXcmIvr3XHdrsXx77LHH4r777otDDz006urq4rHHHotFixbFzjvvHI2NjfG///u/MWfOnOjTp0/07Nkztt9++5g3b17cfPPN8f73vz/uuuuumDZtWrvONXjw4HjsscfipZdeih49ekTv3r2josIkFgAA6Gj8lE7JqazIxKRxwyNiXZH9Ts2PJ40bXpD7edfW1sZDDz0URxxxRAwbNizOO++8uPTSS2PMmDFx0kknxY477hh77bVX9O3bN/785z/HUUcdFaeffnqceuqpsfvuu8cjjzwS3/jGN9p1rjPPPDMqKytj+PDh0bdv3/WuCwcAADqGTJIkGwoFoWgaGxtj7ty5MWTIkKiu3vzp4Hf/bX6c/9vZrRZaq+9ZHZPGDS/IrcTIj3x9/gAA0FGYak7JOnxEfRwyvH88PndJLFzRGHU166aXFyLpBgAA2BiFNyWtsiIT+7y3T7G7AQAAlDHXeAMAAEABKbwBAACggBTeAAAAUEAKbwAAACgghTcAAAAUkMIbAAAACkjhDQAAAAWk8IYUmDx5cuy+++7F7gYAALAZFN4AAABQQJ2K3QEoqGxTxMuPRLz5ekSPfhEN+0ZUVBa7VwAAQBmReFO6Zt8ZccWIiOuOjLj9c+v+vGLEuv0FlCRJXHLJJTF06NDo2rVrjBw5Mm677baIiJg+fXpkMpm47777Yq+99opu3brFvvvuG3PmzGnVxne+853o169f1NTUxOc+97lobGwsaJ8BAIDCUXhTmmbfGXHr8RHLX2u9f/n8dfsLWHyfd955cc0118TUqVNj1qxZcfrpp8dnPvOZePDBB1uOOffcc+PSSy+NJ554Ijp16hQnnnhiy9duvfXWmDRpUnz729+OJ554Iurr6+Oqq64qWH8BAIDCyiRJkhS7E/BOjY2NMXfu3BgyZEhUV1fn3kC2aV2y/e6iu0UmonZAxGnP5n3a+cqVK2ObbbaJ+++/P/bZZ5+W/Z///Odj1apV8YUvfCEOOuig+OMf/xijR4+OiIjf//73MXbs2Hjrrbeiuro69t133xg5cmRMnTq15fkf/OAHo7GxMZ555pm89rcj2uLPHwAAOhiJN6Xn5UfaKLojIpKI5a+uOy7PZs+eHY2NjXHIIYdEjx49Wrbrr78+XnjhhZbjdtttt5a/19fXR0TEwoULIyLi73//e6uiPSLWewwAAKSHxdUoPW++nt/jcpDNZiMi4q677oqBAwe2+lpVVVVL8d25c+eW/ZlMptVzAQCA0iLxpvT06Jff43IwfPjwqKqqinnz5sX222/fahs0aFC72th5551jxowZrfa9+zEAAJAeEm9KT8O+667hXj4/Ija0hMF/rvFu2Dfvp66pqYkzzzwzTj/99Mhms7H//vvH8uXL45FHHokePXpEQ0PDJtv4yle+EuPHj4+99tor9t9//7jxxhtj1qxZMXTo0Lz3FwAAKDyFN6WnojLi8IvXrV4emWhdfK+b1h2Hf6dg9/O+8MILo66uLi666KJ48cUXo1evXrHnnnvGOeec067p5J/85CfjhRdeiLPOOisaGxvjmGOOiZNPPjn+93//tyD9BQAACsuq5nQ4eVvVevadEXef1XqhtdqB64ru4R/e8o5SEFY1BwCg1Ei8KV3DPxyx09h1q5e/+fq6a7ob9i1Y0g0AALAhCm9KW0VlxJAPFbsXAABAGbOqOQAAABSQwhsAAAAKSOFNh2Xdv/LkcwcAoNQovOlwOnfuHBERq1atKnJPKIbmz735+wAAANLO4mp0OJWVldGrV69YuHBhRER069YtMplMkXtFoSVJEqtWrYqFCxdGr169orLS6vMAAJQG9/GmQ0qSJBYsWBBLly4tdlfYynr16hX9+/f3yxYAAEqGwpsOrampKdasWVPsbrCVdO7cWdINAEDJUXgDAABAAVlcDQAAAApI4Q0AAAAFpPAGAACAAlJ4AwAAQAEpvAEAAKCAFN4AAABQQApvAAAAKKD/D/FaV02vzoShAAAAAElFTkSuQmCC",
|
|
"text/plain": [
|
|
"<Figure size 1000x700 with 4 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"class BFS(object):\n",
|
|
"\n",
|
|
" def __init__(self) -> None:\n",
|
|
" # YOUR CODE HERE: initialize self.visited and self.fringe here or in the solve function with the correct datatypes\n",
|
|
" self.visited = set()\n",
|
|
" self.fringe = Queue()\n",
|
|
"\n",
|
|
" def solve(self, problem: Problem):\n",
|
|
" self.fringe.put(problem.get_start_node())\n",
|
|
" print(self.fringe)\n",
|
|
"\n",
|
|
" while self.fringe.has_elements():\n",
|
|
" current = self.fringe.get()\n",
|
|
"\n",
|
|
" if problem.is_end(current):\n",
|
|
" return current\n",
|
|
" if current in self.visited:\n",
|
|
" continue\n",
|
|
" else:\n",
|
|
" self.visited.add(current)\n",
|
|
"\n",
|
|
" for successor in problem.successors(current):\n",
|
|
" self.fringe.put(successor)\n",
|
|
" \n",
|
|
"bfs_search = BFS()\n",
|
|
"maze.reset() # resets maze for hidden tests\n",
|
|
"bfs_solution = bfs_search.solve(maze)\n",
|
|
"\n",
|
|
"if bfs_solution is not None:\n",
|
|
" bfs_solution.pretty_print()\n",
|
|
" maze.visualize(sequences=[('bfs', bfs_solution.get_action_sequence())])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Basic Checks"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "bf5d1779e9b62e8a9be1d3cd10c6a820",
|
|
"grade": true,
|
|
"grade_id": "cell-ca9a92a1cfa1444d",
|
|
"locked": true,
|
|
"points": 0.2,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"assert(bfs_solution is not None), \"your algorithm did not return a solution\"\n",
|
|
"assert(bfs_solution.state == (4, 4)), \"your algorithm did not return the expected solution\"\n",
|
|
"\n",
|
|
"assert(bfs_solution.cost == 20), \"the solution found by your algorithm did not return the expected cost\"\n",
|
|
"assert(bfs_solution.depth == 8), \"the solution found by your algorithm does not have the expected length\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Check visited set"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "170ce4b6b16402c27f4505b590329d0c",
|
|
"grade": true,
|
|
"grade_id": "cell-ced878c4bd3f8b22",
|
|
"locked": true,
|
|
"points": 0.5,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"assert(bfs_search.visited is not None), \"it seems you did not correctly initialize the visited set\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Check fringe"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "432e7c6ad5496a0cf9d4adb22873838d",
|
|
"grade": true,
|
|
"grade_id": "cell-97963b0eac5a8e46",
|
|
"locked": true,
|
|
"points": 0.6,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"assert(bfs_search.fringe is not None), \"it seems you did not correctly initialize the fringe\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Check expaned nodes"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "9416b34fff06cfd2dd7611e489a7d53b",
|
|
"grade": true,
|
|
"grade_id": "cell-25fc2adbfe6e02be",
|
|
"locked": true,
|
|
"points": 0.2,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"bfs_expanded_nodes = maze.get_number_of_expanded_nodes()\n",
|
|
"assert(bfs_expanded_nodes > 0), \"it seems your algorithm did not expand any nodes\"\n",
|
|
"assert(bfs_expanded_nodes == 18), \"it seems your algorithm did not expand the correct number of nodes\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Check different mazes"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Queue [Node(id:139993320819296, parent:139994341380400, state:(0, 0), action:None, cost:0, depth:0)]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"bfs_search = BFS()\n",
|
|
"tiny0 = factory.create_problem_from_json(json_path='boards/tiny0.json')\n",
|
|
"bfs_solution = bfs_search.solve(tiny0)\n",
|
|
"assert(bfs_solution.state == (4, 4)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(bfs_solution.get_action_sequence_hash() == 'c283a9803562a0053fc1ea0c30d421e0b4a7a9f599c699d74477cbeeffec23bc'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Queue [Node(id:139993320819744, parent:139994341380400, state:(0, 0), action:None, cost:0, depth:0)]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"bfs_search = BFS()\n",
|
|
"tiny1 = factory.create_problem_from_json(json_path='boards/tiny1.json')\n",
|
|
"bfs_solution = bfs_search.solve(tiny1)\n",
|
|
"assert(bfs_solution.state == (2, 4)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(bfs_solution.get_action_sequence_hash() == '66ec8af4739b256cec553c3d2c2cbacbc1fd4c853859c633e44996eed1f6021c'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 10,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Queue [Node(id:139993250214784, parent:139994341380400, state:(0, 0), action:None, cost:0, depth:0)]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"bfs_search = BFS()\n",
|
|
"tiny2 = factory.create_problem_from_json(json_path='boards/tiny2.json')\n",
|
|
"bfs_solution = bfs_search.solve(tiny2)\n",
|
|
"assert(bfs_solution.state == (2, 2)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(bfs_solution.get_action_sequence_hash() == '5bda40f5b72290920507aa1d23329fb5a3445346372a30bd35cc85f743c439ac'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 11,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Queue [Node(id:139993250213328, parent:139994341380400, state:(0, 0), action:None, cost:0, depth:0)]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"bfs_search = BFS()\n",
|
|
"tiny3 = factory.create_problem_from_json(json_path='boards/tiny3.json')\n",
|
|
"bfs_solution = bfs_search.solve(tiny3)\n",
|
|
"assert(bfs_solution.state == (2, 2)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(bfs_solution.get_action_sequence_hash() == 'e1c95ac72da74163d0c237b69f99dc766c1bbe5e4270fd2934b721d5eab9de31'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Queue [Node(id:139993250216016, parent:139994341380400, state:(0, 0), action:None, cost:0, depth:0)]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"bfs_search = BFS()\n",
|
|
"tiny4 = factory.create_problem_from_json(json_path='boards/tiny4.json')\n",
|
|
"bfs_solution = bfs_search.solve(tiny4)\n",
|
|
"assert(bfs_solution.state == (4, 4)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(bfs_solution.get_action_sequence_hash() == '0123d362bf2df8f84e7c41197827be005159724c07774ef32d9f15373a440091'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 13,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Queue [Node(id:139993250212880, parent:139994341380400, state:(0, 0), action:None, cost:0, depth:0)]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"bfs_search = BFS()\n",
|
|
"cyclic_map = factory.create_problem_from_json(json_path='boards/cyclic_map.json')\n",
|
|
"bfs_solution = bfs_search.solve(cyclic_map)\n",
|
|
"assert(bfs_solution.state == (2, 2)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(bfs_solution.get_action_sequence_hash() == 'e1c95ac72da74163d0c237b69f99dc766c1bbe5e4270fd2934b721d5eab9de31'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 14,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Queue [Node(id:139993250217808, parent:139994341380400, state:(0, 0), action:None, cost:0, depth:0)]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"bfs_search = BFS()\n",
|
|
"narrow_path = factory.create_problem_from_json(json_path='boards/narrow_path.json')\n",
|
|
"bfs_solution = bfs_search.solve(narrow_path)\n",
|
|
"assert(bfs_solution.state == (2, 4)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(bfs_solution.get_action_sequence_hash() == '2ee4599132a71cf20e4feae6aff58b9ff77ea9486fb0e12225ddd8896ccb9843'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 15,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Queue [Node(id:139993250215792, parent:139994341380400, state:(0, 0), action:None, cost:0, depth:0)]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"bfs_search = BFS()\n",
|
|
"no_possible_path = factory.create_problem_from_json(json_path='boards/no_possible_path.json')\n",
|
|
"bfs_solution = bfs_search.solve(no_possible_path)\n",
|
|
"assert(bfs_solution is None), \"your algorithm magically found a solution in an impossible maze\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 16,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Queue [Node(id:139993250215792, parent:139994341380400, state:(0, 0), action:None, cost:0, depth:0)]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"bfs_search = BFS()\n",
|
|
"start_is_goal = factory.create_problem_from_json(json_path='boards/start_is_goal.json')\n",
|
|
"bfs_solution = bfs_search.solve(start_is_goal)\n",
|
|
"assert(bfs_solution.state == (0, 0)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(bfs_solution.get_action_sequence_hash() == 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 17,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Queue [Node(id:139993250214336, parent:139994341380400, state:(0, 0), action:None, cost:0, depth:0)]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# this test is supposed to test whether the visited set is used somewhat correctly (otherwise it will timeout)\n",
|
|
"\n",
|
|
"bfs_search = BFS()\n",
|
|
"large = factory.create_problem_from_json(json_path='boards/large.json')\n",
|
|
"bfs_solution = bfs_search.solve(large)\n",
|
|
"assert(bfs_solution)\n",
|
|
"assert(bfs_solution.state == (48, 48)), \"your algorithm did not return the expected solution\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Implementing UCS\n",
|
|
"\n",
|
|
"- implement Uniform Cost Search (UCS), a variant of Dijkstra's Graph Search"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 35,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "57efee82377a65469cc75a8c797111ab",
|
|
"grade": false,
|
|
"grade_id": "cell-0bc80e814a5b5029",
|
|
"locked": false,
|
|
"schema_version": 3,
|
|
"solution": true,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"state (4, 4) was reached following the sequence ['D', 'D', 'D', 'D', 'R', 'R', 'R', 'R'] (cost: 12, depth: 8)\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA94AAAIxCAYAAAC7CGDIAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjUsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvWftoOwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAS6xJREFUeJzt3Xl8VNX9//H3ZCdkwSCBsBgWZYnsohawLKIIRFyqdVfA5dsqfltRf1WrFZS2KLV+7bdGsH4tuCOKuFFRqoJWFpFFkShWCYsSBKEQCAaSmfP7I2Z0TBhmwr3cufe+no/HfcDc3Dn3zEzg5JP3uecGjDFGAAAAAADAFklOdwAAAAAAAC+j8AYAAAAAwEYU3gAAAAAA2IjCGwAAAAAAG1F4AwAAAABgIwpvAAAAAABsROENAAAAAICNKLwBAAAAALARhTcAAAAAADai8AYkBQKBmLaFCxdq4cKFCgQCev75523v16pVqzR48GDl5uYqEAjogQceCJ9/4cKFcbcXz3PHjh2r9u3bx30OAPCaRB0jjqQtW7Zo0qRJWr16teVtX3nllRoxYkTEvobGPyeVlpZq0qRJ2rBhg6P9+LENGzYoEAho5syZTnclYT300EMNvj8NvXczZ85UIBBo1Of86KOPqk2bNqqsrGx8Z+FpKU53AEgES5YsiXg8efJkvf3223rrrbci9hcVFWnlypVHrF9XXnmlKisrNWvWLB111FFq3769MjMztWTJEhUVFR2xfgCAnyXqGHEkbdmyRXfddZfat2+v3r17W9buqlWr9Nhjj2nZsmUR+xsa/5xUWlqqu+66S0OGDHG8Lz9UUFCgJUuWqFOnTk53JWE99NBDOvroozV27NiI/Va/d2PGjNG9996rqVOn6q677rKkTXgLhTcg6Sc/+UnE4xYtWigpKane/iPt448/1jXXXKORI0dG7He6XwDgJ4k6RnjBPffco5NOOkn9+vWL2H+w8a+xqqurFQgElJLirR9909PT+T5sJKvfu5SUFP3iF7/Q5MmTdcsttygzM9OytuENTDUHGqm6ulq33367WrdurZycHJ122mlat25dveP++c9/atiwYcrJyVFmZqYGDhyoN998M2rbdVOdampqNG3atPA0Rung08U/+OADnXXWWcrLy1NGRob69Omj2bNnx/RaZs6cqS5duig9PV3dunXT448/HtubAABokJ1jRJ1du3bppptuUseOHZWenq78/HyNGjVKn376afiYnTt36rrrrlObNm2Ulpamjh076vbbb9f+/fsj2nruued08sknKzc3V5mZmerYsaOuvPJKSbXjzoknnihJGjduXHhMmjRpkiRp/fr1uuiii9S6dWulp6erZcuWGjZs2CGnpX/99deaO3euLr/88vC+aOOfVFuQn3322TrqqKOUkZGh3r1767HHHotot26cfOKJJ3TTTTepTZs2Sk9P1+eff37QvkybNk29evVSVlaWsrOz1bVrV/32t78N9+nnP/+5JGno0KHhPv1winIsn+OkSZMUCAS0atUq/exnP1NOTo5yc3N12WWXafv27RHHtm/fXmeeeabmzp2rnj17KiMjQx07dtT//u//RhzX0HTpuvOsXbtWF198sXJzc9WyZUtdeeWV2r17d8Tzd+3apauuukp5eXnKyspScXGx1q9fH/H5RrNp0yZddtllys/PD/8M8ec//1mhUKheH++77z7df//96tChg7KystS/f38tXbr0kOfYvn27rrvuOhUVFSkrK0v5+fk69dRT9e677x7yue3bt9fatWu1aNGi8OdWN2Mhnmn6sf47vfTSS1VRUaFZs2Ydsk34D4U30Ei//e1vtXHjRv3f//2f/va3v+nf//63Ro8erWAwGD7mySef1PDhw5WTk6PHHntMs2fPVl5ens4444yoP1gVFxeHpzaef/75WrJkSb2pjj/09ttva+DAgdq1a5emT5+ul156Sb1799aFF154yAFl5syZGjdunLp166Y5c+bojjvu0OTJk+tNoQQAxM7OMUKS9uzZo1NOOUUPP/ywxo0bp1deeUXTp09X586dVV5eLkmqqqrS0KFD9fjjj+vGG2/UvHnzdNlll2nq1Kn62c9+Fm5ryZIluvDCC9WxY0fNmjVL8+bN05133qmamhpJUt++fTVjxgxJ0h133BEek66++mpJ0qhRo7RixQpNnTpVCxYs0LRp09SnTx/t2rUr6mt44403VF1draFDh4b3RRv/1q1bpwEDBmjt2rX63//9X73wwgsqKirS2LFjNXXq1Hrt33bbbdq0aZOmT5+uV155Rfn5+Q32Y9asWbruuus0ePBgzZ07Vy+++KImTJgQvla3uLhYf/zjHyVJJSUl4T4VFxdLiv9zPPfcc3Xsscfq+eef16RJk/Tiiy/qjDPOUHV1dcRxq1ev1g033KAJEyZo7ty5GjBggH7961/rvvvui/q+1jnvvPPUuXNnzZkzR7feequefvppTZgwIfz1UCik0aNH6+mnn9Ytt9yiuXPn6uSTT653vf3BbN++XQMGDNAbb7yhyZMn6+WXX9Zpp52mm2++Wddff32940tKSrRgwQI98MADeuqpp1RZWalRo0bV+2XAj+3cuVOSNHHiRM2bN08zZsxQx44dNWTIkEOuWTN37lx17NhRffr0CX9uc+fOjen11Ynn823VqpW6du2qefPmxXUO+IQBUM+YMWNM06ZNG/za22+/bSSZUaNGReyfPXu2kWSWLFlijDGmsrLS5OXlmdGjR0ccFwwGTa9evcxJJ510yH5IMuPHj2/w/G+//XZ4X9euXU2fPn1MdXV1xLFnnnmmKSgoMMFgsMHnBoNB07p1a9O3b18TCoXCz9uwYYNJTU01hYWFh+wjAPhNIowRd999t5FkFixYcNBjpk+fbiSZ2bNnR+y/9957jSTzxhtvGGOMue+++4wks2vXroO2tXz5ciPJzJgxI2L/N998YySZBx54IGp/G3LttdeaJk2aRIw/dRoa/y666CKTnp5uNm3aFLF/5MiRJjMzM9z/us9g0KBBMfXj+uuvN82aNYt6zHPPPVdv7DUmvs9x4sSJRpKZMGFCxLFPPfWUkWSefPLJ8L7CwkITCATM6tWrI449/fTTTU5OjqmsrDTGGFNWVlbvc6k7z9SpUyOee91115mMjIzw+z1v3jwjyUybNi3iuClTphhJZuLEiVHfk1tvvdVIMsuWLYvYf+2115pAIGDWrVsX0ccePXqYmpqa8HHvv/++kWSeeeaZqOf5sZqaGlNdXW2GDRtmzj333EMef/zxx5vBgwfX29/QezdjxgwjyZSVlRljGvfv9NJLLzUtW7aM6zXBH0i8gUY666yzIh737NlTkrRx40ZJ0uLFi7Vz506NGTNGNTU14S0UCmnEiBFavny5JStffv755/r000916aWXSlLEuUaNGqXy8vIGpzdKtenBli1bdMkll0RM5SssLNSAAQMOu28A4Fd2jxGvvfaaOnfurNNOO+2gx7z11ltq2rSpzj///Ij9dYtM1aV1ddPIL7jgAs2ePVtfffVVzK8zLy9PnTp10p/+9Cfdf//9WrVqVcQ042i2bNmiFi1aRIw/0bz11lsaNmyY2rVrF7F/7Nix2rdvX72ZYeedd15M7Z500knatWuXLr74Yr300kv65ptvYnqe1LjPsW68rnPBBRcoJSVFb7/9dsT+448/Xr169YrYd8kll6iioiKmRfwa+h6sqqrStm3bJEmLFi0Kn/+HLr744kO2LdV+HkVFRTrppJMi9o8dO1bGmHoz54qLi5WcnBzRH+n7fxPRTJ8+XX379lVGRoZSUlKUmpqqN998U5988klMfW2sxny++fn52rZtW3jGCFCHwhtopObNm0c8Tk9PlyR9++23kmqvXZNqp8qlpqZGbPfee6+MMeHpU4ej7jw333xzvfNcd911knTQHyJ27NghqXZq1I81tA8AEBu7x4jt27erbdu2UfuwY8cOtWrVql5hm5+fr5SUlPAYMGjQIL344ouqqanRFVdcobZt26p79+565plnDvk6A4GA3nzzTZ1xxhmaOnWq+vbtqxYtWuhXv/qV9uzZE/W53377rTIyMg55jh++noKCgnr7W7duHf76DzV0bEMuv/xy/f3vf9fGjRt13nnnKT8/XyeffLIWLFhwyOc25nP88fiakpKi5s2b1+t/tLH5x8c25FDfgzt27FBKSory8vIijmvZsuUh2657fjyfx6H6czD333+/rr32Wp188smaM2eOli5dquXLl2vEiBGHfO7hasznm5GRIWOMqqqqbO0b3MdbSzsCCeToo4+WJP31r3896KqZsQ5usZzntttui7hm74e6dOnS4P66QXDr1q31vtbQPgCANQ53jGjRooW+/PLLqOdo3ry5li1bJmNMRPFdl8bV9UGSzj77bJ199tnav3+/li5dqilTpuiSSy5R+/bt1b9//6jnKSws1KOPPipJ+uyzzzR79mxNmjRJBw4c0PTp0w/6vKOPPjqu2681b948fP36D23ZsiXc3g/FmqRLtYvGjRs3TpWVlXrnnXc0ceJEnXnmmfrss89UWFh40Oc15nPcunWr2rRpE35cU1OjHTt21CtMo43NPz62MZo3b66amhrt3LkzoviOdfyP9/NorCeffFJDhgzRtGnTIvYf6hc7VmjM57tz506lp6crKyvL9v7BXUi8AZsMHDhQzZo1U2lpqfr169fglpaWdtjn6dKli4477jh9+OGHBz1Pdnb2QZ9bUFCgZ555RsaY8P6NGzdq8eLFh903AEDDDneMGDlypD777LOoC2EOGzZMe/fu1Ysvvhixv+7OFcOGDav3nPT0dA0ePFj33nuvpNr7bNftlw6dTnbu3Fl33HGHevTocciiumvXrtqxY8chF9f64et56623woXdD19PZmamJbeGatq0qUaOHKnbb79dBw4c0Nq1ayUd/PU35nN86qmnIh7Pnj1bNTU1GjJkSMT+tWvX6sMPP4zY9/TTTys7O1t9+/Y97Nc6ePBgSdKzzz4bsT/WFbmHDRum0tLSep/z448/rkAgELFo3uEIBALh97/ORx99FHXR2R9KT09vdDLemM93/fr1KioqatT54G0k3oBNsrKy9Ne//lVjxozRzp07df755ys/P1/bt2/Xhx9+qO3bt9f77W1jPfzwwxo5cqTOOOMMjR07Vm3atNHOnTv1ySefaOXKlXruuecafF5SUpImT56sq6++Wueee66uueYa7dq1S5MmTWKqOQDY6HDHiBtuuEHPPvuszj77bN1666066aST9O2332rRokU688wzNXToUF1xxRUqKSnRmDFjtGHDBvXo0UP/+te/9Mc//lGjRo0KXx9+55136ssvv9SwYcPUtm1b7dq1S3/5y1+UmpoaLs46deqkJk2a6KmnnlK3bt2UlZWl1q1b65tvvtH111+vn//85zruuOOUlpamt956Sx999JFuvfXWqO/BkCFDZIzRsmXLNHz48EO+ZxMnTtSrr76qoUOH6s4771ReXp6eeuopzZs3T1OnTlVubm4cn8D3rrnmGjVp0kQDBw5UQUGBtm7dqilTpig3Nzd8/Xv37t0lSX/729+UnZ2tjIwMdejQQc2bN4/7c3zhhReUkpKi008/XWvXrtXvfvc79erVq9611q1bt9ZZZ52lSZMmqaCgQE8++aQWLFige++915J7RI8YMUIDBw7UTTfdpIqKCp1wwglasmRJ+BczSUnR87kJEybo8ccfV3Fxse6++24VFhZq3rx5euihh3Tttdeqc+fOh91HSTrzzDM1efJkTZw4UYMHD9a6det09913q0OHDjFdR92jRw/NmjVLzz77rDp27KiMjAz16NEjpnPH++80FArp/fff11VXXdXo1wsPc2xZNyCBxbJi7XPPPRexv6HVMY0xZtGiRaa4uNjk5eWZ1NRU06ZNG1NcXFzv+Q1RjKuaG2PMhx9+aC644AKTn59vUlNTTatWrcypp55qpk+ffsjn/t///Z857rjjTFpamuncubP5+9//bsaMGcOq5gDQgEQZI/7zn/+YX//61+aYY44xqampJj8/3xQXF5tPP/00fMyOHTvML3/5S1NQUGBSUlJMYWGhue2220xVVVX4mFdffdWMHDnStGnTxqSlpZn8/HwzatQo8+6770ac75lnnjFdu3Y1qamp4VWvv/76azN27FjTtWtX07RpU5OVlWV69uxp/ud//idiBeuGBINB0759e3PdddfV+1pD458xxqxZs8aMHj3a5ObmmrS0NNOrV6967+nBPoODeeyxx8zQoUNNy5YtTVpammndurW54IILzEcffRRx3AMPPGA6dOhgkpOT632WsXyOdauNr1ixwowePdpkZWWZ7Oxsc/HFF5uvv/464lyFhYWmuLjYPP/88+b44483aWlppn379ub++++POC7aqubbt2+POPbHK3YbY8zOnTvNuHHjTLNmzUxmZqY5/fTTzdKlS40k85e//OWQ793GjRvNJZdcYpo3b25SU1NNly5dzJ/+9Kfw3VR+2Mc//elP9Z6vGFZP379/v7n55ptNmzZtTEZGhunbt6958cUXY/45ZcOGDWb48OEmOzvbSAo/J5ZVzevE+u/0zTffDH/GwI8FjPnB/FIAAADgCPnzn/+sP/zhD/rqq6/UpEkTp7tjq0mTJumuu+7S9u3bD3n9c/v27dW9e3e9+uqrR6h333v66ad16aWX6r333uMOJ3G6/PLLtX79er333ntOdwUJiKnmAAAAcMT48eP14IMPqqSkRDfffLPT3fGdZ555Rl999ZV69OihpKQkLV26VH/60580aNAgiu44ffHFF3r22WejrrsAf6PwBgAAgCMyMjL0xBNPhBdxw5GVnZ2tWbNm6fe//70qKytVUFCgsWPH6ve//73TXXOdTZs26cEHH9Qpp5zidFeQoJhqDgAAAACAjbidGAAADnjnnXc0evRotW7dWoFAoN4tnwAAQOKZMmWKAoGAbrjhhrieR+ENAIADKisr1atXLz344INOdwUAAMRg+fLl+tvf/qaePXvG/Vyu8QYAwAEjR47UyJEjne4GAACIwd69e3XppZfqkUceadQ6CHEX3qFQSFu2bFF2drYCgUDcJwQAwEnGmPDtfJKSrJ34ZYypNzamp6crPT3d0vPEgvEaAOB2do3ZjRmvx48fr+LiYp122mn2Ft4lJSUq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",
|
|
"text/plain": [
|
|
"<Figure size 1000x700 with 4 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"class UCS(object):\n",
|
|
"\n",
|
|
" def __init__(self) -> None:\n",
|
|
" # YOUR CODE HERE: initialize self.visited and self.fringe here or in the solve function with the correct datatypes\n",
|
|
" self.visited = set()\n",
|
|
" self.fringe = PriorityQueue()\n",
|
|
"\n",
|
|
" def solve(self, problem: Problem):\n",
|
|
" # YOUR CODE HERE\n",
|
|
"\n",
|
|
" root = problem.get_start_node()\n",
|
|
" self.fringe.put(root.cost, root)\n",
|
|
" while self.fringe.has_elements():\n",
|
|
" current = self.fringe.get()\n",
|
|
"\n",
|
|
" if problem.is_end(current):\n",
|
|
" return current\n",
|
|
"\n",
|
|
" if current in self.visited:\n",
|
|
" continue\n",
|
|
"\n",
|
|
" self.visited.add(current)\n",
|
|
" for successor in problem.successors(current):\n",
|
|
" self.fringe.put(successor.cost, successor)\n",
|
|
" \n",
|
|
" \n",
|
|
" return None\n",
|
|
"\n",
|
|
"ucs_search = UCS()\n",
|
|
"maze.reset() # resets maze for hidden tests\n",
|
|
"ucs_solution = ucs_search.solve(maze)\n",
|
|
"\n",
|
|
"if ucs_solution is not None:\n",
|
|
" ucs_solution.pretty_print()\n",
|
|
" maze.visualize(sequences=[('ucs', ucs_solution.get_action_sequence())])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Basic checks"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 36,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "e5f06248b3e49c5e4347509304ce684c",
|
|
"grade": true,
|
|
"grade_id": "cell-aac452910d38e14e",
|
|
"locked": true,
|
|
"points": 0.2,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"assert(ucs_solution is not None), \"your algorithm did not return a solution\"\n",
|
|
"assert(ucs_solution.state == (4, 4)), \"your algorithm did not return the expected solution\"\n",
|
|
"\n",
|
|
"assert(ucs_solution.depth == 8), \"the solution found by your algorithm does not have the expected length\"\n",
|
|
"\n",
|
|
"ucs_expanded_nodes = maze.get_number_of_expanded_nodes()\n",
|
|
"assert(ucs_expanded_nodes == 12), \"it seems your algorithm did not expand the correct number of nodes\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Check visited set"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 37,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "1eb3167d55f3292f93f4985fcfc514f2",
|
|
"grade": true,
|
|
"grade_id": "cell-f7d28a2a7702c9bd",
|
|
"locked": true,
|
|
"points": 0.5,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"assert(ucs_search.visited is not None), \"it seems you did not correctly initialize the visited set\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Check fringe"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 38,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "8122ec4f35430855efc6c1e0acb75beb",
|
|
"grade": true,
|
|
"grade_id": "cell-7502444279f2a79a",
|
|
"locked": true,
|
|
"points": 0.8,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"assert(ucs_search.fringe is not None), \"it seems you did not correctly initialize the fringe\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Checking cost"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 39,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "ddafb0736b258f1b71dadfaf6824b67c",
|
|
"grade": true,
|
|
"grade_id": "cell-d395b6d5f9d370b1",
|
|
"locked": true,
|
|
"points": 1,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Queue [Node(id:139993250837376, parent:139994341380400, state:(0, 0), action:None, cost:0, depth:0)]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"bfs_search = BFS()\n",
|
|
"maze.reset()\n",
|
|
"bfs_solution = bfs_search.solve(maze)\n",
|
|
"\n",
|
|
"assert(ucs_solution.cost < bfs_solution.cost), \"the solution cost for UCS should be lower than the one for BFS\"\n",
|
|
"assert(ucs_solution.cost == 12), \"the solution found by your algorithm did not return the expected cost\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Check different mazes"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 40,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"ucs_search = UCS()\n",
|
|
"tiny0 = factory.create_problem_from_json(json_path='boards/tiny0.json')\n",
|
|
"ucs_solution = ucs_search.solve(tiny0)\n",
|
|
"assert(ucs_solution.state == (4, 4)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(ucs_solution.get_action_sequence_hash() == '6bdb8d2c34f7d512c6c555c27ec66385b0fd13c5401db6a83cdc68000541dbb5'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 41,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"ucs_search = UCS()\n",
|
|
"tiny1 = factory.create_problem_from_json(json_path='boards/tiny1.json')\n",
|
|
"ucs_solution = ucs_search.solve(tiny1)\n",
|
|
"assert(ucs_solution.state == (2, 4)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(ucs_solution.get_action_sequence_hash() == '473818e05eb92df10661a91a41e2fefd9d3d0b49466df773091a94791b0ac2a5'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 42,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"ucs_search = UCS()\n",
|
|
"tiny2 = factory.create_problem_from_json(json_path='boards/tiny2.json')\n",
|
|
"ucs_solution = ucs_search.solve(tiny2)\n",
|
|
"assert(ucs_solution.state == (2, 2)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(ucs_solution.get_action_sequence_hash() == '5bda40f5b72290920507aa1d23329fb5a3445346372a30bd35cc85f743c439ac'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 43,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"ucs_search = UCS()\n",
|
|
"tiny3 = factory.create_problem_from_json(json_path='boards/tiny3.json')\n",
|
|
"ucs_solution = ucs_search.solve(tiny3)\n",
|
|
"assert(ucs_solution.state == (2, 2)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(ucs_solution.get_action_sequence_hash() == 'e1c95ac72da74163d0c237b69f99dc766c1bbe5e4270fd2934b721d5eab9de31'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 44,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"ucs_search = UCS()\n",
|
|
"tiny4 = factory.create_problem_from_json(json_path='boards/tiny4.json')\n",
|
|
"ucs_solution = ucs_search.solve(tiny4)\n",
|
|
"assert(ucs_solution.state == (4, 4)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(ucs_solution.get_action_sequence_hash() == '0123d362bf2df8f84e7c41197827be005159724c07774ef32d9f15373a440091'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 45,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"ucs_search = UCS()\n",
|
|
"cyclic_map = factory.create_problem_from_json(json_path='boards/cyclic_map.json')\n",
|
|
"ucs_solution = ucs_search.solve(cyclic_map)\n",
|
|
"assert(ucs_solution.state == (2, 2)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(ucs_solution.get_action_sequence_hash() == 'e1c95ac72da74163d0c237b69f99dc766c1bbe5e4270fd2934b721d5eab9de31'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 46,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"ucs_search = UCS()\n",
|
|
"narrow_path = factory.create_problem_from_json(json_path='boards/narrow_path.json')\n",
|
|
"ucs_solution = ucs_search.solve(narrow_path)\n",
|
|
"assert(ucs_solution.state == (2, 4)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(ucs_solution.get_action_sequence_hash() == '2ee4599132a71cf20e4feae6aff58b9ff77ea9486fb0e12225ddd8896ccb9843'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 47,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"ucs_search = UCS()\n",
|
|
"no_possible_path = factory.create_problem_from_json(json_path='boards/no_possible_path.json')\n",
|
|
"ucs_solution = ucs_search.solve(no_possible_path)\n",
|
|
"assert(ucs_solution is None), \"your algorithm did not handle unreachable goal state correctly\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 48,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"ucs_search = UCS()\n",
|
|
"start_is_goal = factory.create_problem_from_json(json_path='boards/start_is_goal.json')\n",
|
|
"ucs_solution = ucs_search.solve(start_is_goal)\n",
|
|
"assert(ucs_solution.state == (0, 0)), \"your algorithm did not return the expected solution when starting from the goal state\"\n",
|
|
"assert(ucs_solution.get_action_sequence_hash() == 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 49,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this test is supposed to test whether the visited set is used somewhat correctly (otherwise it will timeout)\n",
|
|
"\n",
|
|
"ucs_search = UCS()\n",
|
|
"large = factory.create_problem_from_json(json_path='boards/large.json')\n",
|
|
"ucs_solution = ucs_search.solve(large)\n",
|
|
"assert(ucs_solution)\n",
|
|
"assert(ucs_solution.state == (48, 48)), \"your algorithm did not return the expected solution\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Implementing DFS"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 50,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "6c1e9ac7733fbca45f4b842d89e4416f",
|
|
"grade": false,
|
|
"grade_id": "cell-e94fcb80013152e4",
|
|
"locked": false,
|
|
"schema_version": 3,
|
|
"solution": true,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"state (4, 4) was reached following the sequence ['D', 'D', 'D', 'D', 'R', 'R', 'U', 'U', 'R', 'R', 'D', 'D'] (cost: 24, depth: 12)\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA94AAAIxCAYAAAC7CGDIAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjUsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvWftoOwAAAAlwSFlzAAAPYQAAD2EBqD+naQAATpNJREFUeJzt3Xl8VNX9//H3ZE/IZgKBsAVQWSIIImoBFyiCLOJSW+sOuHxbxV8rlVZbVKK0RbFabUW01oJUBVHBDUulImhFkNWFKFZ2ZQkSQyAQksyc3x8xo2PCkAn3cufOfT0fj3mY3Myc+WQmcvLJ+9xzfcYYIwAAAAAAYIs4pwsAAAAAACCW0XgDAAAAAGAjGm8AAAAAAGxE4w0AAAAAgI1ovAEAAAAAsBGNNwAAAAAANqLxBgAAAADARjTeAAAAAADYiMYbAAAAAAAb0XgDknw+X6Nuixcv1uLFi+Xz+fTCCy/YXteaNWt0zjnnKCsrSz6fTw899FDw+RcvXhzxeJE8dvTo0erQoUPEzwEAsSZa54hjafv27SoqKtLatWstH/vaa6/V0KFDQ441NP85qbi4WEVFRdq8ebOjdXzf5s2b5fP5NGPGDKdLiVqPPvpog69PQ6/djBkz5PP5mvQ+P/nkk2rTpo0qKiqaXixiWoLTBQDR4L333gv5fNKkSXrrrbe0aNGikOOFhYVavXr1Mavr2muvVUVFhWbPnq3jjjtOHTp0UFpamt577z0VFhYeszoAwMuidY44lrZv3667775bHTp0UK9evSwbd82aNXrqqae0fPnykOMNzX9OKi4u1t13360BAwY4Xst35efn67333tPxxx/vdClR69FHH1Xz5s01evTokONWv3ajRo3SfffdpylTpujuu++2ZEzEFhpvQNIPfvCDkM9btGihuLi4esePtY8//lg33HCDhg0bFnLc6boAwEuidY6IBffee69OP/109enTJ+T44ea/pqqurpbP51NCQmz96pucnMzPYRNZ/dolJCToZz/7mSZNmqTbbrtNaWlplo2N2MBSc6CJqqurNWHCBLVu3VqZmZk699xztX79+nr3+89//qNBgwYpMzNTaWlp6t+/v958882wY9ctdaqpqdG0adOCyxilwy8XX7lypS644ALl5OQoJSVFp5xyiubMmdOo72XGjBnq0qWLkpOT1a1bN82cObNxLwIAoEF2zhF1ysrKdOutt6pTp05KTk5WXl6ehg8frk8//TR4n9LSUt10001q06aNkpKS1KlTJ02YMEGHDh0KGev555/XGWecoaysLKWlpalTp0669tprJdXOO6eddpokacyYMcE5qaioSJK0ceNGXXbZZWrdurWSk5PVsmVLDRo06IjL0nft2qV58+bp6quvDh4LN/9JtQ35hRdeqOOOO04pKSnq1auXnnrqqZBx6+bJf/7zn7r11lvVpk0bJScn6/PPPz9sLdOmTVPPnj2Vnp6ujIwMde3aVb/73e+CNf3kJz+RJA0cODBY03eXKDfmfSwqKpLP59OaNWv0ox/9SJmZmcrKytJVV12l3bt3h9y3Q4cOOv/88zVv3jydfPLJSklJUadOnfSXv/wl5H4NLZeue55169bp8ssvV1ZWllq2bKlrr71We/fuDXl8WVmZrrvuOuXk5Cg9PV0jRozQxo0bQ97fcLZu3aqrrrpKeXl5wd8hHnjgAQUCgXo1/ulPf9KDDz6ojh07Kj09XX379tWyZcuO+By7d+/WTTfdpMLCQqWnpysvL08//OEP9c477xzxsR06dNC6deu0ZMmS4PtWt2IhkmX6jf3/9Morr1R5eblmz559xDHhPTTeQBP97ne/05YtW/T3v/9df/vb3/S///1PI0eOlN/vD97n6aef1pAhQ5SZmamnnnpKc+bMUU5Ojs4777ywv1iNGDEiuLTxxz/+sd577716Sx2/66233lL//v1VVlamxx57TC+//LJ69eqln/70p0ecUGbMmKExY8aoW7duevHFF3XHHXdo0qRJ9ZZQAgAaz845QpL27dunM888U48//rjGjBmjV199VY899pg6d+6sHTt2SJIqKys1cOBAzZw5U7/61a80f/58XXXVVZoyZYp+9KMfBcd677339NOf/lSdOnXS7NmzNX/+fN11112qqamRJPXu3VvTp0+XJN1xxx3BOen666+XJA0fPlyrVq3SlClTtHDhQk2bNk2nnHKKysrKwn4Pb7zxhqqrqzVw4MDgsXDz3/r169WvXz+tW7dOf/nLXzR37lwVFhZq9OjRmjJlSr3xf/vb32rr1q167LHH9OqrryovL6/BOmbPnq2bbrpJ55xzjubNm6eXXnpJ48aNC56rO2LECP3xj3+UJE2dOjVY04gRIyRF/j5efPHFOuGEE/TCCy+oqKhIL730ks477zxVV1eH3G/t2rW65ZZbNG7cOM2bN0/9+vXTL3/5S/3pT38K+7rWueSSS9S5c2e9+OKLuv322/Xss89q3Lhxwa8HAgGNHDlSzz77rG677TbNmzdPZ5xxRr3z7Q9n9+7d6tevn9544w1NmjRJr7zyis4991yNHz9eN998c737T506VQsXLtRDDz2kZ555RhUVFRo+fHi9PwZ8X2lpqSRp4sSJmj9/vqZPn65OnTppwIABR9yzZt68eerUqZNOOeWU4Ps2b968Rn1/dSJ5f1u1aqWuXbtq/vz5ET0HPMIAqGfUqFGmWbNmDX7trbfeMpLM8OHDQ47PmTPHSDLvvfeeMcaYiooKk5OTY0aOHBlyP7/fb3r27GlOP/30I9YhyYwdO7bB53/rrbeCx7p27WpOOeUUU11dHXLf888/3+Tn5xu/39/gY/1+v2ndurXp3bu3CQQCwcdt3rzZJCYmmoKCgiPWCABeEw1zxD333GMkmYULFx72Po899piRZObMmRNy/L777jOSzBtvvGGMMeZPf/qTkWTKysoOO9aKFSuMJDN9+vSQ41999ZWRZB566KGw9TbkxhtvNKmpqSHzT52G5r/LLrvMJCcnm61bt4YcHzZsmElLSwvWX/cenH322Y2q4+abbzbZ2dlh7/P888/Xm3uNiex9nDhxopFkxo0bF3LfZ555xkgyTz/9dPBYQUGB8fl8Zu3atSH3HTx4sMnMzDQVFRXGGGM2bdpU732pe54pU6aEPPamm24yKSkpwdd7/vz5RpKZNm1ayP0mT55sJJmJEyeGfU1uv/12I8ksX7485PiNN95ofD6fWb9+fUiNPXr0MDU1NcH7vf/++0aSmTVrVtjn+b6amhpTXV1tBg0aZC6++OIj3v+kk04y55xzTr3jDb1206dPN5LMpk2bjDFN+//0yiuvNC1btozoe4I3kHgDTXTBBReEfH7yySdLkrZs2SJJWrp0qUpLSzVq1CjV1NQEb4FAQEOHDtWKFSss2fny888/16effqorr7xSkkKea/jw4dqxY0eDyxul2vRg+/btuuKKK0KW8hUUFKhfv35HXRsAeJXdc8S//vUvde7cWeeee+5h77No0SI1a9ZMP/7xj0OO120yVZfW1S0jv/TSSzVnzhx9+eWXjf4+c3JydPzxx+v+++/Xgw8+qDVr1oQsMw5n+/btatGiRcj8E86iRYs0aNAgtWvXLuT46NGjdeDAgXorwy655JJGjXv66aerrKxMl19+uV5++WV99dVXjXqc1LT3sW6+rnPppZcqISFBb731Vsjxk046ST179gw5dsUVV6i8vLxRm/g19DNYWVmpkpISSdKSJUuCz/9dl19++RHHlmrfj8LCQp1++ukhx0ePHi1jTL2VcyNGjFB8fHxIPdK3/0+E89hjj6l3795KSUlRQkKCEhMT9eabb+qTTz5pVK1N1ZT3Ny8vTyUlJcEVI0AdGm+giXJzc0M+T05OliQdPHhQUu25a1LtUrnExMSQ23333SdjTHD51NGoe57x48fXe56bbrpJkg77S8SePXsk1S6N+r6GjgEAGsfuOWL37t1q27Zt2Br27NmjVq1a1Wts8/LylJCQEJwDzj77bL300kuqqanRNddco7Zt26p79+6aNWvWEb9Pn8+nN998U+edd56mTJmi3r17q0WLFvrFL36hffv2hX3swYMHlZKScsTn+O73k5+fX+9469atg1//robu25Crr75a//jHP7RlyxZdcsklysvL0xlnnKGFCxce8bFNeR+/P78mJCQoNze3Xv3h5ubv37chR/oZ3LNnjxISEpSTkxNyv5YtWx5x7LrHR/J+HKmew3nwwQd144036owzztCLL76oZcuWacWKFRo6dOgRH3u0mvL+pqSkyBijyspKW2uD+8TW1o5AFGnevLkk6a9//ethd81s7OTWmOf57W9/G3LO3nd16dKlweN1k+DOnTvrfa2hYwAAaxztHNGiRQt98cUXYZ8jNzdXy5cvlzEmpPmuS+PqapCkCy+8UBdeeKEOHTqkZcuWafLkybriiivUoUMH9e3bN+zzFBQU6Mknn5QkffbZZ5ozZ46KiopUVVWlxx577LCPa968eUSXX8vNzQ2ev/5d27dvD473XY1N0qXaTePGjBmjiooKvf3225o4caLOP/98ffbZZyooKDjs45ryPu7cuVNt2rQJfl5TU6M9e/bUa0zDzc3fv29T5ObmqqamRqWlpSHNd2Pn/0jfj6Z6+umnNWDAAE2bNi3k+JH+sGOFpry/paWlSk5OVnp6uu31wV1IvAGb9O/fX9nZ2SouLlafPn0avCUlJR3183Tp0kUnnniiPvjgg8M+T0ZGxmEfm5+fr1mzZskYEzy+ZcsWLV269KhrAwA07GjniGHDhumzzz4LuxHmoEGDtH//fr300kshx+uuXDFo0KB6j0lOTtY555yj++67T1LtdbbrjktHTic7d+6sO+64Qz169DhiU921a1ft2bPniJtrfff7WbRoUbCx++73k5aWZsmloZo1a6Zhw4ZpwoQJqqqq0rp16yQd/vtvyvv4zDPPhHw+Z84c1dTUaMCAASHH161bpw8++CDk2LPPPquMjAz17t37qL/Xc845R5L03HPPhRxv7I7cgwYNUnFxcb33eebMmfL5fCGb5h0Nn88XfP3rfPjhh2E3nf2u5OTkJifjTXl/N27cqMLCwiY9H2IbiTdgk/T0dP31r3/VqFGjVFpaqh//+MfKy8vT7t279cEHH2j37t31/nrbVI8//riGDRum8847T6NHj1abNm1UWlqqTz75RKtXr9bzzz/f4OPi4uI0adIkXX/99br44ot1ww03qKysTEVFRSw1BwAbHe0cccstt+i5557ThRdeqNtvv12nn366Dh48qCVLluj888/XwIEDdc0112jq1KkaNWqUNm/erB49eui///2v/vjHP2r48OHB88PvuusuffHFFxo0aJDatm2rsrIyPfzww0pMTAw2Z8cff7xSU1P1zDPPqFu3bkpPT1fr1q311Vdf6eabb9ZPfvITnXjiiUpKStKiRYv04Ycf6vbbbw/7GgwYMEDGGC1fvlxDhgw54ms2ceJEvfbaaxo4cKDuuusu5eTk6JlnntH8+fM1ZcoUZWVlRfAOfOuGG25Qamqq+vfvr/z8fO3cuVOTJ09WVlZW8Pz37t27S5L+9re/KSMjQykpKerYsaNyc3Mjfh/nzp2rhIQEDR48WOvWrdOdd96pnj171jvXunXr1rrgggtUVFSk/Px8Pf3001q4cKHuu+8+S64RPXToUPXv31+33nqrysvLdeqpp+q9994L/mEmLi58Pjdu3DjNnDlTI0aM0D333KOCggLNnz9fjz76qG688UZ17tz5qGuUpPPPP1+TJk3SxIkTdc4552j9+vW655571LFjx0adR92jRw/Nnj1bzz33nDp16qSUlBT16NGjUc8d6f+ngUBA77//vq677romf7+IYY5t6wZEscbsWPv888+HHG9od0xjjFmyZIkZMWKEycnJMYmJiaZNmzZmxIgR9R7fEDVyV3NjjPnggw/MpZdeavLy8kxiYqJp1aqV+eEPf2gee+yx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",
|
|
"text/plain": [
|
|
"<Figure size 1000x700 with 4 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"class DFS(object):\n",
|
|
"\n",
|
|
" def __init__(self) -> None:\n",
|
|
" # YOUR CODE HERE: initialize self.visited and self.fringe here or in the solve function with the correct datatypes\n",
|
|
" self.visited = set()\n",
|
|
" self.fringe = Stack()\n",
|
|
"\n",
|
|
" def solve(self, problem: Problem):\n",
|
|
" # YOUR CODE HERE\n",
|
|
"\n",
|
|
" root = problem.get_start_node()\n",
|
|
" self.fringe.put(root)\n",
|
|
" while self.fringe.has_elements():\n",
|
|
" current = self.fringe.get()\n",
|
|
"\n",
|
|
" if problem.is_end(current):\n",
|
|
" return current\n",
|
|
"\n",
|
|
" if current in self.visited:\n",
|
|
" continue\n",
|
|
"\n",
|
|
" self.visited.add(current)\n",
|
|
" for successor in problem.successors(current):\n",
|
|
" self.fringe.put(successor)\n",
|
|
" \n",
|
|
" \n",
|
|
" return None\n",
|
|
"\n",
|
|
" \n",
|
|
"dfs_search = DFS()\n",
|
|
"maze.reset() # resets maze for hidden tests\n",
|
|
"dfs_solution = dfs_search.solve(maze)\n",
|
|
"\n",
|
|
"if dfs_solution is not None:\n",
|
|
" dfs_solution.pretty_print()\n",
|
|
" maze.visualize(sequences=[('dfs', dfs_solution.get_action_sequence())])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Basic checks"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 51,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "13ec840f2f77f176e68155b1f34fcd9d",
|
|
"grade": true,
|
|
"grade_id": "cell-7729bdb99cbcb357",
|
|
"locked": true,
|
|
"points": 0.2,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"assert(dfs_solution is not None), \"your algorithm did not return a solution\"\n",
|
|
"assert(dfs_solution is not None or isinstance(dfs_solution, type(maze.get_start_node()))), \"your solution is not of the right type\"\n",
|
|
"assert(dfs_solution.state == (4, 4)), \"your algorithm did not return the expected solution\"\n",
|
|
"\n",
|
|
"assert(dfs_solution.cost == 24), \"the solution found by your algorithm did not return the expected cost\"\n",
|
|
"assert(dfs_solution.depth == 12), \"the solution found by your algorithm does not have the expected length\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Check visited set"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 52,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "8c6f1ddd46e0cc7c3830bb347c612fc5",
|
|
"grade": true,
|
|
"grade_id": "cell-ea2de578de0929dd",
|
|
"locked": true,
|
|
"points": 0.5,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"assert(dfs_search.visited is not None), \"it seems you did not correctly initialize the visited set\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Check fringe"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 53,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "31e1861c96a7c40bdca43bd26f943874",
|
|
"grade": true,
|
|
"grade_id": "cell-45ac331b0d77b101",
|
|
"locked": true,
|
|
"points": 0.8,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"assert(dfs_search.fringe is not None), \"it seems you did not correctly initialize the fringe\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Check different mazes"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 54,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "00f5c7aa425bc6f808edea2478337c48",
|
|
"grade": true,
|
|
"grade_id": "cell-fbef9ebfc64d0579",
|
|
"locked": true,
|
|
"points": 0.2,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"dfs_search = DFS()\n",
|
|
"tiny0 = factory.create_problem_from_json(json_path='boards/tiny0.json')\n",
|
|
"dfs_solution = dfs_search.solve(tiny0)\n",
|
|
"assert(dfs_solution.state == (4, 4)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(dfs_solution.get_action_sequence_hash() == 'e1fa32922bd28adb1dbb8a08b56547137b98d1105229a033162ae0edb274f418'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 55,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "fb8984e9d558951d18e22f60972f98ce",
|
|
"grade": true,
|
|
"grade_id": "cell-b7dffcb6abd93552",
|
|
"locked": true,
|
|
"points": 0.2,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"dfs_search = DFS()\n",
|
|
"tiny1 = factory.create_problem_from_json(json_path='boards/tiny1.json')\n",
|
|
"dfs_solution = dfs_search.solve(tiny1)\n",
|
|
"assert(dfs_solution.state == (2, 4)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(dfs_solution.get_action_sequence_hash() == '50ad40a2921e4009cab8f9bdb1c7a00bf36f69fbe7a20b83aeb93227334ee601'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 56,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "cc94a80ee24db1db3fb7bcf2f5fc910b",
|
|
"grade": true,
|
|
"grade_id": "cell-d10f2fec91098425",
|
|
"locked": true,
|
|
"points": 0.2,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"dfs_search = DFS()\n",
|
|
"tiny2 = factory.create_problem_from_json(json_path='boards/tiny2.json')\n",
|
|
"dfs_solution = dfs_search.solve(tiny2)\n",
|
|
"assert(dfs_solution.state == (2, 2)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(dfs_solution.get_action_sequence_hash() == '5bda40f5b72290920507aa1d23329fb5a3445346372a30bd35cc85f743c439ac'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 57,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "4cc6902eda0bdb8335c102f497a4ace0",
|
|
"grade": true,
|
|
"grade_id": "cell-1b277be9230355d0",
|
|
"locked": true,
|
|
"points": 0.2,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"dfs_search = DFS()\n",
|
|
"tiny3 = factory.create_problem_from_json(json_path='boards/tiny3.json')\n",
|
|
"dfs_solution = dfs_search.solve(tiny3)\n",
|
|
"assert(dfs_solution.state == (2, 2)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(dfs_solution.get_action_sequence_hash() == '5bda40f5b72290920507aa1d23329fb5a3445346372a30bd35cc85f743c439ac'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 58,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "09d1faa9749bb1e2cf83b33c1fb528f2",
|
|
"grade": true,
|
|
"grade_id": "cell-c4f7dbe4d3a2ca3d",
|
|
"locked": true,
|
|
"points": 0.2,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"dfs_search = DFS()\n",
|
|
"tiny4 = factory.create_problem_from_json(json_path='boards/tiny4.json')\n",
|
|
"dfs_solution = dfs_search.solve(tiny4)\n",
|
|
"assert(dfs_solution.state == (4, 4)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(dfs_solution.get_action_sequence_hash() == '0123d362bf2df8f84e7c41197827be005159724c07774ef32d9f15373a440091'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 59,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"dfs_search = DFS()\n",
|
|
"cyclic_map = factory.create_problem_from_json(json_path='boards/cyclic_map.json')\n",
|
|
"dfs_solution = dfs_search.solve(cyclic_map)\n",
|
|
"assert(dfs_solution.state == (2, 2)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(dfs_solution.get_action_sequence_hash() == '61ade70d1b7727f7e21ea8d65cbc2afc5239a5cc2a0c056593d39b43edcc82df'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 60,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"dfs_search = DFS()\n",
|
|
"narrow_path = factory.create_problem_from_json(json_path='boards/narrow_path.json')\n",
|
|
"dfs_solution = dfs_search.solve(narrow_path)\n",
|
|
"assert(dfs_solution.state == (2, 4)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(dfs_solution.get_action_sequence_hash() == '2ee4599132a71cf20e4feae6aff58b9ff77ea9486fb0e12225ddd8896ccb9843'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 61,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"dfs_search = DFS()\n",
|
|
"no_possible_path = factory.create_problem_from_json(json_path='boards/no_possible_path.json')\n",
|
|
"dfs_solution = dfs_search.solve(no_possible_path)\n",
|
|
"assert(dfs_solution is None), \"your algorithm magically found a solution in an impossible maze\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 62,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"dfs_search = DFS()\n",
|
|
"start_is_goal = factory.create_problem_from_json(json_path='boards/start_is_goal.json')\n",
|
|
"dfs_solution = dfs_search.solve(start_is_goal)\n",
|
|
"assert(dfs_solution.state == (0, 0)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(dfs_solution.get_action_sequence_hash() == 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 63,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "e9c1cb9ad2c23a47501c54fddb3d4a28",
|
|
"grade": true,
|
|
"grade_id": "cell-f24c21dd867ccc44",
|
|
"locked": true,
|
|
"points": 0.5,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this test is supposed to test whether the visited set is used somewhat correctly (otherwise it will timeout)\n",
|
|
"\n",
|
|
"dfs_search = DFS()\n",
|
|
"large = factory.create_problem_from_json(json_path='boards/large.json')\n",
|
|
"dfs_solution = dfs_search.solve(large)\n",
|
|
"assert(dfs_solution)\n",
|
|
"assert(dfs_solution.state == (48, 48)), \"your algorithm did not return the expected solution\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Implementing DLDFS\n",
|
|
"\n",
|
|
"<strong>Hints:</strong>\n",
|
|
"<ul>\n",
|
|
"<li>This algorithm should be implemented recursively, which means you will not require an explicit fringe. Think about why this is the case!</li>\n",
|
|
"<li>To be comparable to our solution you also do not need to use a visited set for this algorithm.</li>\n",
|
|
"</ul>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 72,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "da284236de56495b7e580ad070a76dc8",
|
|
"grade": false,
|
|
"grade_id": "cell-3e0fae5d39e252d7",
|
|
"locked": false,
|
|
"schema_version": 3,
|
|
"solution": true,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"state (4, 4) was reached following the sequence ['R', 'R', 'R', 'R', 'L', 'L', 'D', 'D', 'R', 'R', 'D', 'D'] (cost: 36, depth: 12)\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "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2WefRV0Ic9CgQdq/f79efPHFiP3Vd64YNGhQjeekpKSof//+mjp1qqSq+2xX75eOnk526NBBd955p7p27XrUorpTp07avXv3URfX+v738+abb4YLu+9/P2lpabbcGqpx48YqLCzUhAkTVFFRobVr10o68vdfn/fx6aefjng8b948VVZWasCAARH7165dq48//jhi3zPPPKOMjAz17NnzmL/X/v37S5Kee+65iP11XZF70KBBWrduXY33+amnnpJlWRGL5h0Ly7LCr3+1f/3rX1EXnf2+lJSUeifj9Xl/N27cqIKCgnqdD/GNxBtwSHp6uv70pz9p1KhR2rNnj376058qJydHO3fu1Mcff6ydO3fW+Ottff35z39WYWGhzj33XI0ePVqtWrXSnj17tH79en344Yd6/vnna31eQkKC7r33Xv3iF7/QhRdeqOuuu04lJSWaNGkSU80BwEHHOkbcfPPNeu655zRy5EjdfvvtOvPMM3Xw4EEtW7ZM5513ngYOHKirr75a06dP16hRo7R582Z17dpV77zzjn7/+99r2LBh4evD77rrLn399dcaNGiQWrdurZKSEj388MNKSkoKF2cnn3yyGjVqpKefflqnnnqq0tPT1bJlS+3atUs33nijfvazn+mUU05RcnKy3nzzTf3rX//S7bffHvU1GDBggIwxeu+99zRkyJCjvmYTJ07Uq6++qoEDB+quu+5Sdna2nn76aS1cuFDTpk1TVlZWDO/Af1x33XVq1KiRzj77bOXm5mrbtm2aPHmysrKywte/d+nSRZL0l7/8RRkZGUpNTVXbtm3VtGnTmN/Hv//970pMTNTgwYO1du1a/fa3v1X37t1rXGvdsmVLnX/++Zo0aZJyc3M1Z84cLV68WFOnTrXlHtFDhw7V2WefrVtvvVWlpaU6/fTTtWLFivAfZhISoudz48aN01NPPaXhw4frnnvuUV5enhYuXKjHHntM119/vTp06HDMfZSk8847T/fee68mTpyo/v37a8OGDbrnnnvUtm3bOl1H3bVrV82dO1fPPfec2rVrp9TUVHXt2rVO5471/9NQKKT3339f1157bb2/X8Qx15Z1AxqwuqxY+/zzz0fsr211TGOMWbZsmRk+fLjJzs42SUlJplWrVmb48OE1nl8b1XFVc2OM+fjjj80ll1xicnJyTFJSkmnRooX5yU9+YmbOnHnU5/7v//6vOeWUU0xycrLp0KGD+etf/2pGjRrFquYAUIuGMkZ8++235qabbjInnXSSSUpKMjk5OWb48OHm008/DR+ze/du86tf/crk5uaaxMREk5eXZ37zm9+Y8vLy8DGvvvqqKSwsNK1atTLJyckmJyfHDBs2zLz99tsR53v22WdNp06dTFJSUnjV6+3bt5vRo0ebTp06mcaNG5v09HTTrVs388c//jFiBevaBINBk5+fb2644YYaX6tt/DPGmE8++cSMGDHCZGVlmeTkZNO9e/car+mR3oMjefLJJ83AgQNN8+bNTXJysmnZsqW55JJLzL/+9a+I4x566CHTtm1bEwgEaryXdXkfq1cbX716tRkxYoRJT083GRkZ5rLLLjPbt2+POFdeXp4ZPny4eeGFF0znzp1NcnKyyc/PNw8++GDEcdFWNd+5c2fEsT9csdsYY/bs2WPGjBljmjRpYtLS0szgwYPNypUrjSTz8MMPH/W127Jli7n88stN06ZNTVJSkunYsaO5//77w3dT+X4f77///hrPVx1WTz906JAZP368adWqlUlNTTU9e/Y0L774Yp1/T9m8ebMZMmSIycjIMJLCz6nLqubV6vr/6RtvvBF+j4Efsoz53vxSAAAA4Dh54IEHdN999+mbb75Ro0aN3O6OoyZNmqS7775bO3fuPOr1z/n5+erSpYteffXV49S7/3jmmWd0xRVX6N133+UOJzG66qqrtHHjRr377rtudwUNEFPNAQAA4IqxY8fq0Ucf1fTp0zV+/Hi3u+M7zz77rL755ht17dpVCQkJWrlype6//37169ePojtGX375pZ577rmo6y7A3yi8AQAA4IrU1FT97W9/Cy/ihuMrIyNDc+fO1e9+9zuVlZUpNzdXo0eP1u9+9zu3u+Y5RUVFevTRR9W3b1+3u4IGiqnmAAAAAAA4iNuJAQDggrfeeksjRoxQy5YtZVlWjVs+AQCAhmfy5MmyLEs333xzTM+j8AYAwAVlZWXq3r27Hn30Ube7AgAA6mDVqlX6y1/+om7dusX8XK7xBgDABYWFhSosLHS7GwAAoA7279+vK664Qo8//ni91kGIufAOhULaunWrMjIyZFlWzCcEAMBNxpjw7XwSEuyd+GWMqTE2pqSkKCUlxdbz1AXjNQDA65was+szXo8dO1bDhw/XOeec42zhPX36dE2f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5ho98sgj6t+/v9q1a6crr7xSY8aM0d///veo7ZaUlOiXv/ylmjdvrtTUVHXp0kWvvvrqEY8fMWKEhg0bpg4dOqhDhw667777lJ6erpUrV4aPmTBhgoYNG6Zp06bptNNOU7t27TR8+HDl5OTU75sHAPgOY3ZNjNlAw0DhDRzFr3/9ay1ZskQLFizQa6+9pqVLl2r16tVHPD4UCumiiy5SIBDQypUrNXPmTN12220RxxQXF6tz58669dZbVVxcrPHjx+uRRx7Ryy+/rHnz5mnDhg2aM2eO8vPz69zP2bNn27Jq6N69e5WdnX3Er4dCIRUWFmr58uWaM2eO1q1bpylTpkTcl9OyLM2ePbvW5weDQc2dO1dlZWXq3bt3uM2FCxeqQ4cOOvfcc5WTk6Ozzjor4vo6AACOhjE7EmM20HAw1RyIYv/+/XriiSf01FNPafDgwZKqply1bt36iM95/fXXtX79em3evDl83O9///uIa6NatGihxMREpaenq0WLFpKkoqIinXLKKerbt68sy4p5OltWVpY6duwY67cYYcWKFZo3b54WLlx4xGNef/11vf/++1q/fr06dKi6/q5du3YRx3Ts2FFZWVkR+z755BP17t1b5eXlSk9P14IFC1RQUCBJ2rFjh/bv368pU6bod7/7naZOnapFixbpoosu0pIlS9S/f/9j+r4AAPGPMbsmxmyg4aDwBqL48ssvVVFREf4rryRlZ2dHHSzXr1+vk046KWKg//7zj2T06NEaPHiwOnbsqKFDh+q8887TkCFD6tzXCy+8UBdeeGGdj/+htWvXauTIkbrrrrvCv7DUZs2aNWrdunV4AK/Np59+WmNfx44dtWbNGpWUlGj+/PkaNWqUli1bpoKCAoVCIUnSyJEjNW7cOElSjx49tHz5cs2cOZNBHABwVIzZNTFmAw0HU82BKIwxtjynLtPJevbsqU2bNunee+/VwYMHdckll+inP/1pzOevj3Xr1uknP/mJrrvuOt15551Rj23UqFG9zpGcnKz27durV69emjx5srp3766HH35YknTiiScqMTEx/Nf0aqeeeqqKiorqdT4AgL8wZtfEmA00HBTeQBTt27dXUlJSxIIi3377rT777Mi3UykoKFBRUZG2bt0a3rdixYo6nS8zM1OXXnqpHn/8cT333HOaP3++9uzZU/9voA7Wrl2rgQMHatSo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",
|
|
"text/plain": [
|
|
"<Figure size 1000x700 with 4 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"class DLDFS_Recursive(object):\n",
|
|
" def __init__(self, max_depth):\n",
|
|
" self.max_depth = max_depth\n",
|
|
"\n",
|
|
" def solve_aux(self, problem, current, depth = 0):\n",
|
|
" if problem.is_end(current):\n",
|
|
" return current\n",
|
|
"\n",
|
|
" if depth >= self.max_depth:\n",
|
|
" return None\n",
|
|
" \n",
|
|
" for successor in problem.successors(current):\n",
|
|
" result = self.solve_aux(problem, successor, depth + 1)\n",
|
|
" if result is not None:\n",
|
|
" return result\n",
|
|
"\n",
|
|
" \n",
|
|
" return None\n",
|
|
"\n",
|
|
" def solve(self, problem: Problem):\n",
|
|
" return self.solve_aux(problem, problem.get_start_node())\n",
|
|
"\n",
|
|
"\n",
|
|
"dldfs_search = DLDFS_Recursive(12)\n",
|
|
"maze.reset() # resets maze for hidden tests\n",
|
|
"dldfs_solution = dldfs_search.solve(maze)\n",
|
|
"\n",
|
|
"if dldfs_solution is not None:\n",
|
|
" dldfs_solution.pretty_print()\n",
|
|
" maze.visualize(sequences=[('dldfs', dldfs_solution.get_action_sequence())])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Basic Checks"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 73,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "8f0da3ceb956f1584b6b0fde776cc8c3",
|
|
"grade": true,
|
|
"grade_id": "cell-07d2f9c64ab2c152",
|
|
"locked": true,
|
|
"points": 2,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"assert(dldfs_solution is not None), \"your algorithm did not return a solution\"\n",
|
|
"assert(dldfs_solution is not None or isinstance(dldfs_solution, type(maze.get_start_node()))), \"your solution is not of the right type\"\n",
|
|
"assert(dldfs_solution.state == (4, 4)), \"your algorithm did not return the expected solution\"\n",
|
|
"\n",
|
|
"assert(dldfs_solution.cost == 36), \"the solution found by your algorithm did not return the expected cost\"\n",
|
|
"assert(dldfs_solution.depth == 12), \"the solution found by your algorithm does not have the expected length\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Check different mazes"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 74,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# we need more depth for some of the problem instances\n",
|
|
"max_dldfs_depth = 25"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 75,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "807edb2d77a6dd6e592db96a14c2df80",
|
|
"grade": true,
|
|
"grade_id": "cell-5fafe913c0c969c2",
|
|
"locked": true,
|
|
"points": 0.4,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"dldfs_search = DLDFS_Recursive(max_depth=max_dldfs_depth)\n",
|
|
"tiny0 = factory.create_problem_from_json(json_path='boards/tiny0.json')\n",
|
|
"dldfs_solution = dldfs_search.solve(tiny0)\n",
|
|
"assert(dldfs_solution.state == (4, 4)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(dldfs_solution.get_action_sequence_hash() == '5eb9f93f575001cbddca893c699d418e47eff2b53f0c9a1a2072c3b9ad643dc7'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 76,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "046f9d9fc7c3aa47f7d1864795046cf6",
|
|
"grade": true,
|
|
"grade_id": "cell-462d4b407fabc045",
|
|
"locked": true,
|
|
"points": 0.4,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"dldfs_search = DLDFS_Recursive(max_depth=max_dldfs_depth)\n",
|
|
"tiny1 = factory.create_problem_from_json(json_path='boards/tiny1.json')\n",
|
|
"dldfs_solution = dldfs_search.solve(tiny1)\n",
|
|
"assert(dldfs_solution.state == (2, 4)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(dldfs_solution.get_action_sequence_hash() == '7f10f7179c1d448ed33e8b8d0bb5372266cea15bd9ec0ffbdd11118438754d99'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 77,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "d9ca3e75bfa55423bc3d947434ba26f9",
|
|
"grade": true,
|
|
"grade_id": "cell-30634f5520d90c17",
|
|
"locked": true,
|
|
"points": 0.4,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"dldfs_search = DLDFS_Recursive(max_depth=max_dldfs_depth)\n",
|
|
"tiny2 = factory.create_problem_from_json(json_path='boards/tiny2.json')\n",
|
|
"dldfs_solution = dldfs_search.solve(tiny2)\n",
|
|
"assert(dldfs_solution.state == (2, 2)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(dldfs_solution.get_action_sequence_hash() == 'ebb80a630c129a7234ed6c9bcde740930a01622f4adde8b304db362ec5a24725'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 78,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "db1f664f956e3158981b58e5a41ae86c",
|
|
"grade": true,
|
|
"grade_id": "cell-4d12d065035af707",
|
|
"locked": true,
|
|
"points": 0.4,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"dldfs_search = DLDFS_Recursive(max_depth=max_dldfs_depth)\n",
|
|
"tiny3 = factory.create_problem_from_json(json_path='boards/tiny3.json')\n",
|
|
"dldfs_solution = dldfs_search.solve(tiny3)\n",
|
|
"assert(dldfs_solution.state == (2, 2)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(dldfs_solution.get_action_sequence_hash() == '8ec892c800ce37ea54e9ba4dab28681de6956e481d2ae0e032b1e11c59e4a718'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 79,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "28b14dd36a9a8cfb1552d94655a67b79",
|
|
"grade": true,
|
|
"grade_id": "cell-9320c5aa64bda863",
|
|
"locked": true,
|
|
"points": 0.4,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"dldfs_search = DLDFS_Recursive(max_depth=max_dldfs_depth)\n",
|
|
"tiny4 = factory.create_problem_from_json(json_path='boards/tiny4.json')\n",
|
|
"dldfs_solution = dldfs_search.solve(tiny4)\n",
|
|
"assert(dldfs_solution.state == (4, 4)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(dldfs_solution.get_action_sequence_hash() == 'e097ad8539f0d2f7abe3160c1a47c24e1b19bdb9b0c40e0dcd7e9ecb3307c7bb'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 80,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"dldfs_search = DLDFS_Recursive(max_depth=2)\n",
|
|
"cyclic_map = factory.create_problem_from_json(json_path='boards/cyclic_map.json')\n",
|
|
"dldfs_solution = dldfs_search.solve(cyclic_map)\n",
|
|
"assert(dldfs_solution is None), \"your algorithm should not find a solution at max_depth=2\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 81,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"dldfs_search = DLDFS_Recursive(max_depth=max_dldfs_depth)\n",
|
|
"cyclic_map = factory.create_problem_from_json(json_path='boards/cyclic_map.json')\n",
|
|
"dldfs_solution = dldfs_search.solve(cyclic_map)\n",
|
|
"assert(dldfs_solution.state == (2, 2)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(dldfs_solution.get_action_sequence_hash() == '7ea076a692e54d03a54b160dbceb28175b083f29615149dda6a21a8c6347b28a'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 82,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"dldfs_search = DLDFS_Recursive(max_depth=max_dldfs_depth)\n",
|
|
"narrow_path = factory.create_problem_from_json(json_path='boards/narrow_path.json')\n",
|
|
"dldfs_solution = dldfs_search.solve(narrow_path)\n",
|
|
"assert(dldfs_solution.state == (2, 4)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(dldfs_solution.get_action_sequence_hash() == 'ffb856b0937bb3fb160f44c61f57d391e0edfa9c6671bbfa773fcdba7c317b13'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 83,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"dldfs_search = DLDFS_Recursive(max_depth=max_dldfs_depth)\n",
|
|
"no_possible_path = factory.create_problem_from_json(json_path='boards/no_possible_path.json')\n",
|
|
"dldfs_solution = dldfs_search.solve(no_possible_path)\n",
|
|
"assert(dldfs_solution is None), \"your algorithm magically found a solution in an impossible maze\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 84,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"dldfs_search = DLDFS_Recursive(max_depth=max_dldfs_depth)\n",
|
|
"start_is_goal = factory.create_problem_from_json(json_path='boards/start_is_goal.json')\n",
|
|
"dldfs_solution = dldfs_search.solve(start_is_goal)\n",
|
|
"assert(dldfs_solution.state == (0, 0)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(dldfs_solution.get_action_sequence_hash() == 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Implementing IDS\n",
|
|
"\n",
|
|
"<strong>Hint:</strong>\n",
|
|
"<ul>\n",
|
|
"<li>Make use of the DLDFS algorithm that you implemented above</li>\n",
|
|
"</ul>"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 86,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "8f21b2a9464561f48f79410a2f8a1467",
|
|
"grade": false,
|
|
"grade_id": "cell-b3614f9983cf1dce",
|
|
"locked": false,
|
|
"schema_version": 3,
|
|
"solution": true,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"state (4, 4) was reached following the sequence ['R', 'R', 'D', 'D', 'R', 'R', 'D', 'D'] (cost: 20, depth: 8)\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA94AAAIxCAYAAAC7CGDIAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjUsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvWftoOwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAS2tJREFUeJzt3XucVWW9P/DvnmEuIAMEMtyEAVRAvGBmmmiKB29IaFfNSsHMc45SJy1/R00NzFOmXY6WiNYp1FKRNDSzPJKKWqLiNQPDVBBTEJQQRLnNXr8/iDmOwDAb9mbP2vv9fr3WC/aatZ/1zN4Mz3z351nPyiRJkgQAAABQEBXF7gAAAACUMoU3AAAAFJDCGwAAAApI4Q0AAAAFpPAGAACAAlJ4AwAAQAEpvAEAAKCAFN4AAABQQApvAAAAKCCFN0REJpNp1TZz5syYOXNmZDKZuPXWWwver6eeeioOO+yw6Ny5c2Qymbjiiiuazj9z5syc28vluePGjYv+/fvnfA6AUtNWx4gd6bXXXouJEyfG008/nfe2v/jFL8YxxxzTbN/mxr9imjt3bkycODEWLFhQ1H6834IFCyKTycR1111X7K60WVdfffVmX5/NvXbXXXddZDKZbXqff/azn0WfPn1i1apV295ZSlq7YncA2oJZs2Y1e3zJJZfE/fffH/fdd1+z/UOHDo0nn3xyh/Xri1/8YqxatSqmTp0aH/jAB6J///7RoUOHmDVrVgwdOnSH9QOgnLXVMWJHeu211+Liiy+O/v37x7777pu3dp966qm4/vrr49FHH222f3PjXzHNnTs3Lr744hgxYkTR+/JevXr1ilmzZsWuu+5a7K60WVdffXXsvPPOMW7cuGb78/3ajR07Ni677LK4/PLL4+KLL85Lm5QWhTdExEc+8pFmj7t37x4VFRWb7N/R/vKXv8Tpp58eo0aNara/2P0CKCdtdYwoBd/97nfjgAMOiP3337/Z/i2Nf9tq3bp1kclkol270vrVt6amxr/DbZTv165du3bxb//2b3HJJZfEueeeGx06dMhb25QGU81hG61bty4uuOCC6N27d3Tq1CmOOOKImDdv3ibH/eEPf4iRI0dGp06dokOHDnHwwQfHvffe22LbG6c6rV+/PiZPntw0jTFiy9PFH3/88TjuuOOia9euUVtbGx/84Adj2rRprfperrvuuhg8eHDU1NTEHnvsETfccEPrXgQANquQY8RGy5cvj69//esxcODAqKmpifr6+jj22GPjr3/9a9Mxy5YtizPPPDP69OkT1dXVMXDgwLjgggtizZo1zdr61a9+FQceeGB07tw5OnToEAMHDowvfvGLEbFh3Pnwhz8cERGnnnpq05g0ceLEiIh46aWX4rOf/Wz07t07ampqokePHjFy5MitTkt//fXXY/r06XHyySc37Wtp/IvYUJAff/zx8YEPfCBqa2tj3333jeuvv75ZuxvHyV/84hfx9a9/Pfr06RM1NTXxwgsvbLEvkydPjmHDhkXHjh2jrq4uhgwZEt/4xjea+vSZz3wmIiIOP/zwpj69d4pya97HiRMnRiaTiaeeeio++clPRqdOnaJz587xhS98IZYuXdrs2P79+8fHPvaxmD59euyzzz5RW1sbAwcOjB/96EfNjtvcdOmN55kzZ06cdNJJ0blz5+jRo0d88YtfjLfeeqvZ85cvXx6nnXZadO3aNTp27BijR4+Ol156qdn725KFCxfGF77whaivr2/6HeIHP/hBZLPZTfr4/e9/P374wx/GgAEDomPHjnHQQQfFI488stVzLF26NM4888wYOnRodOzYMerr6+Nf/uVf4qGHHtrqc/v37x9z5syJBx54oOl92zhjIZdp+q39Of385z8fK1asiKlTp261TcqPwhu20Te+8Y14+eWX43/+53/iJz/5Sfztb3+LMWPGRGNjY9Mxv/zlL+Ooo46KTp06xfXXXx/Tpk2Lrl27xtFHH93iL1ajR49umtr46U9/OmbNmrXJVMf3uv/+++Pggw+O5cuXxzXXXBN33HFH7LvvvnHiiSdudUC57rrr4tRTT4099tgjbrvttrjwwgvjkksu2WQKJQCtV8gxIiJi5cqVccghh8S1114bp556atx5551xzTXXxKBBg2LRokUREbF69eo4/PDD44Ybboivfe1rcdddd8UXvvCFuPzyy+OTn/xkU1uzZs2KE088MQYOHBhTp06Nu+66K775zW/G+vXrIyJiv/32iylTpkRExIUXXtg0Jn3pS1+KiIhjjz02nnjiibj88stjxowZMXny5PjgBz8Yy5cvb/F7uOeee2LdunVx+OGHN+1rafybN29eDB8+PObMmRM/+tGP4te//nUMHTo0xo0bF5dffvkm7Z9//vmxcOHCuOaaa+LOO++M+vr6zfZj6tSpceaZZ8Zhhx0W06dPj9tvvz3OPvvspmt1R48eHd/5znciImLSpElNfRo9enRE5P4+fuITn4jddtstbr311pg4cWLcfvvtcfTRR8e6deuaHff000/HWWedFWeffXZMnz49hg8fHl/96lfj+9//fouv60af+tSnYtCgQXHbbbfFeeedFzfddFOcffbZTV/PZrMxZsyYuOmmm+Lcc8+N6dOnx4EHHrjJ9fZbsnTp0hg+fHjcc889cckll8RvfvObOOKII+Kcc86JL3/5y5scP2nSpJgxY0ZcccUVceONN8aqVavi2GOP3eTDgPdbtmxZRERMmDAh7rrrrpgyZUoMHDgwRowYsdU1a6ZPnx4DBw6MD37wg03v2/Tp01v1/W2Uy/vbs2fPGDJkSNx11105nYMykQCbGDt2bLLTTjtt9mv3339/EhHJscce22z/tGnTkohIZs2alSRJkqxatSrp2rVrMmbMmGbHNTY2JsOGDUsOOOCArfYjIpLx48dv9vz3339/074hQ4YkH/zgB5N169Y1O/ZjH/tY0qtXr6SxsXGzz21sbEx69+6d7Lfffkk2m2163oIFC5KqqqqkoaFhq30EKDdtYYz41re+lUREMmPGjC0ec8011yQRkUybNq3Z/ssuuyyJiOSee+5JkiRJvv/97ycRkSxfvnyLbc2ePTuJiGTKlCnN9r/xxhtJRCRXXHFFi/3dnDPOOCNp3759s/Fno82Nf5/97GeTmpqaZOHChc32jxo1KunQoUNT/ze+B4ceemir+vHlL3856dKlS4vH/OpXv9pk7E2S3N7HCRMmJBGRnH322c2OvfHGG5OISH75y1827WtoaEgymUzy9NNPNzv2yCOPTDp16pSsWrUqSZIkmT9//ibvy8bzXH755c2ee+aZZya1tbVNr/ddd92VREQyefLkZsddeumlSUQkEyZMaPE1Oe+885KISB599NFm+88444wkk8kk8+bNa9bHvffeO1m/fn3TcY899lgSEcnNN9/c4nneb/369cm6deuSkSNHJp/4xCe2evyee+6ZHHbYYZvs39xrN2XKlCQikvnz5ydJsm0/p5///OeTHj165PQ9UR4k3rCNjjvuuGaP99lnn4iIePnllyMi4uGHH45ly5bF2LFjY/369U1bNpuNY445JmbPnp2XlS9feOGF+Otf/xqf//znIyKanevYY4+NRYsWbXZ6Y8SG9OC1116Lz33uc82m8jU0NMTw4cO3u28A5arQY8Tvf//7GDRoUBxxxBFbPOa+++6LnXbaKT796U83279xkamNad3GaeQnnHBCTJs2LV599dVWf59du3aNXXfdNb73ve/FD3/4w3jqqaeaTTNuyWuvvRbdu3dvNv605L777ouRI0dG3759m+0fN25cvPPOO5vMDPvUpz7VqnYPOOCAWL58eZx00klxxx13xBtvvNGq50Vs2/u4cbze6IQTToh27drF/fff32z/nnvuGcOGDWu273Of+1ysWLGiVYv4be7f4OrVq2PJkiUREfHAAw80nf+9TjrppK22HbHh/Rg6dGgccMABzfaPGzcukiTZZObc6NGjo7Kysll/Iv7vZ6Il11xzTey3335RW1sb7dq1i6qqqrj33nvjueeea1Vft9W2vL/19fWxZMmSphkjsJHCG7ZRt27dmj2uqamJiIh33303IjZcuxaxYapcVVVVs+2yyy6LJEmapk9tj43nOeecczY5z5lnnhkRscVfIt58882I2DA16v02tw+A1in0GLF06dLYZZddWuzDm2++GT179tyksK2vr4927do1jQGHHnpo3H777bF+/fo45ZRTYpdddom99torbr755q1+n5lMJu699944+uij4/LLL4/99tsvunfvHv/xH/8RK1eubPG57777btTW1m71HO/9fnr16rXJ/t69ezd9/b02d+zmnHzyyfHzn/88Xn755fjUpz4V9fX1ceCBB8aMGTO2+txteR/fP762a9cuunXrtkn/Wxqb33/s5mzt3+Cbb74Z7dq1i65duzY7rkePHltte+Pzc3k/ttafLfnhD38YZ5xxRhx44IFx2223xSOPPBKzZ8+OY445ZqvP3V7b8v7W1tZGkiSxevXqgvaN9CmtpR2hDdl5550jIuLHP/7xFlfNbO3g1prznH/++c2u2XuvwYMHb3b/xkFw8eLFm3xtc/sAyI/tHSO6d+8ef//731s8R7du3eLRRx+NJEmaFd8b07iNfYiIOP744+P444+PNWvWxCOPPBKXXnppfO5zn4v+/fvHQQcd1OJ5Ghoa4mc/+1lERDz//PMxbdq0mDhxYqxduzauueaaLT5v5513zun2a926dWu6fv29Xnvttab23qu1SXrEhkXjTj311Fi1alU8+OCDMWHChPjYxz4Wzz//fDQ0NGzxedvyPi5evDj69OnT9Hj9+vXx5ptvblKYtjQ2v//YbdGtW7dYv359LFu2rFnx3drxP9f3Y1v98pe/jBEjRsTkyZOb7d/aBzv5sC3v77Jly6KmpiY6duxY8P6RLhJvKJCDDz44unTpEnPnzo39999/s1t1dfV2n2fw4MGx++67xzPPPLPF89TV1W3xub169Yqbb745kiRp2v/yyy/Hww8/vN19A2DztneMGDVqVDz//PMtLoQ5cuTIePvtt+P2229vtn/jnStGjhy5yXNqamrisMMOi8suuywiNtxne+P+iK2nk4MGDYoLL7ww9t57760W1UOGDIk333xzq4trvff7ue+++5oKu/d+Px06dMjLraF22mmnGDVqVFxwwQWxdu3amDNnTkRs+fvflvfxxhtvbPZ42rRpsX79+hgxYkSz/XPmzIlnnnmm2b6bbrop6urqYr/99tvu7/Wwww6LiIhbbrml2f7Wrsg9cuTImDt37ibv8w033BCZTKbZonnbI5PJNL3+G/35z39ucdHZ96qpqdnmZHxb3t+XXnophg4duk3no7RJvKFAOnbsGD/+8Y9j7NixsWzZsvj0pz8d9fX1sXTp0njmmWdi6dKlm3x6u62uvfbaGDVqVBx99NExbty46NOnTyxbtiyee+65ePLJJ+NXv/rVZp9XUVERl1xySXzpS1+KT3ziE3H66afH8uXLY+LEiaaaAxTQ9o4RZ511Vtxyyy1x/PHHx3nnnRcHHHBAvPvuu/HAAw/Exz72sTj88MPjlFNOiUmTJsXYsWNjwYIFsffee8cf//jH+M53vhPHHnts0/Xh3/zmN+Pvf/97jBw5MnbZZZdYvnx5XHnllVFVVdVUnO26667Rvn37uPHGG2OPPfaIjh07Ru/eveONN96IL3/5y/GZz3wmdt9996iuro777rsv/vznP8d5553X4mswYsSISJIkHn300TjqqKO2+ppNmDAhfvvb38bhhx8e3/zmN6Nr165x4403xl133RWXX355dO7cOYd34P+cfvrp0b59+zj44IOjV69esXjx4rj00kujc+fOTde/77XXXhER8ZOf/CTq6uqitrY2BgwYEN26dcv5ffz1r38d7dq1iyOPPDLmzJkTF110UQwbNmyTa6179+4dxx13XEycODF69eoVv/zlL2PGjBlx2WWX5eUe0cccc0wcfPDB8fWvfz1WrFgRH/rQh2LWrFlNH8xUVLScz5199tlxww03xOjRo+Nb3/pWNDQ0xF133RVXX311nHHGGTFo0KDt7mNExMc+9rG45JJLYsKECXHYYYfFvHnz4lvf+lYMGDCgVddR77333jF16tS45ZZbYuDAgVFbWxt77713q86d689pNpuNxx57LE477bRt/n4pYUVb1g3asNasWPurX/2q2f7NrY6ZJEnywAMPJKNHj066du2aVFVVJX369ElGjx69yfM3J1q5qnmSJMkzzzyTnHDCCUl9fX1SVVWV9OzZM/mXf/mX5Jprrtnqc//nf/4n2X333ZPq6upk0KBByc9//vNk7NixVjUH2Iy2Mkb84x//SL761a8m/fr1S6qqqpL6+vpk9OjRyV//+temY958883k3//935NevXol7dq1SxoaGpLzzz8/Wb16ddMxv/3tb5NRo0Ylffr0Saqrq5P6+vrk2GOPTR566KFm57v55puTIUOGJFVVVU2rXr/++uvJuHHjkiFDhiQ77bRT0rFjx2SfffZJ/vu//7vZCtab09jYmPTv3z8588wzN/na5sa/JEmSZ599NhkzZkzSuXPnpLq6Ohk2bNgmr+mW3oMtuf7665PDDz886dGjR1JdXZ307t07OeGEE5I///nPzY674oorkgEDBiSVlZWbvJeteR83rjb+xBNPJGPGjEk6duyY1NXVJSeddFLy+uuvNztXQ0NDMnr06OTWW29N9txzz6S6ujrp379/8sMf/rDZcS2tar506dJmx75/xe4kSZJly5Ylp556atKlS5ekQ4cOyZFHHpk88sgjSUQkV1555VZfu5dffjn53Oc+l3Tr1i2pqqpKBg8enHzve99rupvKe/v4ve99b5PnRytWT1+zZk1yzjnnJH369Elqa2uT/fbbL7n99ttb/XvKggULkqOOOiqpq6tLIqLpOa1Z1Xyj1v6c3nvvvU3vMbxfJkneM78UAAB2kB/84Afx7W9/O1599dVo3759sbtTUBMnToyLL744li5dutXrn/v37x977bVX/Pa3v91Bvfs/N910U3z+85+PP/3pT+5wkqOTTz45XnrppfjTn/5U7K7QBplqDgBAUYwfPz6uuuqqmDRpUpxzzjnF7k7Zufnmm+PVV1+NvffeOyoqKuKRRx6J733ve3HooYcqunP04osvxi23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xtKlS6NDhw7Rrp1SAlrLTwsAANusZ8+eERFNxTelr6KiIvr16+dDFsiBwhsAgG2WyWSiV69eUV9fH+vWrSt2d9gBqquro6LCFauQC4U3AADbrbKy0jW/AFvgoyrYQcaNGxcf//jH89beiBEj4qyzzspbewAAQGFIvClpjdkkHpu/LJasXB31dbVxwICuUVmR7uuR1q1b17SKLAAA0PZJvClZd/9lURxy2X1x0k8fia9OfTpO+ukjcchl98Xdf1lU0PPeeuutsffee0f79u2jW7duccQRR8T/+3//L66//vq44447IpPJRCaTiZkzZ0ZExLnnnhuDBg2KDh06xMCBA+Oiiy5qdo3cxIkTY999942f//znMXDgwKipqYmxY8fGAw88EFdeeWVTewsWLCjo9wUAAGwbiTcl6e6/LIozfvlkJO/bv/it1XHGL5+MyV/YL47Zq1fez7to0aI46aST4vLLL49PfOITsXLlynjooYfilFNOiYULF8aKFStiypQpERHRtWvXiIioq6uL6667Lnr37h3PPvtsnH766VFXVxf/+Z//2dTuCy+8ENOmTYvbbrstKisro6GhIf72t7/FXnvtFd/61rciIqJ79+55/34AAIDtp/Cm5DRmk7j4zrmbFN0REUlEZCLi4jvnxpFDe+Z92vmiRYti/fr18clPfjIaGhoiImLvvfeOiIj27dvHmjVrmm67stGFF17Y9Pf+/fvH17/+9bjllluaFd5r166NX/ziF82K6+rq6ujQocMm7QEAAG2LqeaUnMfmL4tFb63e4teTiFj01up4bP6yvJ972LBhMXLkyNh7773jM5/5TPz0pz+Nf/zjHy0+59Zbb41DDjkkevbsGR07doyLLrooFi5c2OyYhoYGiTYAAKSUwpuSs2TllovubTkuF5WVlTFjxoz4/e9/H0OHDo0f//jHMXjw4Jg/f/5mj3/kkUfis5/9bIwaNSp++9vfxlNPPRUXXHBBrF27ttlxO+20U977CgAA7BimmlNy6utq83pcrjKZTBx88MFx8MEHxze/+c1oaGiI6dOnR3V1dTQ2NjY79k9/+lM0NDTEBRdc0LTv5ZdfbtV5NtceAADQ9ii8KTkHDOgavTrXxuK3Vm/2Ou9MRPTsvOHWYvn26KOPxr333htHHXVU1NfXx6OPPhpLly6NPfbYI1avXh3/+7//G/PmzYtu3bpF586dY7fddouFCxfG1KlT48Mf/nDcddddMX369Fadq3///vHoo4/GggULomPHjtG1a9eoqDCJBQAA2hq/pVNyKisyMWHM0IjYUGS/18bHE8YMLcj9vDt16hQPPvhgHHvssTFo0KC48MIL4wc/+EGMGjUqTj/99Bg8eHDsv//+0b179/jTn/4Uxx9/fJx99tnx5S9/Ofbdd994+OGH46KLLmrVuc4555yorKyMoUOHRvfu3Te5LhwAAGgbMkmSbC4UhKJavXp1zJ8/PwYMGBC1tds2JfzuvyyKi++c22yhtV6da2PCmKEFuZUY2y8f7zsAALQ1pppTso7Zq1ccObRnPDZ/WSxZuTrq6zZMLy9E0g0AALAlCm9KWmVFJg7atVuxuwEAAJQx13gDAABAASm8AQAAoIAU3gAAAFBACm8AAAAoIIU3AAAAFJDCGwAAAApI4Q0AAAAFpPCGFJg4cWLsu+++xe4GAACwDRTeAAAAUEDtit0BKKhsY8TLD0e8/XpExx4RDcMjKiqL3SsAAKCMSLwpXXN/E3HFXhHXfyzittM2/HnFXhv2F1CSJHH55ZfHwIEDo3379jFs2LC49dZbIyJi5syZkclk4t577439998/OnToEMOHD4958+Y1a+O73/1u9OjRI+rq6uK0006L1atXF7TPAABA4Si8KU1zfxMx7ZSIFa81379i0Yb9BSy+L7zwwpgyZUpMnjw55syZE2effXZ84QtfiAceeKDpmAsuuCB+8IMfxOOPPx7t2rWLL37xi01fmzZtWkyYMCG+/e1vx+OPPx69evWKq6++umD9BQAACiuTJElS7E7A+61evTrmz58fAwYMiNra2tyenG3ckGy/v+hukono1DvirGfzPu181apVsfPOO8d9990XBx10UNP+L33pS/HOO+/Ev/7rv8bhhx8ef/jDH2LkyJEREfG73/0uRo8eHe+++27U1tbG8OHDY9iwYTF58uSm53/kIx+J1atXx9NPP53X/rY12/W+AwBAGyXxpvS8/HALRXdERBKx4tUNx+XZ3LlzY/Xq1XHkkUdGx44dm7YbbrghXnzxxabj9tlnn6a/9+rVKyIilixZEhERzz33XLOiPSI2eQwAAKSHxdUoPW+/nt/jcpDNZiMi4q677oo+ffo0+1pNTU1T8V1VVdW0P5PJNHsuAABQWiTelJ6OPfJ7XA6GDh0aNTU1sXDhwthtt92abX379m1VG3vssUc88sgjzfa9/zEAAJAeEm9KT8PwDddwr1gUEZtbwuCf13g3DM/7qevq6uKcc86Js88+O7LZbBxyyCGxYsWKePjhh6Njx47R0NCw1Ta++tWvxtixY2P//fePQw45JG688caYM2dODBw4MO/9BQAACk/hTempqIw45rINq5dHJpoX3xumdccx3y3Y/bwvueSSqK+vj0svvTReeuml6NKlS+y3337xjW98o1XTyU888cR48cUX49xzz43Vq1fHpz71qTjjjDPif//3fwvSXwAAoLCsak6blJfVref+JuLuc5svtNapz4aie+hx+ekoeWVVcwAASpHEm9I19LiIIaM3rF7+9usbruluGF6wpBsAAGBzFN6UtorKiAEfLXYvAACAMmZVcwAAACgghTcAAAAUkMKbNs3af+XF+w0AQClSeNMmVVVVRUTEO++8U+SesCNtfL83vv8AAFAKLK5Gm1RZWRldunSJJUuWREREhw4dIpPJFLlXFEqSJPHOO+/EkiVLokuXLlFZaeV5AABKh/t402YlSRKLFy+O5cuXF7sr7CBdunSJnj17+pAFAICSovCmzWtsbIx169YVuxsUWFVVlaQbAICSpPAGAACAArK4GgAAABSQwhsAAAAKSOENAAAABaTwBgAAgAJSeAMAAEABKbwBAACggBTeAAAAUED/Hy7XDBKQ7I8WAAAAAElFTkSuQmCC",
|
|
"text/plain": [
|
|
"<Figure size 1000x700 with 4 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"class IDS(object):\n",
|
|
" def solve(self, problem: Problem):\n",
|
|
" node = None\n",
|
|
" depth = 0\n",
|
|
"\n",
|
|
" # YOUR CODE HERE\n",
|
|
" while node is None:\n",
|
|
" dldfs_search = DLDFS_Recursive(depth)\n",
|
|
" node = dldfs_search.solve(problem)\n",
|
|
" depth += 1\n",
|
|
"\n",
|
|
" return node\n",
|
|
" \n",
|
|
"ids_search = IDS()\n",
|
|
"maze.reset() # resets maze for hidden tests\n",
|
|
"ids_solution = ids_search.solve(maze)\n",
|
|
"\n",
|
|
"if ids_solution is not None:\n",
|
|
" ids_solution.pretty_print()\n",
|
|
" maze.visualize(sequences=[('ids', ids_solution.get_action_sequence())])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 87,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "05b85a83571ad65322ac4af47727e218",
|
|
"grade": true,
|
|
"grade_id": "cell-36d9e04df571467f",
|
|
"locked": true,
|
|
"points": 0.5,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Queue [Node(id:139993249005168, parent:139994341380400, state:(0, 0), action:None, cost:0, depth:0)]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"assert(ids_solution is not None), \"your algorithm did not return a solution\"\n",
|
|
"assert(ids_solution is not None or isinstance(ids_solution, type(maze.get_start_node()))), \"your solution is not of the right type\"\n",
|
|
"assert(ids_solution.state == (4, 4)), \"your algorithm did not return the expected solution\"\n",
|
|
"\n",
|
|
"assert(ids_solution.cost == 20), \"the solution found by your algorithm did not return the expected cost\"\n",
|
|
"assert(ids_solution.depth == 8), \"the solution found by your algorithm does not have the expected length\"\n",
|
|
"\n",
|
|
"ids_expanded_nodes = maze.get_number_of_expanded_nodes()\n",
|
|
"bfs_search = BFS()\n",
|
|
"maze.reset() # resets maze for hidden tests\n",
|
|
"bfs_solution = bfs_search.solve(maze)\n",
|
|
"bfs_expanded_nodes = maze.get_number_of_expanded_nodes()\n",
|
|
"assert(ids_expanded_nodes > bfs_expanded_nodes), \"the solution found by your algorithm is expected to have more expanded nodes than your solution for BFS.\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Check different mazes"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 88,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "d2957d5766c737d2afc1045b5ccaf34f",
|
|
"grade": true,
|
|
"grade_id": "cell-951813681d37fac0",
|
|
"locked": true,
|
|
"points": 0.1,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"ids_search = IDS()\n",
|
|
"tiny0 = factory.create_problem_from_json(json_path='boards/tiny0.json')\n",
|
|
"ids_solution = ids_search.solve(tiny0)\n",
|
|
"assert(ids_solution.state == (4, 4)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(ids_solution.get_action_sequence_hash() == 'c283a9803562a0053fc1ea0c30d421e0b4a7a9f599c699d74477cbeeffec23bc'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 89,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "458ff494791981e923559334759eb463",
|
|
"grade": true,
|
|
"grade_id": "cell-90bd1d9cace41b93",
|
|
"locked": true,
|
|
"points": 0.1,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"ids_search = IDS()\n",
|
|
"tiny1 = factory.create_problem_from_json(json_path='boards/tiny1.json')\n",
|
|
"ids_solution = ids_search.solve(tiny1)\n",
|
|
"assert(ids_solution.state == (2, 4)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(ids_solution.get_action_sequence_hash() == '66ec8af4739b256cec553c3d2c2cbacbc1fd4c853859c633e44996eed1f6021c'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 90,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "269cd4b03aa9fa4ccd4b09cf9982420b",
|
|
"grade": true,
|
|
"grade_id": "cell-f38380f9ab502704",
|
|
"locked": true,
|
|
"points": 0.1,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"ids_search = IDS()\n",
|
|
"tiny2 = factory.create_problem_from_json(json_path='boards/tiny2.json')\n",
|
|
"ids_solution = ids_search.solve(tiny2)\n",
|
|
"assert(ids_solution.state == (2, 2)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(ids_solution.get_action_sequence_hash() == '5bda40f5b72290920507aa1d23329fb5a3445346372a30bd35cc85f743c439ac'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 91,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "5962b78731fc9cc9fad3645abc3d69ab",
|
|
"grade": true,
|
|
"grade_id": "cell-58d667cc9d701e52",
|
|
"locked": true,
|
|
"points": 0.1,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"ids_search = IDS()\n",
|
|
"tiny3 = factory.create_problem_from_json(json_path='boards/tiny3.json')\n",
|
|
"ids_solution = ids_search.solve(tiny3)\n",
|
|
"assert(ids_solution.state == (2, 2)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(ids_solution.get_action_sequence_hash() == 'e1c95ac72da74163d0c237b69f99dc766c1bbe5e4270fd2934b721d5eab9de31'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 92,
|
|
"metadata": {
|
|
"deletable": false,
|
|
"editable": false,
|
|
"nbgrader": {
|
|
"cell_type": "code",
|
|
"checksum": "c4d100fafaf5c914e3329ac98c1ecec0",
|
|
"grade": true,
|
|
"grade_id": "cell-768a694fd1d7c870",
|
|
"locked": true,
|
|
"points": 0.1,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"ids_search = IDS()\n",
|
|
"tiny4 = factory.create_problem_from_json(json_path='boards/tiny4.json')\n",
|
|
"ids_solution = ids_search.solve(tiny4)\n",
|
|
"assert(ids_solution.state == (4, 4)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(ids_solution.get_action_sequence_hash() == '0123d362bf2df8f84e7c41197827be005159724c07774ef32d9f15373a440091'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 93,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"ids_search = IDS()\n",
|
|
"cyclic_map = factory.create_problem_from_json(json_path='boards/cyclic_map.json')\n",
|
|
"ids_solution = ids_search.solve(cyclic_map)\n",
|
|
"assert(ids_solution.state == (2, 2)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(ids_solution.get_action_sequence_hash() == 'e1c95ac72da74163d0c237b69f99dc766c1bbe5e4270fd2934b721d5eab9de31'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 94,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"ids_search = IDS()\n",
|
|
"narrow_path = factory.create_problem_from_json(json_path='boards/narrow_path.json')\n",
|
|
"ids_solution = ids_search.solve(narrow_path)\n",
|
|
"assert(ids_solution.state == (2, 4)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(ids_solution.get_action_sequence_hash() == '2ee4599132a71cf20e4feae6aff58b9ff77ea9486fb0e12225ddd8896ccb9843'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 95,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# this is a testing cell, do not edit or delete\n",
|
|
"\n",
|
|
"ids_search = IDS()\n",
|
|
"start_is_goal = factory.create_problem_from_json(json_path='boards/start_is_goal.json')\n",
|
|
"ids_solution = ids_search.solve(start_is_goal)\n",
|
|
"assert(ids_solution.state == (0, 0)), \"your algorithm did not return the expected solution\"\n",
|
|
"assert(ids_solution.get_action_sequence_hash() == 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'), \"your algorithm did not return the expected solution path\""
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 3 (ipykernel)",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.13.7"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 4
|
|
}
|