|
15 | 15 | },
|
16 | 16 | {
|
17 | 17 | "cell_type": "code",
|
18 |
| - "execution_count": 3, |
| 18 | + "execution_count": 1, |
19 | 19 | "metadata": {
|
20 | 20 | "collapsed": true,
|
21 | 21 | "deletable": true,
|
|
627 | 627 | "solve_parameters.nassigns"
|
628 | 628 | ]
|
629 | 629 | },
|
| 630 | + { |
| 631 | + "cell_type": "markdown", |
| 632 | + "metadata": {}, |
| 633 | + "source": [ |
| 634 | + "## Tree CSP Solver\n", |
| 635 | + "\n", |
| 636 | + "The `tree_csp_solver` function (**Figure 6.11** in the book) can be used to solve problems whose constraint graph is a tree. Given a CSP, with `neighbors` forming a tree, it returns an assignement that satisfies the given constraints. The algorithm works as follows:\n", |
| 637 | + "\n", |
| 638 | + "First it finds the *topological sort* of the tree. This is an ordering of the tree where each variable/node comes after its parent in the tree. The function that accomplishes this is `topological_sort`, which builds the topological sort using the recursive function `build_topological`. That function is an augmented DFS, where each newly visited node of the tree is pushed on a stack. The stack in the end holds the variables topologically sorted.\n", |
| 639 | + "\n", |
| 640 | + "Then the algorithm makes arcs between each parent and child consistent. *Arc-consistency* between two variables, *a* and *b*, occurs when for every possible value of *a* there is an assignment in *b* that satisfies the problem's constraints. If such an assignment cannot be found, then the problematic value is removed from *a*'s possible values. This is done with the use of the function `make_arc_consistent` which takes as arguments a variable `Xj` and its parent, and makes the arc between them consistent by removing any values from the parent which do not allow for a consistent assignment in `Xj`.\n", |
| 641 | + "\n", |
| 642 | + "If an arc cannot be made consistent, the solver fails. If every arc is made consistent, we move to assigning values.\n", |
| 643 | + "\n", |
| 644 | + "First we assign a random value to the root from its domain and then we start assigning values to the rest of the variables. Since the graph is now arc-consistent, we can simply move from variable to variable picking any remaining consistent values. At the end we are left with a valid assignment. If at any point though we find a variable where no consistent value is left in its domain, the solver fails.\n", |
| 645 | + "\n", |
| 646 | + "The implementation of the algorithm:" |
| 647 | + ] |
| 648 | + }, |
| 649 | + { |
| 650 | + "cell_type": "code", |
| 651 | + "execution_count": 2, |
| 652 | + "metadata": { |
| 653 | + "collapsed": true |
| 654 | + }, |
| 655 | + "outputs": [], |
| 656 | + "source": [ |
| 657 | + "%psource tree_csp_solver" |
| 658 | + ] |
| 659 | + }, |
| 660 | + { |
| 661 | + "cell_type": "markdown", |
| 662 | + "metadata": {}, |
| 663 | + "source": [ |
| 664 | + "We will now use the above function to solve a problem. More specifically, we will solve the problem of coloring the map of Australia. At our disposal we have two colors: Red and Blue. As a reminder, this is the graph of Australia:\n", |
| 665 | + "\n", |
| 666 | + "`\"SA: WA NT Q NSW V; NT: WA Q; NSW: Q V; T: \"`\n", |
| 667 | + "\n", |
| 668 | + "Unfortunately as you can see the above is not a tree. If, though, we remove `SA`, which has arcs to `WA`, `NT`, `Q`, `NSW` and `V`, we are left with a tree (we also remove `T`, since it has no in-or-out arcs). We can now solve this using our algorithm. Let's define the map coloring problem at hand:" |
| 669 | + ] |
| 670 | + }, |
| 671 | + { |
| 672 | + "cell_type": "code", |
| 673 | + "execution_count": 4, |
| 674 | + "metadata": { |
| 675 | + "collapsed": true |
| 676 | + }, |
| 677 | + "outputs": [], |
| 678 | + "source": [ |
| 679 | + "australia_small = MapColoringCSP(list('RB'),\n", |
| 680 | + " 'NT: WA Q; NSW: Q V')" |
| 681 | + ] |
| 682 | + }, |
| 683 | + { |
| 684 | + "cell_type": "markdown", |
| 685 | + "metadata": {}, |
| 686 | + "source": [ |
| 687 | + "We will input `australia_small` to the `tree_csp_solver` and we will print the given assignment." |
| 688 | + ] |
| 689 | + }, |
| 690 | + { |
| 691 | + "cell_type": "code", |
| 692 | + "execution_count": 5, |
| 693 | + "metadata": { |
| 694 | + "collapsed": false |
| 695 | + }, |
| 696 | + "outputs": [ |
| 697 | + { |
| 698 | + "name": "stdout", |
| 699 | + "output_type": "stream", |
| 700 | + "text": [ |
| 701 | + "{'WA': 'B', 'NT': 'R', 'Q': 'B', 'V': 'B', 'NSW': 'R'}\n" |
| 702 | + ] |
| 703 | + } |
| 704 | + ], |
| 705 | + "source": [ |
| 706 | + "assignment = tree_csp_solver(australia_small)\n", |
| 707 | + "print(assignment)" |
| 708 | + ] |
| 709 | + }, |
| 710 | + { |
| 711 | + "cell_type": "markdown", |
| 712 | + "metadata": {}, |
| 713 | + "source": [ |
| 714 | + "`WA`, `Q` and `V` got painted Blue, while `NT` and `NSW` got painted Red." |
| 715 | + ] |
| 716 | + }, |
630 | 717 | {
|
631 | 718 | "cell_type": "markdown",
|
632 | 719 | "metadata": {
|
|
0 commit comments