From 79359461b71553663f3340a0ee30c7e87bfcf97d Mon Sep 17 00:00:00 2001 From: Antonis Maronikolakis Date: Wed, 29 Mar 2017 01:16:59 +0300 Subject: [PATCH] Update csp.ipynb --- csp.ipynb | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) diff --git a/csp.ipynb b/csp.ipynb index 66c7eac6d..5255ff1d8 100644 --- a/csp.ipynb +++ b/csp.ipynb @@ -15,7 +15,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 1, "metadata": { "collapsed": true, "deletable": true, @@ -627,6 +627,93 @@ "solve_parameters.nassigns" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Tree CSP Solver\n", + "\n", + "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", + "\n", + "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", + "\n", + "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", + "\n", + "If an arc cannot be made consistent, the solver fails. If every arc is made consistent, we move to assigning values.\n", + "\n", + "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", + "\n", + "The implementation of the algorithm:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "%psource tree_csp_solver" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "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", + "\n", + "`\"SA: WA NT Q NSW V; NT: WA Q; NSW: Q V; T: \"`\n", + "\n", + "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:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "australia_small = MapColoringCSP(list('RB'),\n", + " 'NT: WA Q; NSW: Q V')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will input `australia_small` to the `tree_csp_solver` and we will print the given assignment." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'WA': 'B', 'NT': 'R', 'Q': 'B', 'V': 'B', 'NSW': 'R'}\n" + ] + } + ], + "source": [ + "assignment = tree_csp_solver(australia_small)\n", + "print(assignment)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`WA`, `Q` and `V` got painted Blue, while `NT` and `NSW` got painted Red." + ] + }, { "cell_type": "markdown", "metadata": {