|
60 | 60 | },
|
61 | 61 | {
|
62 | 62 | "cell_type": "code",
|
63 |
| - "execution_count": 4, |
| 63 | + "execution_count": 3, |
64 | 64 | "metadata": {
|
65 | 65 | "collapsed": false
|
66 | 66 | },
|
|
71 | 71 | "['R', 'G', 'B']"
|
72 | 72 | ]
|
73 | 73 | },
|
74 |
| - "execution_count": 4, |
| 74 | + "execution_count": 3, |
75 | 75 | "metadata": {},
|
76 | 76 | "output_type": "execute_result"
|
77 | 77 | }
|
|
90 | 90 | },
|
91 | 91 | {
|
92 | 92 | "cell_type": "code",
|
93 |
| - "execution_count": 5, |
| 93 | + "execution_count": 4, |
94 | 94 | "metadata": {
|
95 | 95 | "collapsed": true
|
96 | 96 | },
|
|
108 | 108 | },
|
109 | 109 | {
|
110 | 110 | "cell_type": "code",
|
111 |
| - "execution_count": 6, |
| 111 | + "execution_count": 5, |
112 | 112 | "metadata": {
|
113 | 113 | "collapsed": true
|
114 | 114 | },
|
|
117 | 117 | "%pdoc parse_neighbors"
|
118 | 118 | ]
|
119 | 119 | },
|
| 120 | + { |
| 121 | + "cell_type": "markdown", |
| 122 | + "metadata": {}, |
| 123 | + "source": [ |
| 124 | + "The **MapColoringCSP** function creates and returns a CSP with the above constraint function and states. The variables our the keys of the neighbors dict and the constraint is the one specified by the **different_values_constratint** function. **australia**, **usa** and **france** are three CSPs that have been created using **MapColoringCSP**. **australia** corresponds to ** Figure 6.1 ** in the book." |
| 125 | + ] |
| 126 | + }, |
| 127 | + { |
| 128 | + "cell_type": "code", |
| 129 | + "execution_count": 6, |
| 130 | + "metadata": { |
| 131 | + "collapsed": true |
| 132 | + }, |
| 133 | + "outputs": [], |
| 134 | + "source": [ |
| 135 | + "%psource MapColoringCSP" |
| 136 | + ] |
| 137 | + }, |
| 138 | + { |
| 139 | + "cell_type": "code", |
| 140 | + "execution_count": 7, |
| 141 | + "metadata": { |
| 142 | + "collapsed": false |
| 143 | + }, |
| 144 | + "outputs": [ |
| 145 | + { |
| 146 | + "data": { |
| 147 | + "text/plain": [ |
| 148 | + "(<csp.CSP at 0x7f9da0d9aa58>,\n", |
| 149 | + " <csp.CSP at 0x7f9da0da0ac8>,\n", |
| 150 | + " <csp.CSP at 0x7f9da0d2a080>)" |
| 151 | + ] |
| 152 | + }, |
| 153 | + "execution_count": 7, |
| 154 | + "metadata": {}, |
| 155 | + "output_type": "execute_result" |
| 156 | + } |
| 157 | + ], |
| 158 | + "source": [ |
| 159 | + "australia, usa, france" |
| 160 | + ] |
| 161 | + }, |
| 162 | + { |
| 163 | + "cell_type": "markdown", |
| 164 | + "metadata": {}, |
| 165 | + "source": [ |
| 166 | + "### Helper Functions\n", |
| 167 | + "\n", |
| 168 | + "We will now implement few helper functions that will help us visualize the Coloring Problem. We will make some modifications to the existing Classes and Functions for additional book keeping. To begin with we modify the **assign** and **unassign** methods in the **CSP** to add a copy of the assignment to the **assingment_history**. We call this new class **InstruCSP**. This would allow us to see how the assignment evolves over time." |
| 169 | + ] |
| 170 | + }, |
| 171 | + { |
| 172 | + "cell_type": "code", |
| 173 | + "execution_count": 8, |
| 174 | + "metadata": { |
| 175 | + "collapsed": true |
| 176 | + }, |
| 177 | + "outputs": [], |
| 178 | + "source": [ |
| 179 | + "import copy\n", |
| 180 | + "class InstruCSP(CSP):\n", |
| 181 | + " \n", |
| 182 | + " def __init__(self, variables, domains, neighbors, constraints):\n", |
| 183 | + " super().__init__(variables, domains, neighbors, constraints)\n", |
| 184 | + " self.assingment_history = []\n", |
| 185 | + " \n", |
| 186 | + " def assign(self, var, val, assignment):\n", |
| 187 | + " super().assign(var,val, assignment)\n", |
| 188 | + " self.assingment_history.append(copy.deepcopy(assignment))\n", |
| 189 | + " \n", |
| 190 | + " def unassign(self, var, assignment):\n", |
| 191 | + " super().unassign(var,assignment)\n", |
| 192 | + " self.assingment_history.append(copy.deepcopy(assignment)) " |
| 193 | + ] |
| 194 | + }, |
| 195 | + { |
| 196 | + "cell_type": "markdown", |
| 197 | + "metadata": {}, |
| 198 | + "source": [ |
| 199 | + "Next, we modify the **MapColoringCSP** function to use the **InstruCSP**. " |
| 200 | + ] |
| 201 | + }, |
| 202 | + { |
| 203 | + "cell_type": "code", |
| 204 | + "execution_count": 9, |
| 205 | + "metadata": { |
| 206 | + "collapsed": true |
| 207 | + }, |
| 208 | + "outputs": [], |
| 209 | + "source": [ |
| 210 | + "def ModMapColoringCSP(colors, neighbors):\n", |
| 211 | + " if isinstance(neighbors, str):\n", |
| 212 | + " neighbors = parse_neighbors(neighbors)\n", |
| 213 | + " return InstruCSP(list(neighbors.keys()), UniversalDict(colors), neighbors,\n", |
| 214 | + " different_values_constraint)" |
| 215 | + ] |
| 216 | + }, |
| 217 | + { |
| 218 | + "cell_type": "markdown", |
| 219 | + "metadata": {}, |
| 220 | + "source": [ |
| 221 | + "We will now use the france graph for plotting purposes. The **parse_neighbors** function is used for parsing them." |
| 222 | + ] |
| 223 | + }, |
120 | 224 | {
|
121 | 225 | "cell_type": "code",
|
122 |
| - "execution_count": null, |
| 226 | + "execution_count": 10, |
123 | 227 | "metadata": {
|
124 | 228 | "collapsed": true
|
125 | 229 | },
|
126 | 230 | "outputs": [],
|
127 |
| - "source": [] |
| 231 | + "source": [ |
| 232 | + "neighbors = parse_neighbors(\"\"\"AL: LO FC; AQ: MP LI PC; AU: LI CE BO RA LR MP; BO: CE IF CA FC RA\n", |
| 233 | + " AU; BR: NB PL; CA: IF PI LO FC BO; CE: PL NB NH IF BO AU LI PC; FC: BO\n", |
| 234 | + " CA LO AL RA; IF: NH PI CA BO CE; LI: PC CE AU MP AQ; LO: CA AL FC; LR:\n", |
| 235 | + " MP AU RA PA; MP: AQ LI AU LR; NB: NH CE PL BR; NH: PI IF CE NB; NO:\n", |
| 236 | + " PI; PA: LR RA; PC: PL CE LI AQ; PI: NH NO CA IF; PL: BR NB CE PC; RA:\n", |
| 237 | + " AU BO FC PA LR\"\"\")" |
| 238 | + ] |
| 239 | + }, |
| 240 | + { |
| 241 | + "cell_type": "markdown", |
| 242 | + "metadata": {}, |
| 243 | + "source": [ |
| 244 | + "Now we are ready to create an InstruCSP instance for our problem." |
| 245 | + ] |
| 246 | + }, |
| 247 | + { |
| 248 | + "cell_type": "code", |
| 249 | + "execution_count": 11, |
| 250 | + "metadata": { |
| 251 | + "collapsed": true |
| 252 | + }, |
| 253 | + "outputs": [], |
| 254 | + "source": [ |
| 255 | + "coloring_problem1 = ModMapColoringCSP('RGBY', neighbors)" |
| 256 | + ] |
| 257 | + }, |
| 258 | + { |
| 259 | + "cell_type": "markdown", |
| 260 | + "metadata": {}, |
| 261 | + "source": [ |
| 262 | + "# Backtracking Search\n", |
| 263 | + "\n", |
| 264 | + "For solving a CSP the main issue with Naive search algorithms is that they can continue expanding obviously wrong paths. In backtracking search, we check constraints as we go. Backtracking is just the above idea combined with the fact that we are dealing with one variable at a time. Backtracking Search is implemented in the repository as the function **backtracking_search**. This is the same as **Figure 6.5** in the book. The function takes as input a CSP and few other optional parameters which can be used to further speed it up. The function returns the correct assignment if it satisfies the goal. We will discuss these later. Let us solve our **coloring_problem1** with **backtracking_search**.\n" |
| 265 | + ] |
| 266 | + }, |
| 267 | + { |
| 268 | + "cell_type": "code", |
| 269 | + "execution_count": 12, |
| 270 | + "metadata": { |
| 271 | + "collapsed": true |
| 272 | + }, |
| 273 | + "outputs": [], |
| 274 | + "source": [ |
| 275 | + "result = backtracking_search(coloring_problem1)" |
| 276 | + ] |
| 277 | + }, |
| 278 | + { |
| 279 | + "cell_type": "code", |
| 280 | + "execution_count": 13, |
| 281 | + "metadata": { |
| 282 | + "collapsed": false |
| 283 | + }, |
| 284 | + "outputs": [ |
| 285 | + { |
| 286 | + "data": { |
| 287 | + "text/plain": [ |
| 288 | + "{'AL': 'R',\n", |
| 289 | + " 'AQ': 'B',\n", |
| 290 | + " 'AU': 'G',\n", |
| 291 | + " 'BO': 'B',\n", |
| 292 | + " 'BR': 'Y',\n", |
| 293 | + " 'CA': 'R',\n", |
| 294 | + " 'CE': 'R',\n", |
| 295 | + " 'FC': 'Y',\n", |
| 296 | + " 'IF': 'G',\n", |
| 297 | + " 'LI': 'Y',\n", |
| 298 | + " 'LO': 'G',\n", |
| 299 | + " 'LR': 'Y',\n", |
| 300 | + " 'MP': 'R',\n", |
| 301 | + " 'NB': 'G',\n", |
| 302 | + " 'NH': 'B',\n", |
| 303 | + " 'NO': 'R',\n", |
| 304 | + " 'PA': 'G',\n", |
| 305 | + " 'PC': 'G',\n", |
| 306 | + " 'PI': 'Y',\n", |
| 307 | + " 'PL': 'B',\n", |
| 308 | + " 'RA': 'R'}" |
| 309 | + ] |
| 310 | + }, |
| 311 | + "execution_count": 13, |
| 312 | + "metadata": {}, |
| 313 | + "output_type": "execute_result" |
| 314 | + } |
| 315 | + ], |
| 316 | + "source": [ |
| 317 | + "result # A dictonary of assingments." |
| 318 | + ] |
| 319 | + }, |
| 320 | + { |
| 321 | + "cell_type": "markdown", |
| 322 | + "metadata": {}, |
| 323 | + "source": [ |
| 324 | + "Let us also check the number of assingments made." |
| 325 | + ] |
| 326 | + }, |
| 327 | + { |
| 328 | + "cell_type": "code", |
| 329 | + "execution_count": 14, |
| 330 | + "metadata": { |
| 331 | + "collapsed": false |
| 332 | + }, |
| 333 | + "outputs": [ |
| 334 | + { |
| 335 | + "data": { |
| 336 | + "text/plain": [ |
| 337 | + "37" |
| 338 | + ] |
| 339 | + }, |
| 340 | + "execution_count": 14, |
| 341 | + "metadata": {}, |
| 342 | + "output_type": "execute_result" |
| 343 | + } |
| 344 | + ], |
| 345 | + "source": [ |
| 346 | + "coloring_problem1.nassigns" |
| 347 | + ] |
| 348 | + }, |
| 349 | + { |
| 350 | + "cell_type": "markdown", |
| 351 | + "metadata": {}, |
| 352 | + "source": [ |
| 353 | + "Now let us check the total number of assingments and unassingments which is the lentgh ofour assingment history." |
| 354 | + ] |
| 355 | + }, |
| 356 | + { |
| 357 | + "cell_type": "code", |
| 358 | + "execution_count": 15, |
| 359 | + "metadata": { |
| 360 | + "collapsed": false |
| 361 | + }, |
| 362 | + "outputs": [ |
| 363 | + { |
| 364 | + "data": { |
| 365 | + "text/plain": [ |
| 366 | + "53" |
| 367 | + ] |
| 368 | + }, |
| 369 | + "execution_count": 15, |
| 370 | + "metadata": {}, |
| 371 | + "output_type": "execute_result" |
| 372 | + } |
| 373 | + ], |
| 374 | + "source": [ |
| 375 | + "len(coloring_problem1.assingment_history)" |
| 376 | + ] |
128 | 377 | }
|
129 | 378 | ],
|
130 | 379 | "metadata": {
|
|
0 commit comments