From 5693ec89b1da3ffe5ba0281092a192e46a1324f6 Mon Sep 17 00:00:00 2001 From: uldiskk Date: Mon, 6 May 2024 17:29:03 +0300 Subject: [PATCH 1/6] Update to 6x7 grid and some fixes for the 4th edition --- .coveragerc | 3 - .gitignore | 1 + mdp.py | 492 - mdp4e.py | 19 +- .../Passive Reinforcement Learning.html | 8338 +++++++++++++++++ .../Passive Reinforcement Learning.ipynb | 410 +- notebooks/chapter21/images/grid_mdp_4x7.jpg | Bin 0 -> 18622 bytes .../chapter21/images/grid_mdp_4x7_array.jpg | Bin 0 -> 18080 bytes reinforcement_learning.ipynb | 107 +- reinforcement_learning4e.py | 32 +- 10 files changed, 8791 insertions(+), 611 deletions(-) delete mode 100644 .coveragerc delete mode 100644 mdp.py create mode 100644 notebooks/chapter21/Passive Reinforcement Learning.html create mode 100644 notebooks/chapter21/images/grid_mdp_4x7.jpg create mode 100644 notebooks/chapter21/images/grid_mdp_4x7_array.jpg diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index 2398f62e3..000000000 --- a/.coveragerc +++ /dev/null @@ -1,3 +0,0 @@ -[report] -omit = - tests/* \ No newline at end of file diff --git a/.gitignore b/.gitignore index 58e83214e..931f87586 100644 --- a/.gitignore +++ b/.gitignore @@ -76,3 +76,4 @@ target/ # for macOS .DS_Store ._.DS_Store +.vscode/settings.json diff --git a/mdp.py b/mdp.py deleted file mode 100644 index 1003e26b5..000000000 --- a/mdp.py +++ /dev/null @@ -1,492 +0,0 @@ -""" -Markov Decision Processes (Chapter 17) - -First we define an MDP, and the special case of a GridMDP, in which -states are laid out in a 2-dimensional grid. We also represent a policy -as a dictionary of {state: action} pairs, and a Utility function as a -dictionary of {state: number} pairs. We then define the value_iteration -and policy_iteration algorithms. -""" - -import random -from collections import defaultdict - -import numpy as np - -from utils import vector_add, orientations, turn_right, turn_left - - -class MDP: - """A Markov Decision Process, defined by an initial state, transition model, - and reward function. We also keep track of a gamma value, for use by - algorithms. The transition model is represented somewhat differently from - the text. Instead of P(s' | s, a) being a probability number for each - state/state/action triplet, we instead have T(s, a) return a - list of (p, s') pairs. We also keep track of the possible states, - terminal states, and actions for each state. [Page 646]""" - - def __init__(self, init, actlist, terminals, transitions=None, reward=None, states=None, gamma=0.9): - if not (0 < gamma <= 1): - raise ValueError("An MDP must have 0 < gamma <= 1") - - # collect states from transitions table if not passed. - self.states = states or self.get_states_from_transitions(transitions) - - self.init = init - - if isinstance(actlist, list): - # if actlist is a list, all states have the same actions - self.actlist = actlist - - elif isinstance(actlist, dict): - # if actlist is a dict, different actions for each state - self.actlist = actlist - - self.terminals = terminals - self.transitions = transitions or {} - if not self.transitions: - print("Warning: Transition table is empty.") - - self.gamma = gamma - - self.reward = reward or {s: 0 for s in self.states} - - # self.check_consistency() - - def R(self, state): - """Return a numeric reward for this state.""" - - return self.reward[state] - - def T(self, state, action): - """Transition model. From a state and an action, return a list - of (probability, result-state) pairs.""" - - if not self.transitions: - raise ValueError("Transition model is missing") - else: - return self.transitions[state][action] - - def actions(self, state): - """Return a list of actions that can be performed in this state. By default, a - fixed list of actions, except for terminal states. Override this - method if you need to specialize by state.""" - - if state in self.terminals: - return [None] - else: - return self.actlist - - def get_states_from_transitions(self, transitions): - if isinstance(transitions, dict): - s1 = set(transitions.keys()) - s2 = set(tr[1] for actions in transitions.values() - for effects in actions.values() - for tr in effects) - return s1.union(s2) - else: - print('Could not retrieve states from transitions') - return None - - def check_consistency(self): - - # check that all states in transitions are valid - assert set(self.states) == self.get_states_from_transitions(self.transitions) - - # check that init is a valid state - assert self.init in self.states - - # check reward for each state - assert set(self.reward.keys()) == set(self.states) - - # check that all terminals are valid states - assert all(t in self.states for t in self.terminals) - - # check that probability distributions for all actions sum to 1 - for s1, actions in self.transitions.items(): - for a in actions.keys(): - s = 0 - for o in actions[a]: - s += o[0] - assert abs(s - 1) < 0.001 - - -class MDP2(MDP): - """ - Inherits from MDP. Handles terminal states, and transitions to and from terminal states better. - """ - - def __init__(self, init, actlist, terminals, transitions, reward=None, gamma=0.9): - MDP.__init__(self, init, actlist, terminals, transitions, reward, gamma=gamma) - - def T(self, state, action): - if action is None: - return [(0.0, state)] - else: - return self.transitions[state][action] - - -class GridMDP(MDP): - """A two-dimensional grid MDP, as in [Figure 17.1]. All you have to do is - specify the grid as a list of lists of rewards; use None for an obstacle - (unreachable state). Also, you should specify the terminal states. - An action is an (x, y) unit vector; e.g. (1, 0) means move east.""" - - def __init__(self, grid, terminals, init=(0, 0), gamma=.9): - grid.reverse() # because we want row 0 on bottom, not on top - reward = {} - states = set() - self.rows = len(grid) - self.cols = len(grid[0]) - self.grid = grid - for x in range(self.cols): - for y in range(self.rows): - if grid[y][x]: - states.add((x, y)) - reward[(x, y)] = grid[y][x] - self.states = states - actlist = orientations - transitions = {} - for s in states: - transitions[s] = {} - for a in actlist: - transitions[s][a] = self.calculate_T(s, a) - MDP.__init__(self, init, actlist=actlist, - terminals=terminals, transitions=transitions, - reward=reward, states=states, gamma=gamma) - - def calculate_T(self, state, action): - if action: - return [(0.8, self.go(state, action)), - (0.1, self.go(state, turn_right(action))), - (0.1, self.go(state, turn_left(action)))] - else: - return [(0.0, state)] - - def T(self, state, action): - return self.transitions[state][action] if action else [(0.0, state)] - - def go(self, state, direction): - """Return the state that results from going in this direction.""" - - state1 = vector_add(state, direction) - return state1 if state1 in self.states else state - - def to_grid(self, mapping): - """Convert a mapping from (x, y) to v into a [[..., v, ...]] grid.""" - - return list(reversed([[mapping.get((x, y), None) - for x in range(self.cols)] - for y in range(self.rows)])) - - def to_arrows(self, policy): - chars = {(1, 0): '>', (0, 1): '^', (-1, 0): '<', (0, -1): 'v', None: '.'} - return self.to_grid({s: chars[a] for (s, a) in policy.items()}) - - -# ______________________________________________________________________________ - - -""" [Figure 17.1] -A 4x3 grid environment that presents the agent with a sequential decision problem. -""" - -sequential_decision_environment = GridMDP([[-0.04, -0.04, -0.04, +1], - [-0.04, None, -0.04, -1], - [-0.04, -0.04, -0.04, -0.04]], - terminals=[(3, 2), (3, 1)]) - - -# ______________________________________________________________________________ - - -def value_iteration(mdp, epsilon=0.001): - """Solving an MDP by value iteration. [Figure 17.4]""" - - U1 = {s: 0 for s in mdp.states} - R, T, gamma = mdp.R, mdp.T, mdp.gamma - while True: - U = U1.copy() - delta = 0 - for s in mdp.states: - U1[s] = R(s) + gamma * max(sum(p * U[s1] for (p, s1) in T(s, a)) - for a in mdp.actions(s)) - delta = max(delta, abs(U1[s] - U[s])) - if delta <= epsilon * (1 - gamma) / gamma: - return U - - -def best_policy(mdp, U): - """Given an MDP and a utility function U, determine the best policy, - as a mapping from state to action. [Equation 17.4]""" - - pi = {} - for s in mdp.states: - pi[s] = max(mdp.actions(s), key=lambda a: expected_utility(a, s, U, mdp)) - return pi - - -def expected_utility(a, s, U, mdp): - """The expected utility of doing a in state s, according to the MDP and U.""" - - return sum(p * U[s1] for (p, s1) in mdp.T(s, a)) - - -# ______________________________________________________________________________ - - -def policy_iteration(mdp): - """Solve an MDP by policy iteration [Figure 17.7]""" - - U = {s: 0 for s in mdp.states} - pi = {s: random.choice(mdp.actions(s)) for s in mdp.states} - while True: - U = policy_evaluation(pi, U, mdp) - unchanged = True - for s in mdp.states: - a = max(mdp.actions(s), key=lambda a: expected_utility(a, s, U, mdp)) - if a != pi[s]: - pi[s] = a - unchanged = False - if unchanged: - return pi - - -def policy_evaluation(pi, U, mdp, k=20): - """Return an updated utility mapping U from each state in the MDP to its - utility, using an approximation (modified policy iteration).""" - - R, T, gamma = mdp.R, mdp.T, mdp.gamma - for i in range(k): - for s in mdp.states: - U[s] = R(s) + gamma * sum(p * U[s1] for (p, s1) in T(s, pi[s])) - return U - - -class POMDP(MDP): - """A Partially Observable Markov Decision Process, defined by - a transition model P(s'|s,a), actions A(s), a reward function R(s), - and a sensor model P(e|s). We also keep track of a gamma value, - for use by algorithms. The transition and the sensor models - are defined as matrices. We also keep track of the possible states - and actions for each state. [Page 659].""" - - def __init__(self, actions, transitions=None, evidences=None, rewards=None, states=None, gamma=0.95): - """Initialize variables of the pomdp""" - - if not (0 < gamma <= 1): - raise ValueError('A POMDP must have 0 < gamma <= 1') - - self.states = states - self.actions = actions - - # transition model cannot be undefined - self.t_prob = transitions or {} - if not self.t_prob: - print('Warning: Transition model is undefined') - - # sensor model cannot be undefined - self.e_prob = evidences or {} - if not self.e_prob: - print('Warning: Sensor model is undefined') - - self.gamma = gamma - self.rewards = rewards - - def remove_dominated_plans(self, input_values): - """ - Remove dominated plans. - This method finds all the lines contributing to the - upper surface and removes those which don't. - """ - - values = [val for action in input_values for val in input_values[action]] - values.sort(key=lambda x: x[0], reverse=True) - - best = [values[0]] - y1_max = max(val[1] for val in values) - tgt = values[0] - prev_b = 0 - prev_ix = 0 - while tgt[1] != y1_max: - min_b = 1 - min_ix = 0 - for i in range(prev_ix + 1, len(values)): - if values[i][0] - tgt[0] + tgt[1] - values[i][1] != 0: - trans_b = (values[i][0] - tgt[0]) / (values[i][0] - tgt[0] + tgt[1] - values[i][1]) - if 0 <= trans_b <= 1 and trans_b > prev_b and trans_b < min_b: - min_b = trans_b - min_ix = i - prev_b = min_b - prev_ix = min_ix - tgt = values[min_ix] - best.append(tgt) - - return self.generate_mapping(best, input_values) - - def remove_dominated_plans_fast(self, input_values): - """ - Remove dominated plans using approximations. - Resamples the upper boundary at intervals of 100 and - finds the maximum values at these points. - """ - - values = [val for action in input_values for val in input_values[action]] - values.sort(key=lambda x: x[0], reverse=True) - - best = [] - sr = 100 - for i in range(sr + 1): - x = i / float(sr) - maximum = (values[0][1] - values[0][0]) * x + values[0][0] - tgt = values[0] - for value in values: - val = (value[1] - value[0]) * x + value[0] - if val > maximum: - maximum = val - tgt = value - - if all(any(tgt != v) for v in best): - best.append(np.array(tgt)) - - return self.generate_mapping(best, input_values) - - def generate_mapping(self, best, input_values): - """Generate mappings after removing dominated plans""" - - mapping = defaultdict(list) - for value in best: - for action in input_values: - if any(all(value == v) for v in input_values[action]): - mapping[action].append(value) - - return mapping - - def max_difference(self, U1, U2): - """Find maximum difference between two utility mappings""" - - for k, v in U1.items(): - sum1 = 0 - for element in U1[k]: - sum1 += sum(element) - sum2 = 0 - for element in U2[k]: - sum2 += sum(element) - return abs(sum1 - sum2) - - -class Matrix: - """Matrix operations class""" - - @staticmethod - def add(A, B): - """Add two matrices A and B""" - - res = [] - for i in range(len(A)): - row = [] - for j in range(len(A[0])): - row.append(A[i][j] + B[i][j]) - res.append(row) - return res - - @staticmethod - def scalar_multiply(a, B): - """Multiply scalar a to matrix B""" - - for i in range(len(B)): - for j in range(len(B[0])): - B[i][j] = a * B[i][j] - return B - - @staticmethod - def multiply(A, B): - """Multiply two matrices A and B element-wise""" - - matrix = [] - for i in range(len(B)): - row = [] - for j in range(len(B[0])): - row.append(B[i][j] * A[j][i]) - matrix.append(row) - - return matrix - - @staticmethod - def matmul(A, B): - """Inner-product of two matrices""" - - return [[sum(ele_a * ele_b for ele_a, ele_b in zip(row_a, col_b)) for col_b in list(zip(*B))] for row_a in A] - - @staticmethod - def transpose(A): - """Transpose a matrix""" - - return [list(i) for i in zip(*A)] - - -def pomdp_value_iteration(pomdp, epsilon=0.1): - """Solving a POMDP by value iteration.""" - - U = {'': [[0] * len(pomdp.states)]} - count = 0 - while True: - count += 1 - prev_U = U - values = [val for action in U for val in U[action]] - value_matxs = [] - for i in values: - for j in values: - value_matxs.append([i, j]) - - U1 = defaultdict(list) - for action in pomdp.actions: - for u in value_matxs: - u1 = Matrix.matmul(Matrix.matmul(pomdp.t_prob[int(action)], - Matrix.multiply(pomdp.e_prob[int(action)], Matrix.transpose(u))), - [[1], [1]]) - u1 = Matrix.add(Matrix.scalar_multiply(pomdp.gamma, Matrix.transpose(u1)), [pomdp.rewards[int(action)]]) - U1[action].append(u1[0]) - - U = pomdp.remove_dominated_plans_fast(U1) - # replace with U = pomdp.remove_dominated_plans(U1) for accurate calculations - - if count > 10: - if pomdp.max_difference(U, prev_U) < epsilon * (1 - pomdp.gamma) / pomdp.gamma: - return U - - -__doc__ += """ ->>> pi = best_policy(sequential_decision_environment, value_iteration(sequential_decision_environment, .01)) - ->>> sequential_decision_environment.to_arrows(pi) -[['>', '>', '>', '.'], ['^', None, '^', '.'], ['^', '>', '^', '<']] - ->>> from utils import print_table - ->>> print_table(sequential_decision_environment.to_arrows(pi)) -> > > . -^ None ^ . -^ > ^ < - ->>> print_table(sequential_decision_environment.to_arrows(policy_iteration(sequential_decision_environment))) -> > > . -^ None ^ . -^ > ^ < -""" # noqa - -""" -s = { 'a' : { 'plan1' : [(0.2, 'a'), (0.3, 'b'), (0.3, 'c'), (0.2, 'd')], - 'plan2' : [(0.4, 'a'), (0.15, 'b'), (0.45, 'c')], - 'plan3' : [(0.2, 'a'), (0.5, 'b'), (0.3, 'c')], - }, - 'b' : { 'plan1' : [(0.2, 'a'), (0.6, 'b'), (0.2, 'c'), (0.1, 'd')], - 'plan2' : [(0.6, 'a'), (0.2, 'b'), (0.1, 'c'), (0.1, 'd')], - 'plan3' : [(0.3, 'a'), (0.3, 'b'), (0.4, 'c')], - }, - 'c' : { 'plan1' : [(0.3, 'a'), (0.5, 'b'), (0.1, 'c'), (0.1, 'd')], - 'plan2' : [(0.5, 'a'), (0.3, 'b'), (0.1, 'c'), (0.1, 'd')], - 'plan3' : [(0.1, 'a'), (0.3, 'b'), (0.1, 'c'), (0.5, 'd')], - }, - } -""" diff --git a/mdp4e.py b/mdp4e.py index f8871bdc9..644ab8404 100644 --- a/mdp4e.py +++ b/mdp4e.py @@ -191,10 +191,21 @@ def to_arrows(self, policy): A 4x3 grid environment that presents the agent with a sequential decision problem. """ -sequential_decision_environment = GridMDP([[-0.04, -0.04, -0.04, +1], - [-0.04, None, -0.04, -1], - [-0.04, -0.04, -0.04, -0.04]], - terminals=[(3, 2), (3, 1)]) +# sequential_decision_environment = GridMDP([[-0.04, -0.04, -0.04, +1], +# [-0.04, None, -0.04, -1], +# [-0.04, -0.04, -0.04, -0.04]], +# terminals=[(3, 2), (3, 1)]) + +sequential_decision_7x6_environment = GridMDP( + [[-0.04, -0.04, -0.04, None, -0.04, -0.04, +1], #5 + [-0.04, -0.04, -0.04, -0.04, -0.04, -0.04, -0.04], + [-0.04, -0.04, -0.04, -0.04, -0.04, -0.04, -1], + [-0.04, -0.04, -0.04, -0.04, -0.04, -0.04, -0.04], + [-0.04, None, -0.04, -0.04, -0.04, -0.04, -0.04], + [-0.04, -0.04, -0.04, -0.04, -0.04, -0.04, -0.04] #0 + #0 2 4 6 + ], + terminals=[(6, 5), (6, 3)]) # ______________________________________________________________________________ diff --git a/notebooks/chapter21/Passive Reinforcement Learning.html b/notebooks/chapter21/Passive Reinforcement Learning.html new file mode 100644 index 000000000..0c81e54af --- /dev/null +++ b/notebooks/chapter21/Passive Reinforcement Learning.html @@ -0,0 +1,8338 @@ + + + + + +Passive Reinforcement Learning + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + diff --git a/notebooks/chapter21/Passive Reinforcement Learning.ipynb b/notebooks/chapter21/Passive Reinforcement Learning.ipynb index cbb5ae9e3..be2e5d6c7 100644 --- a/notebooks/chapter21/Passive Reinforcement Learning.ipynb +++ b/notebooks/chapter21/Passive Reinforcement Learning.ipynb @@ -1,26 +1,28 @@ { "cells": [ { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# Introduction to Reinforcement Learning\n", "\n", - "This Jupyter notebook and the others in the same folder act as supporting materials for **Chapter 21 Reinforcement Learning** of the book* Artificial Intelligence: A Modern Approach*. The notebooks make use of the implementations in `rl.py` module. We also make use of the implementation of MDPs in the `mdp.py` module to test our agents. It might be helpful if you have already gone through the Jupyter notebook dealing with the Markov decision process. Let us import everything from the `rl` module. It might be helpful to view the source of some of our implementations." + "This Jupyter notebook and the others in the same folder act as supporting materials for **Chapter 22 Reinforcement Learning** of the book* Artificial Intelligence: A Modern Approach*. The notebooks make use of the implementations in `reinforcement_learning4e.py` module. We also make use of the implementation of MDPs in the `mdp4e.py` module to test our agents. It might be helpful if you have already gone through the Jupyter notebook dealing with the Markov decision process. Let us import everything from the `reinforcement_learning4e` module. It might be helpful to view the source of some of our implementations." ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import os, sys\n", "sys.path = [os.path.abspath(\"../../\")] + sys.path\n", - "from rl4e import *" + "from reinforcement_learning4e import *" ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -55,49 +57,62 @@ "\n", "### Implementation\n", "\n", - "Passive agents are implemented in `rl4e.py` as various `Agent-Class`es.\n", + "Passive agents are implemented in `reinforcement_learning4e.py` as various `Agent-Class`es.\n", "\n", - "To demonstrate these agents, we make use of the `GridMDP` object from the `MDP` module. `sequential_decision_environment` is similar to that used for the `MDP` notebook but has discounting with $\\gamma = 0.9$.\n", + "To demonstrate these agents, we make use of the `GridMDP` object from the `MDP` module. `sequential_decision_7x6_environment` is similar to that used for the `MDP` notebook but has discounting with $\\gamma = 0.9$ and a 7x6 environment.\n", "\n", "The `Agent-Program` can be obtained by creating an instance of the relevant `Agent-Class`. The `__call__` method allows the `Agent-Class` to be called as a function. The class needs to be instantiated with a policy ($\\pi$) and an `MDP` whose utility of states will be estimated.\n" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ - "from mdp import sequential_decision_environment" + "from mdp4e import sequential_decision_7x6_environment" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "The `sequential_decision_environment` is a GridMDP object as shown below. The rewards are **+1** and **-1** in the terminal states, and **-0.04** in the rest. Now we define actions and a policy similar to **Fig 21.1** in the book." + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `sequential_decision_7x6_environment` is a GridMDP object.\n", + "The rewards are **+1** and **-1** in the terminal states, and **-0.04** in the rest. Now we define actions and a policy similar to **Fig 22.1** in the book." ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# Action Directions\n", - "north = (0, 1)\n", - "south = (0,-1)\n", - "west = (-1, 0)\n", - "east = (1, 0)\n", + "to_north = (0, 1)\n", + "to_south = (0,-1)\n", + "to_west = (-1, 0)\n", + "to_east = (1, 0)\n", "\n", "policy = {\n", - " (0, 2): east, (1, 2): east, (2, 2): east, (3, 2): None,\n", - " (0, 1): north, (2, 1): north, (3, 1): None,\n", - " (0, 0): north, (1, 0): west, (2, 0): west, (3, 0): west, \n", - "}" + " (0, 5): to_east, (1, 5): to_east, (2, 5): to_south, (4, 5): to_east, (5, 5): to_east, (6, 5): None,\n", + " (0, 4): to_east, (1, 4): to_east, (2, 4): to_east, (3, 4): to_east, (4, 4): to_north, (5, 4): to_north, (6, 4): to_north,\n", + " (0, 3): to_east, (1, 3): to_east, (2, 3): to_east, (3, 3): to_east, (4, 3): to_north, (5, 3): to_north, (6, 3): None,\n", + " (0, 2): to_east, (1, 2): to_east, (2, 2): to_east, (3, 2): to_north, (4, 2): to_north, (5, 2): to_north, (6, 2): to_west,\n", + " (0, 1): to_north, (2, 1): to_north,(3, 1): to_north, (4, 1): to_north, (5, 1): to_north, (6, 1): to_north,\n", + " (0, 0): to_north, (1, 0): to_west, (2, 0): to_north,(3, 0): to_north, (4, 0): to_north, (5, 0): to_north, (6, 0): to_north,\n", + "}\n", + "# (1, 1) and (3, 5) are blocks" ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -105,6 +120,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -118,35 +134,37 @@ " \n", "### Examples\n", "\n", - "The `PassiveDEUAgent` class in the `rl` module implements the Agent Program described in **Fig 21.2** of the AIMA Book. `PassiveDEUAgent` sums over rewards to find the estimated utility for each state. It thus requires the running of several iterations." + "The `PassiveDEUAgent` class in the `reinforcement_learning4e` module implements the Agent Program described in **Fig 22.1** of the AIMA Book. `PassiveDEUAgent` sums over rewards to find the estimated utility for each state. It thus requires the running of several iterations." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ - "%psource PassiveDUEAgent" + "#%psource PassiveDUEAgent" ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ - "Now let's try the `PassiveDEUAgent` on the newly defined `sequential_decision_environment`:" + "Now let's try the `PassiveDEUAgent` on the newly defined `sequential_decision_7x6_environment`:" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ - "DUEagent = PassiveDUEAgent(policy, sequential_decision_environment)" + "DUEagent = PassiveDUEAgent(policy, sequential_decision_7x6_environment)" ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -155,16 +173,17 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "for i in range(200):\n", - " run_single_trial(DUEagent, sequential_decision_environment)\n", + " run_single_trial(DUEagent, sequential_decision_7x6_environment)\n", " DUEagent.estimate_U()" ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -173,30 +192,99 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(0, 0):0.4236075354636989\n", + "(0, 1):0.5019492867686104\n", + "(0, 2):0.5486189416774652\n", + "(0, 3):0.6351350402832031\n", + "(0, 4):0.6799999999999999\n", + "(1, 0):0.25489786307017\n", + "(1, 2):0.5947449797423456\n", + "(1, 3):0.6825157148111611\n", + "(1, 4):0.6100000000000001\n", + "(1, 5):0.54\n", + "(2, 1):0.515815814336141\n", + "(2, 2):0.6350577908865893\n", + "(2, 3):0.7003470823921986\n", + "(2, 4):0.7093750000000001\n", + "(2, 5):0.7\n", + "(3, 1):0.63\n", + "(3, 2):0.6748127730419262\n", + "(3, 3):0.7192622961048641\n", + "(3, 4):0.824402309002987\n", + "(4, 2):0.6483405303955079\n", + "(4, 3):0.748238272517107\n", + "(4, 4):0.8107439163297334\n", + "(4, 5):0.8202581627145792\n", + "(5, 2):0.78\n", + "(5, 3):-0.16917236328125002\n", + "(5, 4):0.9068707057727405\n", + "(5, 5):0.928554663508546\n", + "(6, 3):-1.0\n", + "(6, 4):0.95875\n", + "(6, 5):1.0\n" + ] + } + ], + "source": [ + "sorted_dict = dict(sorted(DUEagent.U.items()))\n", + "print('\\n'.join([str(k)+':'+str(v) for k, v in sorted_dict.items()]))" + ] + }, + { + "cell_type": "code", + "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "(0, 1):0.7956939931414414\n", - "(1, 2):0.9162054322837863\n", - "(3, 2):1.0\n", - "(0, 0):0.734717308253083\n", - "(2, 2):0.9595117143816332\n", - "(0, 2):0.8481387156375687\n", - "(1, 0):0.4355860415209706\n", - "(2, 1):-0.550079982553143\n", - "(3, 1):-1.0\n" + "(6, 3):-1.0\n", + "(5, 3):-0.16917236328125002\n", + "(1, 0):0.25489786307017\n", + "(0, 0):0.4236075354636989\n", + "(0, 1):0.5019492867686104\n", + "(2, 1):0.515815814336141\n", + "(1, 5):0.54\n", + "(0, 2):0.5486189416774652\n", + "(1, 2):0.5947449797423456\n", + "(1, 4):0.6100000000000001\n", + "(3, 1):0.63\n", + "(2, 2):0.6350577908865893\n", + "(0, 3):0.6351350402832031\n", + "(4, 2):0.6483405303955079\n", + "(3, 2):0.6748127730419262\n", + "(0, 4):0.6799999999999999\n", + "(1, 3):0.6825157148111611\n", + "(2, 5):0.7\n", + "(2, 3):0.7003470823921986\n", + "(2, 4):0.7093750000000001\n", + "(3, 3):0.7192622961048641\n", + "(4, 3):0.748238272517107\n", + "(5, 2):0.78\n", + "(4, 4):0.8107439163297334\n", + "(4, 5):0.8202581627145792\n", + "(3, 4):0.824402309002987\n", + "(5, 4):0.9068707057727405\n", + "(5, 5):0.928554663508546\n", + "(6, 4):0.95875\n", + "(6, 5):1.0\n" ] } ], "source": [ - "print('\\n'.join([str(k)+':'+str(v) for k, v in DUEagent.U.items()]))" + "print('\\n'.join([str(k)+':'+str(v) for k, v in sorted(DUEagent.U.items(), key=lambda item: item[1])]))" ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -212,19 +300,20 @@ " \n", "### Examples\n", "\n", - "The `PassiveADPAgent` class in the `rl` module implements the Agent Program described in **Fig 21.2** of the AIMA Book. `PassiveADPAgent` uses state transition and occurrence counts to estimate $P$, and then $U$. Go through the source below to understand the agent." + "The `PassiveADPAgent` class in the `rl` module implements the Agent Program described in **Fig 22.2** of the AIMA Book. `PassiveADPAgent` uses state transition and occurrence counts to estimate $P$, and then $U$. Go through the source below to understand the agent." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ - "%psource" + "#%psource PassiveADPAgent" ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -245,12 +334,13 @@ } ], "source": [ - "ADPagent = PassiveADPAgent(policy, sequential_decision_environment)\n", + "ADPagent = PassiveADPAgent(policy, sequential_decision_7x6_environment)\n", "for i in range(200):\n", - " run_single_trial(ADPagent, sequential_decision_environment)" + " run_single_trial(ADPagent, sequential_decision_7x6_environment)" ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -266,25 +356,112 @@ "name": "stdout", "output_type": "stream", "text": [ - "(0, 0):0.3014408531958584\n", - "(0, 1):0.40583863351329275\n", - "(1, 2):0.6581480346627065\n", - "(3, 2):1.0\n", + "(0, 0):-0.07623967847925393\n", + "(0, 1):-0.026819464027755043\n", + "(0, 2):0.026070814424633\n", + "(0, 3):0.0898912155585346\n", + "(0, 4):0.13956118174593626\n", + "(0, 5):0.0\n", + "(1, 0):-0.11509091726010662\n", + "(1, 2):0.08520207544443542\n", + "(1, 3):0.14923809363558327\n", + "(1, 4):0.19951242416776854\n", + "(1, 5):0.1572060396703305\n", + "(2, 0):0.0\n", + "(2, 1):0.08676528114433374\n", + "(2, 2):0.1453176451935049\n", + "(2, 3):0.21493318655409463\n", + "(2, 4):0.28790869095629196\n", + "(2, 5):0.2191178218559228\n", "(3, 0):0.0\n", - "(3, 1):-1.0\n", - "(2, 1):0.5341859348580892\n", + "(3, 1):0.15696301474218163\n", + "(3, 2):0.21884779416286657\n", + "(3, 3):0.3007460686047139\n", + "(3, 4):0.37928397029167676\n", + "(4, 0):0.0\n", + "(4, 1):0.0\n", + "(4, 2):0.3170521270289436\n", + "(4, 3):0.40798932594936077\n", + "(4, 4):0.5114264677843369\n", + "(4, 5):0.6463636112746671\n", + "(5, 0):0.0\n", + "(5, 1):0.0\n", + "(5, 2):0.38091858032242826\n", + "(5, 3):0.5226408411964897\n", + "(5, 4):0.6387294379851319\n", + "(5, 5):0.8108590985010455\n", + "(6, 0):0.0\n", + "(6, 1):0.0\n", + "(6, 2):0.3028267222879898\n", + "(6, 3):0.0\n", + "(6, 4):0.7064549063271298\n", + "(6, 5):1.0\n" + ] + } + ], + "source": [ + "sorted_dict = dict(sorted(ADPagent.U.items()))\n", + "print('\\n'.join([str(k)+':'+str(v) for k, v in sorted_dict.items()]))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(1, 0):-0.11509091726010662\n", + "(0, 0):-0.07623967847925393\n", + "(0, 1):-0.026819464027755043\n", + "(4, 0):0.0\n", + "(5, 1):0.0\n", + "(0, 5):0.0\n", + "(3, 0):0.0\n", + "(5, 0):0.0\n", + "(6, 1):0.0\n", + "(4, 1):0.0\n", "(2, 0):0.0\n", - "(2, 2):0.810403779650285\n", - "(1, 0):0.23129676787627254\n", - "(0, 2):0.5214746706094832\n" + "(6, 0):0.0\n", + "(6, 3):0.0\n", + "(0, 2):0.026070814424633\n", + "(1, 2):0.08520207544443542\n", + "(2, 1):0.08676528114433374\n", + "(0, 3):0.0898912155585346\n", + "(0, 4):0.13956118174593626\n", + "(2, 2):0.1453176451935049\n", + "(1, 3):0.14923809363558327\n", + "(3, 1):0.15696301474218163\n", + "(1, 5):0.1572060396703305\n", + "(1, 4):0.19951242416776854\n", + "(2, 3):0.21493318655409463\n", + "(3, 2):0.21884779416286657\n", + "(2, 5):0.2191178218559228\n", + "(2, 4):0.28790869095629196\n", + "(3, 3):0.3007460686047139\n", + "(6, 2):0.3028267222879898\n", + "(4, 2):0.3170521270289436\n", + "(3, 4):0.37928397029167676\n", + "(5, 2):0.38091858032242826\n", + "(4, 3):0.40798932594936077\n", + "(4, 4):0.5114264677843369\n", + "(5, 3):0.5226408411964897\n", + "(5, 4):0.6387294379851319\n", + "(4, 5):0.6463636112746671\n", + "(6, 4):0.7064549063271298\n", + "(5, 5):0.8108590985010455\n", + "(6, 5):1.0\n" ] } ], "source": [ - "print('\\n'.join([str(k)+':'+str(v) for k, v in ADPagent.U.items()]))" + "print('\\n'.join([str(k)+':'+str(v) for k, v in sorted(ADPagent.U.items(), key=lambda item: item[1])]))" ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -292,6 +469,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -311,14 +489,15 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ - "%psource PassiveTDAgent" + "#%psource PassiveTDAgent" ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -327,14 +506,15 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ - "TDagent = PassiveTDAgent(policy, sequential_decision_environment, alpha = lambda n: 60./(59+n))" + "TDagent = PassiveTDAgent(policy, sequential_decision_7x6_environment, alpha = lambda n: 60./(59+n))" ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -343,15 +523,16 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "for i in range(200):\n", - " run_single_trial(TDagent,sequential_decision_environment)" + " run_single_trial(TDagent,sequential_decision_7x6_environment)" ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -360,32 +541,119 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(0, 0):-0.06816744339324231\n", + "(0, 1):-0.040562528263606706\n", + "(0, 2):-0.013493772802435557\n", + "(0, 3):-0.05069748077431516\n", + "(0, 4):0.17640258872909165\n", + "(0, 5):0.0\n", + "(1, 0):-0.12274055298989325\n", + "(1, 2):0.08441324404957194\n", + "(1, 3):0.08485166602673662\n", + "(1, 4):0.10832713351599019\n", + "(1, 5):0.1846696109053968\n", + "(2, 0):0.0\n", + "(2, 1):0.0669990568349042\n", + "(2, 2):0.1374297077160365\n", + "(2, 3):0.2456154066636996\n", + "(2, 4):0.31538811836991154\n", + "(2, 5):0.20878101109686703\n", + "(3, 0):0.0\n", + "(3, 1):0.14457846345708605\n", + "(3, 2):0.23920553069402883\n", + "(3, 3):0.352416704597033\n", + "(3, 4):0.42801488656630904\n", + "(4, 0):0.0\n", + "(4, 1):0.0\n", + "(4, 2):0.34481095007523177\n", + "(4, 3):0.20316139389877338\n", + "(4, 4):0.5327401364248504\n", + "(4, 5):0.6519972375057037\n", + "(5, 0):0.0\n", + "(5, 1):0.0\n", + "(5, 2):0.25051847776494396\n", + "(5, 3):0.2927954280996534\n", + "(5, 4):0.5982770886599733\n", + "(5, 5):0.8508474454186945\n", + "(6, 0):0.0\n", + "(6, 1):0.0\n", + "(6, 2):-0.10294029383053863\n", + "(6, 3):-1\n", + "(6, 4):0.844325539872483\n", + "(6, 5):1\n" + ] + } + ], + "source": [ + "sorted_dict = dict(sorted(TDagent.U.items()))\n", + "print('\\n'.join([str(k)+':'+str(v) for k, v in sorted_dict.items()]))" + ] + }, + { + "cell_type": "code", + "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "(0, 1):0.36652562797696076\n", - "(1, 2):0.6584162739552614\n", - "(3, 2):1\n", - "(0, 0):0.27775491505339645\n", + "(6, 3):-1\n", + "(1, 0):-0.12274055298989325\n", + "(6, 2):-0.10294029383053863\n", + "(0, 0):-0.06816744339324231\n", + "(0, 3):-0.05069748077431516\n", + "(0, 1):-0.040562528263606706\n", + "(0, 2):-0.013493772802435557\n", + "(4, 0):0.0\n", + "(5, 1):0.0\n", + "(0, 5):0.0\n", "(3, 0):0.0\n", - "(3, 1):-1\n", - "(2, 1):0.6097040420148784\n", + "(5, 0):0.0\n", + "(6, 1):0.0\n", + "(4, 1):0.0\n", "(2, 0):0.0\n", - "(2, 2):0.7936759402770092\n", - "(1, 0):0.19085842384266813\n", - "(0, 2):0.5258782999305713\n" + "(6, 0):0.0\n", + "(2, 1):0.0669990568349042\n", + "(1, 2):0.08441324404957194\n", + "(1, 3):0.08485166602673662\n", + "(1, 4):0.10832713351599019\n", + "(2, 2):0.1374297077160365\n", + "(3, 1):0.14457846345708605\n", + "(0, 4):0.17640258872909165\n", + "(1, 5):0.1846696109053968\n", + "(4, 3):0.20316139389877338\n", + "(2, 5):0.20878101109686703\n", + "(3, 2):0.23920553069402883\n", + "(2, 3):0.2456154066636996\n", + "(5, 2):0.25051847776494396\n", + "(5, 3):0.2927954280996534\n", + "(2, 4):0.31538811836991154\n", + "(4, 2):0.34481095007523177\n", + "(3, 3):0.352416704597033\n", + "(3, 4):0.42801488656630904\n", + "(4, 4):0.5327401364248504\n", + "(5, 4):0.5982770886599733\n", + "(4, 5):0.6519972375057037\n", + "(6, 4):0.844325539872483\n", + "(5, 5):0.8508474454186945\n", + "(6, 5):1\n" ] } ], "source": [ - "print('\\n'.join([str(k)+':'+str(v) for k, v in TDagent.U.items()]))" + "print('\\n'.join([str(k)+':'+str(v) for k, v in sorted(TDagent.U.items(), key=lambda item: item[1])]))" ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -402,7 +670,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -416,9 +684,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.2" + "version": "3.10.14" } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/notebooks/chapter21/images/grid_mdp_4x7.jpg b/notebooks/chapter21/images/grid_mdp_4x7.jpg new file mode 100644 index 0000000000000000000000000000000000000000..16b5740b9f971b74d4658e42c1df872b6d56fadb GIT binary patch literal 18622 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 literal 0 HcmV?d00001 diff --git a/notebooks/chapter21/images/grid_mdp_4x7_array.jpg b/notebooks/chapter21/images/grid_mdp_4x7_array.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b5f9fa2ef3c1fdddc9bbcdcee67e68b74591012d GIT binary patch literal 18080 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 MYjpPYuUGH>FCe*eE&u=k literal 0 HcmV?d00001 diff --git a/reinforcement_learning.ipynb b/reinforcement_learning.ipynb index ee3b6a5eb..2ac172927 100644 --- a/reinforcement_learning.ipynb +++ b/reinforcement_learning.ipynb @@ -13,7 +13,10 @@ "cell_type": "code", "execution_count": null, "metadata": { - "collapsed": true + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } }, "outputs": [], "source": [ @@ -38,7 +41,10 @@ { "cell_type": "markdown", "metadata": { - "collapsed": true + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } }, "source": [ "## OVERVIEW\n", @@ -117,7 +123,10 @@ "cell_type": "code", "execution_count": null, "metadata": { - "collapsed": true + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } }, "outputs": [], "source": [ @@ -135,7 +144,10 @@ "cell_type": "code", "execution_count": null, "metadata": { - "collapsed": true + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } }, "outputs": [], "source": [ @@ -165,7 +177,10 @@ "cell_type": "code", "execution_count": null, "metadata": { - "collapsed": true + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } }, "outputs": [], "source": [ @@ -176,7 +191,10 @@ "cell_type": "code", "execution_count": null, "metadata": { - "collapsed": true + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } }, "outputs": [], "source": [ @@ -216,7 +234,10 @@ "cell_type": "code", "execution_count": null, "metadata": { - "collapsed": true + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } }, "outputs": [], "source": [ @@ -274,7 +295,10 @@ "cell_type": "code", "execution_count": null, "metadata": { - "collapsed": true + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } }, "outputs": [], "source": [ @@ -292,7 +316,10 @@ "cell_type": "code", "execution_count": null, "metadata": { - "collapsed": true + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } }, "outputs": [], "source": [ @@ -310,7 +337,10 @@ "cell_type": "code", "execution_count": null, "metadata": { - "collapsed": true + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } }, "outputs": [], "source": [ @@ -349,7 +379,10 @@ "cell_type": "code", "execution_count": null, "metadata": { - "collapsed": true + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } }, "outputs": [], "source": [ @@ -386,7 +419,10 @@ "cell_type": "code", "execution_count": null, "metadata": { - "collapsed": true + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } }, "outputs": [], "source": [ @@ -444,7 +480,10 @@ { "cell_type": "markdown", "metadata": { - "collapsed": true + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } }, "source": [ "## ACTIVE REINFORCEMENT LEARNING\n", @@ -465,7 +504,10 @@ "cell_type": "code", "execution_count": null, "metadata": { - "collapsed": true + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } }, "outputs": [], "source": [ @@ -492,7 +534,10 @@ "cell_type": "code", "execution_count": null, "metadata": { - "collapsed": true + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } }, "outputs": [], "source": [ @@ -511,7 +556,10 @@ "cell_type": "code", "execution_count": null, "metadata": { - "collapsed": true + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } }, "outputs": [], "source": [ @@ -556,7 +604,10 @@ "cell_type": "code", "execution_count": null, "metadata": { - "collapsed": true + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } }, "outputs": [], "source": [ @@ -596,7 +647,10 @@ "cell_type": "code", "execution_count": null, "metadata": { - "collapsed": true + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } }, "outputs": [], "source": [] @@ -605,7 +659,10 @@ "cell_type": "code", "execution_count": null, "metadata": { - "collapsed": true + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } }, "outputs": [], "source": [] @@ -613,7 +670,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -627,18 +684,18 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.3" + "version": "3.10.14" }, "pycharm": { "stem_cell": { "cell_type": "raw", - "source": [], "metadata": { "collapsed": false - } + }, + "source": [] } } }, "nbformat": 4, - "nbformat_minor": 1 -} \ No newline at end of file + "nbformat_minor": 4 +} diff --git a/reinforcement_learning4e.py b/reinforcement_learning4e.py index eaaba3e5a..c52cdd79d 100644 --- a/reinforcement_learning4e.py +++ b/reinforcement_learning4e.py @@ -1,4 +1,4 @@ -"""Reinforcement Learning (Chapter 21)""" +"""Reinforcement Learning (Chapter 22)""" import random from collections import defaultdict @@ -7,8 +7,8 @@ # _________________________________________ -# 21.2 Passive Reinforcement Learning -# 21.2.1 Direct utility estimation +# 22.2 Passive Reinforcement Learning +# 22.2.1 Direct utility estimation class PassiveDUEAgent: @@ -17,7 +17,7 @@ class PassiveDUEAgent: on a given MDP and policy. import sys - from mdp import sequential_decision_environment + from mdp4e import sequential_decision_7x6_environment north = (0, 1) south = (0,-1) west = (-1, 0) @@ -80,19 +80,22 @@ def update_state(self, percept): """To be overridden in most cases. The default case assumes the percept to be of type (state, reward)""" return percept + + def print_U(self): + sorted_dict = dict(sorted(self.U.items())) + print('\n'.join([str(k)+':'+str(v) for k, v in sorted_dict.items()])) + return -# 21.2.2 Adaptive dynamic programming - - +# 22.2.2 Adaptive dynamic programming class PassiveADPAgent: """ - [Figure 21.2] + [Figure 22.2] Passive (non-learning) agent that uses adaptive dynamic programming on a given MDP and policy. import sys - from mdp import sequential_decision_environment + from mdp import sequential_decision_7x6_environment north = (0, 1) south = (0,-1) west = (-1, 0) @@ -168,12 +171,10 @@ def update_state(self, percept): return percept -# 21.2.3 Temporal-difference learning - - +# 22.2.3 Temporal-difference learning class PassiveTDAgent: """ - [Figure 21.4] + [Figure 22.4] The abstract class for a Passive (non-learning) agent that uses temporal differences to learn utility estimates. Override update_state method to convert percept to state and reward. The mdp being provided @@ -235,9 +236,8 @@ def update_state(self, percept): # __________________________________________ -# 21.3. Active Reinforcement Learning -# 21.3.2 Learning an action-utility function - +# 22.3. Active Reinforcement Learning +# 22.3.2 Learning an action-utility function class QLearningAgent: """ From 2b82d1d2c985965eed087fcfc703c333e6862bee Mon Sep 17 00:00:00 2001 From: uldiskk Date: Mon, 6 May 2024 17:37:36 +0300 Subject: [PATCH 2/6] Remove all unneeded files --- .flake8 | 4 - .travis.yml | 23 - SUBMODULE.md | 11 - agents.ipynb | 735 -- agents.py | 1070 --- agents4e.py | 1089 --- aima-data | 1 - arc_consistency_heuristics.ipynb | 1999 ----- classical_planning_approaches.ipynb | 2402 ------ csp.ipynb | 3084 -------- csp.py | 1435 ---- deep_learning4e.py | 584 -- games.ipynb | 1669 ----- games.py | 590 -- games4e.ipynb | 1667 ----- games4e.py | 635 -- gui/eight_puzzle.py | 151 - gui/genetic_algorithm_example.py | 189 - gui/grid_mdp.py | 676 -- gui/romania_problem.py | 672 -- gui/tic-tac-toe.py | 232 - gui/tsp.py | 342 - gui/vacuum_agent.py | 154 - gui/xy_vacuum_environment.py | 191 - images/-0.04.jpg | Bin 16933 -> 0 bytes images/-0.4.jpg | Bin 20027 -> 0 bytes images/-4.jpg | Bin 19579 -> 0 bytes images/4.jpg | Bin 21550 -> 0 bytes images/IMAGE-CREDITS | 17 - images/aima3e_big.jpg | Bin 57178 -> 0 bytes images/aima_logo.png | Bin 8063 -> 0 bytes images/bayesnet.png | Bin 81000 -> 0 bytes images/broxrevised.png | Bin 234593 -> 0 bytes images/cake_graph.jpg | Bin 43870 -> 0 bytes images/decisiontree_fruit.jpg | Bin 45995 -> 0 bytes images/dirt.svg | 291 - images/dirt05-icon.jpg | Bin 1772 -> 0 bytes images/ensemble_learner.jpg | Bin 16575 -> 0 bytes images/fig_5_2.png | Bin 49045 -> 0 bytes images/ge0.jpg | Bin 20226 -> 0 bytes images/ge1.jpg | Bin 21080 -> 0 bytes images/ge2.jpg | Bin 26216 -> 0 bytes images/ge4.jpg | Bin 23605 -> 0 bytes images/general_learning_agent.jpg | Bin 32599 -> 0 bytes images/grid_mdp.jpg | Bin 13536 -> 0 bytes images/grid_mdp_agent.jpg | Bin 6643 -> 0 bytes images/hillclimb-tsp.png | Bin 32028 -> 0 bytes images/knn_plot.png | Bin 45256 -> 0 bytes images/knowledge_FOIL_grandparent.png | Bin 18034 -> 0 bytes images/knowledge_foil_family.png | Bin 35686 -> 0 bytes images/makefile | 34 - images/maze.png | Bin 4576 -> 0 bytes images/mdp-a.png | Bin 31989 -> 0 bytes images/mdp-b.png | Bin 17560 -> 0 bytes images/mdp-c.png | Bin 18293 -> 0 bytes images/mdp-d.png | Bin 21321 -> 0 bytes images/mdp.png | Bin 824 -> 0 bytes images/model_based_reflex_agent.jpg | Bin 57354 -> 0 bytes images/model_goal_based_agent.jpg | Bin 61937 -> 0 bytes images/model_utility_based_agent.jpg | Bin 69438 -> 0 bytes images/neural_net.png | Bin 24372 -> 0 bytes images/parse_tree.png | Bin 13655 -> 0 bytes images/perceptron.png | Bin 19756 -> 0 bytes images/pluralityLearner_plot.png | Bin 12658 -> 0 bytes images/point_crossover.png | Bin 5655 -> 0 bytes images/pop.jpg | Bin 109930 -> 0 bytes images/queen_s.png | Bin 14407 -> 0 bytes images/random_forest.png | Bin 190008 -> 0 bytes images/refinement.png | Bin 63029 -> 0 bytes images/restaurant.png | Bin 175445 -> 0 bytes images/romania_map.png | Bin 15206 -> 0 bytes images/search_animal.svg | 1533 ---- images/simple_problem_solving_agent.jpg | Bin 40649 -> 0 bytes images/simple_reflex_agent.jpg | Bin 40659 -> 0 bytes images/sprinklernet.jpg | Bin 42865 -> 0 bytes images/stapler1-test.png | Bin 134386 -> 0 bytes images/uniform_crossover.png | Bin 5675 -> 0 bytes images/vacuum-icon.jpg | Bin 1428 -> 0 bytes images/vacuum.svg | 150 - images/wall-icon.jpg | Bin 35979 -> 0 bytes improving_sat_algorithms.ipynb | 2539 ------- index.ipynb | 68 - intro.ipynb | 140 - ipyviews.py | 157 - js/canvas.js | 135 - js/continuousworld.js | 71 - js/gridworld.js | 126 - knowledge.py | 422 -- knowledge_FOIL.ipynb | 639 -- knowledge_current_best.ipynb | 662 -- knowledge_version_space.ipynb | 1088 --- learning.ipynb | 2264 ------ learning.py | 1253 ---- learning4e.py | 1039 --- learning_apps.ipynb | 988 --- logic.ipynb | 5004 ------------- logic.py | 2164 ------ logic4e.py | 1665 ----- making_simple_decision4e.py | 168 - mdp.ipynb | 5483 -------------- mdp_apps.ipynb | 1825 ----- neural_nets.ipynb | 570 -- nlp.ipynb | 1042 --- nlp.py | 569 -- nlp4e.py | 523 -- nlp_apps.ipynb | 1038 --- notebook.py | 1122 --- notebook4e.py | 1158 --- notebooks/chapter19/Learners.ipynb | 508 -- .../chapter19/Loss Functions and Layers.ipynb | 398 - .../Optimizer and Backpropagation.ipynb | 311 - notebooks/chapter19/RNN.ipynb | 487 -- notebooks/chapter19/images/autoencoder.png | Bin 97033 -> 0 bytes notebooks/chapter19/images/backprop.png | Bin 191236 -> 0 bytes .../chapter19/images/corss_entropy_plot.png | Bin 80081 -> 0 bytes notebooks/chapter19/images/mse_plot.png | Bin 90343 -> 0 bytes notebooks/chapter19/images/nn.png | Bin 108498 -> 0 bytes notebooks/chapter19/images/nn_steps.png | Bin 253098 -> 0 bytes notebooks/chapter19/images/perceptron.png | Bin 19756 -> 0 bytes .../chapter19/images/rnn_connections.png | Bin 337855 -> 0 bytes notebooks/chapter19/images/rnn_unit.png | Bin 34946 -> 0 bytes notebooks/chapter19/images/rnn_units.png | Bin 113593 -> 0 bytes notebooks/chapter19/images/vanilla.png | Bin 66573 -> 0 bytes .../Active Reinforcement Learning.ipynb | 212 - .../Passive Reinforcement Learning.ipynb | 342 +- notebooks/chapter21/images/mdp.png | Bin 824 -> 0 bytes notebooks/chapter22/Grammar.ipynb | 526 -- notebooks/chapter22/Introduction.ipynb | 92 - notebooks/chapter22/Parsing.ipynb | 522 -- notebooks/chapter22/images/parse_tree.png | Bin 13655 -> 0 bytes notebooks/chapter22/nlp_apps.ipynb | 1038 --- .../chapter24/Image Edge Detection.ipynb | 408 - notebooks/chapter24/Image Segmentation.ipynb | 480 -- notebooks/chapter24/Objects in Images.ipynb | 454 -- notebooks/chapter24/images/RCNN.png | Bin 500326 -> 0 bytes .../images/derivative_of_gaussian.png | Bin 113799 -> 0 bytes notebooks/chapter24/images/gradients.png | Bin 109856 -> 0 bytes notebooks/chapter24/images/laplacian.png | Bin 63911 -> 0 bytes .../chapter24/images/laplacian_kernels.png | Bin 41542 -> 0 bytes notebooks/chapter24/images/stapler.png | Bin 134386 -> 0 bytes notebooks/chapter24/images/stapler_bbox.png | Bin 1372038 -> 0 bytes obsolete_search4e.ipynb | 3835 ---------- perception4e.py | 467 -- planning.ipynb | 3867 ---------- planning.py | 2010 ----- planning_angelic_search.ipynb | 638 -- planning_graphPlan.ipynb | 1066 --- planning_hierarchical_search.ipynb | 546 -- planning_partial_order_planner.ipynb | 850 --- planning_total_order_planner.ipynb | 341 - probabilistic_learning.py | 154 - probability.ipynb | 6536 ---------------- probability.py | 870 --- probability4e.ipynb | 1381 ---- probability4e.py | 776 -- pytest.ini | 5 - reinforcement_learning.ipynb | 701 -- reinforcement_learning.py | 337 - search.ipynb | 6579 ----------------- search.py | 1576 ---- search4e.ipynb | 2652 ------- tests/__init__.py | 0 tests/pytest.ini | 3 - tests/test_agents.py | 387 - tests/test_agents4e.py | 386 - tests/test_csp.py | 662 -- tests/test_deep_learning4e.py | 80 - tests/test_games.py | 69 - tests/test_games4e.py | 96 - tests/test_knowledge.py | 285 - tests/test_learning.py | 157 - tests/test_learning4e.py | 127 - tests/test_logic.py | 389 - tests/test_logic4e.py | 359 - tests/test_mdp.py | 168 - tests/test_mdp4e.py | 176 - tests/test_nlp.py | 273 - tests/test_nlp4e.py | 139 - tests/test_perception4e.py | 87 - tests/test_planning.py | 774 -- tests/test_probabilistic_learning.py | 38 - tests/test_probability.py | 437 -- tests/test_probability4e.py | 349 - tests/test_reinforcement_learning.py | 71 - tests/test_reinforcement_learning4e.py | 69 - tests/test_search.py | 396 - tests/test_text.py | 293 - tests/test_utils.py | 303 - text.ipynb | 780 -- text.py | 416 -- utils.py | 790 -- vacuum_world.ipynb | 701 -- viterbi_algorithm.ipynb | 418 -- 193 files changed, 170 insertions(+), 106025 deletions(-) delete mode 100644 .flake8 delete mode 100644 .travis.yml delete mode 100644 SUBMODULE.md delete mode 100644 agents.ipynb delete mode 100644 agents.py delete mode 100644 agents4e.py delete mode 160000 aima-data delete mode 100644 arc_consistency_heuristics.ipynb delete mode 100644 classical_planning_approaches.ipynb delete mode 100644 csp.ipynb delete mode 100644 csp.py delete mode 100644 deep_learning4e.py delete mode 100644 games.ipynb delete mode 100644 games.py delete mode 100644 games4e.ipynb delete mode 100644 games4e.py delete mode 100644 gui/eight_puzzle.py delete mode 100644 gui/genetic_algorithm_example.py delete mode 100644 gui/grid_mdp.py delete mode 100644 gui/romania_problem.py delete mode 100644 gui/tic-tac-toe.py delete mode 100644 gui/tsp.py delete mode 100644 gui/vacuum_agent.py delete mode 100644 gui/xy_vacuum_environment.py delete mode 100644 images/-0.04.jpg delete mode 100644 images/-0.4.jpg delete mode 100644 images/-4.jpg delete mode 100644 images/4.jpg delete mode 100644 images/IMAGE-CREDITS delete mode 100644 images/aima3e_big.jpg delete mode 100644 images/aima_logo.png delete mode 100644 images/bayesnet.png delete mode 100644 images/broxrevised.png delete mode 100644 images/cake_graph.jpg delete mode 100644 images/decisiontree_fruit.jpg delete mode 100644 images/dirt.svg delete mode 100644 images/dirt05-icon.jpg delete mode 100644 images/ensemble_learner.jpg delete mode 100644 images/fig_5_2.png delete mode 100644 images/ge0.jpg delete mode 100644 images/ge1.jpg delete mode 100644 images/ge2.jpg delete mode 100644 images/ge4.jpg delete mode 100644 images/general_learning_agent.jpg delete mode 100644 images/grid_mdp.jpg delete mode 100644 images/grid_mdp_agent.jpg delete mode 100644 images/hillclimb-tsp.png delete mode 100644 images/knn_plot.png delete mode 100644 images/knowledge_FOIL_grandparent.png delete mode 100644 images/knowledge_foil_family.png delete mode 100644 images/makefile delete mode 100644 images/maze.png delete mode 100644 images/mdp-a.png delete mode 100644 images/mdp-b.png delete mode 100644 images/mdp-c.png delete mode 100644 images/mdp-d.png delete mode 100644 images/mdp.png delete mode 100644 images/model_based_reflex_agent.jpg delete mode 100644 images/model_goal_based_agent.jpg delete mode 100644 images/model_utility_based_agent.jpg delete mode 100644 images/neural_net.png delete mode 100644 images/parse_tree.png delete mode 100644 images/perceptron.png delete mode 100644 images/pluralityLearner_plot.png delete mode 100644 images/point_crossover.png delete mode 100644 images/pop.jpg delete mode 100644 images/queen_s.png delete mode 100644 images/random_forest.png delete mode 100644 images/refinement.png delete mode 100644 images/restaurant.png delete mode 100644 images/romania_map.png delete mode 100644 images/search_animal.svg delete mode 100644 images/simple_problem_solving_agent.jpg delete mode 100644 images/simple_reflex_agent.jpg delete mode 100644 images/sprinklernet.jpg delete mode 100644 images/stapler1-test.png delete mode 100644 images/uniform_crossover.png delete mode 100644 images/vacuum-icon.jpg delete mode 100644 images/vacuum.svg delete mode 100644 images/wall-icon.jpg delete mode 100644 improving_sat_algorithms.ipynb delete mode 100644 index.ipynb delete mode 100644 intro.ipynb delete mode 100644 ipyviews.py delete mode 100644 js/canvas.js delete mode 100644 js/continuousworld.js delete mode 100644 js/gridworld.js delete mode 100644 knowledge.py delete mode 100644 knowledge_FOIL.ipynb delete mode 100644 knowledge_current_best.ipynb delete mode 100644 knowledge_version_space.ipynb delete mode 100644 learning.ipynb delete mode 100644 learning.py delete mode 100644 learning4e.py delete mode 100644 learning_apps.ipynb delete mode 100644 logic.ipynb delete mode 100644 logic.py delete mode 100644 logic4e.py delete mode 100644 making_simple_decision4e.py delete mode 100644 mdp.ipynb delete mode 100644 mdp_apps.ipynb delete mode 100644 neural_nets.ipynb delete mode 100644 nlp.ipynb delete mode 100644 nlp.py delete mode 100644 nlp4e.py delete mode 100644 nlp_apps.ipynb delete mode 100644 notebook.py delete mode 100644 notebook4e.py delete mode 100644 notebooks/chapter19/Learners.ipynb delete mode 100644 notebooks/chapter19/Loss Functions and Layers.ipynb delete mode 100644 notebooks/chapter19/Optimizer and Backpropagation.ipynb delete mode 100644 notebooks/chapter19/RNN.ipynb delete mode 100644 notebooks/chapter19/images/autoencoder.png delete mode 100644 notebooks/chapter19/images/backprop.png delete mode 100644 notebooks/chapter19/images/corss_entropy_plot.png delete mode 100644 notebooks/chapter19/images/mse_plot.png delete mode 100644 notebooks/chapter19/images/nn.png delete mode 100644 notebooks/chapter19/images/nn_steps.png delete mode 100644 notebooks/chapter19/images/perceptron.png delete mode 100644 notebooks/chapter19/images/rnn_connections.png delete mode 100644 notebooks/chapter19/images/rnn_unit.png delete mode 100644 notebooks/chapter19/images/rnn_units.png delete mode 100644 notebooks/chapter19/images/vanilla.png delete mode 100644 notebooks/chapter21/Active Reinforcement Learning.ipynb delete mode 100644 notebooks/chapter21/images/mdp.png delete mode 100644 notebooks/chapter22/Grammar.ipynb delete mode 100644 notebooks/chapter22/Introduction.ipynb delete mode 100644 notebooks/chapter22/Parsing.ipynb delete mode 100644 notebooks/chapter22/images/parse_tree.png delete mode 100644 notebooks/chapter22/nlp_apps.ipynb delete mode 100644 notebooks/chapter24/Image Edge Detection.ipynb delete mode 100644 notebooks/chapter24/Image Segmentation.ipynb delete mode 100644 notebooks/chapter24/Objects in Images.ipynb delete mode 100644 notebooks/chapter24/images/RCNN.png delete mode 100644 notebooks/chapter24/images/derivative_of_gaussian.png delete mode 100644 notebooks/chapter24/images/gradients.png delete mode 100644 notebooks/chapter24/images/laplacian.png delete mode 100644 notebooks/chapter24/images/laplacian_kernels.png delete mode 100644 notebooks/chapter24/images/stapler.png delete mode 100644 notebooks/chapter24/images/stapler_bbox.png delete mode 100644 obsolete_search4e.ipynb delete mode 100644 perception4e.py delete mode 100644 planning.ipynb delete mode 100644 planning.py delete mode 100644 planning_angelic_search.ipynb delete mode 100644 planning_graphPlan.ipynb delete mode 100644 planning_hierarchical_search.ipynb delete mode 100644 planning_partial_order_planner.ipynb delete mode 100644 planning_total_order_planner.ipynb delete mode 100644 probabilistic_learning.py delete mode 100644 probability.ipynb delete mode 100644 probability.py delete mode 100644 probability4e.ipynb delete mode 100644 probability4e.py delete mode 100644 pytest.ini delete mode 100644 reinforcement_learning.ipynb delete mode 100644 reinforcement_learning.py delete mode 100644 search.ipynb delete mode 100644 search.py delete mode 100644 search4e.ipynb delete mode 100644 tests/__init__.py delete mode 100644 tests/pytest.ini delete mode 100644 tests/test_agents.py delete mode 100644 tests/test_agents4e.py delete mode 100644 tests/test_csp.py delete mode 100644 tests/test_deep_learning4e.py delete mode 100644 tests/test_games.py delete mode 100644 tests/test_games4e.py delete mode 100644 tests/test_knowledge.py delete mode 100644 tests/test_learning.py delete mode 100644 tests/test_learning4e.py delete mode 100644 tests/test_logic.py delete mode 100644 tests/test_logic4e.py delete mode 100644 tests/test_mdp.py delete mode 100644 tests/test_mdp4e.py delete mode 100644 tests/test_nlp.py delete mode 100644 tests/test_nlp4e.py delete mode 100644 tests/test_perception4e.py delete mode 100644 tests/test_planning.py delete mode 100644 tests/test_probabilistic_learning.py delete mode 100644 tests/test_probability.py delete mode 100644 tests/test_probability4e.py delete mode 100644 tests/test_reinforcement_learning.py delete mode 100644 tests/test_reinforcement_learning4e.py delete mode 100644 tests/test_search.py delete mode 100644 tests/test_text.py delete mode 100644 tests/test_utils.py delete mode 100644 text.ipynb delete mode 100644 text.py delete mode 100644 utils.py delete mode 100644 vacuum_world.ipynb delete mode 100644 viterbi_algorithm.ipynb diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 688024601..000000000 --- a/.flake8 +++ /dev/null @@ -1,4 +0,0 @@ -[flake8] -max-line-length = 100 -ignore = E121,E123,E126,E221,E222,E225,E226,E242,E701,E702,E704,E731,W503,F405,F841 -exclude = tests diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index e465e8e4c..000000000 --- a/.travis.yml +++ /dev/null @@ -1,23 +0,0 @@ -language: python - -python: - - 3.5 - - 3.6 - - 3.7 - - 3.8 - -before_install: - - git submodule update --remote - -install: - - pip install --upgrade -r requirements.txt - -script: - - py.test --cov=./ - - python -m doctest -v *.py - -after_success: - - flake8 --max-line-length 100 --ignore=E121,E123,E126,E221,E222,E225,E226,E242,E701,E702,E704,E731,W503 . - -notifications: - email: false diff --git a/SUBMODULE.md b/SUBMODULE.md deleted file mode 100644 index 2c080bb91..000000000 --- a/SUBMODULE.md +++ /dev/null @@ -1,11 +0,0 @@ -This is a guide on how to update the `aima-data` submodule to the latest version. This needs to be done every time something changes in the [aima-data](https://github.com/aimacode/aima-data) repository. All the below commands should be executed from the local directory of the `aima-python` repository, using `git`. - -``` -git submodule deinit aima-data -git rm aima-data -git submodule add https://github.com/aimacode/aima-data.git aima-data -git commit -git push origin -``` - -Then you need to pull request the changes (unless you are a collaborator, in which case you can commit directly to the master). diff --git a/agents.ipynb b/agents.ipynb deleted file mode 100644 index 636df75e3..000000000 --- a/agents.ipynb +++ /dev/null @@ -1,735 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Intelligent Agents #\n", - "\n", - "This notebook serves as supporting material for topics covered in **Chapter 2 - Intelligent Agents** from the book *Artificial Intelligence: A Modern Approach.* This notebook uses implementations from [agents.py](https://github.com/aimacode/aima-python/blob/master/agents.py) module. Let's start by importing everything from agents module." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from agents import *\n", - "from notebook import psource" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## CONTENTS\n", - "\n", - "* Overview\n", - "* Agent\n", - "* Environment\n", - "* Simple Agent and Environment\n", - "* Agents in a 2-D Environment\n", - "* Wumpus Environment\n", - "\n", - "## OVERVIEW\n", - "\n", - "An agent, as defined in 2.1, is anything that can perceive its environment through sensors, and act upon that environment through actuators based on its agent program. This can be a dog, a robot, or even you. As long as you can perceive the environment and act on it, you are an agent. This notebook will explain how to implement a simple agent, create an environment, and implement a program that helps the agent act on the environment based on its percepts.\n", - "\n", - "## AGENT\n", - "\n", - "Let us now see how we define an agent. Run the next cell to see how `Agent` is defined in agents module." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "psource(Agent)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The `Agent` has two methods.\n", - "* `__init__(self, program=None)`: The constructor defines various attributes of the Agent. These include\n", - "\n", - " * `alive`: which keeps track of whether the agent is alive or not \n", - " \n", - " * `bump`: which tracks if the agent collides with an edge of the environment (for eg, a wall in a park)\n", - " \n", - " * `holding`: which is a list containing the `Things` an agent is holding, \n", - " \n", - " * `performance`: which evaluates the performance metrics of the agent \n", - " \n", - " * `program`: which is the agent program and maps an agent's percepts to actions in the environment. If no implementation is provided, it defaults to asking the user to provide actions for each percept.\n", - " \n", - "* `can_grab(self, thing)`: Is used when an environment contains things that an agent can grab and carry. By default, an agent can carry nothing.\n", - "\n", - "## ENVIRONMENT\n", - "Now, let us see how environments are defined. Running the next cell will display an implementation of the abstract `Environment` class." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "psource(Environment)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`Environment` class has lot of methods! But most of them are incredibly simple, so let's see the ones we'll be using in this notebook.\n", - "\n", - "* `thing_classes(self)`: Returns a static array of `Thing` sub-classes that determine what things are allowed in the environment and what aren't\n", - "\n", - "* `add_thing(self, thing, location=None)`: Adds a thing to the environment at location\n", - "\n", - "* `run(self, steps)`: Runs an environment with the agent in it for a given number of steps.\n", - "\n", - "* `is_done(self)`: Returns true if the objective of the agent and the environment has been completed\n", - "\n", - "The next two functions must be implemented by each subclasses of `Environment` for the agent to recieve percepts and execute actions \n", - "\n", - "* `percept(self, agent)`: Given an agent, this method returns a list of percepts that the agent sees at the current time\n", - "\n", - "* `execute_action(self, agent, action)`: The environment reacts to an action performed by a given agent. The changes may result in agent experiencing new percepts or other elements reacting to agent input." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## SIMPLE AGENT AND ENVIRONMENT\n", - "\n", - "Let's begin by using the `Agent` class to creating our first agent - a blind dog." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "class BlindDog(Agent):\n", - " def eat(self, thing):\n", - " print(\"Dog: Ate food at {}.\".format(self.location))\n", - " \n", - " def drink(self, thing):\n", - " print(\"Dog: Drank water at {}.\".format( self.location))\n", - "\n", - "dog = BlindDog()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "What we have just done is create a dog who can only feel what's in his location (since he's blind), and can eat or drink. Let's see if he's alive..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(dog.alive)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "![Cool dog](https://gifgun.files.wordpress.com/2015/07/wpid-wp-1435860392895.gif)\n", - "This is our dog. How cool is he? Well, he's hungry and needs to go search for food. For him to do this, we need to give him a program. But before that, let's create a park for our dog to play in." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### ENVIRONMENT - Park\n", - "\n", - "A park is an example of an environment because our dog can perceive and act upon it. The Environment class is an abstract class, so we will have to create our own subclass from it before we can use it." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "class Food(Thing):\n", - " pass\n", - "\n", - "class Water(Thing):\n", - " pass\n", - "\n", - "class Park(Environment):\n", - " def percept(self, agent):\n", - " '''return a list of things that are in our agent's location'''\n", - " things = self.list_things_at(agent.location)\n", - " return things\n", - " \n", - " def execute_action(self, agent, action):\n", - " '''changes the state of the environment based on what the agent does.'''\n", - " if action == \"move down\":\n", - " print('{} decided to {} at location: {}'.format(str(agent)[1:-1], action, agent.location))\n", - " agent.movedown()\n", - " elif action == \"eat\":\n", - " items = self.list_things_at(agent.location, tclass=Food)\n", - " if len(items) != 0:\n", - " if agent.eat(items[0]): #Have the dog eat the first item\n", - " print('{} ate {} at location: {}'\n", - " .format(str(agent)[1:-1], str(items[0])[1:-1], agent.location))\n", - " self.delete_thing(items[0]) #Delete it from the Park after.\n", - " elif action == \"drink\":\n", - " items = self.list_things_at(agent.location, tclass=Water)\n", - " if len(items) != 0:\n", - " if agent.drink(items[0]): #Have the dog drink the first item\n", - " print('{} drank {} at location: {}'\n", - " .format(str(agent)[1:-1], str(items[0])[1:-1], agent.location))\n", - " self.delete_thing(items[0]) #Delete it from the Park after.\n", - "\n", - " def is_done(self):\n", - " '''By default, we're done when we can't find a live agent, \n", - " but to prevent killing our cute dog, we will stop before itself - when there is no more food or water'''\n", - " no_edibles = not any(isinstance(thing, Food) or isinstance(thing, Water) for thing in self.things)\n", - " dead_agents = not any(agent.is_alive() for agent in self.agents)\n", - " return dead_agents or no_edibles\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### PROGRAM - BlindDog\n", - "Now that we have a Park Class, we re-implement our BlindDog to be able to move down and eat food or drink water only if it is present.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "class BlindDog(Agent):\n", - " location = 1\n", - " \n", - " def movedown(self):\n", - " self.location += 1\n", - " \n", - " def eat(self, thing):\n", - " '''returns True upon success or False otherwise'''\n", - " if isinstance(thing, Food):\n", - " return True\n", - " return False\n", - " \n", - " def drink(self, thing):\n", - " ''' returns True upon success or False otherwise'''\n", - " if isinstance(thing, Water):\n", - " return True\n", - " return False" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now its time to implement a program module for our dog. A program controls how the dog acts upon its environment. Our program will be very simple, and is shown in the table below.\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
Percept: Feel Food Feel WaterFeel Nothing
Action: eatdrinkmove down
" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def program(percepts):\n", - " '''Returns an action based on the dog's percepts'''\n", - " for p in percepts:\n", - " if isinstance(p, Food):\n", - " return 'eat'\n", - " elif isinstance(p, Water):\n", - " return 'drink'\n", - " return 'move down'" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's now run our simulation by creating a park with some food, water, and our dog." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "park = Park()\n", - "dog = BlindDog(program)\n", - "dogfood = Food()\n", - "water = Water()\n", - "park.add_thing(dog, 1)\n", - "park.add_thing(dogfood, 5)\n", - "park.add_thing(water, 7)\n", - "\n", - "park.run(5)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Notice that the dog moved from location 1 to 4, over 4 steps, and ate food at location 5 in the 5th step.\n", - "\n", - "Let's continue this simulation for 5 more steps." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "park.run(5)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Perfect! Note how the simulation stopped after the dog drank the water - exhausting all the food and water ends our simulation, as we had defined before. Let's add some more water and see if our dog can reach it." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "park.add_thing(water, 15)\n", - "park.run(10)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Above, we learnt to implement an agent, its program, and an environment on which it acts. However, this was a very simple case. Let's try to add complexity to it by creating a 2-Dimensional environment!\n", - "\n", - "\n", - "## AGENTS IN A 2D ENVIRONMENT\n", - "\n", - "For us to not read so many logs of what our dog did, we add a bit of graphics while making our Park 2D. To do so, we will need to make it a subclass of GraphicEnvironment instead of Environment. Parks implemented by subclassing GraphicEnvironment class adds these extra properties to it:\n", - "\n", - " - Our park is indexed in the 4th quadrant of the X-Y plane.\n", - " - Every time we create a park subclassing GraphicEnvironment, we need to define the colors of all the things we plan to put into the park. The colors are defined in typical [RGB digital 8-bit format](https://en.wikipedia.org/wiki/RGB_color_model#Numeric_representations), common across the web.\n", - " - Fences are added automatically to all parks so that our dog does not go outside the park's boundary - it just isn't safe for blind dogs to be outside the park by themselves! GraphicEnvironment provides `is_inbounds` function to check if our dog tries to leave the park.\n", - " \n", - "First let us try to upgrade our 1-dimensional `Park` environment by just replacing its superclass by `GraphicEnvironment`. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "class Park2D(GraphicEnvironment):\n", - " def percept(self, agent):\n", - " '''return a list of things that are in our agent's location'''\n", - " things = self.list_things_at(agent.location)\n", - " return things\n", - " \n", - " def execute_action(self, agent, action):\n", - " '''changes the state of the environment based on what the agent does.'''\n", - " if action == \"move down\":\n", - " print('{} decided to {} at location: {}'.format(str(agent)[1:-1], action, agent.location))\n", - " agent.movedown()\n", - " elif action == \"eat\":\n", - " items = self.list_things_at(agent.location, tclass=Food)\n", - " if len(items) != 0:\n", - " if agent.eat(items[0]): #Have the dog eat the first item\n", - " print('{} ate {} at location: {}'\n", - " .format(str(agent)[1:-1], str(items[0])[1:-1], agent.location))\n", - " self.delete_thing(items[0]) #Delete it from the Park after.\n", - " elif action == \"drink\":\n", - " items = self.list_things_at(agent.location, tclass=Water)\n", - " if len(items) != 0:\n", - " if agent.drink(items[0]): #Have the dog drink the first item\n", - " print('{} drank {} at location: {}'\n", - " .format(str(agent)[1:-1], str(items[0])[1:-1], agent.location))\n", - " self.delete_thing(items[0]) #Delete it from the Park after.\n", - " \n", - " def is_done(self):\n", - " '''By default, we're done when we can't find a live agent, \n", - " but to prevent killing our cute dog, we will stop before itself - when there is no more food or water'''\n", - " no_edibles = not any(isinstance(thing, Food) or isinstance(thing, Water) for thing in self.things)\n", - " dead_agents = not any(agent.is_alive() for agent in self.agents)\n", - " return dead_agents or no_edibles\n", - "\n", - "class BlindDog(Agent):\n", - " location = [0,1] # change location to a 2d value\n", - " direction = Direction(\"down\") # variable to store the direction our dog is facing\n", - " \n", - " def movedown(self):\n", - " self.location[1] += 1\n", - " \n", - " def eat(self, thing):\n", - " '''returns True upon success or False otherwise'''\n", - " if isinstance(thing, Food):\n", - " return True\n", - " return False\n", - " \n", - " def drink(self, thing):\n", - " ''' returns True upon success or False otherwise'''\n", - " if isinstance(thing, Water):\n", - " return True\n", - " return False" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now let's test this new park with our same dog, food and water. We color our dog with a nice red and mark food and water with orange and blue respectively." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "park = Park2D(5,20, color={'BlindDog': (200,0,0), 'Water': (0, 200, 200), 'Food': (230, 115, 40)}) # park width is set to 5, and height to 20\n", - "dog = BlindDog(program)\n", - "dogfood = Food()\n", - "water = Water()\n", - "park.add_thing(dog, [0,1])\n", - "park.add_thing(dogfood, [0,5])\n", - "park.add_thing(water, [0,7])\n", - "morewater = Water()\n", - "park.add_thing(morewater, [0,15])\n", - "print(\"BlindDog starts at (1,1) facing downwards, lets see if he can find any food!\")\n", - "park.run(20)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Adding some graphics was a good idea! We immediately see that the code works, but our blind dog doesn't make any use of the 2 dimensional space available to him. Let's make our dog more energetic so that he turns and moves forward, instead of always moving down. In doing so, we'll also need to make some changes to our environment to be able to handle this extra motion.\n", - "\n", - "### PROGRAM - EnergeticBlindDog\n", - "\n", - "Let's make our dog turn or move forwards at random - except when he's at the edge of our park - in which case we make him change his direction explicitly by turning to avoid trying to leave the park. However, our dog is blind so he wouldn't know which way to turn - he'd just have to try arbitrarily.\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
Percept: Feel Food Feel WaterFeel Nothing
Action: eatdrink\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
Remember being at Edge : At EdgeNot at Edge
Action : Turn Left / Turn Right
( 50% - 50% chance )
Turn Left / Turn Right / Move Forward
( 25% - 25% - 50% chance )
\n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from random import choice\n", - "\n", - "class EnergeticBlindDog(Agent):\n", - " location = [0,1]\n", - " direction = Direction(\"down\")\n", - " \n", - " def moveforward(self, success=True):\n", - " '''moveforward possible only if success (i.e. valid destination location)'''\n", - " if not success:\n", - " return\n", - " if self.direction.direction == Direction.R:\n", - " self.location[0] += 1\n", - " elif self.direction.direction == Direction.L:\n", - " self.location[0] -= 1\n", - " elif self.direction.direction == Direction.D:\n", - " self.location[1] += 1\n", - " elif self.direction.direction == Direction.U:\n", - " self.location[1] -= 1\n", - " \n", - " def turn(self, d):\n", - " self.direction = self.direction + d\n", - " \n", - " def eat(self, thing):\n", - " '''returns True upon success or False otherwise'''\n", - " if isinstance(thing, Food):\n", - " return True\n", - " return False\n", - " \n", - " def drink(self, thing):\n", - " ''' returns True upon success or False otherwise'''\n", - " if isinstance(thing, Water):\n", - " return True\n", - " return False\n", - " \n", - "def program(percepts):\n", - " '''Returns an action based on it's percepts'''\n", - " \n", - " for p in percepts: # first eat or drink - you're a dog!\n", - " if isinstance(p, Food):\n", - " return 'eat'\n", - " elif isinstance(p, Water):\n", - " return 'drink'\n", - " if isinstance(p,Bump): # then check if you are at an edge and have to turn\n", - " turn = False\n", - " choice = random.choice((1,2));\n", - " else:\n", - " choice = random.choice((1,2,3,4)) # 1-right, 2-left, others-forward\n", - " if choice == 1:\n", - " return 'turnright'\n", - " elif choice == 2:\n", - " return 'turnleft'\n", - " else:\n", - " return 'moveforward'\n", - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### ENVIRONMENT - Park2D\n", - "\n", - "We also need to modify our park accordingly, in order to be able to handle all the new actions our dog wishes to execute. Additionally, we'll need to prevent our dog from moving to locations beyond our park boundary - it just isn't safe for blind dogs to be outside the park by themselves." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "class Park2D(GraphicEnvironment):\n", - " def percept(self, agent):\n", - " '''return a list of things that are in our agent's location'''\n", - " things = self.list_things_at(agent.location)\n", - " loc = copy.deepcopy(agent.location) # find out the target location\n", - " #Check if agent is about to bump into a wall\n", - " if agent.direction.direction == Direction.R:\n", - " loc[0] += 1\n", - " elif agent.direction.direction == Direction.L:\n", - " loc[0] -= 1\n", - " elif agent.direction.direction == Direction.D:\n", - " loc[1] += 1\n", - " elif agent.direction.direction == Direction.U:\n", - " loc[1] -= 1\n", - " if not self.is_inbounds(loc):\n", - " things.append(Bump())\n", - " return things\n", - " \n", - " def execute_action(self, agent, action):\n", - " '''changes the state of the environment based on what the agent does.'''\n", - " if action == 'turnright':\n", - " print('{} decided to {} at location: {}'.format(str(agent)[1:-1], action, agent.location))\n", - " agent.turn(Direction.R)\n", - " elif action == 'turnleft':\n", - " print('{} decided to {} at location: {}'.format(str(agent)[1:-1], action, agent.location))\n", - " agent.turn(Direction.L)\n", - " elif action == 'moveforward':\n", - " print('{} decided to move {}wards at location: {}'.format(str(agent)[1:-1], agent.direction.direction, agent.location))\n", - " agent.moveforward()\n", - " elif action == \"eat\":\n", - " items = self.list_things_at(agent.location, tclass=Food)\n", - " if len(items) != 0:\n", - " if agent.eat(items[0]):\n", - " print('{} ate {} at location: {}'\n", - " .format(str(agent)[1:-1], str(items[0])[1:-1], agent.location))\n", - " self.delete_thing(items[0])\n", - " elif action == \"drink\":\n", - " items = self.list_things_at(agent.location, tclass=Water)\n", - " if len(items) != 0:\n", - " if agent.drink(items[0]):\n", - " print('{} drank {} at location: {}'\n", - " .format(str(agent)[1:-1], str(items[0])[1:-1], agent.location))\n", - " self.delete_thing(items[0])\n", - " \n", - " def is_done(self):\n", - " '''By default, we're done when we can't find a live agent, \n", - " but to prevent killing our cute dog, we will stop before itself - when there is no more food or water'''\n", - " no_edibles = not any(isinstance(thing, Food) or isinstance(thing, Water) for thing in self.things)\n", - " dead_agents = not any(agent.is_alive() for agent in self.agents)\n", - " return dead_agents or no_edibles\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now that our park is ready for the 2D motion of our energetic dog, lets test it!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "park = Park2D(5,5, color={'EnergeticBlindDog': (200,0,0), 'Water': (0, 200, 200), 'Food': (230, 115, 40)})\n", - "dog = EnergeticBlindDog(program)\n", - "dogfood = Food()\n", - "water = Water()\n", - "park.add_thing(dog, [0,0])\n", - "park.add_thing(dogfood, [1,2])\n", - "park.add_thing(water, [0,1])\n", - "morewater = Water()\n", - "morefood = Food()\n", - "park.add_thing(morewater, [2,4])\n", - "park.add_thing(morefood, [4,3])\n", - "print(\"dog started at [0,0], facing down. Let's see if he found any food or water!\")\n", - "park.run(20)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "## Wumpus Environment" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from ipythonblocks import BlockGrid\n", - "from agents import *\n", - "\n", - "color = {\"Breeze\": (225, 225, 225),\n", - " \"Pit\": (0,0,0),\n", - " \"Gold\": (253, 208, 23),\n", - " \"Glitter\": (253, 208, 23),\n", - " \"Wumpus\": (43, 27, 23),\n", - " \"Stench\": (128, 128, 128),\n", - " \"Explorer\": (0, 0, 255),\n", - " \"Wall\": (44, 53, 57)\n", - " }\n", - "\n", - "def program(percepts):\n", - " '''Returns an action based on it's percepts'''\n", - " print(percepts)\n", - " return input()\n", - "\n", - "w = WumpusEnvironment(program, 7, 7) \n", - "grid = BlockGrid(w.width, w.height, fill=(123, 234, 123))\n", - "\n", - "def draw_grid(world):\n", - " global grid\n", - " grid[:] = (123, 234, 123)\n", - " for x in range(0, len(world)):\n", - " for y in range(0, len(world[x])):\n", - " if len(world[x][y]):\n", - " grid[y, x] = color[world[x][y][-1].__class__.__name__]\n", - "\n", - "def step():\n", - " global grid, w\n", - " draw_grid(w.get_world())\n", - " grid.show()\n", - " w.step()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "step()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "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.6.4" - } - }, - "nbformat": 4, - "nbformat_minor": 1 -} diff --git a/agents.py b/agents.py deleted file mode 100644 index d29b0c382..000000000 --- a/agents.py +++ /dev/null @@ -1,1070 +0,0 @@ -""" -Implement Agents and Environments. (Chapters 1-2) - -The class hierarchies are as follows: - -Thing ## A physical object that can exist in an environment - Agent - Wumpus - Dirt - Wall - ... - -Environment ## An environment holds objects, runs simulations - XYEnvironment - VacuumEnvironment - WumpusEnvironment - -An agent program is a callable instance, taking percepts and choosing actions - SimpleReflexAgentProgram - ... - -EnvGUI ## A window with a graphical representation of the Environment - -EnvToolbar ## contains buttons for controlling EnvGUI - -EnvCanvas ## Canvas to display the environment of an EnvGUI -""" - -# TODO -# Speed control in GUI does not have any effect -- fix it. - -from utils import distance_squared, turn_heading -from statistics import mean -from ipythonblocks import BlockGrid -from IPython.display import HTML, display, clear_output -from time import sleep - -import random -import copy -import collections -import numbers - - -# ______________________________________________________________________________ - - -class Thing: - """This represents any physical object that can appear in an Environment. - You subclass Thing to get the things you want. Each thing can have a - .__name__ slot (used for output only).""" - - def __repr__(self): - return '<{}>'.format(getattr(self, '__name__', self.__class__.__name__)) - - def is_alive(self): - """Things that are 'alive' should return true.""" - return hasattr(self, 'alive') and self.alive - - def show_state(self): - """Display the agent's internal state. Subclasses should override.""" - print("I don't know how to show_state.") - - def display(self, canvas, x, y, width, height): - """Display an image of this Thing on the canvas.""" - # Do we need this? - pass - - -class Agent(Thing): - """An Agent is a subclass of Thing with one required instance attribute - (aka slot), .program, which should hold a function that takes one argument, - the percept, and returns an action. (What counts as a percept or action - will depend on the specific environment in which the agent exists.) - Note that 'program' is a slot, not a method. If it were a method, then the - program could 'cheat' and look at aspects of the agent. It's not supposed - to do that: the program can only look at the percepts. An agent program - that needs a model of the world (and of the agent itself) will have to - build and maintain its own model. There is an optional slot, .performance, - which is a number giving the performance measure of the agent in its - environment.""" - - def __init__(self, program=None): - self.alive = True - self.bump = False - self.holding = [] - self.performance = 0 - if program is None or not isinstance(program, collections.abc.Callable): - print("Can't find a valid program for {}, falling back to default.".format(self.__class__.__name__)) - - def program(percept): - return eval(input('Percept={}; action? '.format(percept))) - - self.program = program - - def can_grab(self, thing): - """Return True if this agent can grab this thing. - Override for appropriate subclasses of Agent and Thing.""" - return False - - -def TraceAgent(agent): - """Wrap the agent's program to print its input and output. This will let - you see what the agent is doing in the environment.""" - old_program = agent.program - - def new_program(percept): - action = old_program(percept) - print('{} perceives {} and does {}'.format(agent, percept, action)) - return action - - agent.program = new_program - return agent - - -# ______________________________________________________________________________ - - -def TableDrivenAgentProgram(table): - """ - [Figure 2.7] - This agent selects an action based on the percept sequence. - It is practical only for tiny domains. - To customize it, provide as table a dictionary of all - {percept_sequence:action} pairs. - """ - percepts = [] - - def program(percept): - percepts.append(percept) - action = table.get(tuple(percepts)) - return action - - return program - - -def RandomAgentProgram(actions): - """An agent that chooses an action at random, ignoring all percepts. - >>> list = ['Right', 'Left', 'Suck', 'NoOp'] - >>> program = RandomAgentProgram(list) - >>> agent = Agent(program) - >>> environment = TrivialVacuumEnvironment() - >>> environment.add_thing(agent) - >>> environment.run() - >>> environment.status == {(1, 0): 'Clean' , (0, 0): 'Clean'} - True - """ - return lambda percept: random.choice(actions) - - -# ______________________________________________________________________________ - - -def SimpleReflexAgentProgram(rules, interpret_input): - """ - [Figure 2.10] - This agent takes action based solely on the percept. - """ - - def program(percept): - state = interpret_input(percept) - rule = rule_match(state, rules) - action = rule.action - return action - - return program - - -def ModelBasedReflexAgentProgram(rules, update_state, model): - """ - [Figure 2.12] - This agent takes action based on the percept and state. - """ - - def program(percept): - program.state = update_state(program.state, program.action, percept, model) - rule = rule_match(program.state, rules) - action = rule.action - return action - - program.state = program.action = None - return program - - -def rule_match(state, rules): - """Find the first rule that matches state.""" - for rule in rules: - if rule.matches(state): - return rule - - -# ______________________________________________________________________________ - - -loc_A, loc_B = (0, 0), (1, 0) # The two locations for the Vacuum world - - -def RandomVacuumAgent(): - """Randomly choose one of the actions from the vacuum environment. - >>> agent = RandomVacuumAgent() - >>> environment = TrivialVacuumEnvironment() - >>> environment.add_thing(agent) - >>> environment.run() - >>> environment.status == {(1,0):'Clean' , (0,0) : 'Clean'} - True - """ - return Agent(RandomAgentProgram(['Right', 'Left', 'Suck', 'NoOp'])) - - -def TableDrivenVacuumAgent(): - """Tabular approach towards vacuum world as mentioned in [Figure 2.3] - >>> agent = TableDrivenVacuumAgent() - >>> environment = TrivialVacuumEnvironment() - >>> environment.add_thing(agent) - >>> environment.run() - >>> environment.status == {(1,0):'Clean' , (0,0) : 'Clean'} - True - """ - table = {((loc_A, 'Clean'),): 'Right', - ((loc_A, 'Dirty'),): 'Suck', - ((loc_B, 'Clean'),): 'Left', - ((loc_B, 'Dirty'),): 'Suck', - ((loc_A, 'Dirty'), (loc_A, 'Clean')): 'Right', - ((loc_A, 'Clean'), (loc_B, 'Dirty')): 'Suck', - ((loc_B, 'Clean'), (loc_A, 'Dirty')): 'Suck', - ((loc_B, 'Dirty'), (loc_B, 'Clean')): 'Left', - ((loc_A, 'Dirty'), (loc_A, 'Clean'), (loc_B, 'Dirty')): 'Suck', - ((loc_B, 'Dirty'), (loc_B, 'Clean'), (loc_A, 'Dirty')): 'Suck'} - return Agent(TableDrivenAgentProgram(table)) - - -def ReflexVacuumAgent(): - """ - [Figure 2.8] - A reflex agent for the two-state vacuum environment. - >>> agent = ReflexVacuumAgent() - >>> environment = TrivialVacuumEnvironment() - >>> environment.add_thing(agent) - >>> environment.run() - >>> environment.status == {(1,0):'Clean' , (0,0) : 'Clean'} - True - """ - - def program(percept): - location, status = percept - if status == 'Dirty': - return 'Suck' - elif location == loc_A: - return 'Right' - elif location == loc_B: - return 'Left' - - return Agent(program) - - -def ModelBasedVacuumAgent(): - """An agent that keeps track of what locations are clean or dirty. - >>> agent = ModelBasedVacuumAgent() - >>> environment = TrivialVacuumEnvironment() - >>> environment.add_thing(agent) - >>> environment.run() - >>> environment.status == {(1,0):'Clean' , (0,0) : 'Clean'} - True - """ - model = {loc_A: None, loc_B: None} - - def program(percept): - """Same as ReflexVacuumAgent, except if everything is clean, do NoOp.""" - location, status = percept - model[location] = status # Update the model here - if model[loc_A] == model[loc_B] == 'Clean': - return 'NoOp' - elif status == 'Dirty': - return 'Suck' - elif location == loc_A: - return 'Right' - elif location == loc_B: - return 'Left' - - return Agent(program) - - -# ______________________________________________________________________________ - - -class Environment: - """Abstract class representing an Environment. 'Real' Environment classes - inherit from this. Your Environment will typically need to implement: - percept: Define the percept that an agent sees. - execute_action: Define the effects of executing an action. - Also update the agent.performance slot. - The environment keeps a list of .things and .agents (which is a subset - of .things). Each agent has a .performance slot, initialized to 0. - Each thing has a .location slot, even though some environments may not - need this.""" - - def __init__(self): - self.things = [] - self.agents = [] - - def thing_classes(self): - return [] # List of classes that can go into environment - - def percept(self, agent): - """Return the percept that the agent sees at this point. (Implement this.)""" - raise NotImplementedError - - def execute_action(self, agent, action): - """Change the world to reflect this action. (Implement this.)""" - raise NotImplementedError - - def default_location(self, thing): - """Default location to place a new thing with unspecified location.""" - return None - - def exogenous_change(self): - """If there is spontaneous change in the world, override this.""" - pass - - def is_done(self): - """By default, we're done when we can't find a live agent.""" - return not any(agent.is_alive() for agent in self.agents) - - def step(self): - """Run the environment for one time step. If the - actions and exogenous changes are independent, this method will - do. If there are interactions between them, you'll need to - override this method.""" - if not self.is_done(): - actions = [] - for agent in self.agents: - if agent.alive: - actions.append(agent.program(self.percept(agent))) - else: - actions.append("") - for (agent, action) in zip(self.agents, actions): - self.execute_action(agent, action) - self.exogenous_change() - - def run(self, steps=1000): - """Run the Environment for given number of time steps.""" - for step in range(steps): - if self.is_done(): - return - self.step() - - def list_things_at(self, location, tclass=Thing): - """Return all things exactly at a given location.""" - if isinstance(location, numbers.Number): - return [thing for thing in self.things - if thing.location == location and isinstance(thing, tclass)] - return [thing for thing in self.things - if all(x == y for x, y in zip(thing.location, location)) and isinstance(thing, tclass)] - - def some_things_at(self, location, tclass=Thing): - """Return true if at least one of the things at location - is an instance of class tclass (or a subclass).""" - return self.list_things_at(location, tclass) != [] - - def add_thing(self, thing, location=None): - """Add a thing to the environment, setting its location. For - convenience, if thing is an agent program we make a new agent - for it. (Shouldn't need to override this.)""" - if not isinstance(thing, Thing): - thing = Agent(thing) - if thing in self.things: - print("Can't add the same thing twice") - else: - thing.location = location if location is not None else self.default_location(thing) - self.things.append(thing) - if isinstance(thing, Agent): - thing.performance = 0 - self.agents.append(thing) - - def delete_thing(self, thing): - """Remove a thing from the environment.""" - try: - self.things.remove(thing) - except ValueError as e: - print(e) - print(" in Environment delete_thing") - print(" Thing to be removed: {} at {}".format(thing, thing.location)) - print(" from list: {}".format([(thing, thing.location) for thing in self.things])) - if thing in self.agents: - self.agents.remove(thing) - - -class Direction: - """A direction class for agents that want to move in a 2D plane - Usage: - d = Direction("down") - To change directions: - d = d + "right" or d = d + Direction.R #Both do the same thing - Note that the argument to __add__ must be a string and not a Direction object. - Also, it (the argument) can only be right or left.""" - - R = "right" - L = "left" - U = "up" - D = "down" - - def __init__(self, direction): - self.direction = direction - - def __add__(self, heading): - """ - >>> d = Direction('right') - >>> l1 = d.__add__(Direction.L) - >>> l2 = d.__add__(Direction.R) - >>> l1.direction - 'up' - >>> l2.direction - 'down' - >>> d = Direction('down') - >>> l1 = d.__add__('right') - >>> l2 = d.__add__('left') - >>> l1.direction == Direction.L - True - >>> l2.direction == Direction.R - True - """ - if self.direction == self.R: - return { - self.R: Direction(self.D), - self.L: Direction(self.U), - }.get(heading, None) - elif self.direction == self.L: - return { - self.R: Direction(self.U), - self.L: Direction(self.D), - }.get(heading, None) - elif self.direction == self.U: - return { - self.R: Direction(self.R), - self.L: Direction(self.L), - }.get(heading, None) - elif self.direction == self.D: - return { - self.R: Direction(self.L), - self.L: Direction(self.R), - }.get(heading, None) - - def move_forward(self, from_location): - """ - >>> d = Direction('up') - >>> l1 = d.move_forward((0, 0)) - >>> l1 - (0, -1) - >>> d = Direction(Direction.R) - >>> l1 = d.move_forward((0, 0)) - >>> l1 - (1, 0) - """ - # get the iterable class to return - iclass = from_location.__class__ - x, y = from_location - if self.direction == self.R: - return iclass((x + 1, y)) - elif self.direction == self.L: - return iclass((x - 1, y)) - elif self.direction == self.U: - return iclass((x, y - 1)) - elif self.direction == self.D: - return iclass((x, y + 1)) - - -class XYEnvironment(Environment): - """This class is for environments on a 2D plane, with locations - labelled by (x, y) points, either discrete or continuous. - - Agents perceive things within a radius. Each agent in the - environment has a .location slot which should be a location such - as (0, 1), and a .holding slot, which should be a list of things - that are held.""" - - def __init__(self, width=10, height=10): - super().__init__() - - self.width = width - self.height = height - self.observers = [] - # Sets iteration start and end (no walls). - self.x_start, self.y_start = (0, 0) - self.x_end, self.y_end = (self.width, self.height) - - perceptible_distance = 1 - - def things_near(self, location, radius=None): - """Return all things within radius of location.""" - if radius is None: - radius = self.perceptible_distance - radius2 = radius * radius - return [(thing, radius2 - distance_squared(location, thing.location)) - for thing in self.things if distance_squared( - location, thing.location) <= radius2] - - def percept(self, agent): - """By default, agent perceives things within a default radius.""" - return self.things_near(agent.location) - - def execute_action(self, agent, action): - agent.bump = False - if action == 'TurnRight': - agent.direction += Direction.R - elif action == 'TurnLeft': - agent.direction += Direction.L - elif action == 'Forward': - agent.bump = self.move_to(agent, agent.direction.move_forward(agent.location)) - elif action == 'Grab': - things = [thing for thing in self.list_things_at(agent.location) if agent.can_grab(thing)] - if things: - agent.holding.append(things[0]) - print("Grabbing ", things[0].__class__.__name__) - self.delete_thing(things[0]) - elif action == 'Release': - if agent.holding: - dropped = agent.holding.pop() - print("Dropping ", dropped.__class__.__name__) - self.add_thing(dropped, location=agent.location) - - def default_location(self, thing): - location = self.random_location_inbounds() - while self.some_things_at(location, Obstacle): - # we will find a random location with no obstacles - location = self.random_location_inbounds() - return location - - def move_to(self, thing, destination): - """Move a thing to a new location. Returns True on success or False if there is an Obstacle. - If thing is holding anything, they move with him.""" - thing.bump = self.some_things_at(destination, Obstacle) - if not thing.bump: - thing.location = destination - for o in self.observers: - o.thing_moved(thing) - for t in thing.holding: - self.delete_thing(t) - self.add_thing(t, destination) - t.location = destination - return thing.bump - - def add_thing(self, thing, location=None, exclude_duplicate_class_items=False): - """Add things to the world. If (exclude_duplicate_class_items) then the item won't be - added if the location has at least one item of the same class.""" - if location is None: - super().add_thing(thing) - elif self.is_inbounds(location): - if (exclude_duplicate_class_items and - any(isinstance(t, thing.__class__) for t in self.list_things_at(location))): - return - super().add_thing(thing, location) - - def is_inbounds(self, location): - """Checks to make sure that the location is inbounds (within walls if we have walls)""" - x, y = location - return not (x < self.x_start or x > self.x_end or y < self.y_start or y > self.y_end) - - def random_location_inbounds(self, exclude=None): - """Returns a random location that is inbounds (within walls if we have walls)""" - location = (random.randint(self.x_start, self.x_end), - random.randint(self.y_start, self.y_end)) - if exclude is not None: - while location == exclude: - location = (random.randint(self.x_start, self.x_end), - random.randint(self.y_start, self.y_end)) - return location - - def delete_thing(self, thing): - """Deletes thing, and everything it is holding (if thing is an agent)""" - if isinstance(thing, Agent): - del thing.holding - - super().delete_thing(thing) - for obs in self.observers: - obs.thing_deleted(thing) - - def add_walls(self): - """Put walls around the entire perimeter of the grid.""" - for x in range(self.width): - self.add_thing(Wall(), (x, 0)) - self.add_thing(Wall(), (x, self.height - 1)) - for y in range(1, self.height - 1): - self.add_thing(Wall(), (0, y)) - self.add_thing(Wall(), (self.width - 1, y)) - - # Updates iteration start and end (with walls). - self.x_start, self.y_start = (1, 1) - self.x_end, self.y_end = (self.width - 1, self.height - 1) - - def add_observer(self, observer): - """Adds an observer to the list of observers. - An observer is typically an EnvGUI. - - Each observer is notified of changes in move_to and add_thing, - by calling the observer's methods thing_moved(thing) - and thing_added(thing, loc).""" - self.observers.append(observer) - - def turn_heading(self, heading, inc): - """Return the heading to the left (inc=+1) or right (inc=-1) of heading.""" - return turn_heading(heading, inc) - - -class Obstacle(Thing): - """Something that can cause a bump, preventing an agent from - moving into the same square it's in.""" - pass - - -class Wall(Obstacle): - pass - - -# ______________________________________________________________________________ - - -class GraphicEnvironment(XYEnvironment): - def __init__(self, width=10, height=10, boundary=True, color={}, display=False): - """Define all the usual XYEnvironment characteristics, - but initialise a BlockGrid for GUI too.""" - super().__init__(width, height) - self.grid = BlockGrid(width, height, fill=(200, 200, 200)) - if display: - self.grid.show() - self.visible = True - else: - self.visible = False - self.bounded = boundary - self.colors = color - - def get_world(self): - """Returns all the items in the world in a format - understandable by the ipythonblocks BlockGrid.""" - result = [] - x_start, y_start = (0, 0) - x_end, y_end = self.width, self.height - for x in range(x_start, x_end): - row = [] - for y in range(y_start, y_end): - row.append(self.list_things_at((x, y))) - result.append(row) - return result - - """ - def run(self, steps=1000, delay=1): - "" "Run the Environment for given number of time steps, - but update the GUI too." "" - for step in range(steps): - sleep(delay) - if self.visible: - self.reveal() - if self.is_done(): - if self.visible: - self.reveal() - return - self.step() - if self.visible: - self.reveal() - """ - - def run(self, steps=1000, delay=1): - """Run the Environment for given number of time steps, - but update the GUI too.""" - for step in range(steps): - self.update(delay) - if self.is_done(): - break - self.step() - self.update(delay) - - def update(self, delay=1): - sleep(delay) - self.reveal() - - def reveal(self): - """Display the BlockGrid for this world - the last thing to be added - at a location defines the location color.""" - self.draw_world() - # wait for the world to update and - # apply changes to the same grid instead - # of making a new one. - clear_output(1) - self.grid.show() - self.visible = True - - def draw_world(self): - self.grid[:] = (200, 200, 200) - world = self.get_world() - for x in range(0, len(world)): - for y in range(0, len(world[x])): - if len(world[x][y]): - self.grid[y, x] = self.colors[world[x][y][-1].__class__.__name__] - - def conceal(self): - """Hide the BlockGrid for this world""" - self.visible = False - display(HTML('')) - - -# ______________________________________________________________________________ -# Continuous environment - -class ContinuousWorld(Environment): - """Model for Continuous World""" - - def __init__(self, width=10, height=10): - super().__init__() - self.width = width - self.height = height - - def add_obstacle(self, coordinates): - self.things.append(PolygonObstacle(coordinates)) - - -class PolygonObstacle(Obstacle): - - def __init__(self, coordinates): - """Coordinates is a list of tuples.""" - super().__init__() - self.coordinates = coordinates - - -# ______________________________________________________________________________ -# Vacuum environment - - -class Dirt(Thing): - pass - - -class VacuumEnvironment(XYEnvironment): - """The environment of [Ex. 2.12]. Agent perceives dirty or clean, - and bump (into obstacle) or not; 2D discrete world of unknown size; - performance measure is 100 for each dirt cleaned, and -1 for - each turn taken.""" - - def __init__(self, width=10, height=10): - super().__init__(width, height) - self.add_walls() - - def thing_classes(self): - return [Wall, Dirt, ReflexVacuumAgent, RandomVacuumAgent, - TableDrivenVacuumAgent, ModelBasedVacuumAgent] - - def percept(self, agent): - """The percept is a tuple of ('Dirty' or 'Clean', 'Bump' or 'None'). - Unlike the TrivialVacuumEnvironment, location is NOT perceived.""" - status = ('Dirty' if self.some_things_at( - agent.location, Dirt) else 'Clean') - bump = ('Bump' if agent.bump else 'None') - return status, bump - - def execute_action(self, agent, action): - agent.bump = False - if action == 'Suck': - dirt_list = self.list_things_at(agent.location, Dirt) - if dirt_list != []: - dirt = dirt_list[0] - agent.performance += 100 - self.delete_thing(dirt) - else: - super().execute_action(agent, action) - - if action != 'NoOp': - agent.performance -= 1 - - -class TrivialVacuumEnvironment(Environment): - """This environment has two locations, A and B. Each can be Dirty - or Clean. The agent perceives its location and the location's - status. This serves as an example of how to implement a simple - Environment.""" - - def __init__(self): - super().__init__() - self.status = {loc_A: random.choice(['Clean', 'Dirty']), - loc_B: random.choice(['Clean', 'Dirty'])} - - def thing_classes(self): - return [Wall, Dirt, ReflexVacuumAgent, RandomVacuumAgent, TableDrivenVacuumAgent, ModelBasedVacuumAgent] - - def percept(self, agent): - """Returns the agent's location, and the location status (Dirty/Clean).""" - return agent.location, self.status[agent.location] - - def execute_action(self, agent, action): - """Change agent's location and/or location's status; track performance. - Score 10 for each dirt cleaned; -1 for each move.""" - if action == 'Right': - agent.location = loc_B - agent.performance -= 1 - elif action == 'Left': - agent.location = loc_A - agent.performance -= 1 - elif action == 'Suck': - if self.status[agent.location] == 'Dirty': - agent.performance += 10 - self.status[agent.location] = 'Clean' - - def default_location(self, thing): - """Agents start in either location at random.""" - return random.choice([loc_A, loc_B]) - - -# ______________________________________________________________________________ -# The Wumpus World - - -class Gold(Thing): - - def __eq__(self, rhs): - """All Gold are equal""" - return rhs.__class__ == Gold - - pass - - -class Bump(Thing): - pass - - -class Glitter(Thing): - pass - - -class Pit(Thing): - pass - - -class Breeze(Thing): - pass - - -class Arrow(Thing): - pass - - -class Scream(Thing): - pass - - -class Wumpus(Agent): - screamed = False - pass - - -class Stench(Thing): - pass - - -class Explorer(Agent): - holding = [] - has_arrow = True - killed_by = "" - direction = Direction("right") - - def can_grab(self, thing): - """Explorer can only grab gold""" - return thing.__class__ == Gold - - -class WumpusEnvironment(XYEnvironment): - pit_probability = 0.2 # Probability to spawn a pit in a location. (From Chapter 7.2) - - # Room should be 4x4 grid of rooms. The extra 2 for walls - - def __init__(self, agent_program, width=6, height=6): - super().__init__(width, height) - self.init_world(agent_program) - - def init_world(self, program): - """Spawn items in the world based on probabilities from the book""" - - "WALLS" - self.add_walls() - - "PITS" - for x in range(self.x_start, self.x_end): - for y in range(self.y_start, self.y_end): - if random.random() < self.pit_probability: - self.add_thing(Pit(), (x, y), True) - self.add_thing(Breeze(), (x - 1, y), True) - self.add_thing(Breeze(), (x, y - 1), True) - self.add_thing(Breeze(), (x + 1, y), True) - self.add_thing(Breeze(), (x, y + 1), True) - - "WUMPUS" - w_x, w_y = self.random_location_inbounds(exclude=(1, 1)) - self.add_thing(Wumpus(lambda x: ""), (w_x, w_y), True) - self.add_thing(Stench(), (w_x - 1, w_y), True) - self.add_thing(Stench(), (w_x + 1, w_y), True) - self.add_thing(Stench(), (w_x, w_y - 1), True) - self.add_thing(Stench(), (w_x, w_y + 1), True) - - "GOLD" - self.add_thing(Gold(), self.random_location_inbounds(exclude=(1, 1)), True) - - "AGENT" - self.add_thing(Explorer(program), (1, 1), True) - - def get_world(self, show_walls=True): - """Return the items in the world""" - result = [] - x_start, y_start = (0, 0) if show_walls else (1, 1) - - if show_walls: - x_end, y_end = self.width, self.height - else: - x_end, y_end = self.width - 1, self.height - 1 - - for x in range(x_start, x_end): - row = [] - for y in range(y_start, y_end): - row.append(self.list_things_at((x, y))) - result.append(row) - return result - - def percepts_from(self, agent, location, tclass=Thing): - """Return percepts from a given location, - and replaces some items with percepts from chapter 7.""" - thing_percepts = { - Gold: Glitter(), - Wall: Bump(), - Wumpus: Stench(), - Pit: Breeze()} - - """Agents don't need to get their percepts""" - thing_percepts[agent.__class__] = None - - """Gold only glitters in its cell""" - if location != agent.location: - thing_percepts[Gold] = None - - result = [thing_percepts.get(thing.__class__, thing) for thing in self.things - if thing.location == location and isinstance(thing, tclass)] - return result if len(result) else [None] - - def percept(self, agent): - """Return things in adjacent (not diagonal) cells of the agent. - Result format: [Left, Right, Up, Down, Center / Current location]""" - x, y = agent.location - result = [] - result.append(self.percepts_from(agent, (x - 1, y))) - result.append(self.percepts_from(agent, (x + 1, y))) - result.append(self.percepts_from(agent, (x, y - 1))) - result.append(self.percepts_from(agent, (x, y + 1))) - result.append(self.percepts_from(agent, (x, y))) - - """The wumpus gives out a loud scream once it's killed.""" - wumpus = [thing for thing in self.things if isinstance(thing, Wumpus)] - if len(wumpus) and not wumpus[0].alive and not wumpus[0].screamed: - result[-1].append(Scream()) - wumpus[0].screamed = True - - return result - - def execute_action(self, agent, action): - """Modify the state of the environment based on the agent's actions. - Performance score taken directly out of the book.""" - - if isinstance(agent, Explorer) and self.in_danger(agent): - return - - agent.bump = False - if action in ['TurnRight', 'TurnLeft', 'Forward', 'Grab']: - super().execute_action(agent, action) - agent.performance -= 1 - elif action == 'Climb': - if agent.location == (1, 1): # Agent can only climb out of (1,1) - agent.performance += 1000 if Gold() in agent.holding else 0 - self.delete_thing(agent) - elif action == 'Shoot': - """The arrow travels straight down the path the agent is facing""" - if agent.has_arrow: - arrow_travel = agent.direction.move_forward(agent.location) - while self.is_inbounds(arrow_travel): - wumpus = [thing for thing in self.list_things_at(arrow_travel) - if isinstance(thing, Wumpus)] - if len(wumpus): - wumpus[0].alive = False - break - arrow_travel = agent.direction.move_forward(agent.location) - agent.has_arrow = False - - def in_danger(self, agent): - """Check if Explorer is in danger (Pit or Wumpus), if he is, kill him""" - for thing in self.list_things_at(agent.location): - if isinstance(thing, Pit) or (isinstance(thing, Wumpus) and thing.alive): - agent.alive = False - agent.performance -= 1000 - agent.killed_by = thing.__class__.__name__ - return True - return False - - def is_done(self): - """The game is over when the Explorer is killed - or if he climbs out of the cave only at (1,1).""" - explorer = [agent for agent in self.agents if isinstance(agent, Explorer)] - if len(explorer): - if explorer[0].alive: - return False - else: - print("Death by {} [-1000].".format(explorer[0].killed_by)) - else: - print("Explorer climbed out {}." - .format("with Gold [+1000]!" if Gold() not in self.things else "without Gold [+0]")) - return True - - # TODO: Arrow needs to be implemented - - -# ______________________________________________________________________________ - - -def compare_agents(EnvFactory, AgentFactories, n=10, steps=1000): - """See how well each of several agents do in n instances of an environment. - Pass in a factory (constructor) for environments, and several for agents. - Create n instances of the environment, and run each agent in copies of - each one for steps. Return a list of (agent, average-score) tuples. - >>> environment = TrivialVacuumEnvironment - >>> agents = [ModelBasedVacuumAgent, ReflexVacuumAgent] - >>> result = compare_agents(environment, agents) - >>> performance_ModelBasedVacuumAgent = result[0][1] - >>> performance_ReflexVacuumAgent = result[1][1] - >>> performance_ReflexVacuumAgent <= performance_ModelBasedVacuumAgent - True - """ - envs = [EnvFactory() for i in range(n)] - return [(A, test_agent(A, steps, copy.deepcopy(envs))) - for A in AgentFactories] - - -def test_agent(AgentFactory, steps, envs): - """Return the mean score of running an agent in each of the envs, for steps - >>> def constant_prog(percept): - ... return percept - ... - >>> agent = Agent(constant_prog) - >>> result = agent.program(5) - >>> result == 5 - True - """ - - def score(env): - agent = AgentFactory() - env.add_thing(agent) - env.run(steps) - return agent.performance - - return mean(map(score, envs)) - - -# _________________________________________________________________________ - - -__doc__ += """ ->>> a = ReflexVacuumAgent() ->>> a.program((loc_A, 'Clean')) -'Right' ->>> a.program((loc_B, 'Clean')) -'Left' ->>> a.program((loc_A, 'Dirty')) -'Suck' ->>> a.program((loc_A, 'Dirty')) -'Suck' - ->>> e = TrivialVacuumEnvironment() ->>> e.add_thing(ModelBasedVacuumAgent()) ->>> e.run(5) - -""" diff --git a/agents4e.py b/agents4e.py deleted file mode 100644 index 75369a69a..000000000 --- a/agents4e.py +++ /dev/null @@ -1,1089 +0,0 @@ -""" -Implement Agents and Environments. (Chapters 1-2) - -The class hierarchies are as follows: - -Thing ## A physical object that can exist in an environment - Agent - Wumpus - Dirt - Wall - ... - -Environment ## An environment holds objects, runs simulations - XYEnvironment - VacuumEnvironment - WumpusEnvironment - -An agent program is a callable instance, taking percepts and choosing actions - SimpleReflexAgentProgram - ... - -EnvGUI ## A window with a graphical representation of the Environment - -EnvToolbar ## contains buttons for controlling EnvGUI - -EnvCanvas ## Canvas to display the environment of an EnvGUI -""" - -# TODO -# Implement grabbing correctly. -# When an object is grabbed, does it still have a location? -# What if it is released? -# What if the grabbed or the grabber is deleted? -# What if the grabber moves? -# Speed control in GUI does not have any effect -- fix it. - -from utils4e import distance_squared, turn_heading -from statistics import mean -from ipythonblocks import BlockGrid -from IPython.display import HTML, display, clear_output -from time import sleep - -import random -import copy -import collections -import numbers - - -# ______________________________________________________________________________ - - -class Thing: - """This represents any physical object that can appear in an Environment. - You subclass Thing to get the things you want. Each thing can have a - .__name__ slot (used for output only).""" - - def __repr__(self): - return '<{}>'.format(getattr(self, '__name__', self.__class__.__name__)) - - def is_alive(self): - """Things that are 'alive' should return true.""" - return hasattr(self, 'alive') and self.alive - - def show_state(self): - """Display the agent's internal state. Subclasses should override.""" - print("I don't know how to show_state.") - - def display(self, canvas, x, y, width, height): - """Display an image of this Thing on the canvas.""" - # Do we need this? - pass - - -class Agent(Thing): - """An Agent is a subclass of Thing with one required slot, - .program, which should hold a function that takes one argument, the - percept, and returns an action. (What counts as a percept or action - will depend on the specific environment in which the agent exists.) - Note that 'program' is a slot, not a method. If it were a method, - then the program could 'cheat' and look at aspects of the agent. - It's not supposed to do that: the program can only look at the - percepts. An agent program that needs a model of the world (and of - the agent itself) will have to build and maintain its own model. - There is an optional slot, .performance, which is a number giving - the performance measure of the agent in its environment.""" - - def __init__(self, program=None): - self.alive = True - self.bump = False - self.holding = [] - self.performance = 0 - if program is None or not isinstance(program, collections.abc.Callable): - print("Can't find a valid program for {}, falling back to default.".format(self.__class__.__name__)) - - def program(percept): - return eval(input('Percept={}; action? '.format(percept))) - - self.program = program - - def can_grab(self, thing): - """Return True if this agent can grab this thing. - Override for appropriate subclasses of Agent and Thing.""" - return False - - -def TraceAgent(agent): - """Wrap the agent's program to print its input and output. This will let - you see what the agent is doing in the environment.""" - old_program = agent.program - - def new_program(percept): - action = old_program(percept) - print('{} perceives {} and does {}'.format(agent, percept, action)) - return action - - agent.program = new_program - return agent - - -# ______________________________________________________________________________ - - -def TableDrivenAgentProgram(table): - """ - [Figure 2.7] - This agent selects an action based on the percept sequence. - It is practical only for tiny domains. - To customize it, provide as table a dictionary of all - {percept_sequence:action} pairs. - """ - percepts = [] - - def program(percept): - percepts.append(percept) - action = table.get(tuple(percepts)) - return action - - return program - - -def RandomAgentProgram(actions): - """An agent that chooses an action at random, ignoring all percepts. - >>> list = ['Right', 'Left', 'Suck', 'NoOp'] - >>> program = RandomAgentProgram(list) - >>> agent = Agent(program) - >>> environment = TrivialVacuumEnvironment() - >>> environment.add_thing(agent) - >>> environment.run() - >>> environment.status == {(1, 0): 'Clean' , (0, 0): 'Clean'} - True - """ - return lambda percept: random.choice(actions) - - -# ______________________________________________________________________________ - - -def SimpleReflexAgentProgram(rules, interpret_input): - """ - [Figure 2.10] - This agent takes action based solely on the percept. - """ - - def program(percept): - state = interpret_input(percept) - rule = rule_match(state, rules) - action = rule.action - return action - - return program - - -def ModelBasedReflexAgentProgram(rules, update_state, transition_model, sensor_model): - """ - [Figure 2.12] - This agent takes action based on the percept and state. - """ - - def program(percept): - program.state = update_state(program.state, program.action, percept, transition_model, sensor_model) - rule = rule_match(program.state, rules) - action = rule.action - return action - - program.state = program.action = None - return program - - -def rule_match(state, rules): - """Find the first rule that matches state.""" - for rule in rules: - if rule.matches(state): - return rule - - -# ______________________________________________________________________________ - - -loc_A, loc_B = (0, 0), (1, 0) # The two locations for the Vacuum world - - -def RandomVacuumAgent(): - """Randomly choose one of the actions from the vacuum environment. - >>> agent = RandomVacuumAgent() - >>> environment = TrivialVacuumEnvironment() - >>> environment.add_thing(agent) - >>> environment.run() - >>> environment.status == {(1,0):'Clean' , (0,0) : 'Clean'} - True - """ - return Agent(RandomAgentProgram(['Right', 'Left', 'Suck', 'NoOp'])) - - -def TableDrivenVacuumAgent(): - """Tabular approach towards vacuum world as mentioned in [Figure 2.3] - >>> agent = TableDrivenVacuumAgent() - >>> environment = TrivialVacuumEnvironment() - >>> environment.add_thing(agent) - >>> environment.run() - >>> environment.status == {(1,0):'Clean' , (0,0) : 'Clean'} - True - """ - table = {((loc_A, 'Clean'),): 'Right', - ((loc_A, 'Dirty'),): 'Suck', - ((loc_B, 'Clean'),): 'Left', - ((loc_B, 'Dirty'),): 'Suck', - ((loc_A, 'Dirty'), (loc_A, 'Clean')): 'Right', - ((loc_A, 'Clean'), (loc_B, 'Dirty')): 'Suck', - ((loc_B, 'Clean'), (loc_A, 'Dirty')): 'Suck', - ((loc_B, 'Dirty'), (loc_B, 'Clean')): 'Left', - ((loc_A, 'Dirty'), (loc_A, 'Clean'), (loc_B, 'Dirty')): 'Suck', - ((loc_B, 'Dirty'), (loc_B, 'Clean'), (loc_A, 'Dirty')): 'Suck'} - return Agent(TableDrivenAgentProgram(table)) - - -def ReflexVacuumAgent(): - """ - [Figure 2.8] - A reflex agent for the two-state vacuum environment. - >>> agent = ReflexVacuumAgent() - >>> environment = TrivialVacuumEnvironment() - >>> environment.add_thing(agent) - >>> environment.run() - >>> environment.status == {(1,0):'Clean' , (0,0) : 'Clean'} - True - """ - - def program(percept): - location, status = percept - if status == 'Dirty': - return 'Suck' - elif location == loc_A: - return 'Right' - elif location == loc_B: - return 'Left' - - return Agent(program) - - -def ModelBasedVacuumAgent(): - """An agent that keeps track of what locations are clean or dirty. - >>> agent = ModelBasedVacuumAgent() - >>> environment = TrivialVacuumEnvironment() - >>> environment.add_thing(agent) - >>> environment.run() - >>> environment.status == {(1,0):'Clean' , (0,0) : 'Clean'} - True - """ - model = {loc_A: None, loc_B: None} - - def program(percept): - """Same as ReflexVacuumAgent, except if everything is clean, do NoOp.""" - location, status = percept - model[location] = status # Update the model here - if model[loc_A] == model[loc_B] == 'Clean': - return 'NoOp' - elif status == 'Dirty': - return 'Suck' - elif location == loc_A: - return 'Right' - elif location == loc_B: - return 'Left' - - return Agent(program) - - -# ______________________________________________________________________________ - - -class Environment: - """Abstract class representing an Environment. 'Real' Environment classes - inherit from this. Your Environment will typically need to implement: - percept: Define the percept that an agent sees. - execute_action: Define the effects of executing an action. - Also update the agent.performance slot. - The environment keeps a list of .things and .agents (which is a subset - of .things). Each agent has a .performance slot, initialized to 0. - Each thing has a .location slot, even though some environments may not - need this.""" - - def __init__(self): - self.things = [] - self.agents = [] - - def thing_classes(self): - return [] # List of classes that can go into environment - - def percept(self, agent): - """Return the percept that the agent sees at this point. (Implement this.)""" - raise NotImplementedError - - def execute_action(self, agent, action): - """Change the world to reflect this action. (Implement this.)""" - raise NotImplementedError - - def default_location(self, thing): - """Default location to place a new thing with unspecified location.""" - return None - - def exogenous_change(self): - """If there is spontaneous change in the world, override this.""" - pass - - def is_done(self): - """By default, we're done when we can't find a live agent.""" - return not any(agent.is_alive() for agent in self.agents) - - def step(self): - """Run the environment for one time step. If the - actions and exogenous changes are independent, this method will - do. If there are interactions between them, you'll need to - override this method.""" - if not self.is_done(): - actions = [] - for agent in self.agents: - if agent.alive: - actions.append(agent.program(self.percept(agent))) - else: - actions.append("") - for (agent, action) in zip(self.agents, actions): - self.execute_action(agent, action) - self.exogenous_change() - - def run(self, steps=1000): - """Run the Environment for given number of time steps.""" - for step in range(steps): - if self.is_done(): - return - self.step() - - def list_things_at(self, location, tclass=Thing): - """Return all things exactly at a given location.""" - if isinstance(location, numbers.Number): - return [thing for thing in self.things - if thing.location == location and isinstance(thing, tclass)] - return [thing for thing in self.things - if all(x == y for x, y in zip(thing.location, location)) and isinstance(thing, tclass)] - - def some_things_at(self, location, tclass=Thing): - """Return true if at least one of the things at location - is an instance of class tclass (or a subclass).""" - return self.list_things_at(location, tclass) != [] - - def add_thing(self, thing, location=None): - """Add a thing to the environment, setting its location. For - convenience, if thing is an agent program we make a new agent - for it. (Shouldn't need to override this.)""" - if not isinstance(thing, Thing): - thing = Agent(thing) - if thing in self.things: - print("Can't add the same thing twice") - else: - thing.location = location if location is not None else self.default_location(thing) - self.things.append(thing) - if isinstance(thing, Agent): - thing.performance = 0 - self.agents.append(thing) - - def delete_thing(self, thing): - """Remove a thing from the environment.""" - try: - self.things.remove(thing) - except ValueError as e: - print(e) - print(" in Environment delete_thing") - print(" Thing to be removed: {} at {}".format(thing, thing.location)) - print(" from list: {}".format([(thing, thing.location) for thing in self.things])) - if thing in self.agents: - self.agents.remove(thing) - - -class Direction: - """A direction class for agents that want to move in a 2D plane - Usage: - d = Direction("down") - To change directions: - d = d + "right" or d = d + Direction.R #Both do the same thing - Note that the argument to __add__ must be a string and not a Direction object. - Also, it (the argument) can only be right or left.""" - - R = "right" - L = "left" - U = "up" - D = "down" - - def __init__(self, direction): - self.direction = direction - - def __add__(self, heading): - """ - >>> d = Direction('right') - >>> l1 = d.__add__(Direction.L) - >>> l2 = d.__add__(Direction.R) - >>> l1.direction - 'up' - >>> l2.direction - 'down' - >>> d = Direction('down') - >>> l1 = d.__add__('right') - >>> l2 = d.__add__('left') - >>> l1.direction == Direction.L - True - >>> l2.direction == Direction.R - True - """ - if self.direction == self.R: - return { - self.R: Direction(self.D), - self.L: Direction(self.U), - }.get(heading, None) - elif self.direction == self.L: - return { - self.R: Direction(self.U), - self.L: Direction(self.D), - }.get(heading, None) - elif self.direction == self.U: - return { - self.R: Direction(self.R), - self.L: Direction(self.L), - }.get(heading, None) - elif self.direction == self.D: - return { - self.R: Direction(self.L), - self.L: Direction(self.R), - }.get(heading, None) - - def move_forward(self, from_location): - """ - >>> d = Direction('up') - >>> l1 = d.move_forward((0, 0)) - >>> l1 - (0, -1) - >>> d = Direction(Direction.R) - >>> l1 = d.move_forward((0, 0)) - >>> l1 - (1, 0) - """ - # get the iterable class to return - iclass = from_location.__class__ - x, y = from_location - if self.direction == self.R: - return iclass((x + 1, y)) - elif self.direction == self.L: - return iclass((x - 1, y)) - elif self.direction == self.U: - return iclass((x, y - 1)) - elif self.direction == self.D: - return iclass((x, y + 1)) - - -class XYEnvironment(Environment): - """This class is for environments on a 2D plane, with locations - labelled by (x, y) points, either discrete or continuous. - - Agents perceive things within a radius. Each agent in the - environment has a .location slot which should be a location such - as (0, 1), and a .holding slot, which should be a list of things - that are held.""" - - def __init__(self, width=10, height=10): - super().__init__() - - self.width = width - self.height = height - self.observers = [] - # Sets iteration start and end (no walls). - self.x_start, self.y_start = (0, 0) - self.x_end, self.y_end = (self.width, self.height) - - perceptible_distance = 1 - - def things_near(self, location, radius=None): - """Return all things within radius of location.""" - if radius is None: - radius = self.perceptible_distance - radius2 = radius * radius - return [(thing, radius2 - distance_squared(location, thing.location)) - for thing in self.things if distance_squared( - location, thing.location) <= radius2] - - def percept(self, agent): - """By default, agent perceives things within a default radius.""" - return self.things_near(agent.location) - - def execute_action(self, agent, action): - agent.bump = False - if action == 'TurnRight': - agent.direction += Direction.R - elif action == 'TurnLeft': - agent.direction += Direction.L - elif action == 'Forward': - agent.bump = self.move_to(agent, agent.direction.move_forward(agent.location)) - # elif action == 'Grab': - # things = [thing for thing in self.list_things_at(agent.location) - # if agent.can_grab(thing)] - # if things: - # agent.holding.append(things[0]) - elif action == 'Release': - if agent.holding: - agent.holding.pop() - - def default_location(self, thing): - location = self.random_location_inbounds() - while self.some_things_at(location, Obstacle): - # we will find a random location with no obstacles - location = self.random_location_inbounds() - return location - - def move_to(self, thing, destination): - """Move a thing to a new location. Returns True on success or False if there is an Obstacle. - If thing is holding anything, they move with him.""" - thing.bump = self.some_things_at(destination, Obstacle) - if not thing.bump: - thing.location = destination - for o in self.observers: - o.thing_moved(thing) - for t in thing.holding: - self.delete_thing(t) - self.add_thing(t, destination) - t.location = destination - return thing.bump - - def add_thing(self, thing, location=None, exclude_duplicate_class_items=False): - """Add things to the world. If (exclude_duplicate_class_items) then the item won't be - added if the location has at least one item of the same class.""" - if location is None: - super().add_thing(thing) - elif self.is_inbounds(location): - if (exclude_duplicate_class_items and - any(isinstance(t, thing.__class__) for t in self.list_things_at(location))): - return - super().add_thing(thing, location) - - def is_inbounds(self, location): - """Checks to make sure that the location is inbounds (within walls if we have walls)""" - x, y = location - return not (x < self.x_start or x > self.x_end or y < self.y_start or y > self.y_end) - - def random_location_inbounds(self, exclude=None): - """Returns a random location that is inbounds (within walls if we have walls)""" - location = (random.randint(self.x_start, self.x_end), - random.randint(self.y_start, self.y_end)) - if exclude is not None: - while location == exclude: - location = (random.randint(self.x_start, self.x_end), - random.randint(self.y_start, self.y_end)) - return location - - def delete_thing(self, thing): - """Deletes thing, and everything it is holding (if thing is an agent)""" - if isinstance(thing, Agent): - for obj in thing.holding: - super().delete_thing(obj) - for obs in self.observers: - obs.thing_deleted(obj) - - super().delete_thing(thing) - for obs in self.observers: - obs.thing_deleted(thing) - - def add_walls(self): - """Put walls around the entire perimeter of the grid.""" - for x in range(self.width): - self.add_thing(Wall(), (x, 0)) - self.add_thing(Wall(), (x, self.height - 1)) - for y in range(1, self.height - 1): - self.add_thing(Wall(), (0, y)) - self.add_thing(Wall(), (self.width - 1, y)) - - # Updates iteration start and end (with walls). - self.x_start, self.y_start = (1, 1) - self.x_end, self.y_end = (self.width - 1, self.height - 1) - - def add_observer(self, observer): - """Adds an observer to the list of observers. - An observer is typically an EnvGUI. - - Each observer is notified of changes in move_to and add_thing, - by calling the observer's methods thing_moved(thing) - and thing_added(thing, loc).""" - self.observers.append(observer) - - def turn_heading(self, heading, inc): - """Return the heading to the left (inc=+1) or right (inc=-1) of heading.""" - return turn_heading(heading, inc) - - -class Obstacle(Thing): - """Something that can cause a bump, preventing an agent from - moving into the same square it's in.""" - pass - - -class Wall(Obstacle): - pass - - -# ______________________________________________________________________________ - - -class GraphicEnvironment(XYEnvironment): - def __init__(self, width=10, height=10, boundary=True, color={}, display=False): - """Define all the usual XYEnvironment characteristics, - but initialise a BlockGrid for GUI too.""" - super().__init__(width, height) - self.grid = BlockGrid(width, height, fill=(200, 200, 200)) - if display: - self.grid.show() - self.visible = True - else: - self.visible = False - self.bounded = boundary - self.colors = color - - def get_world(self): - """Returns all the items in the world in a format - understandable by the ipythonblocks BlockGrid.""" - result = [] - x_start, y_start = (0, 0) - x_end, y_end = self.width, self.height - for x in range(x_start, x_end): - row = [] - for y in range(y_start, y_end): - row.append(self.list_things_at((x, y))) - result.append(row) - return result - - """ - def run(self, steps=1000, delay=1): - "" "Run the Environment for given number of time steps, - but update the GUI too." "" - for step in range(steps): - sleep(delay) - if self.visible: - self.reveal() - if self.is_done(): - if self.visible: - self.reveal() - return - self.step() - if self.visible: - self.reveal() - """ - - def run(self, steps=1000, delay=1): - """Run the Environment for given number of time steps, - but update the GUI too.""" - for step in range(steps): - self.update(delay) - if self.is_done(): - break - self.step() - self.update(delay) - - def update(self, delay=1): - sleep(delay) - self.reveal() - - def reveal(self): - """Display the BlockGrid for this world - the last thing to be added - at a location defines the location color.""" - self.draw_world() - # wait for the world to update and - # apply changes to the same grid instead - # of making a new one. - clear_output(1) - self.grid.show() - self.visible = True - - def draw_world(self): - self.grid[:] = (200, 200, 200) - world = self.get_world() - for x in range(0, len(world)): - for y in range(0, len(world[x])): - if len(world[x][y]): - self.grid[y, x] = self.colors[world[x][y][-1].__class__.__name__] - - def conceal(self): - """Hide the BlockGrid for this world""" - self.visible = False - display(HTML('')) - - -# ______________________________________________________________________________ -# Continuous environment - -class ContinuousWorld(Environment): - """Model for Continuous World""" - - def __init__(self, width=10, height=10): - super().__init__() - self.width = width - self.height = height - - def add_obstacle(self, coordinates): - self.things.append(PolygonObstacle(coordinates)) - - -class PolygonObstacle(Obstacle): - - def __init__(self, coordinates): - """Coordinates is a list of tuples.""" - super().__init__() - self.coordinates = coordinates - - -# ______________________________________________________________________________ -# Vacuum environment - - -class Dirt(Thing): - pass - - -class VacuumEnvironment(XYEnvironment): - """The environment of [Ex. 2.12]. Agent perceives dirty or clean, - and bump (into obstacle) or not; 2D discrete world of unknown size; - performance measure is 100 for each dirt cleaned, and -1 for - each turn taken.""" - - def __init__(self, width=10, height=10): - super().__init__(width, height) - self.add_walls() - - def thing_classes(self): - return [Wall, Dirt, ReflexVacuumAgent, RandomVacuumAgent, - TableDrivenVacuumAgent, ModelBasedVacuumAgent] - - def percept(self, agent): - """The percept is a tuple of ('Dirty' or 'Clean', 'Bump' or 'None'). - Unlike the TrivialVacuumEnvironment, location is NOT perceived.""" - status = ('Dirty' if self.some_things_at( - agent.location, Dirt) else 'Clean') - bump = ('Bump' if agent.bump else 'None') - return status, bump - - def execute_action(self, agent, action): - agent.bump = False - if action == 'Suck': - dirt_list = self.list_things_at(agent.location, Dirt) - if dirt_list != []: - dirt = dirt_list[0] - agent.performance += 100 - self.delete_thing(dirt) - else: - super().execute_action(agent, action) - - if action != 'NoOp': - agent.performance -= 1 - - -class TrivialVacuumEnvironment(Environment): - """This environment has two locations, A and B. Each can be Dirty - or Clean. The agent perceives its location and the location's - status. This serves as an example of how to implement a simple - Environment.""" - - def __init__(self): - super().__init__() - self.status = {loc_A: random.choice(['Clean', 'Dirty']), - loc_B: random.choice(['Clean', 'Dirty'])} - - def thing_classes(self): - return [Wall, Dirt, ReflexVacuumAgent, RandomVacuumAgent, TableDrivenVacuumAgent, ModelBasedVacuumAgent] - - def percept(self, agent): - """Returns the agent's location, and the location status (Dirty/Clean).""" - return agent.location, self.status[agent.location] - - def execute_action(self, agent, action): - """Change agent's location and/or location's status; track performance. - Score 10 for each dirt cleaned; -1 for each move.""" - if action == 'Right': - agent.location = loc_B - agent.performance -= 1 - elif action == 'Left': - agent.location = loc_A - agent.performance -= 1 - elif action == 'Suck': - if self.status[agent.location] == 'Dirty': - agent.performance += 10 - self.status[agent.location] = 'Clean' - - def default_location(self, thing): - """Agents start in either location at random.""" - return random.choice([loc_A, loc_B]) - - -# ______________________________________________________________________________ -# The Wumpus World - - -class Gold(Thing): - - def __eq__(self, rhs): - """All Gold are equal""" - return rhs.__class__ == Gold - - pass - - -class Bump(Thing): - pass - - -class Glitter(Thing): - pass - - -class Pit(Thing): - pass - - -class Breeze(Thing): - pass - - -class Arrow(Thing): - pass - - -class Scream(Thing): - pass - - -class Wumpus(Agent): - screamed = False - pass - - -class Stench(Thing): - pass - - -class Explorer(Agent): - holding = [] - has_arrow = True - killed_by = "" - direction = Direction("right") - - def can_grab(self, thing): - """Explorer can only grab gold""" - return thing.__class__ == Gold - - -class WumpusEnvironment(XYEnvironment): - pit_probability = 0.2 # Probability to spawn a pit in a location. (From Chapter 7.2) - - # Room should be 4x4 grid of rooms. The extra 2 for walls - - def __init__(self, agent_program, width=6, height=6): - super().__init__(width, height) - self.init_world(agent_program) - - def init_world(self, program): - """Spawn items in the world based on probabilities from the book""" - - "WALLS" - self.add_walls() - - "PITS" - for x in range(self.x_start, self.x_end): - for y in range(self.y_start, self.y_end): - if random.random() < self.pit_probability: - self.add_thing(Pit(), (x, y), True) - self.add_thing(Breeze(), (x - 1, y), True) - self.add_thing(Breeze(), (x, y - 1), True) - self.add_thing(Breeze(), (x + 1, y), True) - self.add_thing(Breeze(), (x, y + 1), True) - - "WUMPUS" - w_x, w_y = self.random_location_inbounds(exclude=(1, 1)) - self.add_thing(Wumpus(lambda x: ""), (w_x, w_y), True) - self.add_thing(Stench(), (w_x - 1, w_y), True) - self.add_thing(Stench(), (w_x + 1, w_y), True) - self.add_thing(Stench(), (w_x, w_y - 1), True) - self.add_thing(Stench(), (w_x, w_y + 1), True) - - "GOLD" - self.add_thing(Gold(), self.random_location_inbounds(exclude=(1, 1)), True) - - "AGENT" - self.add_thing(Explorer(program), (1, 1), True) - - def get_world(self, show_walls=True): - """Return the items in the world""" - result = [] - x_start, y_start = (0, 0) if show_walls else (1, 1) - - if show_walls: - x_end, y_end = self.width, self.height - else: - x_end, y_end = self.width - 1, self.height - 1 - - for x in range(x_start, x_end): - row = [] - for y in range(y_start, y_end): - row.append(self.list_things_at((x, y))) - result.append(row) - return result - - def percepts_from(self, agent, location, tclass=Thing): - """Return percepts from a given location, - and replaces some items with percepts from chapter 7.""" - thing_percepts = { - Gold: Glitter(), - Wall: Bump(), - Wumpus: Stench(), - Pit: Breeze()} - - """Agents don't need to get their percepts""" - thing_percepts[agent.__class__] = None - - """Gold only glitters in its cell""" - if location != agent.location: - thing_percepts[Gold] = None - - result = [thing_percepts.get(thing.__class__, thing) for thing in self.things - if thing.location == location and isinstance(thing, tclass)] - return result if len(result) else [None] - - def percept(self, agent): - """Return things in adjacent (not diagonal) cells of the agent. - Result format: [Left, Right, Up, Down, Center / Current location]""" - x, y = agent.location - result = [] - result.append(self.percepts_from(agent, (x - 1, y))) - result.append(self.percepts_from(agent, (x + 1, y))) - result.append(self.percepts_from(agent, (x, y - 1))) - result.append(self.percepts_from(agent, (x, y + 1))) - result.append(self.percepts_from(agent, (x, y))) - - """The wumpus gives out a loud scream once it's killed.""" - wumpus = [thing for thing in self.things if isinstance(thing, Wumpus)] - if len(wumpus) and not wumpus[0].alive and not wumpus[0].screamed: - result[-1].append(Scream()) - wumpus[0].screamed = True - - return result - - def execute_action(self, agent, action): - """Modify the state of the environment based on the agent's actions. - Performance score taken directly out of the book.""" - - if isinstance(agent, Explorer) and self.in_danger(agent): - return - - agent.bump = False - if action == 'TurnRight': - agent.direction += Direction.R - agent.performance -= 1 - elif action == 'TurnLeft': - agent.direction += Direction.L - agent.performance -= 1 - elif action == 'Forward': - agent.bump = self.move_to(agent, agent.direction.move_forward(agent.location)) - agent.performance -= 1 - elif action == 'Grab': - things = [thing for thing in self.list_things_at(agent.location) - if agent.can_grab(thing)] - if len(things): - print("Grabbing", things[0].__class__.__name__) - if len(things): - agent.holding.append(things[0]) - agent.performance -= 1 - elif action == 'Climb': - if agent.location == (1, 1): # Agent can only climb out of (1,1) - agent.performance += 1000 if Gold() in agent.holding else 0 - self.delete_thing(agent) - elif action == 'Shoot': - """The arrow travels straight down the path the agent is facing""" - if agent.has_arrow: - arrow_travel = agent.direction.move_forward(agent.location) - while self.is_inbounds(arrow_travel): - wumpus = [thing for thing in self.list_things_at(arrow_travel) - if isinstance(thing, Wumpus)] - if len(wumpus): - wumpus[0].alive = False - break - arrow_travel = agent.direction.move_forward(agent.location) - agent.has_arrow = False - - def in_danger(self, agent): - """Check if Explorer is in danger (Pit or Wumpus), if he is, kill him""" - for thing in self.list_things_at(agent.location): - if isinstance(thing, Pit) or (isinstance(thing, Wumpus) and thing.alive): - agent.alive = False - agent.performance -= 1000 - agent.killed_by = thing.__class__.__name__ - return True - return False - - def is_done(self): - """The game is over when the Explorer is killed - or if he climbs out of the cave only at (1,1).""" - explorer = [agent for agent in self.agents if isinstance(agent, Explorer)] - if len(explorer): - if explorer[0].alive: - return False - else: - print("Death by {} [-1000].".format(explorer[0].killed_by)) - else: - print("Explorer climbed out {}." - .format("with Gold [+1000]!" if Gold() not in self.things else "without Gold [+0]")) - return True - - # TODO: Arrow needs to be implemented - - -# ______________________________________________________________________________ - - -def compare_agents(EnvFactory, AgentFactories, n=10, steps=1000): - """See how well each of several agents do in n instances of an environment. - Pass in a factory (constructor) for environments, and several for agents. - Create n instances of the environment, and run each agent in copies of - each one for steps. Return a list of (agent, average-score) tuples. - >>> environment = TrivialVacuumEnvironment - >>> agents = [ModelBasedVacuumAgent, ReflexVacuumAgent] - >>> result = compare_agents(environment, agents) - >>> performance_ModelBasedVacuumAgent = result[0][1] - >>> performance_ReflexVacuumAgent = result[1][1] - >>> performance_ReflexVacuumAgent <= performance_ModelBasedVacuumAgent - True - """ - envs = [EnvFactory() for i in range(n)] - return [(A, test_agent(A, steps, copy.deepcopy(envs))) - for A in AgentFactories] - - -def test_agent(AgentFactory, steps, envs): - """Return the mean score of running an agent in each of the envs, for steps - >>> def constant_prog(percept): - ... return percept - ... - >>> agent = Agent(constant_prog) - >>> result = agent.program(5) - >>> result == 5 - True - """ - - def score(env): - agent = AgentFactory() - env.add_thing(agent) - env.run(steps) - return agent.performance - - return mean(map(score, envs)) - - -# _________________________________________________________________________ - - -__doc__ += """ ->>> a = ReflexVacuumAgent() ->>> a.program((loc_A, 'Clean')) -'Right' ->>> a.program((loc_B, 'Clean')) -'Left' ->>> a.program((loc_A, 'Dirty')) -'Suck' ->>> a.program((loc_A, 'Dirty')) -'Suck' - ->>> e = TrivialVacuumEnvironment() ->>> e.add_thing(ModelBasedVacuumAgent()) ->>> e.run(5) - -""" diff --git a/aima-data b/aima-data deleted file mode 160000 index f6cbea61a..000000000 --- a/aima-data +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f6cbea61ad0c21c6b7be826d17af5a8d3a7c2c86 diff --git a/arc_consistency_heuristics.ipynb b/arc_consistency_heuristics.ipynb deleted file mode 100644 index fb2241819..000000000 --- a/arc_consistency_heuristics.ipynb +++ /dev/null @@ -1,1999 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "pycharm": {} - }, - "source": [ - "# Constraint Satisfaction Problems\n", - "---\n", - "# Heuristics for Arc-Consistency Algorithms\n", - "\n", - "## Introduction\n", - "A ***Constraint Satisfaction Problem*** is a triple $(X,D,C)$ where: \n", - "- $X$ is a set of variables $X_1, …, X_n$;\n", - "- $D$ is a set of domains $D_1, …, D_n$, one for each variable and each of which consists of a set of allowable values $v_1, ..., v_k$;\n", - "- $C$ is a set of constraints that specify allowable combinations of values.\n", - "\n", - "A CSP is called *arc-consistent* if every value in the domain of every variable is supported by all the neighbors of the variable while, is called *inconsistent*, if it has no solutions.
\n", - "***Arc-consistency algorithms*** remove all unsupported values from the domains of variables making the CSP *arc-consistent* or decide that a CSP is *inconsistent* by finding that some variable has no supported values in its domain.
\n", - "Heuristics significantly enhance the efficiency of the *arc-consistency algorithms* improving their average performance in terms of *consistency-checks* which can be considered a standard measure of goodness for such algorithms. *Arc-heuristic* operate at arc-level and selects the constraint that will be used for the next check, while *domain-heuristics* operate at domain-level and selects which values will be used for the next support-check." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "from csp import *" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Domain-Heuristics for Arc-Consistency Algorithms\n", - "In [[1]](#cite-van2002domain) are investigated the effects of a *domain-heuristic* based on the notion of a *double-support check* by studying its average time-complexity.\n", - "\n", - "The objective of *arc-consistency algorithms* is to resolve some uncertainty; it has to be know, for each $v_i \\in D_i$ and for each $v_j \\in D_j$, whether it is supported.\n", - "\n", - "A *single-support check*, $(v_i, v_j) \\in C_{ij}$, is one in which, before the check is done, it is already known that either $v_i$ or $v_j$ are supported. \n", - "\n", - "A *double-support check* $(v_i, v_j) \\in C_{ij}$, is one in which there is still, before the check, uncertainty about the support-status of both $v_i$ and $v_j$. \n", - "\n", - "If a *double-support check* is successful, two uncertainties are resolved. If a *single-support check* is successful, only one uncertainty is resolved. A good *arc-consistency algorithm*, therefore, would always choose to do a *double-support check* in preference of a *single-support check*, because the cormer offers the potential higher payback.\n", - "\n", - "The improvement with *double-support check* is that, where possible, *consistency-checks* are used to find supports for two values, one value in the domain of each variable, which were previously known to be unsupported. It is motivated by the insight that *in order to minimize the number of consistency-checks it is necessary to maximize the number of uncertainties which are resolved per check*." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "pycharm": {} - }, - "source": [ - "### AC-3b: an improved version of AC-3 with Double-Support Checks" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As shown in [[2]](#cite-van2000improving) the idea is to use *double-support checks* to improve the average performance of `AC3` which does not exploit the fact that relations are bidirectional and results in a new general purpose *arc-consistency algorithm* called `AC3b`." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;32mdef\u001b[0m \u001b[0mAC3\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcsp\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mqueue\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mremovals\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0marc_heuristic\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdom_j_up\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"[Figure 6.3]\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mqueue\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mqueue\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXk\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mXi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvariables\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mXk\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mneighbors\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msupport_pruning\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mqueue\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0marc_heuristic\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcsp\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mqueue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mchecks\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0mqueue\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXj\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mqueue\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpop\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mrevised\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchecks\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrevise\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcsp\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mremovals\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchecks\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mrevised\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurr_domains\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchecks\u001b[0m \u001b[0;31m# CSP is inconsistent\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mXk\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mneighbors\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mXk\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0mXj\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mqueue\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXk\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXi\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchecks\u001b[0m \u001b[0;31m# CSP is satisfiable\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%psource AC3" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;32mdef\u001b[0m \u001b[0mrevise\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcsp\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mremovals\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchecks\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"Return true if we remove a value.\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mrevised\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mx\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurr_domains\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# If Xi=x conflicts with Xj=y for every possible y, eliminate Xi=x\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# if all(not csp.constraints(Xi, x, Xj, y) for y in csp.curr_domains[Xj]):\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mconflict\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0my\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurr_domains\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mXj\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconstraints\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mconflict\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mchecks\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mconflict\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mbreak\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mconflict\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mprune\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mremovals\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mrevised\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mrevised\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchecks\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%psource revise" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "At any stage in the process of making 2-variable CSP *arc-consistent* in `AC3b`:\n", - "- there is a set $S_i^+ \\subseteq D_i$ whose values are all known to be supported by $X_j$;\n", - "- there is a set $S_i^? = D_i \\setminus S_i^+$ whose values are unknown, as yet, to be supported by $X_j$.\n", - "\n", - "The same holds if the roles for $X_i$ and $X_j$ are exchanged.\n", - "\n", - "In order to establish support for a value $v_i^? \\in S_i^?$ it seems better to try to find a support among the values in $S_j^?$ first, because for each $v_j^? \\in S_j^?$ the check $(v_i^?,v_j^?) \\in C_{ij}$ is a *double-support check* and it is just as likely that any $v_j^? \\in S_j^?$ supports $v_i^?$ than it is that any $v_j^+ \\in S_j^+$ does. Only if no support can be found among the elements in $S_j^?$, should the elements $v_j^+$ in $S_j^+$ be used for *single-support checks* $(v_i^?,v_j^+) \\in C_{ij}$. After it has been decided for each value in $D_i$ whether it is supported or not, either $S_x^+ = \\emptyset$ and the 2-variable CSP is *inconsistent*, or $S_x^+ \\neq \\emptyset$ and the CSP is *satisfiable*. In the latter case, the elements from $D_i$ which are supported by $j$ are given by $S_x^+$. The elements in $D_j$ which are supported by $x$ are given by the union of $S_j^+$ with the set of those elements of $S_j^?$ which further processing will show to be supported by some $v_i^+ \\in S_x^+$." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;32mdef\u001b[0m \u001b[0mAC3b\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcsp\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mqueue\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mremovals\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0marc_heuristic\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdom_j_up\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mqueue\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mqueue\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXk\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mXi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvariables\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mXk\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mneighbors\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msupport_pruning\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mqueue\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0marc_heuristic\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcsp\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mqueue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mchecks\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0mqueue\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXj\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mqueue\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpop\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# Si_p values are all known to be supported by Xj\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# Sj_p values are all known to be supported by Xi\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# Dj - Sj_p = Sj_u values are unknown, as yet, to be supported by Xi\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mSi_p\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mSj_p\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mSj_u\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchecks\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpartition\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcsp\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchecks\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mSi_p\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchecks\u001b[0m \u001b[0;31m# CSP is inconsistent\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mrevised\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mx\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurr_domains\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mSi_p\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mprune\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mremovals\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mrevised\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mrevised\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mXk\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mneighbors\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mXk\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0mXj\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mqueue\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXk\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXi\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mXj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXi\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mqueue\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mqueue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mset\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# or queue -= {(Xj, Xi)} or queue.remove((Xj, Xi))\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mqueue\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdifference_update\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m{\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXi\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mqueue\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdifference_update\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXi\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# the elements in D_j which are supported by Xi are given by the union of Sj_p with the set of those\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# elements of Sj_u which further processing will show to be supported by some vi_p in Si_p\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mvj_p\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mSj_u\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mvi_p\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mSi_p\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mconflict\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconstraints\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvj_p\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvi_p\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mconflict\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mSj_p\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvj_p\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mchecks\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mconflict\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mbreak\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mrevised\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mx\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurr_domains\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mXj\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mSj_p\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mprune\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mremovals\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mrevised\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mrevised\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mXk\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mneighbors\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mXj\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mXk\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0mXi\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mqueue\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXk\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXj\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchecks\u001b[0m \u001b[0;31m# CSP is satisfiable\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%psource AC3b" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;32mdef\u001b[0m \u001b[0mpartition\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcsp\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchecks\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mSi_p\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mSj_p\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mSj_u\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurr_domains\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mXj\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mvi_u\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurr_domains\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mconflict\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# now, in order to establish support for a value vi_u in Di it seems better to try to find a support among\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# the values in Sj_u first, because for each vj_u in Sj_u the check (vi_u, vj_u) is a double-support check\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# and it is just as likely that any vj_u in Sj_u supports vi_u than it is that any vj_p in Sj_p does...\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mvj_u\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mSj_u\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mSj_p\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# double-support check\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconstraints\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvi_u\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvj_u\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mconflict\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mSi_p\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvi_u\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mSj_p\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvj_u\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mchecks\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mconflict\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mbreak\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# ... and only if no support can be found among the elements in Sj_u, should the elements vj_p in Sj_p be used\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# for single-support checks (vi_u, vj_p)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mconflict\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mvj_p\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mSj_p\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# single-support check\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconstraints\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvi_u\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvj_p\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mconflict\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mSi_p\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvi_u\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mchecks\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mconflict\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mbreak\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mSi_p\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mSj_p\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mSj_u\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mSj_p\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchecks\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%psource partition" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "pycharm": {} - }, - "source": [ - "`AC3b` is a refinement of the `AC3` algorithm which consists of the fact that if, when arc $(i,j)$ is being processed and the reverse arc $(j,i)$ is also in the queue, then consistency-checks can be saved because only support for the elements in $S_j^?$ has to be found (as opposed to support for all the elements in $D_j$ in the\n", - "`AC3` algorithm).
\n", - "`AC3b` inherits all its properties like $\\mathcal{O}(ed^3)$ time-complexity and $\\mathcal{O}(e + nd)$ space-complexity fron `AC3` and where $n$ denotes the number of variables in the CSP, $e$ denotes the number of binary constraints and $d$ denotes the maximum domain-size of the variables." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "pycharm": {} - }, - "source": [ - "## Arc-Heuristics for Arc-Consistency Algorithms" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "pycharm": {} - }, - "source": [ - "Many *arc-heuristics* can be devised, based on three major features of CSPs:\n", - "- the number of acceptable pairs in each constraint (the *constraint size* or *satisfiability*);\n", - "- the *domain size*;\n", - "- the number of binary constraints that each variable participates in, equal to the *degree* of the node of that variable in the constraint graph. \n", - "\n", - "Simple examples of heuristics that might be expected to improve the efficiency of relaxation are:\n", - "- ordering the list of variable pairs by *increasing* relative *satisfiability*;\n", - "- ordering by *increasing size of the domain* of the variable $v_j$ relaxed against $v_i$;\n", - "- ordering by *descending degree* of node of the variable relaxed.\n", - "\n", - "In
[[3]](#cite-wallace1992ordering) are investigated the effects of these *arc-heuristics* in an empirical way, experimenting the effects of them on random CSPs. Their results demonstrate that the first two, later called `sat up` and `dom j up` for n-ary and binary CSPs respectively, significantly reduce the number of *consistency-checks*." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;32mdef\u001b[0m \u001b[0mdom_j_up\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcsp\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mqueue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mSortedSet\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mqueue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkey\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mlambda\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mneg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurr_domains\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mt\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%psource dom_j_up" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;32mdef\u001b[0m \u001b[0msat_up\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mto_do\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mSortedSet\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mto_do\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkey\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mlambda\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m1\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mvar\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mvar\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mscope\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%psource sat_up" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "pycharm": {} - }, - "source": [ - "## Experimental Results" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "pycharm": {} - }, - "source": [ - "For the experiments below on binary CSPs, in addition to the two *arc-consistency algorithms* already cited above, `AC3` and `AC3b`, the `AC4` algorithm was used.
\n", - "The `AC4` algorithm runs in $\\mathcal{O}(ed^2)$ worst-case time but can be slower than `AC3` on average cases." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;32mdef\u001b[0m \u001b[0mAC4\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcsp\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mqueue\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mremovals\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0marc_heuristic\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdom_j_up\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mqueue\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mqueue\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXk\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mXi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvariables\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mXk\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mneighbors\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msupport_pruning\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mqueue\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0marc_heuristic\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcsp\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mqueue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0msupport_counter\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mCounter\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mvariable_value_pairs_supported\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdefaultdict\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mset\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0munsupported_variable_value_pairs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mchecks\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# construction and initialization of support sets\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0mqueue\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXj\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mqueue\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpop\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mrevised\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mx\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurr_domains\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0my\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurr_domains\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mXj\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconstraints\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0msupport_counter\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXj\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mvariable_value_pairs_supported\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mchecks\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0msupport_counter\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXj\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mprune\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mremovals\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mrevised\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0munsupported_variable_value_pairs\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mrevised\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurr_domains\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchecks\u001b[0m \u001b[0;31m# CSP is inconsistent\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# propagation of removed values\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0munsupported_variable_value_pairs\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mXj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0munsupported_variable_value_pairs\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpop\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mvariable_value_pairs_supported\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mrevised\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mx\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurr_domains\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0msupport_counter\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXj\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m-=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0msupport_counter\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mXj\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mprune\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mremovals\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mrevised\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0munsupported_variable_value_pairs\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mrevised\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurr_domains\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mXi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchecks\u001b[0m \u001b[0;31m# CSP is inconsistent\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchecks\u001b[0m \u001b[0;31m# CSP is satisfiable\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%psource AC4" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Sudoku" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "pycharm": {} - }, - "source": [ - "#### Easy Sudoku" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - ". . 3 | . 2 . | 6 . .\n", - "9 . . | 3 . 5 | . . 1\n", - ". . 1 | 8 . 6 | 4 . .\n", - "------+-------+------\n", - ". . 8 | 1 . 2 | 9 . .\n", - "7 . . | . . . | . . 8\n", - ". . 6 | 7 . 8 | 2 . .\n", - "------+-------+------\n", - ". . 2 | 6 . 9 | 5 . .\n", - "8 . . | 2 . 3 | . . 9\n", - ". . 5 | . 1 . | 3 . .\n" - ] - } - ], - "source": [ - "sudoku = Sudoku(easy1)\n", - "sudoku.display(sudoku.infer_assignment())" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 23.6 ms, sys: 0 ns, total: 23.6 ms\n", - "Wall time: 22.4 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "'AC3 needs 11322 consistency-checks'" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time _, checks = AC3(sudoku, arc_heuristic=no_arc_heuristic)\n", - "f'AC3 needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 7.43 ms, sys: 3.68 ms, total: 11.1 ms\n", - "Wall time: 10.7 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "'AC3b needs 8345 consistency-checks'" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sudoku = Sudoku(easy1)\n", - "%time _, checks = AC3b(sudoku, arc_heuristic=no_arc_heuristic)\n", - "f'AC3b needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 56.3 ms, sys: 0 ns, total: 56.3 ms\n", - "Wall time: 55.4 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "'AC4 needs 27718 consistency-checks'" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sudoku = Sudoku(easy1)\n", - "%time _, checks = AC4(sudoku, arc_heuristic=no_arc_heuristic)\n", - "f'AC4 needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 17.2 ms, sys: 0 ns, total: 17.2 ms\n", - "Wall time: 16.9 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "'AC3 with DOM J UP arc heuristic needs 6925 consistency-checks'" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sudoku = Sudoku(easy1)\n", - "%time _, checks = AC3(sudoku, arc_heuristic=dom_j_up)\n", - "f'AC3 with DOM J UP arc heuristic needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 40.9 ms, sys: 2.47 ms, total: 43.4 ms\n", - "Wall time: 41.7 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "'AC3b with DOM J UP arc heuristic needs 6278 consistency-checks'" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sudoku = Sudoku(easy1)\n", - "%time _, checks = AC3b(sudoku, arc_heuristic=dom_j_up)\n", - "f'AC3b with DOM J UP arc heuristic needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 38.9 ms, sys: 1.96 ms, total: 40.9 ms\n", - "Wall time: 40.7 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "'AC4 with DOM J UP arc heuristic needs 9393 consistency-checks'" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sudoku = Sudoku(easy1)\n", - "%time _, checks = AC4(sudoku, arc_heuristic=dom_j_up)\n", - "f'AC4 with DOM J UP arc heuristic needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4 8 3 | 9 2 1 | 6 5 7\n", - "9 6 7 | 3 4 5 | 8 2 1\n", - "2 5 1 | 8 7 6 | 4 9 3\n", - "------+-------+------\n", - "5 4 8 | 1 3 2 | 9 7 6\n", - "7 2 9 | 5 6 4 | 1 3 8\n", - "1 3 6 | 7 9 8 | 2 4 5\n", - "------+-------+------\n", - "3 7 2 | 6 8 9 | 5 1 4\n", - "8 1 4 | 2 5 3 | 7 6 9\n", - "6 9 5 | 4 1 7 | 3 8 2\n" - ] - } - ], - "source": [ - "backtracking_search(sudoku, select_unassigned_variable=mrv, inference=forward_checking)\n", - "sudoku.display(sudoku.infer_assignment())" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "pycharm": {} - }, - "source": [ - "#### Harder Sudoku" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4 1 7 | 3 6 9 | 8 . 5\n", - ". 3 . | . . . | . . .\n", - ". . . | 7 . . | . . .\n", - "------+-------+------\n", - ". 2 . | . . . | . 6 .\n", - ". . . | . 8 . | 4 . .\n", - ". . . | . 1 . | . . .\n", - "------+-------+------\n", - ". . . | 6 . 3 | . 7 .\n", - "5 . . | 2 . . | . . .\n", - "1 . 4 | . . . | . . .\n" - ] - } - ], - "source": [ - "sudoku = Sudoku(harder1)\n", - "sudoku.display(sudoku.infer_assignment())" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 17.7 ms, sys: 481 µs, total: 18.2 ms\n", - "Wall time: 17.2 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "'AC3 needs 12837 consistency-checks'" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time _, checks = AC3(sudoku, arc_heuristic=no_arc_heuristic)\n", - "f'AC3 needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 24.1 ms, sys: 2.6 ms, total: 26.7 ms\n", - "Wall time: 25.1 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "'AC3b needs 8864 consistency-checks'" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sudoku = Sudoku(harder1)\n", - "%time _, checks = AC3b(sudoku, arc_heuristic=no_arc_heuristic)\n", - "f'AC3b needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 63.4 ms, sys: 3.48 ms, total: 66.9 ms\n", - "Wall time: 65.5 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "'AC4 needs 44213 consistency-checks'" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sudoku = Sudoku(harder1)\n", - "%time _, checks = AC4(sudoku, arc_heuristic=no_arc_heuristic)\n", - "f'AC4 needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 9.96 ms, sys: 570 µs, total: 10.5 ms\n", - "Wall time: 10.3 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "'AC3 with DOM J UP arc heuristic needs 7045 consistency-checks'" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sudoku = Sudoku(harder1)\n", - "%time _, checks = AC3(sudoku, arc_heuristic=dom_j_up)\n", - "f'AC3 with DOM J UP arc heuristic needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 36.1 ms, sys: 0 ns, total: 36.1 ms\n", - "Wall time: 35.5 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "'AC3b with DOM J UP arc heuristic needs 6994 consistency-checks'" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sudoku = Sudoku(harder1)\n", - "%time _, checks = AC3b(sudoku, arc_heuristic=dom_j_up)\n", - "f'AC3b with DOM J UP arc heuristic needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 40.3 ms, sys: 0 ns, total: 40.3 ms\n", - "Wall time: 39.7 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "'AC4 with DOM J UP arc heuristic needs 19210 consistency-checks'" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sudoku = Sudoku(harder1)\n", - "%time _, checks = AC4(sudoku, arc_heuristic=dom_j_up)\n", - "f'AC4 with DOM J UP arc heuristic needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4 1 7 | 3 6 9 | 8 2 5\n", - "6 3 2 | 1 5 8 | 9 4 7\n", - "9 5 8 | 7 2 4 | 3 1 6\n", - "------+-------+------\n", - "8 2 5 | 4 3 7 | 1 6 9\n", - "7 9 1 | 5 8 6 | 4 3 2\n", - "3 4 6 | 9 1 2 | 7 5 8\n", - "------+-------+------\n", - "2 8 9 | 6 4 3 | 5 7 1\n", - "5 7 3 | 2 9 1 | 6 8 4\n", - "1 6 4 | 8 7 5 | 2 9 3\n" - ] - } - ], - "source": [ - "backtracking_search(sudoku, select_unassigned_variable=mrv, inference=forward_checking)\n", - "sudoku.display(sudoku.infer_assignment())" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "pycharm": {} - }, - "source": [ - "### 8 Queens" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - ". - . - . - . - 0 0 0 0 0 0 0 0 \n", - "- . - . - . - . 0 0 0 0 0 0 0 0 \n", - ". - . - . - . - 0 0 0 0 0 0 0 0 \n", - "- . - . - . - . 0 0 0 0 0 0 0 0 \n", - ". - . - . - . - 0 0 0 0 0 0 0 0 \n", - "- . - . - . - . 0 0 0 0 0 0 0 0 \n", - ". - . - . - . - 0 0 0 0 0 0 0 0 \n", - "- . - . - . - . 0 0 0 0 0 0 0 0 \n" - ] - } - ], - "source": [ - "chess = NQueensCSP(8)\n", - "chess.display(chess.infer_assignment())" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 689 µs, sys: 193 µs, total: 882 µs\n", - "Wall time: 892 µs\n" - ] - }, - { - "data": { - "text/plain": [ - "'AC3 needs 666 consistency-checks'" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time _, checks = AC3(chess, arc_heuristic=no_arc_heuristic)\n", - "f'AC3 needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 451 µs, sys: 127 µs, total: 578 µs\n", - "Wall time: 584 µs\n" - ] - }, - { - "data": { - "text/plain": [ - "'AC3b needs 428 consistency-checks'" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "chess = NQueensCSP(8)\n", - "%time _, checks = AC3b(chess, arc_heuristic=no_arc_heuristic)\n", - "f'AC3b needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 8.53 ms, sys: 109 µs, total: 8.64 ms\n", - "Wall time: 8.48 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "'AC4 needs 4096 consistency-checks'" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "chess = NQueensCSP(8)\n", - "%time _, checks = AC4(chess, arc_heuristic=no_arc_heuristic)\n", - "f'AC4 needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 1.88 ms, sys: 0 ns, total: 1.88 ms\n", - "Wall time: 1.88 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "'AC3 with DOM J UP arc heuristic needs 666 consistency-checks'" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "chess = NQueensCSP(8)\n", - "%time _, checks = AC3(chess, arc_heuristic=dom_j_up)\n", - "f'AC3 with DOM J UP arc heuristic needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 1.21 ms, sys: 326 µs, total: 1.53 ms\n", - "Wall time: 1.54 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "'AC3b with DOM J UP arc heuristic needs 792 consistency-checks'" - ] - }, - "execution_count": 36, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "chess = NQueensCSP(8)\n", - "%time _, checks = AC3b(chess, arc_heuristic=dom_j_up)\n", - "f'AC3b with DOM J UP arc heuristic needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 4.71 ms, sys: 0 ns, total: 4.71 ms\n", - "Wall time: 4.65 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "'AC4 with DOM J UP arc heuristic needs 4096 consistency-checks'" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "chess = NQueensCSP(8)\n", - "%time _, checks = AC4(chess, arc_heuristic=dom_j_up)\n", - "f'AC4 with DOM J UP arc heuristic needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - ". - . - Q - . - 2 2 3 3 0* 1 1 2 \n", - "- Q - . - . - . 1 0* 3 3 2 2 2 2 \n", - ". - . - . Q . - 3 2 3 2 2 0* 3 2 \n", - "Q . - . - . - . 0* 3 1 2 3 3 3 3 \n", - ". - . - . - Q - 2 2 2 2 3 3 0* 2 \n", - "- . - Q - . - . 2 1 3 0* 2 3 2 2 \n", - ". - . - . - . Q 1 3 2 3 3 1 2 0* \n", - "- . Q . - . - . 2 2 0* 2 2 2 2 2 \n" - ] - } - ], - "source": [ - "backtracking_search(chess, select_unassigned_variable=mrv, inference=forward_checking)\n", - "chess.display(chess.infer_assignment())" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For the experiments below on n-ary CSPs, due to the n-ary constraints, the `GAC` algorithm was used.
\n", - "The `GAC` algorithm has $\\mathcal{O}(er^2d^t)$ time-complexity and $\\mathcal{O}(erd)$ space-complexity where $e$ denotes the number of n-ary constraints, $r$ denotes the constraint arity and $d$ denotes the maximum domain-size of the variables." - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "data": { - "text/plain": [ - " \u001b[0;32mdef\u001b[0m \u001b[0mGAC\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0morig_domains\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mto_do\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0marc_heuristic\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msat_up\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"Makes this CSP arc-consistent using Generalized Arc Consistency\u001b[0m\n", - "\u001b[0;34m orig_domains is the original domains\u001b[0m\n", - "\u001b[0;34m to_do is a set of (variable,constraint) pairs\u001b[0m\n", - "\u001b[0;34m returns the reduced domains (an arc-consistent variable:domain dictionary)\u001b[0m\n", - "\u001b[0;34m \"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0morig_domains\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0morig_domains\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdomains\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mto_do\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mto_do\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvar\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mconst\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mconst\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcsp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconstraints\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mvar\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mconst\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mscope\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mto_do\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mto_do\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcopy\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mdomains\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0morig_domains\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcopy\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mto_do\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0marc_heuristic\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mto_do\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mchecks\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0mto_do\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mvar\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mconst\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mto_do\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpop\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mother_vars\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mov\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mov\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mconst\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mscope\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mov\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0mvar\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mnew_domain\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mother_vars\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mval\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mdomains\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mvar\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mconst\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mholds\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m{\u001b[0m\u001b[0mvar\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mval\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mnew_domain\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mval\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mchecks\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# new_domain = {val for val in domains[var]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# if const.holds({var: val})}\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mother_vars\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mother\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mother_vars\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mval\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mdomains\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mvar\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mother_val\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mdomains\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mother\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mchecks\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mconst\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mholds\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m{\u001b[0m\u001b[0mvar\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mval\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mother_val\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mnew_domain\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mval\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mbreak\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# new_domain = {val for val in domains[var]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# if any(const.holds({var: val, other: other_val})\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# for other_val in domains[other])}\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;31m# general case\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mval\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mdomains\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mvar\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mholds\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchecks\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0many_holds\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdomains\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mconst\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0mvar\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mval\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mother_vars\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchecks\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mchecks\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mholds\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mnew_domain\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mval\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# new_domain = {val for val in domains[var]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# if self.any_holds(domains, const, {var: val}, other_vars)}\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mnew_domain\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0mdomains\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mvar\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mdomains\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mvar\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnew_domain\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mnew_domain\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdomains\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchecks\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0madd_to_do\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnew_to_do\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvar\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mconst\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdifference\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mto_do\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mto_do\u001b[0m \u001b[0;34m|=\u001b[0m \u001b[0madd_to_do\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdomains\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchecks\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%psource ACSolver.GAC" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "pycharm": {} - }, - "source": [ - "### Crossword" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[_] [_] [_] [*] [*] \n", - "[_] [*] [_] [*] [*] \n", - "[_] [_] [_] [_] [*] \n", - "[_] [*] [_] [*] [*] \n", - "[*] [*] [_] [_] [_] \n", - "[*] [*] [_] [*] [*] \n" - ] - }, - { - "data": { - "text/plain": [ - "{'ant',\n", - " 'big',\n", - " 'book',\n", - " 'bus',\n", - " 'buys',\n", - " 'car',\n", - " 'ginger',\n", - " 'has',\n", - " 'hold',\n", - " 'lane',\n", - " 'search',\n", - " 'symbol',\n", - " 'syntax',\n", - " 'year'}" - ] - }, - "execution_count": 41, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "crossword = Crossword(crossword1, words1)\n", - "crossword.display()\n", - "words1" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 1min 20s, sys: 2.02 ms, total: 1min 20s\n", - "Wall time: 1min 20s\n" - ] - }, - { - "data": { - "text/plain": [ - "'GAC needs 64617645 consistency-checks'" - ] - }, - "execution_count": 36, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time _, _, checks = ACSolver(crossword).GAC(arc_heuristic=no_heuristic)\n", - "f'GAC needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 1.19 s, sys: 0 ns, total: 1.19 s\n", - "Wall time: 1.19 s\n" - ] - }, - { - "data": { - "text/plain": [ - "'GAC with SAT UP arc heuristic needs 908015 consistency-checks'" - ] - }, - "execution_count": 42, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "crossword = Crossword(crossword1, words1)\n", - "%time _, _, checks = ACSolver(crossword).GAC(arc_heuristic=sat_up)\n", - "f'GAC with SAT UP arc heuristic needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[B] [U] [S] [*] [*] \n", - "[U] [*] [E] [*] [*] \n", - "[Y] [E] [A] [R] [*] \n", - "[S] [*] [R] [*] [*] \n", - "[*] [*] [C] [A] [R] \n", - "[*] [*] [H] [*] [*] \n" - ] - } - ], - "source": [ - "crossword.display(ACSolver(crossword).domain_splitting())" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "pycharm": {} - }, - "source": [ - "### Kakuro" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Easy Kakuro" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[*]\t10\\\t13\\\t[*]\t\n", - "\\3\t[_]\t[_]\t13\\\t\n", - "\\12\t[_]\t[_]\t[_]\t\n", - "\\21\t[_]\t[_]\t[_]\t\n" - ] - } - ], - "source": [ - "kakuro = Kakuro(kakuro2)\n", - "kakuro.display()" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 17.8 ms, sys: 171 µs, total: 18 ms\n", - "Wall time: 16.4 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "'GAC needs 2752 consistency-checks'" - ] - }, - "execution_count": 45, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time _, _, checks = ACSolver(kakuro).GAC(arc_heuristic=no_heuristic)\n", - "f'GAC needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 8.55 ms, sys: 0 ns, total: 8.55 ms\n", - "Wall time: 8.39 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "'GAC with SAT UP arc heuristic needs 1765 consistency-checks'" - ] - }, - "execution_count": 46, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "kakuro = Kakuro(kakuro2)\n", - "%time _, _, checks = ACSolver(kakuro).GAC(arc_heuristic=sat_up)\n", - "f'GAC with SAT UP arc heuristic needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[*]\t10\\\t13\\\t[*]\t\n", - "\\3\t[1]\t[2]\t13\\\t\n", - "\\12\t[5]\t[3]\t[4]\t\n", - "\\21\t[4]\t[8]\t[9]\t\n" - ] - } - ], - "source": [ - "kakuro.display(ACSolver(kakuro).domain_splitting())" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "pycharm": {} - }, - "source": [ - "#### Medium Kakuro" - ] - }, - { - "cell_type": "code", - "execution_count": 48, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[*]\t17\\\t28\\\t[*]\t42\\\t22\\\t\n", - "\\9\t[_]\t[_]\t31\\14\t[_]\t[_]\t\n", - "\\20\t[_]\t[_]\t[_]\t[_]\t[_]\t\n", - "[*]\t\\30\t[_]\t[_]\t[_]\t[_]\t\n", - "[*]\t22\\24\t[_]\t[_]\t[_]\t[*]\t\n", - "\\25\t[_]\t[_]\t[_]\t[_]\t11\\\t\n", - "\\20\t[_]\t[_]\t[_]\t[_]\t[_]\t\n", - "\\14\t[_]\t[_]\t\\17\t[_]\t[_]\t\n" - ] - } - ], - "source": [ - "kakuro = Kakuro(kakuro3)\n", - "kakuro.display()" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 1.96 s, sys: 0 ns, total: 1.96 s\n", - "Wall time: 1.96 s\n" - ] - }, - { - "data": { - "text/plain": [ - "'GAC needs 1290179 consistency-checks'" - ] - }, - "execution_count": 49, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time _, _, checks = ACSolver(kakuro).GAC(arc_heuristic=no_heuristic)\n", - "f'GAC needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 225 ms, sys: 0 ns, total: 225 ms\n", - "Wall time: 223 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "'GAC with SAT UP arc heuristic needs 148780 consistency-checks'" - ] - }, - "execution_count": 50, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "kakuro = Kakuro(kakuro3)\n", - "%time _, _, checks = ACSolver(kakuro).GAC(arc_heuristic=sat_up)\n", - "f'GAC with SAT UP arc heuristic needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[*]\t17\\\t28\\\t[*]\t42\\\t22\\\t\n", - "\\9\t[8]\t[1]\t31\\14\t[5]\t[9]\t\n", - "\\20\t[9]\t[2]\t[1]\t[3]\t[5]\t\n", - "[*]\t\\30\t[6]\t[9]\t[7]\t[8]\t\n", - "[*]\t22\\24\t[7]\t[8]\t[9]\t[*]\t\n", - "\\25\t[8]\t[4]\t[7]\t[6]\t11\\\t\n", - "\\20\t[5]\t[3]\t[6]\t[4]\t[2]\t\n", - "\\14\t[9]\t[5]\t\\17\t[8]\t[9]\t\n" - ] - } - ], - "source": [ - "kakuro.display(ACSolver(kakuro).domain_splitting())" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "pycharm": {} - }, - "source": [ - "#### Harder Kakuro" - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[*]\t[*]\t[*]\t[*]\t[*]\t4\\\t24\\\t11\\\t[*]\t[*]\t[*]\t11\\\t17\\\t[*]\t[*]\t\n", - "[*]\t[*]\t[*]\t17\\\t11\\12\t[_]\t[_]\t[_]\t[*]\t[*]\t24\\10\t[_]\t[_]\t11\\\t[*]\t\n", - "[*]\t4\\\t16\\26\t[_]\t[_]\t[_]\t[_]\t[_]\t[*]\t\\20\t[_]\t[_]\t[_]\t[_]\t16\\\t\n", - "\\20\t[_]\t[_]\t[_]\t[_]\t24\\13\t[_]\t[_]\t16\\\t\\12\t[_]\t[_]\t23\\10\t[_]\t[_]\t\n", - "\\10\t[_]\t[_]\t24\\12\t[_]\t[_]\t16\\5\t[_]\t[_]\t16\\30\t[_]\t[_]\t[_]\t[_]\t[_]\t\n", - "[*]\t[*]\t3\\26\t[_]\t[_]\t[_]\t[_]\t\\12\t[_]\t[_]\t4\\\t16\\14\t[_]\t[_]\t[*]\t\n", - "[*]\t\\8\t[_]\t[_]\t\\15\t[_]\t[_]\t34\\26\t[_]\t[_]\t[_]\t[_]\t[_]\t[*]\t[*]\t\n", - "[*]\t\\11\t[_]\t[_]\t3\\\t17\\\t\\14\t[_]\t[_]\t\\8\t[_]\t[_]\t7\\\t17\\\t[*]\t\n", - "[*]\t[*]\t[*]\t23\\10\t[_]\t[_]\t3\\9\t[_]\t[_]\t4\\\t23\\\t\\13\t[_]\t[_]\t[*]\t\n", - "[*]\t[*]\t10\\26\t[_]\t[_]\t[_]\t[_]\t[_]\t\\7\t[_]\t[_]\t30\\9\t[_]\t[_]\t[*]\t\n", - "[*]\t17\\11\t[_]\t[_]\t11\\\t24\\8\t[_]\t[_]\t11\\21\t[_]\t[_]\t[_]\t[_]\t16\\\t17\\\t\n", - "\\29\t[_]\t[_]\t[_]\t[_]\t[_]\t\\7\t[_]\t[_]\t23\\14\t[_]\t[_]\t3\\17\t[_]\t[_]\t\n", - "\\10\t[_]\t[_]\t3\\10\t[_]\t[_]\t[*]\t\\8\t[_]\t[_]\t4\\25\t[_]\t[_]\t[_]\t[_]\t\n", - "[*]\t\\16\t[_]\t[_]\t[_]\t[_]\t[*]\t\\23\t[_]\t[_]\t[_]\t[_]\t[_]\t[*]\t[*]\t\n", - "[*]\t[*]\t\\6\t[_]\t[_]\t[*]\t[*]\t\\15\t[_]\t[_]\t[_]\t[*]\t[*]\t[*]\t[*]\t\n" - ] - } - ], - "source": [ - "kakuro = Kakuro(kakuro4)\n", - "kakuro.display()" - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 76.5 ms, sys: 847 µs, total: 77.4 ms\n", - "Wall time: 77 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "'GAC needs 46633 consistency-checks'" - ] - }, - "execution_count": 53, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time _, _, checks = ACSolver(kakuro).GAC()\n", - "f'GAC needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 64.6 ms, sys: 0 ns, total: 64.6 ms\n", - "Wall time: 63.6 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "'GAC with SAT UP arc heuristic needs 36828 consistency-checks'" - ] - }, - "execution_count": 54, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "kakuro = Kakuro(kakuro4)\n", - "%time _, _, checks = ACSolver(kakuro).GAC(arc_heuristic=sat_up)\n", - "f'GAC with SAT UP arc heuristic needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[*]\t[*]\t[*]\t[*]\t[*]\t4\\\t24\\\t11\\\t[*]\t[*]\t[*]\t11\\\t17\\\t[*]\t[*]\t\n", - "[*]\t[*]\t[*]\t17\\\t11\\12\t[3]\t[7]\t[2]\t[*]\t[*]\t24\\10\t[2]\t[8]\t11\\\t[*]\t\n", - "[*]\t4\\\t16\\26\t[8]\t[5]\t[1]\t[9]\t[3]\t[*]\t\\20\t[8]\t[1]\t[9]\t[2]\t16\\\t\n", - "\\20\t[3]\t[7]\t[9]\t[1]\t24\\13\t[8]\t[5]\t16\\\t\\12\t[9]\t[3]\t23\\10\t[3]\t[7]\t\n", - "\\10\t[1]\t[9]\t24\\12\t[3]\t[9]\t16\\5\t[1]\t[4]\t16\\30\t[7]\t[5]\t[8]\t[1]\t[9]\t\n", - "[*]\t[*]\t3\\26\t[8]\t[2]\t[7]\t[9]\t\\12\t[3]\t[9]\t4\\\t16\\14\t[9]\t[5]\t[*]\t\n", - "[*]\t\\8\t[1]\t[7]\t\\15\t[8]\t[7]\t34\\26\t[1]\t[7]\t[3]\t[9]\t[6]\t[*]\t[*]\t\n", - "[*]\t\\11\t[2]\t[9]\t3\\\t17\\\t\\14\t[8]\t[6]\t\\8\t[1]\t[7]\t7\\\t17\\\t[*]\t\n", - "[*]\t[*]\t[*]\t23\\10\t[1]\t[9]\t3\\9\t[7]\t[2]\t4\\\t23\\\t\\13\t[4]\t[9]\t[*]\t\n", - "[*]\t[*]\t10\\26\t[6]\t[2]\t[8]\t[1]\t[9]\t\\7\t[1]\t[6]\t30\\9\t[1]\t[8]\t[*]\t\n", - "[*]\t17\\11\t[3]\t[8]\t11\\\t24\\8\t[2]\t[6]\t11\\21\t[3]\t[9]\t[7]\t[2]\t16\\\t17\\\t\n", - "\\29\t[8]\t[2]\t[9]\t[3]\t[7]\t\\7\t[4]\t[3]\t23\\14\t[8]\t[6]\t3\\17\t[9]\t[8]\t\n", - "\\10\t[9]\t[1]\t3\\10\t[2]\t[8]\t[*]\t\\8\t[2]\t[6]\t4\\25\t[8]\t[1]\t[7]\t[9]\t\n", - "[*]\t\\16\t[4]\t[2]\t[1]\t[9]\t[*]\t\\23\t[1]\t[8]\t[3]\t[9]\t[2]\t[*]\t[*]\t\n", - "[*]\t[*]\t\\6\t[1]\t[5]\t[*]\t[*]\t\\15\t[5]\t[9]\t[1]\t[*]\t[*]\t[*]\t[*]\t\n" - ] - } - ], - "source": [ - "kakuro.display(ACSolver(kakuro).domain_splitting())" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "pycharm": {} - }, - "source": [ - "### Cryptarithmetic Puzzle" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "$$\n", - "\\begin{array}{@{}r@{}}\n", - " S E N D \\\\\n", - "{} + M O R E \\\\\n", - " \\hline\n", - " M O N E Y\n", - "\\end{array}\n", - "$$" - ] - }, - { - "cell_type": "code", - "execution_count": 57, - "metadata": { - "pycharm": {} - }, - "outputs": [], - "source": [ - "cryptarithmetic = NaryCSP(\n", - " {'S': set(range(1, 10)), 'M': set(range(1, 10)),\n", - " 'E': set(range(0, 10)), 'N': set(range(0, 10)), 'D': set(range(0, 10)),\n", - " 'O': set(range(0, 10)), 'R': set(range(0, 10)), 'Y': set(range(0, 10)),\n", - " 'C1': set(range(0, 2)), 'C2': set(range(0, 2)), 'C3': set(range(0, 2)),\n", - " 'C4': set(range(0, 2))},\n", - " [Constraint(('S', 'E', 'N', 'D', 'M', 'O', 'R', 'Y'), all_diff),\n", - " Constraint(('D', 'E', 'Y', 'C1'), lambda d, e, y, c1: d + e == y + 10 * c1),\n", - " Constraint(('N', 'R', 'E', 'C1', 'C2'), lambda n, r, e, c1, c2: c1 + n + r == e + 10 * c2),\n", - " Constraint(('E', 'O', 'N', 'C2', 'C3'), lambda e, o, n, c2, c3: c2 + e + o == n + 10 * c3),\n", - " Constraint(('S', 'M', 'O', 'C3', 'C4'), lambda s, m, o, c3, c4: c3 + s + m == o + 10 * c4),\n", - " Constraint(('M', 'C4'), eq)])" - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 21.7 s, sys: 0 ns, total: 21.7 s\n", - "Wall time: 21.7 s\n" - ] - }, - { - "data": { - "text/plain": [ - "'GAC needs 14080592 consistency-checks'" - ] - }, - "execution_count": 52, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time _, _, checks = ACSolver(cryptarithmetic).GAC(arc_heuristic=no_heuristic)\n", - "f'GAC needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 58, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 939 ms, sys: 0 ns, total: 939 ms\n", - "Wall time: 938 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "'GAC with SAT UP arc heuristic needs 573120 consistency-checks'" - ] - }, - "execution_count": 58, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time _, _, checks = ACSolver(cryptarithmetic).GAC(arc_heuristic=sat_up)\n", - "f'GAC with SAT UP arc heuristic needs {checks} consistency-checks'" - ] - }, - { - "cell_type": "code", - "execution_count": 59, - "metadata": { - "pycharm": {} - }, - "outputs": [ - { - "data": { - "text/latex": [ - "\\begin{array}{@{}r@{}} 9567 \\\\ + 1085 \\\\ \\hline 10652 \\end{array}" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "assignment = ACSolver(cryptarithmetic).domain_splitting()\n", - "\n", - "from IPython.display import Latex\n", - "display(Latex(r'\\begin{array}{@{}r@{}} ' + '{}{}{}{}'.format(assignment['S'], assignment['E'], assignment['N'], assignment['D']) + r' \\\\ + ' + \n", - " '{}{}{}{}'.format(assignment['M'], assignment['O'], assignment['R'], assignment['E']) + r' \\\\ \\hline ' + \n", - " '{}{}{}{}{}'.format(assignment['M'], assignment['O'], assignment['N'], assignment['E'], assignment['Y']) + ' \\end{array}'))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "pycharm": {} - }, - "source": [ - "## References\n", - "\n", - "
[[1]](#ref-1) Van Dongen, Marc RC. 2002. _Domain-heuristics for arc-consistency algorithms_.\n", - "\n", - "[[2]](#ref-2) Van Dongen, MRC and Bowen, JA. 2000. _Improving arc-consistency algorithms with double-support checks_.\n", - "\n", - "[[3]](#ref-3) Wallace, Richard J and Freuder, Eugene Charles. 1992. _Ordering heuristics for arc consistency algorithms_." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "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.7.5rc1" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/classical_planning_approaches.ipynb b/classical_planning_approaches.ipynb deleted file mode 100644 index b3373b367..000000000 --- a/classical_planning_approaches.ipynb +++ /dev/null @@ -1,2402 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Classical Planning\n", - "---\n", - "# Classical Planning Approaches\n", - "\n", - "## Introduction \n", - "***Planning*** combines the two major areas of AI: *search* and *logic*. A planner can be seen either as a program that searches for a solution or as one that constructively proves the existence of a solution.\n", - "\n", - "Currently, the most popular and effective approaches to fully automated planning are:\n", - "- searching using a *planning graph*;\n", - "- *state-space search* with heuristics;\n", - "- translating to a *constraint satisfaction (CSP) problem*;\n", - "- translating to a *boolean satisfiability (SAT) problem*." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "from planning import *" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Planning as Planning Graph Search\n", - "\n", - "A *planning graph* is a directed graph organized into levels each of which contains information about the current state of the knowledge base and the possible state-action links to and from that level. \n", - "\n", - "The first level contains the initial state with nodes representing each fluent that holds in that level. This level has state-action links linking each state to valid actions in that state. Each action is linked to all its preconditions and its effect states. Based on these effects, the next level is constructed and contains similarly structured information about the next state. In this way, the graph is expanded using state-action links till we reach a state where all the required goals hold true simultaneously.\n", - "\n", - "In every planning problem, we are allowed to carry out the *no-op* action, ie, we can choose no action for a particular state. These are called persistence actions and has effects same as its preconditions. This enables us to carry a state to the next level.\n", - "\n", - "Mutual exclusivity (*mutex*) between two actions means that these cannot be taken together and occurs in the following cases:\n", - "- *inconsistent effects*: one action negates the effect of the other;\n", - "- *interference*: one of the effects of an action is the negation of a precondition of the other;\n", - "- *competing needs*: one of the preconditions of one action is mutually exclusive with a precondition of the other.\n", - "\n", - "We can say that we have reached our goal if none of the goal states in the current level are mutually exclusive." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;32mclass\u001b[0m \u001b[0mGraph\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"\u001b[0m\n", - "\u001b[0;34m Contains levels of state and actions\u001b[0m\n", - "\u001b[0;34m Used in graph planning algorithm to extract a solution\u001b[0m\n", - "\u001b[0;34m \"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__init__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mplanning_problem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplanning_problem\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mplanning_problem\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkb\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mFolKB\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mplanning_problem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minitial\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlevels\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mLevel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkb\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mobjects\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marg\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mclause\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkb\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclauses\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0marg\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mclause\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__call__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexpand_graph\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mexpand_graph\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"Expands the graph by a level\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mlast_level\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlevels\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mlast_level\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplanning_problem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mactions\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mobjects\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlevels\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlast_level\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mperform_actions\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mnon_mutex_goals\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mgoals\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"Checks whether the goals are mutually exclusive\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mgoal_perm\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mitertools\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcombinations\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgoals\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mg\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mgoal_perm\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mg\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlevels\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmutex\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%psource Graph" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;32mclass\u001b[0m \u001b[0mLevel\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"\u001b[0m\n", - "\u001b[0;34m Contains the state of the planning problem\u001b[0m\n", - "\u001b[0;34m and exhaustive list of actions which use the\u001b[0m\n", - "\u001b[0;34m states as pre-condition.\u001b[0m\n", - "\u001b[0;34m \"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__init__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkb\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"Initializes variables to hold state and action details of a level\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkb\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mkb\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# current state\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurrent_state\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mkb\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclauses\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# current action to state link\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurrent_action_links\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# current state to action link\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurrent_state_links\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# current action to next state link\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnext_action_links\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# next state to current action link\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnext_state_links\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# mutually exclusive actions\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmutex\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__call__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mactions\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mobjects\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbuild\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mactions\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mobjects\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfind_mutex\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mseparate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"Separates an iterable of elements into positive and negative parts\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mpositive\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mnegative\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mclause\u001b[0m \u001b[0;32min\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mclause\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mop\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'Not'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mnegative\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mclause\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mpositive\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mclause\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mpositive\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnegative\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mfind_mutex\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"Finds mutually exclusive actions\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# Inconsistent effects\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mpos_nsl\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mneg_nsl\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mseparate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnext_state_links\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mnegeff\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mneg_nsl\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mnew_negeff\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mExpr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnegeff\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mop\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mnegeff\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mposeff\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mpos_nsl\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mnew_negeff\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mposeff\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0ma\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnext_state_links\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mposeff\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mb\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnext_state_links\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mnegeff\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mb\u001b[0m\u001b[0;34m}\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmutex\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmutex\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m{\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mb\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# Interference will be calculated with the last step\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mpos_csl\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mneg_csl\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mseparate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurrent_state_links\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# Competing needs\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mpos_precond\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mpos_csl\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mneg_precond\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mneg_csl\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mnew_neg_precond\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mExpr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mneg_precond\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mop\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mneg_precond\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mnew_neg_precond\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mpos_precond\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0ma\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurrent_state_links\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mpos_precond\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mb\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurrent_state_links\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mneg_precond\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mb\u001b[0m\u001b[0;34m}\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmutex\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmutex\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m{\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mb\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# Inconsistent support\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mstate_mutex\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mpair\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmutex\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mnext_state_0\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnext_action_links\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpair\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpair\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mnext_state_1\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnext_action_links\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpair\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mnext_state_1\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnext_action_links\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpair\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnext_state_0\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnext_state_1\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mstate_mutex\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m{\u001b[0m\u001b[0mnext_state_0\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnext_state_1\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmutex\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmutex\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mstate_mutex\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mbuild\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mactions\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mobjects\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"Populates the lists and dictionaries containing the state action dependencies\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mclause\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurrent_state\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mp_expr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mExpr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'P'\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mclause\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mop\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mclause\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurrent_action_links\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mp_expr\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mclause\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnext_action_links\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mp_expr\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mclause\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurrent_state_links\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mclause\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mp_expr\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnext_state_links\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mclause\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mp_expr\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0ma\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mactions\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mnum_args\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mpossible_args\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtuple\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mitertools\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpermutations\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobjects\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnum_args\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0marg\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mpossible_args\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcheck_precond\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkb\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0marg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mnum\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msymbol\u001b[0m \u001b[0;32min\u001b[0m \u001b[0menumerate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0msymbol\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mop\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mislower\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0marg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0marg\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mnum\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msymbol\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0marg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtuple\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mnew_action\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msubstitute\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mExpr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0marg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurrent_action_links\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mnew_action\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mclause\u001b[0m \u001b[0;32min\u001b[0m \u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mprecond\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mnew_clause\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msubstitute\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mclause\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0marg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurrent_action_links\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mnew_action\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnew_clause\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mnew_clause\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurrent_state_links\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurrent_state_links\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mnew_clause\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnew_action\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurrent_state_links\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mnew_clause\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mnew_action\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnext_action_links\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mnew_action\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mclause\u001b[0m \u001b[0;32min\u001b[0m \u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0meffect\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mnew_clause\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msubstitute\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mclause\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0marg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnext_action_links\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mnew_action\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnew_clause\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mnew_clause\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnext_state_links\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnext_state_links\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mnew_clause\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnew_action\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnext_state_links\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mnew_clause\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mnew_action\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mperform_actions\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"Performs the necessary actions and returns a new Level\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mnew_kb\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mFolKB\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnext_state_links\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkeys\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mLevel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnew_kb\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%psource Level" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A *planning graph* can be used to give better heuristic estimates which can be applied to any of the search techniques. Alternatively, we can search for a solution over the space formed by the planning graph, using an algorithm called `GraphPlan`.\n", - "\n", - "The `GraphPlan` algorithm repeatedly adds a level to a planning graph. Once all the goals show up as non-mutex in the graph, the algorithm runs backward from the last level to the first searching for a plan that solves the problem. If that fails, it records the (level , goals) pair as a *no-good* (as in constraint learning for CSPs), expands another level and tries again, terminating with failure when there is no reason to go on. " - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;32mclass\u001b[0m \u001b[0mGraphPlan\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"\u001b[0m\n", - "\u001b[0;34m Class for formulation GraphPlan algorithm\u001b[0m\n", - "\u001b[0;34m Constructs a graph of state and action space\u001b[0m\n", - "\u001b[0;34m Returns solution for the planning problem\u001b[0m\n", - "\u001b[0;34m \"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__init__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mplanning_problem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgraph\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mGraph\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mplanning_problem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mno_goods\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msolution\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mcheck_leveloff\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"Checks if the graph has levelled off\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mcheck\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgraph\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlevels\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurrent_state\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgraph\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlevels\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurrent_state\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mcheck\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mextract_solution\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mgoals\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"Extracts the solution\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mlevel\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgraph\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlevels\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgraph\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnon_mutex_goals\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgoals\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mno_goods\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlevel\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mgoals\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mlevel\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgraph\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlevels\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mindex\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# Create all combinations of actions that satisfy the goal\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mactions\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mgoal\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mgoals\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mactions\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlevel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnext_state_links\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mgoal\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mall_actions\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mitertools\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mproduct\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mactions\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# Filter out non-mutex actions\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mnon_mutex_actions\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0maction_tuple\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mall_actions\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0maction_pairs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mitertools\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcombinations\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0maction_tuple\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mnon_mutex_actions\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0maction_tuple\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mpair\u001b[0m \u001b[0;32min\u001b[0m \u001b[0maction_pairs\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpair\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mlevel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmutex\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mnon_mutex_actions\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpop\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mbreak\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# Recursion\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0maction_list\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mnon_mutex_actions\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0maction_list\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msolution\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msolution\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0maction_list\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mnew_goals\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mact\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0maction_list\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mact\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mlevel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurrent_action_links\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mnew_goals\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnew_goals\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mlevel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurrent_action_links\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mact\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mabs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgraph\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlevels\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mlevel\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnew_goals\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mno_goods\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mextract_solution\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnew_goals\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindex\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# Level-Order multiple solutions\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0msolution\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mitem\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msolution\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mitem\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0msolution\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0msolution\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0msolution\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mnum\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mitem\u001b[0m \u001b[0;32min\u001b[0m \u001b[0menumerate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msolution\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mitem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreverse\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0msolution\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mnum\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mitem\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0msolution\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mgoal_test\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkb\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mall\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkb\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mask\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mq\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mFalse\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mq\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgraph\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplanning_problem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgoals\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mexecute\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"Executes the GraphPlan algorithm for the given problem\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgraph\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexpand_graph\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgoal_test\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgraph\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlevels\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkb\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgraph\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnon_mutex_goals\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgraph\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplanning_problem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgoals\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0msolution\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mextract_solution\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgraph\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplanning_problem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgoals\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0msolution\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0msolution\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgraph\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlevels\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>=\u001b[0m \u001b[0;36m2\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcheck_leveloff\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%psource GraphPlan" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Planning as State-Space Search" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The description of a planning problem defines a search problem: we can search from the initial state through the space of states, looking for a goal. One of the nice advantages of the declarative representation of action schemas is that we can also search backward from the goal, looking for the initial state. \n", - "\n", - "However, neither forward nor backward search is efficient without a good heuristic function because the real-world planning problems often have large state spaces. A heuristic function $h(s)$ estimates the distance from a state $s$ to the goal and, if it is admissible, ie if does not overestimate, then we can use $A^∗$ search to find optimal solutions.\n", - "\n", - "Planning uses a factored representation for states and action schemas which makes it possible to define good domain-independent heuristics to prune the search space.\n", - "\n", - "An admissible heuristic can be derived by defining a relaxed problem that is easier to solve. The length of the solution of this easier problem then becomes the heuristic for the original problem. Assume that all goals and preconditions contain only positive literals, ie that the problem is defined according to the *Stanford Research Institute Problem Solver* (STRIPS) notation: we want to create a relaxed version of the original problem that will be easier to solve by ignoring delete lists from all actions, ie removing all negative literals from effects. As shown in [[1]](#cite-hoffmann2001ff) the planning graph of a relaxed problem does not contain any mutex relations at all (which is the crucial thing when building a planning graph) and for this reason GraphPlan will never backtrack looking for a solution: for this reason the **ignore delete lists** heuristic makes it possible to find the optimal solution for relaxed problem in polynomial time through `GraphPlan` algorithm." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "from search import *" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Forward State-Space Search" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Forward search through the space of states, starting in the initial state and using the problem’s actions to search forward for a member of the set of goal states." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;32mclass\u001b[0m \u001b[0mForwardPlan\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msearch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mProblem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"\u001b[0m\n", - "\u001b[0;34m [Section 10.2.1]\u001b[0m\n", - "\u001b[0;34m Forward state-space search\u001b[0m\n", - "\u001b[0;34m \"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__init__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mplanning_problem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0msuper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__init__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0massociate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'&'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mplanning_problem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minitial\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0massociate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'&'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mplanning_problem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgoals\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplanning_problem\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mplanning_problem\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexpanded_actions\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplanning_problem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexpand_actions\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mactions\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstate\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0maction\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0maction\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexpanded_actions\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mall\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpre\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mconjuncts\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstate\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mpre\u001b[0m \u001b[0;32min\u001b[0m \u001b[0maction\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mprecond\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstate\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maction\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0massociate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'&'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maction\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mconjuncts\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstate\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maction\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclauses\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mgoal_test\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstate\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mall\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgoal\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mconjuncts\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstate\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mgoal\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplanning_problem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgoals\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mh\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstate\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"\u001b[0m\n", - "\u001b[0;34m Computes ignore delete lists heuristic by creating a relaxed version of the original problem (we can do that\u001b[0m\n", - "\u001b[0;34m by removing the delete lists from all actions, i.e. removing all negative literals from effects) that will be\u001b[0m\n", - "\u001b[0;34m easier to solve through GraphPlan and where the length of the solution will serve as a good heuristic.\u001b[0m\n", - "\u001b[0;34m \"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mrelaxed_planning_problem\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mPlanningProblem\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minitial\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mstate\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstate\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mgoals\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgoal\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mactions\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0maction\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrelaxed\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0maction\u001b[0m \u001b[0;32min\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplanning_problem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mactions\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlinearize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mGraphPlan\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrelaxed_planning_problem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexecute\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mexcept\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mfloat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'inf'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%psource ForwardPlan" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Backward Relevant-States Search" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Backward search through sets of relevant states, starting at the set of states representing the goal and using the inverse of the actions to search backward for the initial state." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;32mclass\u001b[0m \u001b[0mBackwardPlan\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msearch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mProblem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"\u001b[0m\n", - "\u001b[0;34m [Section 10.2.2]\u001b[0m\n", - "\u001b[0;34m Backward relevant-states search\u001b[0m\n", - "\u001b[0;34m \"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__init__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mplanning_problem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0msuper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__init__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0massociate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'&'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mplanning_problem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgoals\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0massociate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'&'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mplanning_problem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minitial\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplanning_problem\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mplanning_problem\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexpanded_actions\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplanning_problem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexpand_actions\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mactions\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubgoal\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"\u001b[0m\n", - "\u001b[0;34m Returns True if the action is relevant to the subgoal, i.e.:\u001b[0m\n", - "\u001b[0;34m - the action achieves an element of the effects\u001b[0m\n", - "\u001b[0;34m - the action doesn't delete something that needs to be achieved\u001b[0m\n", - "\u001b[0;34m - the preconditions are consistent with other subgoals that need to be achieved\u001b[0m\n", - "\u001b[0;34m \"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mnegate_clause\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mclause\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mExpr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mclause\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mop\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreplace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Not'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m''\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mclause\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mclause\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mop\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'Not'\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0mExpr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m'Not'\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mclause\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mop\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mclause\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0msubgoal\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mconjuncts\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msubgoal\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0maction\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0maction\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexpanded_actions\u001b[0m \u001b[0;32mif\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0many\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mprop\u001b[0m \u001b[0;32min\u001b[0m \u001b[0maction\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0meffect\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mprop\u001b[0m \u001b[0;32min\u001b[0m \u001b[0msubgoal\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mand\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0many\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnegate_clause\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mprop\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32min\u001b[0m \u001b[0msubgoal\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mprop\u001b[0m \u001b[0;32min\u001b[0m \u001b[0maction\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0meffect\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mand\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0many\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnegate_clause\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mprop\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32min\u001b[0m \u001b[0msubgoal\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mnegate_clause\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mprop\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0maction\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0meffect\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mprop\u001b[0m \u001b[0;32min\u001b[0m \u001b[0maction\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mprecond\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubgoal\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maction\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# g' = (g - effects(a)) + preconds(a)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0massociate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'&'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mconjuncts\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msubgoal\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdifference\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0maction\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0meffect\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0munion\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0maction\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mprecond\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mgoal_test\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubgoal\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mall\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgoal\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mconjuncts\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgoal\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mgoal\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mconjuncts\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msubgoal\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mh\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubgoal\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"\u001b[0m\n", - "\u001b[0;34m Computes ignore delete lists heuristic by creating a relaxed version of the original problem (we can do that\u001b[0m\n", - "\u001b[0;34m by removing the delete lists from all actions, i.e. removing all negative literals from effects) that will be\u001b[0m\n", - "\u001b[0;34m easier to solve through GraphPlan and where the length of the solution will serve as a good heuristic.\u001b[0m\n", - "\u001b[0;34m \"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mrelaxed_planning_problem\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mPlanningProblem\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minitial\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgoal\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mgoals\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msubgoal\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstate\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mactions\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0maction\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrelaxed\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0maction\u001b[0m \u001b[0;32min\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplanning_problem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mactions\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlinearize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mGraphPlan\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrelaxed_planning_problem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexecute\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mexcept\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mfloat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'inf'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%psource BackwardPlan" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Planning as Constraint Satisfaction Problem" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In forward planning, the search is constrained by the initial state and only uses the goal as a stopping criterion and as a source for heuristics. In regression planning, the search is constrained by the goal and only uses the start state as a stopping criterion and as a source for heuristics. By converting the problem to a constraint satisfaction problem (CSP), the initial state can be used to prune what is not reachable and the goal to prune what is not useful. The CSP will be defined for a finite number of steps; the number of steps can be adjusted to find the shortest plan. One of the CSP methods can then be used to solve the CSP and thus find a plan.\n", - "\n", - "To construct a CSP from a planning problem, first choose a fixed planning *horizon*, which is the number of time steps over which to plan. Suppose the horizon is \n", - "$k$. The CSP has the following variables:\n", - "\n", - "- a *state variable* for each feature and each time from 0 to $k$. If there are $n$ features for a horizon of $k$, there are $n \\cdot (k+1)$ state variables. The domain of the state variable is the domain of the corresponding feature;\n", - "- an *action variable*, $Action_t$, for each $t$ in the range 0 to $k-1$. The domain of $Action_t$, represents the action that takes the agent from the state at time $t$ to the state at time $t+1$.\n", - "\n", - "There are several types of constraints:\n", - "\n", - "- a *precondition constraint* between a state variable at time $t$ and the variable $Actiont_t$ constrains what actions are legal at time $t$;\n", - "- an *effect constraint* between $Action_t$ and a state variable at time $t+1$ constrains the values of a state variable that is a direct effect of the action;\n", - "- a *frame constraint* among a state variable at time $t$, the variable $Action_t$, and the corresponding state variable at time $t+1$ specifies when the variable that does not change as a result of an action has the same value before and after the action;\n", - "- an *initial-state constraint* constrains a variable on the initial state (at time 0). The initial state is represented as a set of domain constraints on the state variables at time 0;\n", - "- a *goal constraint* constrains the final state to be a state that satisfies the achievement goal. These are domain constraints on the variables that appear in the goal;\n", - "- a *state constraint* is a constraint among variables at the same time step. These can include physical constraints on the state or can ensure that states that violate maintenance goals are forbidden. This is extra knowledge beyond the power of the feature-based or PDDL representations of the action.\n", - "\n", - "The PDDL representation gives precondition, effect and frame constraints for each time \n", - "$t$ as follows:\n", - "\n", - "- for each $Var = v$ in the precondition of action $A$, there is a precondition constraint:\n", - "$$ Var_t = v \\leftarrow Action_t = A $$\n", - "that specifies that if the action is to be $A$, $Var_t$ must have value $v$ immediately before. This constraint is violated when $Action_t = A$ and $Var_t \\neq v$, and thus is equivalent to $\\lnot{(Var_t \\neq v \\land Action_t = A)}$;\n", - "- or each $Var = v$ in the effect of action $A$, there is a effect constraint:\n", - "$$ Var_{t+1} = v \\leftarrow Action_t = A $$\n", - "which is violated when $Action_t = A$ and $Var_{t+1} \\neq v$, and thus is equivalent to $\\lnot{(Var_{t+1} \\neq v \\land Action_t = A)}$;\n", - "- for each $Var$, there is a frame constraint, where $As$ is the set of actions that include $Var$ in the effect of the action:\n", - "$$ Var_{t+1} = Var_t \\leftarrow Action_t \\notin As $$\n", - "which specifies that the feature $Var$ has the same value before and after any action that does not affect $Var$.\n", - "\n", - "The CSP representation assumes a fixed planning horizon (ie a fixed number of steps). To find a plan over any number of steps, the algorithm can be run for a horizon of $k = 0, 1, 2, \\dots$ until a solution is found." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [], - "source": [ - "from csp import *" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;32mdef\u001b[0m \u001b[0mCSPlan\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mplanning_problem\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msolution_length\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mCSP_solver\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mac_search_solver\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0marc_heuristic\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msat_up\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"\u001b[0m\n", - "\u001b[0;34m [Section 10.4.3]\u001b[0m\n", - "\u001b[0;34m Planning as Constraint Satisfaction Problem\u001b[0m\n", - "\u001b[0;34m \"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mst\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvar\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstage\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"Returns a string for the var-stage pair that can be used as a variable\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvar\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m\"_\"\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstage\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mif_\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mv1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mv2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"If the second argument is v2, the first argument must be v1\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mif_fun\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mx1\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mv1\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mx2\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mv2\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mif_fun\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__name__\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"if the second argument is \"\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mv2\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m\" then the first argument is \"\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mv1\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m\" \"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mif_fun\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0meq_if_not_in_\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mactset\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"First and third arguments are equal if action is not in actset\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0meq_if_not_in\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mx1\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mx2\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0ma\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mactset\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0meq_if_not_in\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__name__\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"first and third arguments are equal if action is not in \"\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mactset\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m\" \"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0meq_if_not_in\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mexpanded_actions\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mplanning_problem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexpand_actions\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mfluent_values\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mplanning_problem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexpand_fluents\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mhorizon\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msolution_length\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mact_vars\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mst\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'action'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstage\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mstage\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhorizon\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mdomains\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0mav\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmap\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mlambda\u001b[0m \u001b[0maction\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mexpr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0maction\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mexpanded_actions\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mav\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mact_vars\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mdomains\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mupdate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m{\u001b[0m\u001b[0mst\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvar\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstage\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m}\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mvar\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mfluent_values\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mstage\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhorizon\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# initial state constraints\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mconstraints\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mConstraint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mst\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvar\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mis_\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mval\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mvar\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mval\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32min\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0mexpr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfluent\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreplace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Not'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m''\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mTrue\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mfluent\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mop\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0;34m'Not'\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mfluent\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mplanning_problem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minitial\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mconstraints\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mConstraint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mst\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvar\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mis_\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mvar\u001b[0m \u001b[0;32min\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0mexpr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfluent\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreplace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Not'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m''\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mfluent\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mfluent_values\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mfluent\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mplanning_problem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minitial\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# goal state constraints\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mconstraints\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mConstraint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mst\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvar\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mhorizon\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mis_\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mval\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mvar\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mval\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32min\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0mexpr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfluent\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreplace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Not'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m''\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mTrue\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mfluent\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mop\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0;34m'Not'\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mfluent\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mplanning_problem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgoals\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# precondition constraints\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mconstraints\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mConstraint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mst\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvar\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstage\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mst\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'action'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstage\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mif_\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mval\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mact\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# st(var, stage) == val if st('action', stage) == act\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mact\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstrps\u001b[0m \u001b[0;32min\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0mexpr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0maction\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0maction\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0maction\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mexpanded_actions\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mvar\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mval\u001b[0m \u001b[0;32min\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0mexpr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfluent\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreplace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Not'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m''\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mTrue\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mfluent\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mop\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0;34m'Not'\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mfluent\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mstrps\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mprecond\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mstage\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhorizon\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# effect constraints\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mconstraints\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mConstraint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mst\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvar\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstage\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mst\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'action'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstage\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mif_\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mval\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mact\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# st(var, stage + 1) == val if st('action', stage) == act\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mact\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstrps\u001b[0m \u001b[0;32min\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0mexpr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0maction\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0maction\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0maction\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mexpanded_actions\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mvar\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mval\u001b[0m \u001b[0;32min\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0mexpr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfluent\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreplace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Not'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m''\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;32mTrue\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mfluent\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mop\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0;34m'Not'\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mfluent\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mstrps\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0meffect\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mstage\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhorizon\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# frame constraints\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mconstraints\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mConstraint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mst\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvar\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstage\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mst\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'action'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstage\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mst\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvar\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstage\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0meq_if_not_in_\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmap\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mlambda\u001b[0m \u001b[0maction\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mexpr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0maction\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0mact\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mact\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mexpanded_actions\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mvar\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mact\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0meffect\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mExpr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Not'\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mvar\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mop\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mvar\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mact\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0meffect\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mvar\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mfluent_values\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mstage\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhorizon\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mcsp\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mNaryCSP\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdomains\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mconstraints\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0msol\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mCSP_solver\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcsp\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0marc_heuristic\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0marc_heuristic\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0msol\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0msol\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0ma\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mact_vars\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%psource CSPlan" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Planning as Boolean Satisfiability Problem\n", - "\n", - "As shown in [[2]](cite-kautz1992planning) the translation of a *Planning Domain Definition Language* (PDDL) description into a *Conjunctive Normal Form* (CNF) formula is a series of straightforward steps:\n", - "- *propositionalize the actions*: replace each action schema with a set of ground actions formed by substituting constants for each of the variables. These ground actions are not part of the translation, but will be used in subsequent steps;\n", - "- *define the initial state*: assert $F^0$ for every fluent $F$ in the problem’s initial state, and $\\lnot{F}$ for every fluent not mentioned in the initial state;\n", - "- *propositionalize the goal*: for every variable in the goal, replace the literals that contain the variable with a disjunction over constants;\n", - "- *add successor-state axioms*: for each fluent $F$, add an axiom of the form\n", - "\n", - "$$ F^{t+1} \\iff ActionCausesF^t \\lor (F^t \\land \\lnot{ActionCausesNotF^t}) $$\n", - "\n", - "where $ActionCausesF$ is a disjunction of all the ground actions that have $F$ in their add list, and $ActionCausesNotF$ is a disjunction of all the ground actions that have $F$ in their delete list;\n", - "- *add precondition axioms*: for each ground action $A$, add the axiom $A^t \\implies PRE(A)^t$, that is, if an action is taken at time $t$, then the preconditions must have been true;\n", - "- *add action exclusion axioms*: say that every action is distinct from every other action.\n", - "\n", - "A propositional planning procedure implements the basic idea just given but, because the agent does not know how many steps it will take to reach the goal, the algorithm tries each possible number of steps $t$, up to some maximum conceivable plan length $T_{max}$ . In this way, it is guaranteed to find the shortest plan if one exists. Because of the way the propositional planning procedure searches for a solution, this approach cannot be used in a partially observable environment, ie WalkSAT, but would just set the unobservable variables to the values it needs to create a solution." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [], - "source": [ - "from logic import *" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;32mdef\u001b[0m \u001b[0mSATPlan\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mplanning_problem\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msolution_length\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mSAT_solver\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mcdcl_satisfiable\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"\u001b[0m\n", - "\u001b[0;34m [Section 10.4.1]\u001b[0m\n", - "\u001b[0;34m Planning as Boolean satisfiability\u001b[0m\n", - "\u001b[0;34m \"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mexpand_transitions\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstate\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mactions\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mstate\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msorted\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mconjuncts\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstate\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0maction\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mfilter\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mlambda\u001b[0m \u001b[0mact\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mact\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcheck_precond\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstate\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mact\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mactions\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mtransition\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0massociate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'&'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstate\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mupdate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0mExpr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0maction\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0maction\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0massociate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'&'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msorted\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfilter\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mlambda\u001b[0m \u001b[0mclause\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mclause\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mop\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0;34m'Not'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0maction\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstate\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maction\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclauses\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mplanning_problem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mis_strips\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0massociate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'&'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msorted\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0maction\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstate\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maction\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclauses\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mstate\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mtransition\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0massociate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'&'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstate\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalues\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mstate\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mtransition\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mexpand_transitions\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mexpr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstate\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mactions\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mtransition\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdefaultdict\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdict\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mexpand_transitions\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0massociate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'&'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mplanning_problem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minitial\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mplanning_problem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexpand_actions\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mSAT_plan\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0massociate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'&'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msorted\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mplanning_problem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minitial\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtransition\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0massociate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'&'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msorted\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mplanning_problem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgoals\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msolution_length\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mSAT_solver\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mSAT_solver\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%psource SATPlan" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;32mdef\u001b[0m \u001b[0mSAT_plan\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minit\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtransition\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mgoal\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mt_max\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mSAT_solver\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mcdcl_satisfiable\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"Converts a planning problem to Satisfaction problem by translating it to a cnf sentence.\u001b[0m\n", - "\u001b[0;34m [Figure 7.22]\u001b[0m\n", - "\u001b[0;34m >>> transition = {'A': {'Left': 'A', 'Right': 'B'}, 'B': {'Left': 'A', 'Right': 'C'}, 'C': {'Left': 'B', 'Right': 'C'}}\u001b[0m\n", - "\u001b[0;34m >>> SAT_plan('A', transition, 'C', 1) is None\u001b[0m\n", - "\u001b[0;34m True\u001b[0m\n", - "\u001b[0;34m \"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# Functions used by SAT_plan\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mtranslate_to_SAT\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minit\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtransition\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mgoal\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mclauses\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mstates\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mstate\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mstate\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mtransition\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# Symbol claiming state s at time t\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mstate_counter\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mitertools\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcount\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0ms\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mstates\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mt\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtime\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mstate_sym\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mExpr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"S{}\"\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstate_counter\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# Add initial state axiom\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mclauses\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstate_sym\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0minit\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# Add goal state axiom\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mclauses\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstate_sym\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mfirst\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mclause\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mclause\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mstate_sym\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mconjuncts\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mclause\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0missuperset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mconjuncts\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgoal\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \\\n", - " \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgoal\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mExpr\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0mclauses\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstate_sym\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mgoal\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# All possible transitions\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mtransition_counter\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mitertools\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcount\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0ms\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mstates\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0maction\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mtransition\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0ms_\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtransition\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0maction\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mt\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# Action 'action' taken from state 's' at time 't' to reach 's_'\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0maction_sym\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maction\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mExpr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"T{}\"\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtransition_counter\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# Change the state from s to s_\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mclauses\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0maction_sym\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maction\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m|\u001b[0m \u001b[0;34m'==>'\u001b[0m \u001b[0;34m|\u001b[0m \u001b[0mstate_sym\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mclauses\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0maction_sym\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maction\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m|\u001b[0m \u001b[0;34m'==>'\u001b[0m \u001b[0;34m|\u001b[0m \u001b[0mstate_sym\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0ms_\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mt\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# Allow only one state at any time\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mt\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtime\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# must be a state at any time\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mclauses\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0massociate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'|'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mstate_sym\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0ms\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mstates\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0ms\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mstates\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0ms_\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mstates\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mstates\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# for each pair of states s, s_ only one is possible at time t\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mclauses\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m~\u001b[0m\u001b[0mstate_sym\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m|\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m~\u001b[0m\u001b[0mstate_sym\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0ms_\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# Restrict to one transition per timestep\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mt\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# list of possible transitions at time t\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mtransitions_t\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mtr\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mtr\u001b[0m \u001b[0;32min\u001b[0m \u001b[0maction_sym\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mtr\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# make sure at least one of the transitions happens\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mclauses\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0massociate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'|'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0maction_sym\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mtr\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mtr\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mtransitions_t\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mtr\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mtransitions_t\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mtr_\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mtransitions_t\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mtransitions_t\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtr\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# there cannot be two transitions tr and tr_ at time t\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mclauses\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m~\u001b[0m\u001b[0maction_sym\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mtr\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m|\u001b[0m \u001b[0;34m~\u001b[0m\u001b[0maction_sym\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mtr_\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# Combine the clauses to form the cnf\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0massociate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'&'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mclauses\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mextract_solution\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmodel\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mtrue_transitions\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mt\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mt\u001b[0m \u001b[0;32min\u001b[0m \u001b[0maction_sym\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mmodel\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0maction_sym\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mt\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# Sort transitions based on time, which is the 3rd element of the tuple\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mtrue_transitions\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msort\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mlambda\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0maction\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0ms\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maction\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtime\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mtrue_transitions\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# Body of SAT_plan algorithm\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mt\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mt_max\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;31m# dictionaries to help extract the solution from model\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mstate_sym\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0maction_sym\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mcnf\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtranslate_to_SAT\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minit\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtransition\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mgoal\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mmodel\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mSAT_solver\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcnf\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mmodel\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mextract_solution\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmodel\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%psource SAT_plan" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "pycharm": {} - }, - "source": [ - "## Experimental Results" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Blocks World" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;32mdef\u001b[0m \u001b[0mthree_block_tower\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"\u001b[0m\n", - "\u001b[0;34m [Figure 10.3] THREE-BLOCK-TOWER\u001b[0m\n", - "\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m A blocks-world problem of stacking three blocks in a certain configuration,\u001b[0m\n", - "\u001b[0;34m also known as the Sussman Anomaly.\u001b[0m\n", - "\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m Example:\u001b[0m\n", - "\u001b[0;34m >>> from planning import *\u001b[0m\n", - "\u001b[0;34m >>> tbt = three_block_tower()\u001b[0m\n", - "\u001b[0;34m >>> tbt.goal_test()\u001b[0m\n", - "\u001b[0;34m False\u001b[0m\n", - "\u001b[0;34m >>> tbt.act(expr('MoveToTable(C, A)'))\u001b[0m\n", - "\u001b[0;34m >>> tbt.act(expr('Move(B, Table, C)'))\u001b[0m\n", - "\u001b[0;34m >>> tbt.goal_test()\u001b[0m\n", - "\u001b[0;34m False\u001b[0m\n", - "\u001b[0;34m >>> tbt.act(expr('Move(A, Table, B)'))\u001b[0m\n", - "\u001b[0;34m >>> tbt.goal_test()\u001b[0m\n", - "\u001b[0;34m True\u001b[0m\n", - "\u001b[0;34m >>>\u001b[0m\n", - "\u001b[0;34m \"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mPlanningProblem\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minitial\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'On(A, Table) & On(B, Table) & On(C, A) & Clear(B) & Clear(C)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mgoals\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'On(A, B) & On(B, C)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mactions\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mAction\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Move(b, x, y)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mprecond\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'On(b, x) & Clear(b) & Clear(y)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0meffect\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'On(b, y) & Clear(x) & ~On(b, x) & ~Clear(y)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mdomain\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'Block(b) & Block(y)'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mAction\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'MoveToTable(b, x)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mprecond\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'On(b, x) & Clear(b)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0meffect\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'On(b, Table) & Clear(x) & ~On(b, x)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mdomain\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'Block(b) & Block(x)'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mdomain\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'Block(A) & Block(B) & Block(C)'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%psource three_block_tower" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### GraphPlan" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 4.46 ms, sys: 124 µs, total: 4.59 ms\n", - "Wall time: 4.48 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "[MoveToTable(C, A), Move(B, Table, C), Move(A, Table, B)]" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time blocks_world_solution = GraphPlan(three_block_tower()).execute()\n", - "linearize(blocks_world_solution)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### ForwardPlan" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "14 paths have been expanded and 28 paths remain in the frontier\n", - "CPU times: user 91 ms, sys: 0 ns, total: 91 ms\n", - "Wall time: 89.8 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "[MoveToTable(C, A), Move(B, Table, C), Move(A, Table, B)]" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time blocks_world_solution = uniform_cost_search(ForwardPlan(three_block_tower()), display=True).solution()\n", - "blocks_world_solution = list(map(lambda action: Expr(action.name, *action.args), blocks_world_solution))\n", - "blocks_world_solution" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### ForwardPlan with Ignore Delete Lists Heuristic" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3 paths have been expanded and 9 paths remain in the frontier\n", - "CPU times: user 81.3 ms, sys: 3.11 ms, total: 84.5 ms\n", - "Wall time: 83 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "[MoveToTable(C, A), Move(B, Table, C), Move(A, Table, B)]" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time blocks_world_solution = astar_search(ForwardPlan(three_block_tower()), display=True).solution()\n", - "blocks_world_solution = list(map(lambda action: Expr(action.name, *action.args), blocks_world_solution))\n", - "blocks_world_solution" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### BackwardPlan" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "116 paths have been expanded and 289 paths remain in the frontier\n", - "CPU times: user 266 ms, sys: 718 µs, total: 267 ms\n", - "Wall time: 265 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "[MoveToTable(C, A), Move(B, Table, C), Move(A, Table, B)]" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time blocks_world_solution = uniform_cost_search(BackwardPlan(three_block_tower()), display=True).solution()\n", - "blocks_world_solution = list(map(lambda action: Expr(action.name, *action.args), blocks_world_solution))\n", - "blocks_world_solution[::-1]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### BackwardPlan with Ignore Delete Lists Heuristic" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4 paths have been expanded and 20 paths remain in the frontier\n", - "CPU times: user 477 ms, sys: 450 µs, total: 477 ms\n", - "Wall time: 476 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "[MoveToTable(C, A), Move(B, Table, C), Move(A, Table, B)]" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time blocks_world_solution = astar_search(BackwardPlan(three_block_tower()), display=True).solution()\n", - "blocks_world_solution = list(map(lambda action: Expr(action.name, *action.args), blocks_world_solution))\n", - "blocks_world_solution[::-1]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### CSPlan" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 172 ms, sys: 4.52 ms, total: 176 ms\n", - "Wall time: 175 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "[MoveToTable(C, A), Move(B, Table, C), Move(A, Table, B)]" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time blocks_world_solution = CSPlan(three_block_tower(), 3, arc_heuristic=no_heuristic)\n", - "blocks_world_solution" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### CSPlan with SAT UP Arc Heuristic" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 267 ms, sys: 0 ns, total: 267 ms\n", - "Wall time: 266 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "[MoveToTable(C, A), Move(B, Table, C), Move(A, Table, B)]" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time blocks_world_solution = CSPlan(three_block_tower(), 3, arc_heuristic=sat_up)\n", - "blocks_world_solution" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### SATPlan with DPLL" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 34.9 s, sys: 15.9 ms, total: 34.9 s\n", - "Wall time: 34.9 s\n" - ] - }, - { - "data": { - "text/plain": [ - "[MoveToTable(C, A), Move(B, Table, C), Move(A, Table, B)]" - ] - }, - "execution_count": 27, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time blocks_world_solution = SATPlan(three_block_tower(), 4, SAT_solver=dpll_satisfiable)\n", - "blocks_world_solution" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### SATPlan with CDCL" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 1.15 s, sys: 4.01 ms, total: 1.15 s\n", - "Wall time: 1.15 s\n" - ] - }, - { - "data": { - "text/plain": [ - "[MoveToTable(C, A), Move(B, Table, C), Move(A, Table, B)]" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time blocks_world_solution = SATPlan(three_block_tower(), 4, SAT_solver=cdcl_satisfiable)\n", - "blocks_world_solution" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Spare Tire" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;32mdef\u001b[0m \u001b[0mspare_tire\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"\u001b[0m\n", - "\u001b[0;34m [Figure 10.2] SPARE-TIRE-PROBLEM\u001b[0m\n", - "\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m A problem involving changing the flat tire of a car\u001b[0m\n", - "\u001b[0;34m with a spare tire from the trunk.\u001b[0m\n", - "\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m Example:\u001b[0m\n", - "\u001b[0;34m >>> from planning import *\u001b[0m\n", - "\u001b[0;34m >>> st = spare_tire()\u001b[0m\n", - "\u001b[0;34m >>> st.goal_test()\u001b[0m\n", - "\u001b[0;34m False\u001b[0m\n", - "\u001b[0;34m >>> st.act(expr('Remove(Spare, Trunk)'))\u001b[0m\n", - "\u001b[0;34m >>> st.act(expr('Remove(Flat, Axle)'))\u001b[0m\n", - "\u001b[0;34m >>> st.goal_test()\u001b[0m\n", - "\u001b[0;34m False\u001b[0m\n", - "\u001b[0;34m >>> st.act(expr('PutOn(Spare, Axle)'))\u001b[0m\n", - "\u001b[0;34m >>> st.goal_test()\u001b[0m\n", - "\u001b[0;34m True\u001b[0m\n", - "\u001b[0;34m >>>\u001b[0m\n", - "\u001b[0;34m \"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mPlanningProblem\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minitial\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'At(Flat, Axle) & At(Spare, Trunk)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mgoals\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'At(Spare, Axle) & At(Flat, Ground)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mactions\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mAction\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Remove(obj, loc)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mprecond\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'At(obj, loc)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0meffect\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'At(obj, Ground) & ~At(obj, loc)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mdomain\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'Tire(obj)'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mAction\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'PutOn(t, Axle)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mprecond\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'At(t, Ground) & ~At(Flat, Axle)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0meffect\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'At(t, Axle) & ~At(t, Ground)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mdomain\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'Tire(t)'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mAction\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'LeaveOvernight'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mprecond\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m''\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0meffect\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'~At(Spare, Ground) & ~At(Spare, Axle) & ~At(Spare, Trunk) & \\\u001b[0m\n", - "\u001b[0;34m ~At(Flat, Ground) & ~At(Flat, Axle) & ~At(Flat, Trunk)'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mdomain\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'Tire(Flat) & Tire(Spare)'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%psource spare_tire" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### GraphPlan" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 4.24 ms, sys: 1 µs, total: 4.24 ms\n", - "Wall time: 4.16 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "[Remove(Flat, Axle), Remove(Spare, Trunk), PutOn(Spare, Axle)]" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time spare_tire_solution = GraphPlan(spare_tire()).execute()\n", - "linearize(spare_tire_solution)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### ForwardPlan" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "11 paths have been expanded and 9 paths remain in the frontier\n", - "CPU times: user 10.3 ms, sys: 0 ns, total: 10.3 ms\n", - "Wall time: 9.89 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "[Remove(Flat, Axle), Remove(Spare, Trunk), PutOn(Spare, Axle)]" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time spare_tire_solution = uniform_cost_search(ForwardPlan(spare_tire()), display=True).solution()\n", - "spare_tire_solution = list(map(lambda action: Expr(action.name, *action.args), spare_tire_solution))\n", - "spare_tire_solution" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### ForwardPlan with Ignore Delete Lists Heuristic" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "5 paths have been expanded and 8 paths remain in the frontier\n", - "CPU times: user 20.4 ms, sys: 1 µs, total: 20.4 ms\n", - "Wall time: 19.4 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "[Remove(Flat, Axle), Remove(Spare, Trunk), PutOn(Spare, Axle)]" - ] - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time spare_tire_solution = astar_search(ForwardPlan(spare_tire()), display=True).solution()\n", - "spare_tire_solution = list(map(lambda action: Expr(action.name, *action.args), spare_tire_solution))\n", - "spare_tire_solution" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### BackwardPlan" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "29 paths have been expanded and 22 paths remain in the frontier\n", - "CPU times: user 22.2 ms, sys: 7 µs, total: 22.2 ms\n", - "Wall time: 21.3 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "[Remove(Flat, Axle), Remove(Spare, Trunk), PutOn(Spare, Axle)]" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time spare_tire_solution = uniform_cost_search(BackwardPlan(spare_tire()), display=True).solution()\n", - "spare_tire_solution = list(map(lambda action: Expr(action.name, *action.args), spare_tire_solution))\n", - "spare_tire_solution[::-1]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### BackwardPlan with Ignore Delete Lists Heuristic" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3 paths have been expanded and 11 paths remain in the frontier\n", - "CPU times: user 13 ms, sys: 0 ns, total: 13 ms\n", - "Wall time: 12.5 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "[Remove(Spare, Trunk), Remove(Flat, Axle), PutOn(Spare, Axle)]" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time spare_tire_solution = astar_search(BackwardPlan(spare_tire()), display=True).solution()\n", - "spare_tire_solution = list(map(lambda action: Expr(action.name, *action.args), spare_tire_solution))\n", - "spare_tire_solution[::-1]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### CSPlan" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 94.7 ms, sys: 0 ns, total: 94.7 ms\n", - "Wall time: 93.2 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "[Remove(Spare, Trunk), Remove(Flat, Axle), PutOn(Spare, Axle)]" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time spare_tire_solution = CSPlan(spare_tire(), 3, arc_heuristic=no_heuristic)\n", - "spare_tire_solution" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### CSPlan with SAT UP Arc Heuristic" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 119 ms, sys: 0 ns, total: 119 ms\n", - "Wall time: 118 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "[Remove(Spare, Trunk), Remove(Flat, Axle), PutOn(Spare, Axle)]" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time spare_tire_solution = CSPlan(spare_tire(), 3, arc_heuristic=sat_up)\n", - "spare_tire_solution" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### SATPlan with DPLL" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 9.01 s, sys: 3.98 ms, total: 9.01 s\n", - "Wall time: 9.01 s\n" - ] - }, - { - "data": { - "text/plain": [ - "[Remove(Flat, Axle), Remove(Spare, Trunk), PutOn(Spare, Axle)]" - ] - }, - "execution_count": 36, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time spare_tire_solution = SATPlan(spare_tire(), 4, SAT_solver=dpll_satisfiable)\n", - "spare_tire_solution" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### SATPlan with CDCL" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 630 ms, sys: 6 µs, total: 630 ms\n", - "Wall time: 628 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "[Remove(Spare, Trunk), Remove(Flat, Axle), PutOn(Spare, Axle)]" - ] - }, - "execution_count": 37, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time spare_tire_solution = SATPlan(spare_tire(), 4, SAT_solver=cdcl_satisfiable)\n", - "spare_tire_solution" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Shopping Problem" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;32mdef\u001b[0m \u001b[0mshopping_problem\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"\u001b[0m\n", - "\u001b[0;34m SHOPPING-PROBLEM\u001b[0m\n", - "\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m A problem of acquiring some items given their availability at certain stores.\u001b[0m\n", - "\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m Example:\u001b[0m\n", - "\u001b[0;34m >>> from planning import *\u001b[0m\n", - "\u001b[0;34m >>> sp = shopping_problem()\u001b[0m\n", - "\u001b[0;34m >>> sp.goal_test()\u001b[0m\n", - "\u001b[0;34m False\u001b[0m\n", - "\u001b[0;34m >>> sp.act(expr('Go(Home, HW)'))\u001b[0m\n", - "\u001b[0;34m >>> sp.act(expr('Buy(Drill, HW)'))\u001b[0m\n", - "\u001b[0;34m >>> sp.act(expr('Go(HW, SM)'))\u001b[0m\n", - "\u001b[0;34m >>> sp.act(expr('Buy(Banana, SM)'))\u001b[0m\n", - "\u001b[0;34m >>> sp.goal_test()\u001b[0m\n", - "\u001b[0;34m False\u001b[0m\n", - "\u001b[0;34m >>> sp.act(expr('Buy(Milk, SM)'))\u001b[0m\n", - "\u001b[0;34m >>> sp.goal_test()\u001b[0m\n", - "\u001b[0;34m True\u001b[0m\n", - "\u001b[0;34m >>>\u001b[0m\n", - "\u001b[0;34m \"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mPlanningProblem\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minitial\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'At(Home) & Sells(SM, Milk) & Sells(SM, Banana) & Sells(HW, Drill)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mgoals\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'Have(Milk) & Have(Banana) & Have(Drill)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mactions\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mAction\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Buy(x, store)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mprecond\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'At(store) & Sells(store, x)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0meffect\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'Have(x)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mdomain\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'Store(store) & Item(x)'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mAction\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Go(x, y)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mprecond\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'At(x)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0meffect\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'At(y) & ~At(x)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mdomain\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'Place(x) & Place(y)'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mdomain\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'Place(Home) & Place(SM) & Place(HW) & Store(SM) & Store(HW) & '\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m'Item(Milk) & Item(Banana) & Item(Drill)'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%psource shopping_problem" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### GraphPlan" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 5.08 ms, sys: 3 µs, total: 5.08 ms\n", - "Wall time: 5.03 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "[Go(Home, HW), Go(Home, SM), Buy(Milk, SM), Buy(Drill, HW), Buy(Banana, SM)]" - ] - }, - "execution_count": 45, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time shopping_problem_solution = GraphPlan(shopping_problem()).execute()\n", - "linearize(shopping_problem_solution)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### ForwardPlan" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "167 paths have been expanded and 257 paths remain in the frontier\n", - "CPU times: user 187 ms, sys: 4.01 ms, total: 191 ms\n", - "Wall time: 190 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "[Go(Home, SM), Buy(Banana, SM), Buy(Milk, SM), Go(SM, HW), Buy(Drill, HW)]" - ] - }, - "execution_count": 46, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time shopping_problem_solution = uniform_cost_search(ForwardPlan(shopping_problem()), display=True).solution()\n", - "shopping_problem_solution = list(map(lambda action: Expr(action.name, *action.args), shopping_problem_solution))\n", - "shopping_problem_solution" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### ForwardPlan with Ignore Delete Lists Heuristic" - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "9 paths have been expanded and 22 paths remain in the frontier\n", - "CPU times: user 101 ms, sys: 3 µs, total: 101 ms\n", - "Wall time: 100 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "[Go(Home, SM), Buy(Banana, SM), Buy(Milk, SM), Go(SM, HW), Buy(Drill, HW)]" - ] - }, - "execution_count": 47, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time shopping_problem_solution = astar_search(ForwardPlan(shopping_problem()), display=True).solution()\n", - "shopping_problem_solution = list(map(lambda action: Expr(action.name, *action.args), shopping_problem_solution))\n", - "shopping_problem_solution" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### BackwardPlan" - ] - }, - { - "cell_type": "code", - "execution_count": 48, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "176 paths have been expanded and 7 paths remain in the frontier\n", - "CPU times: user 109 ms, sys: 2 µs, total: 109 ms\n", - "Wall time: 107 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "[Go(Home, HW), Buy(Drill, HW), Go(HW, SM), Buy(Milk, SM), Buy(Banana, SM)]" - ] - }, - "execution_count": 48, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time shopping_problem_solution = uniform_cost_search(BackwardPlan(shopping_problem()), display=True).solution()\n", - "shopping_problem_solution = list(map(lambda action: Expr(action.name, *action.args), shopping_problem_solution))\n", - "shopping_problem_solution[::-1]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### BackwardPlan with Ignore Delete Lists Heuristic" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "18 paths have been expanded and 28 paths remain in the frontier\n", - "CPU times: user 235 ms, sys: 9 µs, total: 235 ms\n", - "Wall time: 234 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "[Go(Home, SM), Buy(Banana, SM), Buy(Milk, SM), Go(SM, HW), Buy(Drill, HW)]" - ] - }, - "execution_count": 49, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time shopping_problem_solution = astar_search(BackwardPlan(shopping_problem()), display=True).solution()\n", - "shopping_problem_solution = list(map(lambda action: Expr(action.name, *action.args), shopping_problem_solution))\n", - "shopping_problem_solution[::-1]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### CSPlan" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 194 ms, sys: 6 µs, total: 194 ms\n", - "Wall time: 192 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "[Go(Home, HW), Buy(Drill, HW), Go(HW, SM), Buy(Banana, SM), Buy(Milk, SM)]" - ] - }, - "execution_count": 50, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time shopping_problem_solution = CSPlan(shopping_problem(), 5, arc_heuristic=no_heuristic)\n", - "shopping_problem_solution" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### CSPlan with SAT UP Arc Heuristic" - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 235 ms, sys: 7 µs, total: 235 ms\n", - "Wall time: 233 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "[Go(Home, HW), Buy(Drill, HW), Go(HW, SM), Buy(Banana, SM), Buy(Milk, SM)]" - ] - }, - "execution_count": 51, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time shopping_problem_solution = CSPlan(shopping_problem(), 5, arc_heuristic=sat_up)\n", - "shopping_problem_solution" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### SATPlan with CDCL" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 1min 29s, sys: 36 ms, total: 1min 29s\n", - "Wall time: 1min 29s\n" - ] - }, - { - "data": { - "text/plain": [ - "[Go(Home, HW), Buy(Drill, HW), Go(HW, SM), Buy(Banana, SM), Buy(Milk, SM)]" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time shopping_problem_solution = SATPlan(shopping_problem(), 5, SAT_solver=cdcl_satisfiable)\n", - "shopping_problem_solution" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Air Cargo" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;32mdef\u001b[0m \u001b[0mair_cargo\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"\u001b[0m\n", - "\u001b[0;34m [Figure 10.1] AIR-CARGO-PROBLEM\u001b[0m\n", - "\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m An air-cargo shipment problem for delivering cargo to different locations,\u001b[0m\n", - "\u001b[0;34m given the starting location and airplanes.\u001b[0m\n", - "\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m Example:\u001b[0m\n", - "\u001b[0;34m >>> from planning import *\u001b[0m\n", - "\u001b[0;34m >>> ac = air_cargo()\u001b[0m\n", - "\u001b[0;34m >>> ac.goal_test()\u001b[0m\n", - "\u001b[0;34m False\u001b[0m\n", - "\u001b[0;34m >>> ac.act(expr('Load(C2, P2, JFK)'))\u001b[0m\n", - "\u001b[0;34m >>> ac.act(expr('Load(C1, P1, SFO)'))\u001b[0m\n", - "\u001b[0;34m >>> ac.act(expr('Fly(P1, SFO, JFK)'))\u001b[0m\n", - "\u001b[0;34m >>> ac.act(expr('Fly(P2, JFK, SFO)'))\u001b[0m\n", - "\u001b[0;34m >>> ac.act(expr('Unload(C2, P2, SFO)'))\u001b[0m\n", - "\u001b[0;34m >>> ac.goal_test()\u001b[0m\n", - "\u001b[0;34m False\u001b[0m\n", - "\u001b[0;34m >>> ac.act(expr('Unload(C1, P1, JFK)'))\u001b[0m\n", - "\u001b[0;34m >>> ac.goal_test()\u001b[0m\n", - "\u001b[0;34m True\u001b[0m\n", - "\u001b[0;34m >>>\u001b[0m\n", - "\u001b[0;34m \"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mPlanningProblem\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minitial\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'At(C1, SFO) & At(C2, JFK) & At(P1, SFO) & At(P2, JFK)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mgoals\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'At(C1, JFK) & At(C2, SFO)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mactions\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mAction\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Load(c, p, a)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mprecond\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'At(c, a) & At(p, a)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0meffect\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'In(c, p) & ~At(c, a)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mdomain\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'Cargo(c) & Plane(p) & Airport(a)'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mAction\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Unload(c, p, a)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mprecond\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'In(c, p) & At(p, a)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0meffect\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'At(c, a) & ~In(c, p)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mdomain\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'Cargo(c) & Plane(p) & Airport(a)'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mAction\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Fly(p, f, to)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mprecond\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'At(p, f)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0meffect\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'At(p, to) & ~At(p, f)'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mdomain\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'Plane(p) & Airport(f) & Airport(to)'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", - "\u001b[0;34m\u001b[0m \u001b[0mdomain\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'Cargo(C1) & Cargo(C2) & Plane(P1) & Plane(P2) & Airport(SFO) & Airport(JFK)'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%psource air_cargo" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### GraphPlan" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 9.06 ms, sys: 3 µs, total: 9.06 ms\n", - "Wall time: 8.94 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "[Load(C2, P2, JFK),\n", - " Fly(P2, JFK, SFO),\n", - " Load(C1, P1, SFO),\n", - " Fly(P1, SFO, JFK),\n", - " Unload(C1, P1, JFK),\n", - " Unload(C2, P2, SFO)]" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time air_cargo_solution = GraphPlan(air_cargo()).execute()\n", - "linearize(air_cargo_solution)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### ForwardPlan" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "838 paths have been expanded and 1288 paths remain in the frontier\n", - "CPU times: user 3.56 s, sys: 4 ms, total: 3.57 s\n", - "Wall time: 3.56 s\n" - ] - }, - { - "data": { - "text/plain": [ - "[Load(C2, P2, JFK),\n", - " Fly(P2, JFK, SFO),\n", - " Unload(C2, P2, SFO),\n", - " Load(C1, P2, SFO),\n", - " Fly(P2, SFO, JFK),\n", - " Unload(C1, P2, JFK)]" - ] - }, - "execution_count": 39, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time air_cargo_solution = uniform_cost_search(ForwardPlan(air_cargo()), display=True).solution()\n", - "air_cargo_solution = list(map(lambda action: Expr(action.name, *action.args), air_cargo_solution))\n", - "air_cargo_solution" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### ForwardPlan with Ignore Delete Lists Heuristic" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "17 paths have been expanded and 54 paths remain in the frontier\n", - "CPU times: user 716 ms, sys: 0 ns, total: 716 ms\n", - "Wall time: 717 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "[Load(C2, P2, JFK),\n", - " Fly(P2, JFK, SFO),\n", - " Unload(C2, P2, SFO),\n", - " Load(C1, P2, SFO),\n", - " Fly(P2, SFO, JFK),\n", - " Unload(C1, P2, JFK)]" - ] - }, - "execution_count": 40, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time air_cargo_solution = astar_search(ForwardPlan(air_cargo()), display=True).solution()\n", - "air_cargo_solution = list(map(lambda action: Expr(action.name, *action.args), air_cargo_solution))\n", - "air_cargo_solution" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### BackwardPlan" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "506 paths have been expanded and 65 paths remain in the frontier\n", - "CPU times: user 970 ms, sys: 0 ns, total: 970 ms\n", - "Wall time: 971 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "[Load(C1, P1, SFO),\n", - " Fly(P1, SFO, JFK),\n", - " Load(C2, P1, JFK),\n", - " Unload(C1, P1, JFK),\n", - " Fly(P1, JFK, SFO),\n", - " Unload(C2, P1, SFO)]" - ] - }, - "execution_count": 41, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time air_cargo_solution = uniform_cost_search(BackwardPlan(air_cargo()), display=True).solution()\n", - "air_cargo_solution = list(map(lambda action: Expr(action.name, *action.args), air_cargo_solution))\n", - "air_cargo_solution[::-1]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### BackwardPlan with Ignore Delete Lists Heuristic" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "23 paths have been expanded and 50 paths remain in the frontier\n", - "CPU times: user 1.19 s, sys: 2 µs, total: 1.19 s\n", - "Wall time: 1.2 s\n" - ] - }, - { - "data": { - "text/plain": [ - "[Load(C2, P2, JFK),\n", - " Fly(P2, JFK, SFO),\n", - " Unload(C2, P2, SFO),\n", - " Load(C1, P2, SFO),\n", - " Fly(P2, SFO, JFK),\n", - " Unload(C1, P2, JFK)]" - ] - }, - "execution_count": 42, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time air_cargo_solution = astar_search(BackwardPlan(air_cargo()), display=True).solution()\n", - "air_cargo_solution = list(map(lambda action: Expr(action.name, *action.args), air_cargo_solution))\n", - "air_cargo_solution[::-1]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### CSPlan" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 6.5 s, sys: 0 ns, total: 6.5 s\n", - "Wall time: 6.51 s\n" - ] - }, - { - "data": { - "text/plain": [ - "[Load(C1, P1, SFO),\n", - " Fly(P1, SFO, JFK),\n", - " Load(C2, P1, JFK),\n", - " Unload(C1, P1, JFK),\n", - " Fly(P1, JFK, SFO),\n", - " Unload(C2, P1, SFO)]" - ] - }, - "execution_count": 43, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time air_cargo_solution = CSPlan(air_cargo(), 6, arc_heuristic=no_heuristic)\n", - "air_cargo_solution" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### CSPlan with SAT UP Arc Heuristic" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 13.6 s, sys: 7.98 ms, total: 13.7 s\n", - "Wall time: 13.7 s\n" - ] - }, - { - "data": { - "text/plain": [ - "[Load(C1, P1, SFO),\n", - " Fly(P1, SFO, JFK),\n", - " Load(C2, P1, JFK),\n", - " Unload(C1, P1, JFK),\n", - " Fly(P1, JFK, SFO),\n", - " Unload(C2, P1, SFO)]" - ] - }, - "execution_count": 44, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time air_cargo_solution = CSPlan(air_cargo(), 6, arc_heuristic=sat_up)\n", - "air_cargo_solution" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## References\n", - "\n", - "[[1]](#ref-1) Hoffmann, Jörg. 2001. _FF: The fast-forward planning system_.\n", - "\n", - "[[2]](#ref-2) Kautz, Henry A and Selman, Bart and others. 1992. _Planning as Satisfiability_." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "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.7.5rc1" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/csp.ipynb b/csp.ipynb deleted file mode 100644 index 5d490846b..000000000 --- a/csp.ipynb +++ /dev/null @@ -1,3084 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# CONSTRAINT SATISFACTION PROBLEMS\n", - "\n", - "This IPy notebook acts as supporting material for topics covered in **Chapter 6 Constraint Satisfaction Problems** of the book* Artificial Intelligence: A Modern Approach*. We make use of the implementations in **csp.py** module. Even though this notebook includes a brief summary of the main topics, familiarity with the material present in the book is expected. We will look at some visualizations and solve some of the CSP problems described in the book. Let us import everything from the csp module to get started." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "from csp import *\n", - "from notebook import psource, plot_NQueens\n", - "%matplotlib inline\n", - "\n", - "# Hide warnings in the matplotlib sections\n", - "import warnings\n", - "warnings.filterwarnings(\"ignore\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## CONTENTS\n", - "\n", - "* Overview\n", - "* Graph Coloring\n", - "* N-Queens\n", - "* AC-3\n", - "* Backtracking Search\n", - "* Tree CSP Solver\n", - "* Graph Coloring Visualization\n", - "* N-Queens Visualization" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## OVERVIEW\n", - "\n", - "CSPs are a special kind of search problems. Here we don't treat the space as a black box but the state has a particular form and we use that to our advantage to tweak our algorithms to be more suited to the problems. A CSP State is defined by a set of variables which can take values from corresponding domains. These variables can take only certain values in their domains to satisfy the constraints. A set of assignments which satisfies all constraints passes the goal test. Let us start by exploring the CSP class which we will use to model our CSPs. You can keep the popup open and read the main page to get a better idea of the code." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "

\n", - "\n", - "
class CSP(search.Problem):\n",
-       "    """This class describes finite-domain Constraint Satisfaction Problems.\n",
-       "    A CSP is specified by the following inputs:\n",
-       "        variables   A list of variables; each is atomic (e.g. int or string).\n",
-       "        domains     A dict of {var:[possible_value, ...]} entries.\n",
-       "        neighbors   A dict of {var:[var,...]} that for each variable lists\n",
-       "                    the other variables that participate in constraints.\n",
-       "        constraints A function f(A, a, B, b) that returns true if neighbors\n",
-       "                    A, B satisfy the constraint when they have values A=a, B=b\n",
-       "\n",
-       "    In the textbook and in most mathematical definitions, the\n",
-       "    constraints are specified as explicit pairs of allowable values,\n",
-       "    but the formulation here is easier to express and more compact for\n",
-       "    most cases. (For example, the n-Queens problem can be represented\n",
-       "    in O(n) space using this notation, instead of O(N^4) for the\n",
-       "    explicit representation.) In terms of describing the CSP as a\n",
-       "    problem, that's all there is.\n",
-       "\n",
-       "    However, the class also supports data structures and methods that help you\n",
-       "    solve CSPs by calling a search function on the CSP. Methods and slots are\n",
-       "    as follows, where the argument 'a' represents an assignment, which is a\n",
-       "    dict of {var:val} entries:\n",
-       "        assign(var, val, a)     Assign a[var] = val; do other bookkeeping\n",
-       "        unassign(var, a)        Do del a[var], plus other bookkeeping\n",
-       "        nconflicts(var, val, a) Return the number of other variables that\n",
-       "                                conflict with var=val\n",
-       "        curr_domains[var]       Slot: remaining consistent values for var\n",
-       "                                Used by constraint propagation routines.\n",
-       "    The following methods are used only by graph_search and tree_search:\n",
-       "        actions(state)          Return a list of actions\n",
-       "        result(state, action)   Return a successor of state\n",
-       "        goal_test(state)        Return true if all constraints satisfied\n",
-       "    The following are just for debugging purposes:\n",
-       "        nassigns                Slot: tracks the number of assignments made\n",
-       "        display(a)              Print a human-readable representation\n",
-       "    """\n",
-       "\n",
-       "    def __init__(self, variables, domains, neighbors, constraints):\n",
-       "        """Construct a CSP problem. If variables is empty, it becomes domains.keys()."""\n",
-       "        variables = variables or list(domains.keys())\n",
-       "        self.variables = variables\n",
-       "        self.domains = domains\n",
-       "        self.neighbors = neighbors\n",
-       "        self.constraints = constraints\n",
-       "        self.initial = ()\n",
-       "        self.curr_domains = None\n",
-       "        self.nassigns = 0\n",
-       "\n",
-       "    def assign(self, var, val, assignment):\n",
-       "        """Add {var: val} to assignment; Discard the old value if any."""\n",
-       "        assignment[var] = val\n",
-       "        self.nassigns += 1\n",
-       "\n",
-       "    def unassign(self, var, assignment):\n",
-       "        """Remove {var: val} from assignment.\n",
-       "        DO NOT call this if you are changing a variable to a new value;\n",
-       "        just call assign for that."""\n",
-       "        if var in assignment:\n",
-       "            del assignment[var]\n",
-       "\n",
-       "    def nconflicts(self, var, val, assignment):\n",
-       "        """Return the number of conflicts var=val has with other variables."""\n",
-       "\n",
-       "        # Subclasses may implement this more efficiently\n",
-       "        def conflict(var2):\n",
-       "            return (var2 in assignment and\n",
-       "                    not self.constraints(var, val, var2, assignment[var2]))\n",
-       "\n",
-       "        return count(conflict(v) for v in self.neighbors[var])\n",
-       "\n",
-       "    def display(self, assignment):\n",
-       "        """Show a human-readable representation of the CSP."""\n",
-       "        # Subclasses can print in a prettier way, or display with a GUI\n",
-       "        print('CSP:', self, 'with assignment:', assignment)\n",
-       "\n",
-       "    # These methods are for the tree and graph-search interface:\n",
-       "\n",
-       "    def actions(self, state):\n",
-       "        """Return a list of applicable actions: nonconflicting\n",
-       "        assignments to an unassigned variable."""\n",
-       "        if len(state) == len(self.variables):\n",
-       "            return []\n",
-       "        else:\n",
-       "            assignment = dict(state)\n",
-       "            var = first([v for v in self.variables if v not in assignment])\n",
-       "            return [(var, val) for val in self.domains[var]\n",
-       "                    if self.nconflicts(var, val, assignment) == 0]\n",
-       "\n",
-       "    def result(self, state, action):\n",
-       "        """Perform an action and return the new state."""\n",
-       "        (var, val) = action\n",
-       "        return state + ((var, val),)\n",
-       "\n",
-       "    def goal_test(self, state):\n",
-       "        """The goal is to assign all variables, with all constraints satisfied."""\n",
-       "        assignment = dict(state)\n",
-       "        return (len(assignment) == len(self.variables)\n",
-       "                and all(self.nconflicts(variables, assignment[variables], assignment) == 0\n",
-       "                        for variables in self.variables))\n",
-       "\n",
-       "    # These are for constraint propagation\n",
-       "\n",
-       "    def support_pruning(self):\n",
-       "        """Make sure we can prune values from domains. (We want to pay\n",
-       "        for this only if we use it.)"""\n",
-       "        if self.curr_domains is None:\n",
-       "            self.curr_domains = {v: list(self.domains[v]) for v in self.variables}\n",
-       "\n",
-       "    def suppose(self, var, value):\n",
-       "        """Start accumulating inferences from assuming var=value."""\n",
-       "        self.support_pruning()\n",
-       "        removals = [(var, a) for a in self.curr_domains[var] if a != value]\n",
-       "        self.curr_domains[var] = [value]\n",
-       "        return removals\n",
-       "\n",
-       "    def prune(self, var, value, removals):\n",
-       "        """Rule out var=value."""\n",
-       "        self.curr_domains[var].remove(value)\n",
-       "        if removals is not None:\n",
-       "            removals.append((var, value))\n",
-       "\n",
-       "    def choices(self, var):\n",
-       "        """Return all values for var that aren't currently ruled out."""\n",
-       "        return (self.curr_domains or self.domains)[var]\n",
-       "\n",
-       "    def infer_assignment(self):\n",
-       "        """Return the partial assignment implied by the current inferences."""\n",
-       "        self.support_pruning()\n",
-       "        return {v: self.curr_domains[v][0]\n",
-       "                for v in self.variables if 1 == len(self.curr_domains[v])}\n",
-       "\n",
-       "    def restore(self, removals):\n",
-       "        """Undo a supposition and all inferences from it."""\n",
-       "        for B, b in removals:\n",
-       "            self.curr_domains[B].append(b)\n",
-       "\n",
-       "    # This is for min_conflicts search\n",
-       "\n",
-       "    def conflicted_vars(self, current):\n",
-       "        """Return a list of variables in current assignment that are in conflict"""\n",
-       "        return [var for var in self.variables\n",
-       "                if self.nconflicts(var, current[var], current) > 0]\n",
-       "
\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "psource(CSP)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The __ _ _init_ _ __ method parameters specify the CSP. Variables can be passed as a list of strings or integers. Domains are passed as dict (dictionary datatpye) where \"key\" specifies the variables and \"value\" specifies the domains. The variables are passed as an empty list. Variables are extracted from the keys of the domain dictionary. Neighbor is a dict of variables that essentially describes the constraint graph. Here each variable key has a list of its values which are the variables that are constraint along with it. The constraint parameter should be a function **f(A, a, B, b**) that **returns true** if neighbors A, B **satisfy the constraint** when they have values **A=a, B=b**. We have additional parameters like nassings which is incremented each time an assignment is made when calling the assign method. You can read more about the methods and parameters in the class doc string. We will talk more about them as we encounter their use. Let us jump to an example." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## GRAPH COLORING\n", - "\n", - "We use the graph coloring problem as our running example for demonstrating the different algorithms in the **csp module**. The idea of map coloring problem is that the adjacent nodes (those connected by edges) should not have the same color throughout the graph. The graph can be colored using a fixed number of colors. Here each node is a variable and the values are the colors that can be assigned to them. Given that the domain will be the same for all our nodes we use a custom dict defined by the **UniversalDict** class. The **UniversalDict** Class takes in a parameter and returns it as a value for all the keys of the dict. It is very similar to **defaultdict** in Python except that it does not support item assignment." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['R', 'G', 'B']" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s = UniversalDict(['R','G','B'])\n", - "s[5]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For our CSP we also need to define a constraint function **f(A, a, B, b)**. In this, we need to ensure that the neighbors don't have the same color. This is defined in the function **different_values_constraint** of the module." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "

\n", - "\n", - "
def different_values_constraint(A, a, B, b):\n",
-       "    """A constraint saying two neighboring variables must differ in value."""\n",
-       "    return a != b\n",
-       "
\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "psource(different_values_constraint)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The CSP class takes neighbors in the form of a Dict. The module specifies a simple helper function named **parse_neighbors** which allows us to take input in the form of strings and return a Dict of a form that is compatible with the **CSP Class**." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "%pdoc parse_neighbors" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The **MapColoringCSP** function creates and returns a CSP with the above constraint function and states. The variables are 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." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "

\n", - "\n", - "
def MapColoringCSP(colors, neighbors):\n",
-       "    """Make a CSP for the problem of coloring a map with different colors\n",
-       "    for any two adjacent regions. Arguments are a list of colors, and a\n",
-       "    dict of {region: [neighbor,...]} entries. This dict may also be\n",
-       "    specified as a string of the form defined by parse_neighbors."""\n",
-       "    if isinstance(neighbors, str):\n",
-       "        neighbors = parse_neighbors(neighbors)\n",
-       "    return CSP(list(neighbors.keys()), UniversalDict(colors), neighbors,\n",
-       "               different_values_constraint)\n",
-       "
\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "psource(MapColoringCSP)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(,\n", - " ,\n", - " )" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "australia_csp, usa_csp, france_csp" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## N-QUEENS\n", - "\n", - "The N-queens puzzle is the problem of placing N chess queens on an N×N chessboard in a way such that no two queens threaten each other. Here N is a natural number. Like the graph coloring problem, NQueens is also implemented in the csp module. The **NQueensCSP** class inherits from the **CSP** class. It makes some modifications in the methods to suit this particular problem. The queens are assumed to be placed one per column, from left to right. That means position (x, y) represents (var, val) in the CSP. The constraint that needs to be passed to the CSP is defined in the **queen_constraint** function. The constraint is satisfied (true) if A, B are really the same variable, or if they are not in the same row, down diagonal, or up diagonal. " - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "

\n", - "\n", - "
def queen_constraint(A, a, B, b):\n",
-       "    """Constraint is satisfied (true) if A, B are really the same variable,\n",
-       "    or if they are not in the same row, down diagonal, or up diagonal."""\n",
-       "    return A == B or (a != b and A + a != B + b and A - a != B - b)\n",
-       "
\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "psource(queen_constraint)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The **NQueensCSP** method implements methods that support solving the problem via **min_conflicts** which is one of the many popular techniques for solving CSPs. Because **min_conflicts** hill climbs the number of conflicts to solve, the CSP **assign** and **unassign** are modified to record conflicts. More details about the structures: **rows**, **downs**, **ups** which help in recording conflicts are explained in the docstring." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "

\n", - "\n", - "
class NQueensCSP(CSP):\n",
-       "    """Make a CSP for the nQueens problem for search with min_conflicts.\n",
-       "    Suitable for large n, it uses only data structures of size O(n).\n",
-       "    Think of placing queens one per column, from left to right.\n",
-       "    That means position (x, y) represents (var, val) in the CSP.\n",
-       "    The main structures are three arrays to count queens that could conflict:\n",
-       "        rows[i]      Number of queens in the ith row (i.e val == i)\n",
-       "        downs[i]     Number of queens in the \\ diagonal\n",
-       "                     such that their (x, y) coordinates sum to i\n",
-       "        ups[i]       Number of queens in the / diagonal\n",
-       "                     such that their (x, y) coordinates have x-y+n-1 = i\n",
-       "    We increment/decrement these counts each time a queen is placed/moved from\n",
-       "    a row/diagonal. So moving is O(1), as is nconflicts.  But choosing\n",
-       "    a variable, and a best value for the variable, are each O(n).\n",
-       "    If you want, you can keep track of conflicted variables, then variable\n",
-       "    selection will also be O(1).\n",
-       "    >>> len(backtracking_search(NQueensCSP(8)))\n",
-       "    8\n",
-       "    """\n",
-       "\n",
-       "    def __init__(self, n):\n",
-       "        """Initialize data structures for n Queens."""\n",
-       "        CSP.__init__(self, list(range(n)), UniversalDict(list(range(n))),\n",
-       "                     UniversalDict(list(range(n))), queen_constraint)\n",
-       "\n",
-       "        self.rows = [0] * n\n",
-       "        self.ups = [0] * (2 * n - 1)\n",
-       "        self.downs = [0] * (2 * n - 1)\n",
-       "\n",
-       "    def nconflicts(self, var, val, assignment):\n",
-       "        """The number of conflicts, as recorded with each assignment.\n",
-       "        Count conflicts in row and in up, down diagonals. If there\n",
-       "        is a queen there, it can't conflict with itself, so subtract 3."""\n",
-       "        n = len(self.variables)\n",
-       "        c = self.rows[val] + self.downs[var + val] + self.ups[var - val + n - 1]\n",
-       "        if assignment.get(var, None) == val:\n",
-       "            c -= 3\n",
-       "        return c\n",
-       "\n",
-       "    def assign(self, var, val, assignment):\n",
-       "        """Assign var, and keep track of conflicts."""\n",
-       "        oldval = assignment.get(var, None)\n",
-       "        if val != oldval:\n",
-       "            if oldval is not None:  # Remove old val if there was one\n",
-       "                self.record_conflict(assignment, var, oldval, -1)\n",
-       "            self.record_conflict(assignment, var, val, +1)\n",
-       "            CSP.assign(self, var, val, assignment)\n",
-       "\n",
-       "    def unassign(self, var, assignment):\n",
-       "        """Remove var from assignment (if it is there) and track conflicts."""\n",
-       "        if var in assignment:\n",
-       "            self.record_conflict(assignment, var, assignment[var], -1)\n",
-       "        CSP.unassign(self, var, assignment)\n",
-       "\n",
-       "    def record_conflict(self, assignment, var, val, delta):\n",
-       "        """Record conflicts caused by addition or deletion of a Queen."""\n",
-       "        n = len(self.variables)\n",
-       "        self.rows[val] += delta\n",
-       "        self.downs[var + val] += delta\n",
-       "        self.ups[var - val + n - 1] += delta\n",
-       "\n",
-       "    def display(self, assignment):\n",
-       "        """Print the queens and the nconflicts values (for debugging)."""\n",
-       "        n = len(self.variables)\n",
-       "        for val in range(n):\n",
-       "            for var in range(n):\n",
-       "                if assignment.get(var, '') == val:\n",
-       "                    ch = 'Q'\n",
-       "                elif (var + val) % 2 == 0:\n",
-       "                    ch = '.'\n",
-       "                else:\n",
-       "                    ch = '-'\n",
-       "                print(ch, end=' ')\n",
-       "            print('    ', end=' ')\n",
-       "            for var in range(n):\n",
-       "                if assignment.get(var, '') == val:\n",
-       "                    ch = '*'\n",
-       "                else:\n",
-       "                    ch = ' '\n",
-       "                print(str(self.nconflicts(var, val, assignment)) + ch, end=' ')\n",
-       "            print()\n",
-       "
\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "psource(NQueensCSP)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The _ ___init___ _ method takes only one parameter **n** i.e. the size of the problem. To create an instance, we just pass the required value of n into the constructor." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [], - "source": [ - "eight_queens = NQueensCSP(8)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We have defined our CSP. \n", - "Now, we need to solve this.\n", - "\n", - "### Min-conflicts\n", - "As stated above, the `min_conflicts` algorithm is an efficient method to solve such a problem.\n", - "
\n", - "In the start, all the variables of the CSP are _randomly_ initialized. \n", - "
\n", - "The algorithm then randomly selects a variable that has conflicts and violates some constraints of the CSP.\n", - "
\n", - "The selected variable is then assigned a value that _minimizes_ the number of conflicts.\n", - "
\n", - "This is a simple **stochastic algorithm** which works on a principle similar to **Hill-climbing**.\n", - "The conflicting state is repeatedly changed into a state with fewer conflicts in an attempt to reach an approximate solution.\n", - "
\n", - "This algorithm sometimes benefits from having a good initial assignment.\n", - "Using greedy techniques to get a good initial assignment and then using `min_conflicts` to solve the CSP can speed up the procedure dramatically, especially for CSPs with a large state space." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "

\n", - "\n", - "
def min_conflicts(csp, max_steps=100000):\n",
-       "    """Solve a CSP by stochastic Hill Climbing on the number of conflicts."""\n",
-       "    # Generate a complete assignment for all variables (probably with conflicts)\n",
-       "    csp.current = current = {}\n",
-       "    for var in csp.variables:\n",
-       "        val = min_conflicts_value(csp, var, current)\n",
-       "        csp.assign(var, val, current)\n",
-       "    # Now repeatedly choose a random conflicted variable and change it\n",
-       "    for i in range(max_steps):\n",
-       "        conflicted = csp.conflicted_vars(current)\n",
-       "        if not conflicted:\n",
-       "            return current\n",
-       "        var = random.choice(conflicted)\n",
-       "        val = min_conflicts_value(csp, var, current)\n",
-       "        csp.assign(var, val, current)\n",
-       "    return None\n",
-       "
\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "psource(min_conflicts)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's use this algorithm to solve the `eight_queens` CSP." - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [], - "source": [ - "solution = min_conflicts(eight_queens)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This is indeed a valid solution. \n", - "
\n", - "`notebook.py` has a helper function to visualize the solution space." - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "plot_NQueens(solution)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Lets' see if we can find a different solution." - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "eight_queens = NQueensCSP(8)\n", - "solution = min_conflicts(eight_queens)\n", - "plot_NQueens(solution)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The solution is a bit different this time. \n", - "Running the above cell several times should give you different valid solutions.\n", - "
\n", - "In the `search.ipynb` notebook, we will see how NQueensProblem can be solved using a **heuristic search method** such as `uniform_cost_search` and `astar_search`." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Helper Functions\n", - "\n", - "We will now implement a few helper functions that will allow us to visualize the Coloring Problem; we'll also make a few modifications to the existing classes and functions for additional record keeping. To begin, we modify the **assign** and **unassign** methods in the **CSP** in order to add a copy of the assignment to the **assignment_history**. We name this new class as **InstruCSP**; it will allow us to see how the assignment evolves over time. " - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [], - "source": [ - "import copy\n", - "class InstruCSP(CSP):\n", - " \n", - " def __init__(self, variables, domains, neighbors, constraints):\n", - " super().__init__(variables, domains, neighbors, constraints)\n", - " self.assignment_history = []\n", - " \n", - " def assign(self, var, val, assignment):\n", - " super().assign(var,val, assignment)\n", - " self.assignment_history.append(copy.deepcopy(assignment))\n", - " \n", - " def unassign(self, var, assignment):\n", - " super().unassign(var,assignment)\n", - " self.assignment_history.append(copy.deepcopy(assignment))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Next, we define **make_instru** which takes an instance of **CSP** and returns an instance of **InstruCSP**." - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [], - "source": [ - "def make_instru(csp):\n", - " return InstruCSP(csp.variables, csp.domains, csp.neighbors, csp.constraints)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We will now use a graph defined as a dictionary for plotting purposes in our Graph Coloring Problem. The keys are the nodes and their values are the corresponding nodes they are connected to." - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [], - "source": [ - "neighbors = {\n", - " 0: [6, 11, 15, 18, 4, 11, 6, 15, 18, 4], \n", - " 1: [12, 12, 14, 14], \n", - " 2: [17, 6, 11, 6, 11, 10, 17, 14, 10, 14], \n", - " 3: [20, 8, 19, 12, 20, 19, 8, 12], \n", - " 4: [11, 0, 18, 5, 18, 5, 11, 0], \n", - " 5: [4, 4], \n", - " 6: [8, 15, 0, 11, 2, 14, 8, 11, 15, 2, 0, 14], \n", - " 7: [13, 16, 13, 16], \n", - " 8: [19, 15, 6, 14, 12, 3, 6, 15, 19, 12, 3, 14], \n", - " 9: [20, 15, 19, 16, 15, 19, 20, 16], \n", - " 10: [17, 11, 2, 11, 17, 2], \n", - " 11: [6, 0, 4, 10, 2, 6, 2, 0, 10, 4], \n", - " 12: [8, 3, 8, 14, 1, 3, 1, 14], \n", - " 13: [7, 15, 18, 15, 16, 7, 18, 16], \n", - " 14: [8, 6, 2, 12, 1, 8, 6, 2, 1, 12], \n", - " 15: [8, 6, 16, 13, 18, 0, 6, 8, 19, 9, 0, 19, 13, 18, 9, 16], \n", - " 16: [7, 15, 13, 9, 7, 13, 15, 9], \n", - " 17: [10, 2, 2, 10], \n", - " 18: [15, 0, 13, 4, 0, 15, 13, 4], \n", - " 19: [20, 8, 15, 9, 15, 8, 3, 20, 3, 9], \n", - " 20: [3, 19, 9, 19, 3, 9]\n", - "}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we are ready to create an InstruCSP instance for our problem. We are doing this for an instance of **MapColoringProblem** class which inherits from the **CSP** Class. This means that our **make_instru** function will work perfectly for it." - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [], - "source": [ - "coloring_problem = MapColoringCSP('RGBY', neighbors)" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [], - "source": [ - "coloring_problem1 = make_instru(coloring_problem)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### CONSTRAINT PROPAGATION\n", - "Algorithms that solve CSPs have a choice between searching and or doing a _constraint propagation_, a specific type of inference.\n", - "The constraints can be used to reduce the number of legal values for another variable, which in turn can reduce the legal values for some other variable, and so on. \n", - "
\n", - "Constraint propagation tries to enforce _local consistency_.\n", - "Consider each variable as a node in a graph and each binary constraint as an arc.\n", - "Enforcing local consistency causes inconsistent values to be eliminated throughout the graph, \n", - "a lot like the `GraphPlan` algorithm in planning, where mutex links are removed from a planning graph.\n", - "There are different types of local consistencies:\n", - "1. Node consistency\n", - "2. Arc consistency\n", - "3. Path consistency\n", - "4. K-consistency\n", - "5. Global constraints\n", - "\n", - "Refer __section 6.2__ in the book for details.\n", - "
" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## AC-3\n", - "Before we dive into AC-3, we need to know what _arc-consistency_ is.\n", - "
\n", - "A variable $X_i$ is __arc-consistent__ with respect to another variable $X_j$ if for every value in the current domain $D_i$ there is some value in the domain $D_j$ that satisfies the binary constraint on the arc $(X_i, X_j)$.\n", - "
\n", - "A network is arc-consistent if every variable is arc-consistent with every other variable.\n", - "
\n", - "\n", - "AC-3 is an algorithm that enforces arc consistency.\n", - "After applying AC-3, either every arc is arc-consistent, or some variable has an empty domain, indicating that the CSP cannot be solved.\n", - "Let's see how `AC3` is implemented in the module." - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "

\n", - "\n", - "
def AC3(csp, queue=None, removals=None, arc_heuristic=dom_j_up):\n",
-       "    """[Figure 6.3]"""\n",
-       "    if queue is None:\n",
-       "        queue = {(Xi, Xk) for Xi in csp.variables for Xk in csp.neighbors[Xi]}\n",
-       "    csp.support_pruning()\n",
-       "    queue = arc_heuristic(csp, queue)\n",
-       "    while queue:\n",
-       "        (Xi, Xj) = queue.pop()\n",
-       "        if revise(csp, Xi, Xj, removals):\n",
-       "            if not csp.curr_domains[Xi]:\n",
-       "                return False\n",
-       "            for Xk in csp.neighbors[Xi]:\n",
-       "                if Xk != Xj:\n",
-       "                    queue.add((Xk, Xi))\n",
-       "    return True\n",
-       "
\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "psource(AC3)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`AC3` also employs a helper function `revise`." - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "

\n", - "\n", - "
def revise(csp, Xi, Xj, removals):\n",
-       "    """Return true if we remove a value."""\n",
-       "    revised = False\n",
-       "    for x in csp.curr_domains[Xi][:]:\n",
-       "        # If Xi=x conflicts with Xj=y for every possible y, eliminate Xi=x\n",
-       "        if all(not csp.constraints(Xi, x, Xj, y) for y in csp.curr_domains[Xj]):\n",
-       "            csp.prune(Xi, x, removals)\n",
-       "            revised = True\n",
-       "    return revised\n",
-       "
\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "psource(revise)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`AC3` maintains a queue of arcs to consider which initially contains all the arcs in the CSP.\n", - "An arbitrary arc $(X_i, X_j)$ is popped from the queue and $X_i$ is made _arc-consistent_ with respect to $X_j$.\n", - "
\n", - "If in doing so, $D_i$ is left unchanged, the algorithm just moves to the next arc, \n", - "but if the domain $D_i$ is revised, then we add all the neighboring arcs $(X_k, X_i)$ to the queue.\n", - "
\n", - "We repeat this process and if at any point, the domain $D_i$ is reduced to nothing, then we know the whole CSP has no consistent solution and `AC3` can immediately return failure.\n", - "
\n", - "Otherwise, we keep removing values from the domains of variables until the queue is empty.\n", - "We finally get the arc-consistent CSP which is faster to search because the variables have smaller domains." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's see how `AC3` can be used.\n", - "
\n", - "We'll first define the required variables." - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [], - "source": [ - "neighbors = parse_neighbors('A: B; B: ')\n", - "domains = {'A': [0, 1, 2, 3, 4], 'B': [0, 1, 2, 3, 4]}\n", - "constraints = lambda X, x, Y, y: x % 2 == 0 and (x + y) == 4 and y % 2 != 0\n", - "removals = []" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We'll now define a `CSP` object." - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [], - "source": [ - "csp = CSP(variables=None, domains=domains, neighbors=neighbors, constraints=constraints)" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "AC3(csp, removals=removals)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This configuration is inconsistent." - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [], - "source": [ - "constraints = lambda X, x, Y, y: (x % 2) == 0 and (x + y) == 4\n", - "removals = []\n", - "csp = CSP(variables=None, domains=domains, neighbors=neighbors, constraints=constraints)" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "AC3(csp,removals=removals)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This configuration is consistent." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## BACKTRACKING SEARCH\n", - "\n", - "The main issue with using Naive Search Algorithms to solve a CSP is that they can continue to expand obviously wrong paths; whereas, in **backtracking search**, we check the constraints as we go and we deal with only 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 a few other optional parameters which can be used to speed it up further. The function returns the correct assignment if it satisfies the goal. However, we will discuss these later. For now, let us solve our **coloring_problem1** with **backtracking_search**." - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [], - "source": [ - "result = backtracking_search(coloring_problem1)" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{0: 'R',\n", - " 1: 'R',\n", - " 2: 'R',\n", - " 3: 'R',\n", - " 4: 'G',\n", - " 5: 'R',\n", - " 6: 'G',\n", - " 7: 'R',\n", - " 8: 'B',\n", - " 9: 'R',\n", - " 10: 'G',\n", - " 11: 'B',\n", - " 12: 'G',\n", - " 13: 'G',\n", - " 14: 'Y',\n", - " 15: 'Y',\n", - " 16: 'B',\n", - " 17: 'B',\n", - " 18: 'B',\n", - " 19: 'G',\n", - " 20: 'B'}" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "result # A dictonary of assignments." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let us also check the number of assignments made." - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "21" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "coloring_problem1.nassigns" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now, let us check the total number of assignments and unassignments, which would be the length of our assignment history. We can see it by using the command below. " - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "21" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(coloring_problem1.assignment_history)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now let us explore the optional keyword arguments that the **backtracking_search** function takes. These optional arguments help speed up the assignment further. Along with these, we will also point out the methods in the CSP class that help to make this work. \n", - "\n", - "The first one is **select_unassigned_variable**. It takes in, as a parameter, a function that helps in deciding the order in which the variables will be selected for assignment. We use a heuristic called Most Restricted Variable which is implemented by the function **mrv**. The idea behind **mrv** is to choose the variable with the least legal values left in its domain. The intuition behind selecting the **mrv** or the most constrained variable is that it allows us to encounter failure quickly before going too deep into a tree if we have selected a wrong step before. The **mrv** implementation makes use of another function **num_legal_values** to sort out the variables by the number of legal values left in its domain. This function, in turn, calls the **nconflicts** method of the **CSP** to return such values." - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "

\n", - "\n", - "
def mrv(assignment, csp):\n",
-       "    """Minimum-remaining-values heuristic."""\n",
-       "    return argmin_random_tie(\n",
-       "        [v for v in csp.variables if v not in assignment],\n",
-       "        key=lambda var: num_legal_values(csp, var, assignment))\n",
-       "
\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "psource(mrv)" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "

\n", - "\n", - "
def num_legal_values(csp, var, assignment):\n",
-       "    if csp.curr_domains:\n",
-       "        return len(csp.curr_domains[var])\n",
-       "    else:\n",
-       "        return count(csp.nconflicts(var, val, assignment) == 0\n",
-       "                     for val in csp.domains[var])\n",
-       "
\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "psource(num_legal_values)" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "

\n", - "\n", - "
    def nconflicts(self, var, val, assignment):\n",
-       "        """Return the number of conflicts var=val has with other variables."""\n",
-       "\n",
-       "        # Subclasses may implement this more efficiently\n",
-       "        def conflict(var2):\n",
-       "            return (var2 in assignment and\n",
-       "                    not self.constraints(var, val, var2, assignment[var2]))\n",
-       "\n",
-       "        return count(conflict(v) for v in self.neighbors[var])\n",
-       "
\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "psource(CSP.nconflicts)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Another ordering related parameter **order_domain_values** governs the value ordering. Here we select the Least Constraining Value which is implemented by the function **lcv**. The idea is to select the value which rules out least number of values in the remaining variables. The intuition behind selecting the **lcv** is that it allows a lot of freedom to assign values later. The idea behind selecting the mrc and lcv makes sense because we need to do all variables but for values, and it's better to try the ones that are likely. So for vars, we face the hard ones first." - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "

\n", - "\n", - "
def lcv(var, assignment, csp):\n",
-       "    """Least-constraining-values heuristic."""\n",
-       "    return sorted(csp.choices(var),\n",
-       "                  key=lambda val: csp.nconflicts(var, val, assignment))\n",
-       "
\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "psource(lcv)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Finally, the third parameter **inference** can make use of one of the two techniques called Arc Consistency or Forward Checking. The details of these methods can be found in the **Section 6.3.2** of the book. In short the idea of inference is to detect the possible failure before it occurs and to look ahead to not make mistakes. **mac** and **forward_checking** implement these two techniques. The **CSP** methods **support_pruning**, **suppose**, **prune**, **choices**, **infer_assignment** and **restore** help in using these techniques. You can find out more about these by looking up the source code." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now let us compare the performance with these parameters enabled vs the default parameters. We will use the Graph Coloring problem instance 'usa' for comparison. We will call the instances **solve_simple** and **solve_parameters** and solve them using backtracking and compare the number of assignments." - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "metadata": {}, - "outputs": [], - "source": [ - "solve_simple = copy.deepcopy(usa_csp)\n", - "solve_parameters = copy.deepcopy(usa_csp)" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'SD': 'R',\n", - " 'MN': 'G',\n", - " 'ND': 'B',\n", - " 'MT': 'G',\n", - " 'IA': 'B',\n", - " 'WI': 'R',\n", - " 'NE': 'G',\n", - " 'MO': 'R',\n", - " 'IL': 'G',\n", - " 'WY': 'B',\n", - " 'ID': 'R',\n", - " 'KA': 'B',\n", - " 'UT': 'G',\n", - " 'NV': 'B',\n", - " 'OK': 'G',\n", - " 'CO': 'R',\n", - " 'OR': 'G',\n", - " 'KY': 'B',\n", - " 'AZ': 'R',\n", - " 'CA': 'Y',\n", - " 'IN': 'R',\n", - " 'OH': 'G',\n", - " 'WA': 'B',\n", - " 'MI': 'B',\n", - " 'AR': 'B',\n", - " 'NM': 'B',\n", - " 'TN': 'G',\n", - " 'TX': 'R',\n", - " 'MS': 'R',\n", - " 'AL': 'B',\n", - " 'VA': 'R',\n", - " 'WV': 'Y',\n", - " 'PA': 'R',\n", - " 'LA': 'G',\n", - " 'GA': 'R',\n", - " 'MD': 'G',\n", - " 'NC': 'B',\n", - " 'DC': 'B',\n", - " 'DE': 'B',\n", - " 'SC': 'G',\n", - " 'FL': 'G',\n", - " 'NJ': 'G',\n", - " 'NY': 'B',\n", - " 'MA': 'R',\n", - " 'CT': 'G',\n", - " 'RI': 'B',\n", - " 'VT': 'G',\n", - " 'NH': 'B',\n", - " 'ME': 'R'}" - ] - }, - "execution_count": 36, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "backtracking_search(solve_simple)\n", - "backtracking_search(solve_parameters, order_domain_values=lcv, select_unassigned_variable=mrv, inference=mac)" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "49" - ] - }, - "execution_count": 37, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "solve_simple.nassigns" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "49" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "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 assignment 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`; it builds the topological sort using the recursive function `build_topological`. That function is an augmented DFS (Depth First Search), 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, 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 assign 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", - "Run the cell below to see the implementation of the algorithm:" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "

\n", - "\n", - "
def tree_csp_solver(csp):\n",
-       "    """[Figure 6.11]"""\n",
-       "    assignment = {}\n",
-       "    root = csp.variables[0]\n",
-       "    X, parent = topological_sort(csp, root)\n",
-       "\n",
-       "    csp.support_pruning()\n",
-       "    for Xj in reversed(X[1:]):\n",
-       "        if not make_arc_consistent(parent[Xj], Xj, csp):\n",
-       "            return None\n",
-       "\n",
-       "    assignment[root] = csp.curr_domains[root][0]\n",
-       "    for Xi in X[1:]:\n",
-       "        assignment[Xi] = assign_value(parent[Xi], Xi, csp, assignment)\n",
-       "        if not assignment[Xi]:\n",
-       "            return None\n",
-       "    return assignment\n",
-       "
\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "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 Australia's map. We have two colors at our disposal: 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. However, if 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": 40, - "metadata": {}, - "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 print the given assignment." - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'NT': 'R', 'Q': 'B', 'NSW': 'R', 'V': 'B', 'WA': 'B'}\n" - ] - } - ], - "source": [ - "assignment = tree_csp_solver(australia_small)\n", - "print(assignment)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`WA`, `Q` and `V` got painted with the same color and `NT` and `NSW` got painted with the other." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## GRAPH COLORING VISUALIZATION\n", - "\n", - "Next, we define some functions to create the visualisation from the assignment_history of **coloring_problem1**. The readers need not concern themselves with the code that immediately follows as it is the usage of Matplotib with IPython Widgets. If you are interested in reading more about these, visit [ipywidgets.readthedocs.io](http://ipywidgets.readthedocs.io). We will be using the **networkx** library to generate graphs. These graphs can be treated as graphs that need to be colored or as constraint graphs for this problem. If interested you can check out a fairly simple tutorial [here](https://www.udacity.com/wiki/creating-network-graphs-with-python). We start by importing the necessary libraries and initializing matplotlib inline.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "metadata": {}, - "outputs": [], - "source": [ - "%matplotlib inline\n", - "import networkx as nx\n", - "import matplotlib.pyplot as plt\n", - "import matplotlib\n", - "import time" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The ipython widgets we will be using require the plots in the form of a step function such that there is a graph corresponding to each value. We define the **make_update_step_function** which returns such a function. It takes in as inputs the neighbors/graph along with an instance of the **InstruCSP**. The example below will elaborate it further. If this sounds confusing, don't worry. This is not part of the core material and our only goal is to help you visualize how the process works." - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "metadata": {}, - "outputs": [], - "source": [ - "def make_update_step_function(graph, instru_csp):\n", - " \n", - " #define a function to draw the graphs\n", - " def draw_graph(graph):\n", - " \n", - " G=nx.Graph(graph)\n", - " pos = nx.spring_layout(G,k=0.15)\n", - " return (G, pos)\n", - " \n", - " G, pos = draw_graph(graph)\n", - " \n", - " def update_step(iteration):\n", - " # here iteration is the index of the assignment_history we want to visualize.\n", - " current = instru_csp.assignment_history[iteration]\n", - " # We convert the particular assignment to a default dict so that the color for nodes which \n", - " # have not been assigned defaults to black.\n", - " current = defaultdict(lambda: 'Black', current)\n", - "\n", - " # Now we use colors in the list and default to black otherwise.\n", - " colors = [current[node] for node in G.node.keys()]\n", - " # Finally drawing the nodes.\n", - " nx.draw(G, pos, node_color=colors, node_size=500)\n", - "\n", - " labels = {label:label for label in G.node}\n", - " # Labels shifted by offset so that nodes don't overlap\n", - " label_pos = {key:[value[0], value[1]+0.03] for key, value in pos.items()}\n", - " nx.draw_networkx_labels(G, label_pos, labels, font_size=20)\n", - "\n", - " # display the graph\n", - " plt.show()\n", - "\n", - " return update_step # <-- this is a function\n", - "\n", - "def make_visualize(slider):\n", - " ''' Takes an input a slider and returns \n", - " callback function for timer and animation\n", - " '''\n", - " \n", - " def visualize_callback(Visualize, time_step):\n", - " if Visualize is True:\n", - " for i in range(slider.min, slider.max + 1):\n", - " slider.value = i\n", - " time.sleep(float(time_step))\n", - " \n", - " return visualize_callback\n", - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Finally let us plot our problem. We first use the function below to obtain a step function." - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "metadata": {}, - "outputs": [], - "source": [ - "step_func = make_update_step_function(neighbors, coloring_problem1)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Next, we set the canvas size." - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [], - "source": [ - "matplotlib.rcParams['figure.figsize'] = (18.0, 18.0)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Finally, our plot using ipywidget slider and matplotib. You can move the slider to experiment and see the colors change. It is also possible to move the slider using arrow keys or to jump to the value by directly editing the number with a double click. The **Visualize Button** will automatically animate the slider for you. The **Extra Delay Box** allows you to set time delay in seconds (upto one second) for each time step." - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "1882dd95ddd0465c8ec91d93a8a7224f", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "interactive(children=(IntSlider(value=0, description='iteration', max=20), Output()), _dom_classes=('widget-in…" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "3967e7c0226d434e8c08c7f4a59e2b2a", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "interactive(children=(ToggleButton(value=False, description='Visualize'), ToggleButtons(description='Extra Del…" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import ipywidgets as widgets\n", - "from IPython.display import display\n", - "\n", - "iteration_slider = widgets.IntSlider(min=0, max=len(coloring_problem1.assignment_history)-1, step=1, value=0)\n", - "w=widgets.interactive(step_func,iteration=iteration_slider)\n", - "display(w)\n", - "\n", - "visualize_callback = make_visualize(iteration_slider)\n", - "\n", - "visualize_button = widgets.ToggleButton(description = \"Visualize\", value = False)\n", - "time_select = widgets.ToggleButtons(description='Extra Delay:',options=['0', '0.1', '0.2', '0.5', '0.7', '1.0'])\n", - "\n", - "a = widgets.interactive(visualize_callback, Visualize = visualize_button, time_step=time_select)\n", - "display(a)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## N-QUEENS VISUALIZATION\n", - "\n", - "Just like the Graph Coloring Problem, we will start with defining a few helper functions to help us visualize the assignments as they evolve over time. The **make_plot_board_step_function** behaves similar to the **make_update_step_function** introduced earlier. It initializes a chess board in the form of a 2D grid with alternating 0s and 1s. This is used by **plot_board_step** function which draws the board using matplotlib and adds queens to it. This function also calls the **label_queen_conflicts** which modifies the grid placing a 3 in any position where there is a conflict." - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "metadata": {}, - "outputs": [], - "source": [ - "def label_queen_conflicts(assignment,grid):\n", - " ''' Mark grid with queens that are under conflict. '''\n", - " for col, row in assignment.items(): # check each queen for conflict\n", - " conflicts = {temp_col:temp_row for temp_col,temp_row in assignment.items() \n", - " if (temp_row == row and temp_col != col)\n", - " or (temp_row+temp_col == row+col and temp_col != col)\n", - " or (temp_row-temp_col == row-col and temp_col != col)}\n", - " \n", - " # Place a 3 in positions where this is a conflict\n", - " for col, row in conflicts.items():\n", - " grid[col][row] = 3\n", - "\n", - " return grid\n", - "\n", - "def make_plot_board_step_function(instru_csp):\n", - " '''ipywidgets interactive function supports\n", - " single parameter as input. This function\n", - " creates and return such a function by taking\n", - " in input other parameters.\n", - " '''\n", - " n = len(instru_csp.variables)\n", - " \n", - " \n", - " def plot_board_step(iteration):\n", - " ''' Add Queens to the Board.'''\n", - " data = instru_csp.assignment_history[iteration]\n", - " \n", - " grid = [[(col+row+1)%2 for col in range(n)] for row in range(n)]\n", - " grid = label_queen_conflicts(data, grid) # Update grid with conflict labels.\n", - " \n", - " # color map of fixed colors\n", - " cmap = matplotlib.colors.ListedColormap(['white','lightsteelblue','red'])\n", - " bounds=[0,1,2,3] # 0 for white 1 for black 2 onwards for conflict labels (red).\n", - " norm = matplotlib.colors.BoundaryNorm(bounds, cmap.N)\n", - " \n", - " fig = plt.imshow(grid, interpolation='nearest', cmap = cmap,norm=norm)\n", - "\n", - " plt.axis('off')\n", - " fig.axes.get_xaxis().set_visible(False)\n", - " fig.axes.get_yaxis().set_visible(False)\n", - "\n", - " # Place the Queens Unicode Symbol\n", - " for col, row in data.items():\n", - " fig.axes.text(row, col, u\"\\u265B\", va='center', ha='center', family='Dejavu Sans', fontsize=32)\n", - " plt.show()\n", - " \n", - " return plot_board_step" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now let us visualize a solution obtained via backtracking. We make use of the previosuly defined **make_instru** function for keeping a history of steps." - ] - }, - { - "cell_type": "code", - "execution_count": 48, - "metadata": {}, - "outputs": [], - "source": [ - "twelve_queens_csp = NQueensCSP(12)\n", - "backtracking_instru_queen = make_instru(twelve_queens_csp)\n", - "result = backtracking_search(backtracking_instru_queen)" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "metadata": {}, - "outputs": [], - "source": [ - "backtrack_queen_step = make_plot_board_step_function(backtracking_instru_queen) # Step Function for Widgets" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now finally we set some matplotlib parameters to adjust how our plot will look like. The font is necessary because the Black Queen Unicode character is not a part of all fonts. You can move the slider to experiment and observe how the queens are assigned. It is also possible to move the slider using arrow keys or to jump to the value by directly editing the number with a double click. The **Visualize Button** will automatically animate the slider for you. The **Extra Delay Box** allows you to set time delay in seconds of upto one second for each time step." - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "582e8f9b8d2e4a31aa7d45de68fd5b7c", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "interactive(children=(IntSlider(value=0, description='iteration', max=473, step=0), Output()), _dom_classes=('…" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "bb0f50b970764cb4bbebeb69cd4fbd19", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "interactive(children=(ToggleButton(value=False, description='Visualize'), ToggleButtons(description='Extra Del…" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "matplotlib.rcParams['figure.figsize'] = (8.0, 8.0)\n", - "matplotlib.rcParams['font.family'].append(u'Dejavu Sans')\n", - "\n", - "iteration_slider = widgets.IntSlider(min=0, max=len(backtracking_instru_queen.assignment_history)-1, step=0, value=0)\n", - "w=widgets.interactive(backtrack_queen_step,iteration=iteration_slider)\n", - "display(w)\n", - "\n", - "visualize_callback = make_visualize(iteration_slider)\n", - "\n", - "visualize_button = widgets.ToggleButton(description = \"Visualize\", value = False)\n", - "time_select = widgets.ToggleButtons(description='Extra Delay:',options=['0', '0.1', '0.2', '0.5', '0.7', '1.0'])\n", - "\n", - "a = widgets.interactive(visualize_callback, Visualize = visualize_button, time_step=time_select)\n", - "display(a)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now let us finally repeat the above steps for **min_conflicts** solution." - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "metadata": {}, - "outputs": [], - "source": [ - "conflicts_instru_queen = make_instru(twelve_queens_csp)\n", - "result = min_conflicts(conflicts_instru_queen)" - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "metadata": {}, - "outputs": [], - "source": [ - "conflicts_step = make_plot_board_step_function(conflicts_instru_queen)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This visualization has same features as the one above; however, this one also highlights the conflicts by labeling the conflicted queens with a red background." - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "409c4961f6e04fbea5d07a01cb1797ea", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "interactive(children=(IntSlider(value=0, description='iteration', max=27, step=0), Output()), _dom_classes=('w…" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "a55b1b50a9a44085a484b357aa26b50f", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "interactive(children=(ToggleButton(value=False, description='Visualize'), ToggleButtons(description='Extra Del…" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "iteration_slider = widgets.IntSlider(min=0, max=len(conflicts_instru_queen.assignment_history)-1, step=0, value=0)\n", - "w=widgets.interactive(conflicts_step,iteration=iteration_slider)\n", - "display(w)\n", - "\n", - "visualize_callback = make_visualize(iteration_slider)\n", - "\n", - "visualize_button = widgets.ToggleButton(description = \"Visualize\", value = False)\n", - "time_select = widgets.ToggleButtons(description='Extra Delay:',options=['0', '0.1', '0.2', '0.5', '0.7', '1.0'])\n", - "\n", - "a = widgets.interactive(visualize_callback, Visualize = visualize_button, time_step=time_select)\n", - "display(a)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "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.6.8" - }, - "pycharm": { - "stem_cell": { - "cell_type": "raw", - "source": [], - "metadata": { - "collapsed": false - } - } - } - }, - "nbformat": 4, - "nbformat_minor": 1 -} \ No newline at end of file diff --git a/csp.py b/csp.py deleted file mode 100644 index 46ae07dd5..000000000 --- a/csp.py +++ /dev/null @@ -1,1435 +0,0 @@ -"""CSP (Constraint Satisfaction Problems) problems and solvers. (Chapter 6)""" - -import itertools -import random -import re -import string -from collections import defaultdict, Counter -from functools import reduce -from operator import eq, neg - -from sortedcontainers import SortedSet - -import search -from utils import argmin_random_tie, count, first, extend - - -class CSP(search.Problem): - """This class describes finite-domain Constraint Satisfaction Problems. - A CSP is specified by the following inputs: - variables A list of variables; each is atomic (e.g. int or string). - domains A dict of {var:[possible_value, ...]} entries. - neighbors A dict of {var:[var,...]} that for each variable lists - the other variables that participate in constraints. - constraints A function f(A, a, B, b) that returns true if neighbors - A, B satisfy the constraint when they have values A=a, B=b - - In the textbook and in most mathematical definitions, the - constraints are specified as explicit pairs of allowable values, - but the formulation here is easier to express and more compact for - most cases (for example, the n-Queens problem can be represented - in O(n) space using this notation, instead of O(n^4) for the - explicit representation). In terms of describing the CSP as a - problem, that's all there is. - - However, the class also supports data structures and methods that help you - solve CSPs by calling a search function on the CSP. Methods and slots are - as follows, where the argument 'a' represents an assignment, which is a - dict of {var:val} entries: - assign(var, val, a) Assign a[var] = val; do other bookkeeping - unassign(var, a) Do del a[var], plus other bookkeeping - nconflicts(var, val, a) Return the number of other variables that - conflict with var=val - curr_domains[var] Slot: remaining consistent values for var - Used by constraint propagation routines. - The following methods are used only by graph_search and tree_search: - actions(state) Return a list of actions - result(state, action) Return a successor of state - goal_test(state) Return true if all constraints satisfied - The following are just for debugging purposes: - nassigns Slot: tracks the number of assignments made - display(a) Print a human-readable representation - """ - - def __init__(self, variables, domains, neighbors, constraints): - """Construct a CSP problem. If variables is empty, it becomes domains.keys().""" - super().__init__(()) - variables = variables or list(domains.keys()) - self.variables = variables - self.domains = domains - self.neighbors = neighbors - self.constraints = constraints - self.curr_domains = None - self.nassigns = 0 - - def assign(self, var, val, assignment): - """Add {var: val} to assignment; Discard the old value if any.""" - assignment[var] = val - self.nassigns += 1 - - def unassign(self, var, assignment): - """Remove {var: val} from assignment. - DO NOT call this if you are changing a variable to a new value; - just call assign for that.""" - if var in assignment: - del assignment[var] - - def nconflicts(self, var, val, assignment): - """Return the number of conflicts var=val has with other variables.""" - - # Subclasses may implement this more efficiently - def conflict(var2): - return var2 in assignment and not self.constraints(var, val, var2, assignment[var2]) - - return count(conflict(v) for v in self.neighbors[var]) - - def display(self, assignment): - """Show a human-readable representation of the CSP.""" - # Subclasses can print in a prettier way, or display with a GUI - print(assignment) - - # These methods are for the tree and graph-search interface: - - def actions(self, state): - """Return a list of applicable actions: non conflicting - assignments to an unassigned variable.""" - if len(state) == len(self.variables): - return [] - else: - assignment = dict(state) - var = first([v for v in self.variables if v not in assignment]) - return [(var, val) for val in self.domains[var] - if self.nconflicts(var, val, assignment) == 0] - - def result(self, state, action): - """Perform an action and return the new state.""" - (var, val) = action - return state + ((var, val),) - - def goal_test(self, state): - """The goal is to assign all variables, with all constraints satisfied.""" - assignment = dict(state) - return (len(assignment) == len(self.variables) - and all(self.nconflicts(variables, assignment[variables], assignment) == 0 - for variables in self.variables)) - - # These are for constraint propagation - - def support_pruning(self): - """Make sure we can prune values from domains. (We want to pay - for this only if we use it.)""" - if self.curr_domains is None: - self.curr_domains = {v: list(self.domains[v]) for v in self.variables} - - def suppose(self, var, value): - """Start accumulating inferences from assuming var=value.""" - self.support_pruning() - removals = [(var, a) for a in self.curr_domains[var] if a != value] - self.curr_domains[var] = [value] - return removals - - def prune(self, var, value, removals): - """Rule out var=value.""" - self.curr_domains[var].remove(value) - if removals is not None: - removals.append((var, value)) - - def choices(self, var): - """Return all values for var that aren't currently ruled out.""" - return (self.curr_domains or self.domains)[var] - - def infer_assignment(self): - """Return the partial assignment implied by the current inferences.""" - self.support_pruning() - return {v: self.curr_domains[v][0] - for v in self.variables if 1 == len(self.curr_domains[v])} - - def restore(self, removals): - """Undo a supposition and all inferences from it.""" - for B, b in removals: - self.curr_domains[B].append(b) - - # This is for min_conflicts search - - def conflicted_vars(self, current): - """Return a list of variables in current assignment that are in conflict""" - return [var for var in self.variables - if self.nconflicts(var, current[var], current) > 0] - - -# ______________________________________________________________________________ -# Constraint Propagation with AC3 - - -def no_arc_heuristic(csp, queue): - return queue - - -def dom_j_up(csp, queue): - return SortedSet(queue, key=lambda t: neg(len(csp.curr_domains[t[1]]))) - - -def AC3(csp, queue=None, removals=None, arc_heuristic=dom_j_up): - """[Figure 6.3]""" - if queue is None: - queue = {(Xi, Xk) for Xi in csp.variables for Xk in csp.neighbors[Xi]} - csp.support_pruning() - queue = arc_heuristic(csp, queue) - checks = 0 - while queue: - (Xi, Xj) = queue.pop() - revised, checks = revise(csp, Xi, Xj, removals, checks) - if revised: - if not csp.curr_domains[Xi]: - return False, checks # CSP is inconsistent - for Xk in csp.neighbors[Xi]: - if Xk != Xj: - queue.add((Xk, Xi)) - return True, checks # CSP is satisfiable - - -def revise(csp, Xi, Xj, removals, checks=0): - """Return true if we remove a value.""" - revised = False - for x in csp.curr_domains[Xi][:]: - # If Xi=x conflicts with Xj=y for every possible y, eliminate Xi=x - # if all(not csp.constraints(Xi, x, Xj, y) for y in csp.curr_domains[Xj]): - conflict = True - for y in csp.curr_domains[Xj]: - if csp.constraints(Xi, x, Xj, y): - conflict = False - checks += 1 - if not conflict: - break - if conflict: - csp.prune(Xi, x, removals) - revised = True - return revised, checks - - -# Constraint Propagation with AC3b: an improved version -# of AC3 with double-support domain-heuristic - -def AC3b(csp, queue=None, removals=None, arc_heuristic=dom_j_up): - if queue is None: - queue = {(Xi, Xk) for Xi in csp.variables for Xk in csp.neighbors[Xi]} - csp.support_pruning() - queue = arc_heuristic(csp, queue) - checks = 0 - while queue: - (Xi, Xj) = queue.pop() - # Si_p values are all known to be supported by Xj - # Sj_p values are all known to be supported by Xi - # Dj - Sj_p = Sj_u values are unknown, as yet, to be supported by Xi - Si_p, Sj_p, Sj_u, checks = partition(csp, Xi, Xj, checks) - if not Si_p: - return False, checks # CSP is inconsistent - revised = False - for x in set(csp.curr_domains[Xi]) - Si_p: - csp.prune(Xi, x, removals) - revised = True - if revised: - for Xk in csp.neighbors[Xi]: - if Xk != Xj: - queue.add((Xk, Xi)) - if (Xj, Xi) in queue: - if isinstance(queue, set): - # or queue -= {(Xj, Xi)} or queue.remove((Xj, Xi)) - queue.difference_update({(Xj, Xi)}) - else: - queue.difference_update((Xj, Xi)) - # the elements in D_j which are supported by Xi are given by the union of Sj_p with the set of those - # elements of Sj_u which further processing will show to be supported by some vi_p in Si_p - for vj_p in Sj_u: - for vi_p in Si_p: - conflict = True - if csp.constraints(Xj, vj_p, Xi, vi_p): - conflict = False - Sj_p.add(vj_p) - checks += 1 - if not conflict: - break - revised = False - for x in set(csp.curr_domains[Xj]) - Sj_p: - csp.prune(Xj, x, removals) - revised = True - if revised: - for Xk in csp.neighbors[Xj]: - if Xk != Xi: - queue.add((Xk, Xj)) - return True, checks # CSP is satisfiable - - -def partition(csp, Xi, Xj, checks=0): - Si_p = set() - Sj_p = set() - Sj_u = set(csp.curr_domains[Xj]) - for vi_u in csp.curr_domains[Xi]: - conflict = True - # now, in order to establish support for a value vi_u in Di it seems better to try to find a support among - # the values in Sj_u first, because for each vj_u in Sj_u the check (vi_u, vj_u) is a double-support check - # and it is just as likely that any vj_u in Sj_u supports vi_u than it is that any vj_p in Sj_p does... - for vj_u in Sj_u - Sj_p: - # double-support check - if csp.constraints(Xi, vi_u, Xj, vj_u): - conflict = False - Si_p.add(vi_u) - Sj_p.add(vj_u) - checks += 1 - if not conflict: - break - # ... and only if no support can be found among the elements in Sj_u, should the elements vj_p in Sj_p be used - # for single-support checks (vi_u, vj_p) - if conflict: - for vj_p in Sj_p: - # single-support check - if csp.constraints(Xi, vi_u, Xj, vj_p): - conflict = False - Si_p.add(vi_u) - checks += 1 - if not conflict: - break - return Si_p, Sj_p, Sj_u - Sj_p, checks - - -# Constraint Propagation with AC4 - -def AC4(csp, queue=None, removals=None, arc_heuristic=dom_j_up): - if queue is None: - queue = {(Xi, Xk) for Xi in csp.variables for Xk in csp.neighbors[Xi]} - csp.support_pruning() - queue = arc_heuristic(csp, queue) - support_counter = Counter() - variable_value_pairs_supported = defaultdict(set) - unsupported_variable_value_pairs = [] - checks = 0 - # construction and initialization of support sets - while queue: - (Xi, Xj) = queue.pop() - revised = False - for x in csp.curr_domains[Xi][:]: - for y in csp.curr_domains[Xj]: - if csp.constraints(Xi, x, Xj, y): - support_counter[(Xi, x, Xj)] += 1 - variable_value_pairs_supported[(Xj, y)].add((Xi, x)) - checks += 1 - if support_counter[(Xi, x, Xj)] == 0: - csp.prune(Xi, x, removals) - revised = True - unsupported_variable_value_pairs.append((Xi, x)) - if revised: - if not csp.curr_domains[Xi]: - return False, checks # CSP is inconsistent - # propagation of removed values - while unsupported_variable_value_pairs: - Xj, y = unsupported_variable_value_pairs.pop() - for Xi, x in variable_value_pairs_supported[(Xj, y)]: - revised = False - if x in csp.curr_domains[Xi][:]: - support_counter[(Xi, x, Xj)] -= 1 - if support_counter[(Xi, x, Xj)] == 0: - csp.prune(Xi, x, removals) - revised = True - unsupported_variable_value_pairs.append((Xi, x)) - if revised: - if not csp.curr_domains[Xi]: - return False, checks # CSP is inconsistent - return True, checks # CSP is satisfiable - - -# ______________________________________________________________________________ -# CSP Backtracking Search - -# Variable ordering - - -def first_unassigned_variable(assignment, csp): - """The default variable order.""" - return first([var for var in csp.variables if var not in assignment]) - - -def mrv(assignment, csp): - """Minimum-remaining-values heuristic.""" - return argmin_random_tie([v for v in csp.variables if v not in assignment], - key=lambda var: num_legal_values(csp, var, assignment)) - - -def num_legal_values(csp, var, assignment): - if csp.curr_domains: - return len(csp.curr_domains[var]) - else: - return count(csp.nconflicts(var, val, assignment) == 0 for val in csp.domains[var]) - - -# Value ordering - - -def unordered_domain_values(var, assignment, csp): - """The default value order.""" - return csp.choices(var) - - -def lcv(var, assignment, csp): - """Least-constraining-values heuristic.""" - return sorted(csp.choices(var), key=lambda val: csp.nconflicts(var, val, assignment)) - - -# Inference - - -def no_inference(csp, var, value, assignment, removals): - return True - - -def forward_checking(csp, var, value, assignment, removals): - """Prune neighbor values inconsistent with var=value.""" - csp.support_pruning() - for B in csp.neighbors[var]: - if B not in assignment: - for b in csp.curr_domains[B][:]: - if not csp.constraints(var, value, B, b): - csp.prune(B, b, removals) - if not csp.curr_domains[B]: - return False - return True - - -def mac(csp, var, value, assignment, removals, constraint_propagation=AC3b): - """Maintain arc consistency.""" - return constraint_propagation(csp, {(X, var) for X in csp.neighbors[var]}, removals) - - -# The search, proper - - -def backtracking_search(csp, select_unassigned_variable=first_unassigned_variable, - order_domain_values=unordered_domain_values, inference=no_inference): - """[Figure 6.5]""" - - def backtrack(assignment): - if len(assignment) == len(csp.variables): - return assignment - var = select_unassigned_variable(assignment, csp) - for value in order_domain_values(var, assignment, csp): - if 0 == csp.nconflicts(var, value, assignment): - csp.assign(var, value, assignment) - removals = csp.suppose(var, value) - if inference(csp, var, value, assignment, removals): - result = backtrack(assignment) - if result is not None: - return result - csp.restore(removals) - csp.unassign(var, assignment) - return None - - result = backtrack({}) - assert result is None or csp.goal_test(result) - return result - - -# ______________________________________________________________________________ -# Min-conflicts Hill Climbing search for CSPs - - -def min_conflicts(csp, max_steps=100000): - """Solve a CSP by stochastic Hill Climbing on the number of conflicts.""" - # Generate a complete assignment for all variables (probably with conflicts) - csp.current = current = {} - for var in csp.variables: - val = min_conflicts_value(csp, var, current) - csp.assign(var, val, current) - # Now repeatedly choose a random conflicted variable and change it - for i in range(max_steps): - conflicted = csp.conflicted_vars(current) - if not conflicted: - return current - var = random.choice(conflicted) - val = min_conflicts_value(csp, var, current) - csp.assign(var, val, current) - return None - - -def min_conflicts_value(csp, var, current): - """Return the value that will give var the least number of conflicts. - If there is a tie, choose at random.""" - return argmin_random_tie(csp.domains[var], key=lambda val: csp.nconflicts(var, val, current)) - - -# ______________________________________________________________________________ - - -def tree_csp_solver(csp): - """[Figure 6.11]""" - assignment = {} - root = csp.variables[0] - X, parent = topological_sort(csp, root) - - csp.support_pruning() - for Xj in reversed(X[1:]): - if not make_arc_consistent(parent[Xj], Xj, csp): - return None - - assignment[root] = csp.curr_domains[root][0] - for Xi in X[1:]: - assignment[Xi] = assign_value(parent[Xi], Xi, csp, assignment) - if not assignment[Xi]: - return None - return assignment - - -def topological_sort(X, root): - """Returns the topological sort of X starting from the root. - - Input: - X is a list with the nodes of the graph - N is the dictionary with the neighbors of each node - root denotes the root of the graph. - - Output: - stack is a list with the nodes topologically sorted - parents is a dictionary pointing to each node's parent - - Other: - visited shows the state (visited - not visited) of nodes - - """ - neighbors = X.neighbors - - visited = defaultdict(lambda: False) - - stack = [] - parents = {} - - build_topological(root, None, neighbors, visited, stack, parents) - return stack, parents - - -def build_topological(node, parent, neighbors, visited, stack, parents): - """Build the topological sort and the parents of each node in the graph.""" - visited[node] = True - - for n in neighbors[node]: - if not visited[n]: - build_topological(n, node, neighbors, visited, stack, parents) - - parents[node] = parent - stack.insert(0, node) - - -def make_arc_consistent(Xj, Xk, csp): - """Make arc between parent (Xj) and child (Xk) consistent under the csp's constraints, - by removing the possible values of Xj that cause inconsistencies.""" - # csp.curr_domains[Xj] = [] - for val1 in csp.domains[Xj]: - keep = False # Keep or remove val1 - for val2 in csp.domains[Xk]: - if csp.constraints(Xj, val1, Xk, val2): - # Found a consistent assignment for val1, keep it - keep = True - break - - if not keep: - # Remove val1 - csp.prune(Xj, val1, None) - - return csp.curr_domains[Xj] - - -def assign_value(Xj, Xk, csp, assignment): - """Assign a value to Xk given Xj's (Xk's parent) assignment. - Return the first value that satisfies the constraints.""" - parent_assignment = assignment[Xj] - for val in csp.curr_domains[Xk]: - if csp.constraints(Xj, parent_assignment, Xk, val): - return val - - # No consistent assignment available - return None - - -# ______________________________________________________________________________ -# Map Coloring CSP Problems - - -class UniversalDict: - """A universal dict maps any key to the same value. We use it here - as the domains dict for CSPs in which all variables have the same domain. - >>> d = UniversalDict(42) - >>> d['life'] - 42 - """ - - def __init__(self, value): self.value = value - - def __getitem__(self, key): return self.value - - def __repr__(self): return '{{Any: {0!r}}}'.format(self.value) - - -def different_values_constraint(A, a, B, b): - """A constraint saying two neighboring variables must differ in value.""" - return a != b - - -def MapColoringCSP(colors, neighbors): - """Make a CSP for the problem of coloring a map with different colors - for any two adjacent regions. Arguments are a list of colors, and a - dict of {region: [neighbor,...]} entries. This dict may also be - specified as a string of the form defined by parse_neighbors.""" - if isinstance(neighbors, str): - neighbors = parse_neighbors(neighbors) - return CSP(list(neighbors.keys()), UniversalDict(colors), neighbors, different_values_constraint) - - -def parse_neighbors(neighbors): - """Convert a string of the form 'X: Y Z; Y: Z' into a dict mapping - regions to neighbors. The syntax is a region name followed by a ':' - followed by zero or more region names, followed by ';', repeated for - each region name. If you say 'X: Y' you don't need 'Y: X'. - >>> parse_neighbors('X: Y Z; Y: Z') == {'Y': ['X', 'Z'], 'X': ['Y', 'Z'], 'Z': ['X', 'Y']} - True - """ - dic = defaultdict(list) - specs = [spec.split(':') for spec in neighbors.split(';')] - for (A, Aneighbors) in specs: - A = A.strip() - for B in Aneighbors.split(): - dic[A].append(B) - dic[B].append(A) - return dic - - -australia_csp = MapColoringCSP(list('RGB'), """SA: WA NT Q NSW V; NT: WA Q; NSW: Q V; T: """) - -usa_csp = MapColoringCSP(list('RGBY'), - """WA: OR ID; OR: ID NV CA; CA: NV AZ; NV: ID UT AZ; ID: MT WY UT; - UT: WY CO AZ; MT: ND SD WY; WY: SD NE CO; CO: NE KA OK NM; NM: OK TX AZ; - ND: MN SD; SD: MN IA NE; NE: IA MO KA; KA: MO OK; OK: MO AR TX; - TX: AR LA; MN: WI IA; IA: WI IL MO; MO: IL KY TN AR; AR: MS TN LA; - LA: MS; WI: MI IL; IL: IN KY; IN: OH KY; MS: TN AL; AL: TN GA FL; - MI: OH IN; OH: PA WV KY; KY: WV VA TN; TN: VA NC GA; GA: NC SC FL; - PA: NY NJ DE MD WV; WV: MD VA; VA: MD DC NC; NC: SC; NY: VT MA CT NJ; - NJ: DE; DE: MD; MD: DC; VT: NH MA; MA: NH RI CT; CT: RI; ME: NH; - HI: ; AK: """) - -france_csp = MapColoringCSP(list('RGBY'), - """AL: LO FC; AQ: MP LI PC; AU: LI CE BO RA LR MP; BO: CE IF CA FC RA - AU; BR: NB PL; CA: IF PI LO FC BO; CE: PL NB NH IF BO AU LI PC; FC: BO - CA LO AL RA; IF: NH PI CA BO CE; LI: PC CE AU MP AQ; LO: CA AL FC; LR: - MP AU RA PA; MP: AQ LI AU LR; NB: NH CE PL BR; NH: PI IF CE NB; NO: - PI; PA: LR RA; PC: PL CE LI AQ; PI: NH NO CA IF; PL: BR NB CE PC; RA: - AU BO FC PA LR""") - - -# ______________________________________________________________________________ -# n-Queens Problem - - -def queen_constraint(A, a, B, b): - """Constraint is satisfied (true) if A, B are really the same variable, - or if they are not in the same row, down diagonal, or up diagonal.""" - return A == B or (a != b and A + a != B + b and A - a != B - b) - - -class NQueensCSP(CSP): - """ - Make a CSP for the nQueens problem for search with min_conflicts. - Suitable for large n, it uses only data structures of size O(n). - Think of placing queens one per column, from left to right. - That means position (x, y) represents (var, val) in the CSP. - The main structures are three arrays to count queens that could conflict: - rows[i] Number of queens in the ith row (i.e. val == i) - downs[i] Number of queens in the \ diagonal - such that their (x, y) coordinates sum to i - ups[i] Number of queens in the / diagonal - such that their (x, y) coordinates have x-y+n-1 = i - We increment/decrement these counts each time a queen is placed/moved from - a row/diagonal. So moving is O(1), as is nconflicts. But choosing - a variable, and a best value for the variable, are each O(n). - If you want, you can keep track of conflicted variables, then variable - selection will also be O(1). - >>> len(backtracking_search(NQueensCSP(8))) - 8 - """ - - def __init__(self, n): - """Initialize data structures for n Queens.""" - CSP.__init__(self, list(range(n)), UniversalDict(list(range(n))), - UniversalDict(list(range(n))), queen_constraint) - - self.rows = [0] * n - self.ups = [0] * (2 * n - 1) - self.downs = [0] * (2 * n - 1) - - def nconflicts(self, var, val, assignment): - """The number of conflicts, as recorded with each assignment. - Count conflicts in row and in up, down diagonals. If there - is a queen there, it can't conflict with itself, so subtract 3.""" - n = len(self.variables) - c = self.rows[val] + self.downs[var + val] + self.ups[var - val + n - 1] - if assignment.get(var, None) == val: - c -= 3 - return c - - def assign(self, var, val, assignment): - """Assign var, and keep track of conflicts.""" - old_val = assignment.get(var, None) - if val != old_val: - if old_val is not None: # Remove old val if there was one - self.record_conflict(assignment, var, old_val, -1) - self.record_conflict(assignment, var, val, +1) - CSP.assign(self, var, val, assignment) - - def unassign(self, var, assignment): - """Remove var from assignment (if it is there) and track conflicts.""" - if var in assignment: - self.record_conflict(assignment, var, assignment[var], -1) - CSP.unassign(self, var, assignment) - - def record_conflict(self, assignment, var, val, delta): - """Record conflicts caused by addition or deletion of a Queen.""" - n = len(self.variables) - self.rows[val] += delta - self.downs[var + val] += delta - self.ups[var - val + n - 1] += delta - - def display(self, assignment): - """Print the queens and the nconflicts values (for debugging).""" - n = len(self.variables) - for val in range(n): - for var in range(n): - if assignment.get(var, '') == val: - ch = 'Q' - elif (var + val) % 2 == 0: - ch = '.' - else: - ch = '-' - print(ch, end=' ') - print(' ', end=' ') - for var in range(n): - if assignment.get(var, '') == val: - ch = '*' - else: - ch = ' ' - print(str(self.nconflicts(var, val, assignment)) + ch, end=' ') - print() - - -# ______________________________________________________________________________ -# Sudoku - - -def flatten(seqs): - return sum(seqs, []) - - -easy1 = '..3.2.6..9..3.5..1..18.64....81.29..7.......8..67.82....26.95..8..2.3..9..5.1.3..' -harder1 = '4173698.5.3..........7......2.....6.....8.4......1.......6.3.7.5..2.....1.4......' - -_R3 = list(range(3)) -_CELL = itertools.count().__next__ -_BGRID = [[[[_CELL() for x in _R3] for y in _R3] for bx in _R3] for by in _R3] -_BOXES = flatten([list(map(flatten, brow)) for brow in _BGRID]) -_ROWS = flatten([list(map(flatten, zip(*brow))) for brow in _BGRID]) -_COLS = list(zip(*_ROWS)) - -_NEIGHBORS = {v: set() for v in flatten(_ROWS)} -for unit in map(set, _BOXES + _ROWS + _COLS): - for v in unit: - _NEIGHBORS[v].update(unit - {v}) - - -class Sudoku(CSP): - """ - A Sudoku problem. - The box grid is a 3x3 array of boxes, each a 3x3 array of cells. - Each cell holds a digit in 1..9. In each box, all digits are - different; the same for each row and column as a 9x9 grid. - >>> e = Sudoku(easy1) - >>> e.display(e.infer_assignment()) - . . 3 | . 2 . | 6 . . - 9 . . | 3 . 5 | . . 1 - . . 1 | 8 . 6 | 4 . . - ------+-------+------ - . . 8 | 1 . 2 | 9 . . - 7 . . | . . . | . . 8 - . . 6 | 7 . 8 | 2 . . - ------+-------+------ - . . 2 | 6 . 9 | 5 . . - 8 . . | 2 . 3 | . . 9 - . . 5 | . 1 . | 3 . . - >>> AC3(e) # doctest: +ELLIPSIS - (True, ...) - >>> e.display(e.infer_assignment()) - 4 8 3 | 9 2 1 | 6 5 7 - 9 6 7 | 3 4 5 | 8 2 1 - 2 5 1 | 8 7 6 | 4 9 3 - ------+-------+------ - 5 4 8 | 1 3 2 | 9 7 6 - 7 2 9 | 5 6 4 | 1 3 8 - 1 3 6 | 7 9 8 | 2 4 5 - ------+-------+------ - 3 7 2 | 6 8 9 | 5 1 4 - 8 1 4 | 2 5 3 | 7 6 9 - 6 9 5 | 4 1 7 | 3 8 2 - >>> h = Sudoku(harder1) - >>> backtracking_search(h, select_unassigned_variable=mrv, inference=forward_checking) is not None - True - """ - - R3 = _R3 - Cell = _CELL - bgrid = _BGRID - boxes = _BOXES - rows = _ROWS - cols = _COLS - neighbors = _NEIGHBORS - - def __init__(self, grid): - """Build a Sudoku problem from a string representing the grid: - the digits 1-9 denote a filled cell, '.' or '0' an empty one; - other characters are ignored.""" - squares = iter(re.findall(r'\d|\.', grid)) - domains = {var: [ch] if ch in '123456789' else '123456789' - for var, ch in zip(flatten(self.rows), squares)} - for _ in squares: - raise ValueError("Not a Sudoku grid", grid) # Too many squares - CSP.__init__(self, None, domains, self.neighbors, different_values_constraint) - - def display(self, assignment): - def show_box(box): return [' '.join(map(show_cell, row)) for row in box] - - def show_cell(cell): return str(assignment.get(cell, '.')) - - def abut(lines1, lines2): return list( - map(' | '.join, list(zip(lines1, lines2)))) - - print('\n------+-------+------\n'.join( - '\n'.join(reduce( - abut, map(show_box, brow))) for brow in self.bgrid)) - - -# ______________________________________________________________________________ -# The Zebra Puzzle - - -def Zebra(): - """Return an instance of the Zebra Puzzle.""" - Colors = 'Red Yellow Blue Green Ivory'.split() - Pets = 'Dog Fox Snails Horse Zebra'.split() - Drinks = 'OJ Tea Coffee Milk Water'.split() - Countries = 'Englishman Spaniard Norwegian Ukranian Japanese'.split() - Smokes = 'Kools Chesterfields Winston LuckyStrike Parliaments'.split() - variables = Colors + Pets + Drinks + Countries + Smokes - domains = {} - for var in variables: - domains[var] = list(range(1, 6)) - domains['Norwegian'] = [1] - domains['Milk'] = [3] - neighbors = parse_neighbors("""Englishman: Red; - Spaniard: Dog; Kools: Yellow; Chesterfields: Fox; - Norwegian: Blue; Winston: Snails; LuckyStrike: OJ; - Ukranian: Tea; Japanese: Parliaments; Kools: Horse; - Coffee: Green; Green: Ivory""") - for type in [Colors, Pets, Drinks, Countries, Smokes]: - for A in type: - for B in type: - if A != B: - if B not in neighbors[A]: - neighbors[A].append(B) - if A not in neighbors[B]: - neighbors[B].append(A) - - def zebra_constraint(A, a, B, b, recurse=0): - same = (a == b) - next_to = abs(a - b) == 1 - if A == 'Englishman' and B == 'Red': - return same - if A == 'Spaniard' and B == 'Dog': - return same - if A == 'Chesterfields' and B == 'Fox': - return next_to - if A == 'Norwegian' and B == 'Blue': - return next_to - if A == 'Kools' and B == 'Yellow': - return same - if A == 'Winston' and B == 'Snails': - return same - if A == 'LuckyStrike' and B == 'OJ': - return same - if A == 'Ukranian' and B == 'Tea': - return same - if A == 'Japanese' and B == 'Parliaments': - return same - if A == 'Kools' and B == 'Horse': - return next_to - if A == 'Coffee' and B == 'Green': - return same - if A == 'Green' and B == 'Ivory': - return a - 1 == b - if recurse == 0: - return zebra_constraint(B, b, A, a, 1) - if ((A in Colors and B in Colors) or - (A in Pets and B in Pets) or - (A in Drinks and B in Drinks) or - (A in Countries and B in Countries) or - (A in Smokes and B in Smokes)): - return not same - raise Exception('error') - - return CSP(variables, domains, neighbors, zebra_constraint) - - -def solve_zebra(algorithm=min_conflicts, **args): - z = Zebra() - ans = algorithm(z, **args) - for h in range(1, 6): - print('House', h, end=' ') - for (var, val) in ans.items(): - if val == h: - print(var, end=' ') - print() - return ans['Zebra'], ans['Water'], z.nassigns, ans - - -# ______________________________________________________________________________ -# n-ary Constraint Satisfaction Problem - -class NaryCSP: - """ - A nary-CSP consists of: - domains : a dictionary that maps each variable to its domain - constraints : a list of constraints - variables : a set of variables - var_to_const: a variable to set of constraints dictionary - """ - - def __init__(self, domains, constraints): - """Domains is a variable:domain dictionary - constraints is a list of constraints - """ - self.variables = set(domains) - self.domains = domains - self.constraints = constraints - self.var_to_const = {var: set() for var in self.variables} - for con in constraints: - for var in con.scope: - self.var_to_const[var].add(con) - - def __str__(self): - """String representation of CSP""" - return str(self.domains) - - def display(self, assignment=None): - """More detailed string representation of CSP""" - if assignment is None: - assignment = {} - print(assignment) - - def consistent(self, assignment): - """assignment is a variable:value dictionary - returns True if all of the constraints that can be evaluated - evaluate to True given assignment. - """ - return all(con.holds(assignment) - for con in self.constraints - if all(v in assignment for v in con.scope)) - - -class Constraint: - """ - A Constraint consists of: - scope : a tuple of variables - condition: a function that can applied to a tuple of values - for the variables. - """ - - def __init__(self, scope, condition): - self.scope = scope - self.condition = condition - - def __repr__(self): - return self.condition.__name__ + str(self.scope) - - def holds(self, assignment): - """Returns the value of Constraint con evaluated in assignment. - - precondition: all variables are assigned in assignment - """ - return self.condition(*tuple(assignment[v] for v in self.scope)) - - -def all_diff_constraint(*values): - """Returns True if all values are different, False otherwise""" - return len(values) is len(set(values)) - - -def is_word_constraint(words): - """Returns True if the letters concatenated form a word in words, False otherwise""" - - def isw(*letters): - return "".join(letters) in words - - return isw - - -def meet_at_constraint(p1, p2): - """Returns a function that is True when the words meet at the positions (p1, p2), False otherwise""" - - def meets(w1, w2): - return w1[p1] == w2[p2] - - meets.__name__ = "meet_at(" + str(p1) + ',' + str(p2) + ')' - return meets - - -def adjacent_constraint(x, y): - """Returns True if x and y are adjacent numbers, False otherwise""" - return abs(x - y) == 1 - - -def sum_constraint(n): - """Returns a function that is True when the the sum of all values is n, False otherwise""" - - def sumv(*values): - return sum(values) is n - - sumv.__name__ = str(n) + "==sum" - return sumv - - -def is_constraint(val): - """Returns a function that is True when x is equal to val, False otherwise""" - - def isv(x): - return val == x - - isv.__name__ = str(val) + "==" - return isv - - -def ne_constraint(val): - """Returns a function that is True when x is not equal to val, False otherwise""" - - def nev(x): - return val != x - - nev.__name__ = str(val) + "!=" - return nev - - -def no_heuristic(to_do): - return to_do - - -def sat_up(to_do): - return SortedSet(to_do, key=lambda t: 1 / len([var for var in t[1].scope])) - - -class ACSolver: - """Solves a CSP with arc consistency and domain splitting""" - - def __init__(self, csp): - """a CSP solver that uses arc consistency - * csp is the CSP to be solved - """ - self.csp = csp - - def GAC(self, orig_domains=None, to_do=None, arc_heuristic=sat_up): - """ - Makes this CSP arc-consistent using Generalized Arc Consistency - orig_domains: is the original domains - to_do : is a set of (variable,constraint) pairs - returns the reduced domains (an arc-consistent variable:domain dictionary) - """ - if orig_domains is None: - orig_domains = self.csp.domains - if to_do is None: - to_do = {(var, const) for const in self.csp.constraints for var in const.scope} - else: - to_do = to_do.copy() - domains = orig_domains.copy() - to_do = arc_heuristic(to_do) - checks = 0 - while to_do: - var, const = to_do.pop() - other_vars = [ov for ov in const.scope if ov != var] - new_domain = set() - if len(other_vars) == 0: - for val in domains[var]: - if const.holds({var: val}): - new_domain.add(val) - checks += 1 - # new_domain = {val for val in domains[var] - # if const.holds({var: val})} - elif len(other_vars) == 1: - other = other_vars[0] - for val in domains[var]: - for other_val in domains[other]: - checks += 1 - if const.holds({var: val, other: other_val}): - new_domain.add(val) - break - # new_domain = {val for val in domains[var] - # if any(const.holds({var: val, other: other_val}) - # for other_val in domains[other])} - else: # general case - for val in domains[var]: - holds, checks = self.any_holds(domains, const, {var: val}, other_vars, checks=checks) - if holds: - new_domain.add(val) - # new_domain = {val for val in domains[var] - # if self.any_holds(domains, const, {var: val}, other_vars)} - if new_domain != domains[var]: - domains[var] = new_domain - if not new_domain: - return False, domains, checks - add_to_do = self.new_to_do(var, const).difference(to_do) - to_do |= add_to_do - return True, domains, checks - - def new_to_do(self, var, const): - """ - Returns new elements to be added to to_do after assigning - variable var in constraint const. - """ - return {(nvar, nconst) for nconst in self.csp.var_to_const[var] - if nconst != const - for nvar in nconst.scope - if nvar != var} - - def any_holds(self, domains, const, env, other_vars, ind=0, checks=0): - """ - Returns True if Constraint const holds for an assignment - that extends env with the variables in other_vars[ind:] - env is a dictionary - Warning: this has side effects and changes the elements of env - """ - if ind == len(other_vars): - return const.holds(env), checks + 1 - else: - var = other_vars[ind] - for val in domains[var]: - # env = dict_union(env, {var:val}) # no side effects - env[var] = val - holds, checks = self.any_holds(domains, const, env, other_vars, ind + 1, checks) - if holds: - return True, checks - return False, checks - - def domain_splitting(self, domains=None, to_do=None, arc_heuristic=sat_up): - """ - Return a solution to the current CSP or False if there are no solutions - to_do is the list of arcs to check - """ - if domains is None: - domains = self.csp.domains - consistency, new_domains, _ = self.GAC(domains, to_do, arc_heuristic) - if not consistency: - return False - elif all(len(new_domains[var]) == 1 for var in domains): - return {var: first(new_domains[var]) for var in domains} - else: - var = first(x for x in self.csp.variables if len(new_domains[x]) > 1) - if var: - dom1, dom2 = partition_domain(new_domains[var]) - new_doms1 = extend(new_domains, var, dom1) - new_doms2 = extend(new_domains, var, dom2) - to_do = self.new_to_do(var, None) - return self.domain_splitting(new_doms1, to_do, arc_heuristic) or \ - self.domain_splitting(new_doms2, to_do, arc_heuristic) - - -def partition_domain(dom): - """Partitions domain dom into two""" - split = len(dom) // 2 - dom1 = set(list(dom)[:split]) - dom2 = dom - dom1 - return dom1, dom2 - - -class ACSearchSolver(search.Problem): - """A search problem with arc consistency and domain splitting - A node is a CSP""" - - def __init__(self, csp, arc_heuristic=sat_up): - self.cons = ACSolver(csp) - consistency, self.domains, _ = self.cons.GAC(arc_heuristic=arc_heuristic) - if not consistency: - raise Exception('CSP is inconsistent') - self.heuristic = arc_heuristic - super().__init__(self.domains) - - def goal_test(self, node): - """Node is a goal if all domains have 1 element""" - return all(len(node[var]) == 1 for var in node) - - def actions(self, state): - var = first(x for x in state if len(state[x]) > 1) - neighs = [] - if var: - dom1, dom2 = partition_domain(state[var]) - to_do = self.cons.new_to_do(var, None) - for dom in [dom1, dom2]: - new_domains = extend(state, var, dom) - consistency, cons_doms, _ = self.cons.GAC(new_domains, to_do, self.heuristic) - if consistency: - neighs.append(cons_doms) - return neighs - - def result(self, state, action): - return action - - -def ac_solver(csp, arc_heuristic=sat_up): - """Arc consistency (domain splitting interface)""" - return ACSolver(csp).domain_splitting(arc_heuristic=arc_heuristic) - - -def ac_search_solver(csp, arc_heuristic=sat_up): - """Arc consistency (search interface)""" - from search import depth_first_tree_search - solution = None - try: - solution = depth_first_tree_search(ACSearchSolver(csp, arc_heuristic=arc_heuristic)).state - except: - return solution - if solution: - return {var: first(solution[var]) for var in solution} - - -# ______________________________________________________________________________ -# Crossword Problem - - -csp_crossword = NaryCSP({'one_across': {'ant', 'big', 'bus', 'car', 'has'}, - 'one_down': {'book', 'buys', 'hold', 'lane', 'year'}, - 'two_down': {'ginger', 'search', 'symbol', 'syntax'}, - 'three_across': {'book', 'buys', 'hold', 'land', 'year'}, - 'four_across': {'ant', 'big', 'bus', 'car', 'has'}}, - [Constraint(('one_across', 'one_down'), meet_at_constraint(0, 0)), - Constraint(('one_across', 'two_down'), meet_at_constraint(2, 0)), - Constraint(('three_across', 'two_down'), meet_at_constraint(2, 2)), - Constraint(('three_across', 'one_down'), meet_at_constraint(0, 2)), - Constraint(('four_across', 'two_down'), meet_at_constraint(0, 4))]) - -crossword1 = [['_', '_', '_', '*', '*'], - ['_', '*', '_', '*', '*'], - ['_', '_', '_', '_', '*'], - ['_', '*', '_', '*', '*'], - ['*', '*', '_', '_', '_'], - ['*', '*', '_', '*', '*']] - -words1 = {'ant', 'big', 'bus', 'car', 'has', 'book', 'buys', 'hold', - 'lane', 'year', 'ginger', 'search', 'symbol', 'syntax'} - - -class Crossword(NaryCSP): - - def __init__(self, puzzle, words): - domains = {} - constraints = [] - for i, line in enumerate(puzzle): - scope = [] - for j, element in enumerate(line): - if element == '_': - var = "p" + str(j) + str(i) - domains[var] = list(string.ascii_lowercase) - scope.append(var) - else: - if len(scope) > 1: - constraints.append(Constraint(tuple(scope), is_word_constraint(words))) - scope.clear() - if len(scope) > 1: - constraints.append(Constraint(tuple(scope), is_word_constraint(words))) - puzzle_t = list(map(list, zip(*puzzle))) - for i, line in enumerate(puzzle_t): - scope = [] - for j, element in enumerate(line): - if element == '_': - scope.append("p" + str(i) + str(j)) - else: - if len(scope) > 1: - constraints.append(Constraint(tuple(scope), is_word_constraint(words))) - scope.clear() - if len(scope) > 1: - constraints.append(Constraint(tuple(scope), is_word_constraint(words))) - super().__init__(domains, constraints) - self.puzzle = puzzle - - def display(self, assignment=None): - for i, line in enumerate(self.puzzle): - puzzle = "" - for j, element in enumerate(line): - if element == '*': - puzzle += "[*] " - else: - var = "p" + str(j) + str(i) - if assignment is not None: - if isinstance(assignment[var], set) and len(assignment[var]) == 1: - puzzle += "[" + str(first(assignment[var])).upper() + "] " - elif isinstance(assignment[var], str): - puzzle += "[" + str(assignment[var]).upper() + "] " - else: - puzzle += "[_] " - else: - puzzle += "[_] " - print(puzzle) - - -# ______________________________________________________________________________ -# Kakuro Problem - - -# difficulty 0 -kakuro1 = [['*', '*', '*', [6, ''], [3, '']], - ['*', [4, ''], [3, 3], '_', '_'], - [['', 10], '_', '_', '_', '_'], - [['', 3], '_', '_', '*', '*']] - -# difficulty 0 -kakuro2 = [ - ['*', [10, ''], [13, ''], '*'], - [['', 3], '_', '_', [13, '']], - [['', 12], '_', '_', '_'], - [['', 21], '_', '_', '_']] - -# difficulty 1 -kakuro3 = [ - ['*', [17, ''], [28, ''], '*', [42, ''], [22, '']], - [['', 9], '_', '_', [31, 14], '_', '_'], - [['', 20], '_', '_', '_', '_', '_'], - ['*', ['', 30], '_', '_', '_', '_'], - ['*', [22, 24], '_', '_', '_', '*'], - [['', 25], '_', '_', '_', '_', [11, '']], - [['', 20], '_', '_', '_', '_', '_'], - [['', 14], '_', '_', ['', 17], '_', '_']] - -# difficulty 2 -kakuro4 = [ - ['*', '*', '*', '*', '*', [4, ''], [24, ''], [11, ''], '*', '*', '*', [11, ''], [17, ''], '*', '*'], - ['*', '*', '*', [17, ''], [11, 12], '_', '_', '_', '*', '*', [24, 10], '_', '_', [11, ''], '*'], - ['*', [4, ''], [16, 26], '_', '_', '_', '_', '_', '*', ['', 20], '_', '_', '_', '_', [16, '']], - [['', 20], '_', '_', '_', '_', [24, 13], '_', '_', [16, ''], ['', 12], '_', '_', [23, 10], '_', '_'], - [['', 10], '_', '_', [24, 12], '_', '_', [16, 5], '_', '_', [16, 30], '_', '_', '_', '_', '_'], - ['*', '*', [3, 26], '_', '_', '_', '_', ['', 12], '_', '_', [4, ''], [16, 14], '_', '_', '*'], - ['*', ['', 8], '_', '_', ['', 15], '_', '_', [34, 26], '_', '_', '_', '_', '_', '*', '*'], - ['*', ['', 11], '_', '_', [3, ''], [17, ''], ['', 14], '_', '_', ['', 8], '_', '_', [7, ''], [17, ''], '*'], - ['*', '*', '*', [23, 10], '_', '_', [3, 9], '_', '_', [4, ''], [23, ''], ['', 13], '_', '_', '*'], - ['*', '*', [10, 26], '_', '_', '_', '_', '_', ['', 7], '_', '_', [30, 9], '_', '_', '*'], - ['*', [17, 11], '_', '_', [11, ''], [24, 8], '_', '_', [11, 21], '_', '_', '_', '_', [16, ''], [17, '']], - [['', 29], '_', '_', '_', '_', '_', ['', 7], '_', '_', [23, 14], '_', '_', [3, 17], '_', '_'], - [['', 10], '_', '_', [3, 10], '_', '_', '*', ['', 8], '_', '_', [4, 25], '_', '_', '_', '_'], - ['*', ['', 16], '_', '_', '_', '_', '*', ['', 23], '_', '_', '_', '_', '_', '*', '*'], - ['*', '*', ['', 6], '_', '_', '*', '*', ['', 15], '_', '_', '_', '*', '*', '*', '*']] - - -class Kakuro(NaryCSP): - - def __init__(self, puzzle): - variables = [] - for i, line in enumerate(puzzle): - # print line - for j, element in enumerate(line): - if element == '_': - var1 = str(i) - if len(var1) == 1: - var1 = "0" + var1 - var2 = str(j) - if len(var2) == 1: - var2 = "0" + var2 - variables.append("X" + var1 + var2) - domains = {} - for var in variables: - domains[var] = set(range(1, 10)) - constraints = [] - for i, line in enumerate(puzzle): - for j, element in enumerate(line): - if element != '_' and element != '*': - # down - column - if element[0] != '': - x = [] - for k in range(i + 1, len(puzzle)): - if puzzle[k][j] != '_': - break - var1 = str(k) - if len(var1) == 1: - var1 = "0" + var1 - var2 = str(j) - if len(var2) == 1: - var2 = "0" + var2 - x.append("X" + var1 + var2) - constraints.append(Constraint(x, sum_constraint(element[0]))) - constraints.append(Constraint(x, all_diff_constraint)) - # right - line - if element[1] != '': - x = [] - for k in range(j + 1, len(puzzle[i])): - if puzzle[i][k] != '_': - break - var1 = str(i) - if len(var1) == 1: - var1 = "0" + var1 - var2 = str(k) - if len(var2) == 1: - var2 = "0" + var2 - x.append("X" + var1 + var2) - constraints.append(Constraint(x, sum_constraint(element[1]))) - constraints.append(Constraint(x, all_diff_constraint)) - super().__init__(domains, constraints) - self.puzzle = puzzle - - def display(self, assignment=None): - for i, line in enumerate(self.puzzle): - puzzle = "" - for j, element in enumerate(line): - if element == '*': - puzzle += "[*]\t" - elif element == '_': - var1 = str(i) - if len(var1) == 1: - var1 = "0" + var1 - var2 = str(j) - if len(var2) == 1: - var2 = "0" + var2 - var = "X" + var1 + var2 - if assignment is not None: - if isinstance(assignment[var], set) and len(assignment[var]) == 1: - puzzle += "[" + str(first(assignment[var])) + "]\t" - elif isinstance(assignment[var], int): - puzzle += "[" + str(assignment[var]) + "]\t" - else: - puzzle += "[_]\t" - else: - puzzle += "[_]\t" - else: - puzzle += str(element[0]) + "\\" + str(element[1]) + "\t" - print(puzzle) - - -# ______________________________________________________________________________ -# Cryptarithmetic Problem - -# [Figure 6.2] -# T W O + T W O = F O U R -two_two_four = NaryCSP({'T': set(range(1, 10)), 'F': set(range(1, 10)), - 'W': set(range(0, 10)), 'O': set(range(0, 10)), 'U': set(range(0, 10)), 'R': set(range(0, 10)), - 'C1': set(range(0, 2)), 'C2': set(range(0, 2)), 'C3': set(range(0, 2))}, - [Constraint(('T', 'F', 'W', 'O', 'U', 'R'), all_diff_constraint), - Constraint(('O', 'R', 'C1'), lambda o, r, c1: o + o == r + 10 * c1), - Constraint(('W', 'U', 'C1', 'C2'), lambda w, u, c1, c2: c1 + w + w == u + 10 * c2), - Constraint(('T', 'O', 'C2', 'C3'), lambda t, o, c2, c3: c2 + t + t == o + 10 * c3), - Constraint(('F', 'C3'), eq)]) - -# S E N D + M O R E = M O N E Y -send_more_money = NaryCSP({'S': set(range(1, 10)), 'M': set(range(1, 10)), - 'E': set(range(0, 10)), 'N': set(range(0, 10)), 'D': set(range(0, 10)), - 'O': set(range(0, 10)), 'R': set(range(0, 10)), 'Y': set(range(0, 10)), - 'C1': set(range(0, 2)), 'C2': set(range(0, 2)), 'C3': set(range(0, 2)), - 'C4': set(range(0, 2))}, - [Constraint(('S', 'E', 'N', 'D', 'M', 'O', 'R', 'Y'), all_diff_constraint), - Constraint(('D', 'E', 'Y', 'C1'), lambda d, e, y, c1: d + e == y + 10 * c1), - Constraint(('N', 'R', 'E', 'C1', 'C2'), lambda n, r, e, c1, c2: c1 + n + r == e + 10 * c2), - Constraint(('E', 'O', 'N', 'C2', 'C3'), lambda e, o, n, c2, c3: c2 + e + o == n + 10 * c3), - Constraint(('S', 'M', 'O', 'C3', 'C4'), lambda s, m, o, c3, c4: c3 + s + m == o + 10 * c4), - Constraint(('M', 'C4'), eq)]) diff --git a/deep_learning4e.py b/deep_learning4e.py deleted file mode 100644 index 9f5b0a8f7..000000000 --- a/deep_learning4e.py +++ /dev/null @@ -1,584 +0,0 @@ -"""Deep learning. (Chapters 20)""" - -import random -import statistics - -import numpy as np -from keras import Sequential, optimizers -from keras.layers import Embedding, SimpleRNN, Dense -from keras.preprocessing import sequence - -from utils4e import (conv1D, gaussian_kernel, element_wise_product, vector_add, random_weights, - scalar_vector_product, map_vector, mean_squared_error_loss) - - -class Node: - """ - A single unit of a layer in a neural network - :param weights: weights between parent nodes and current node - :param value: value of current node - """ - - def __init__(self, weights=None, value=None): - self.value = value - self.weights = weights or [] - - -class Layer: - """ - A layer in a neural network based on a computational graph. - :param size: number of units in the current layer - """ - - def __init__(self, size): - self.nodes = np.array([Node() for _ in range(size)]) - - def forward(self, inputs): - """Define the operation to get the output of this layer""" - raise NotImplementedError - - -class Activation: - - def function(self, x): - return NotImplementedError - - def derivative(self, x): - return NotImplementedError - - def __call__(self, x): - return self.function(x) - - -class Sigmoid(Activation): - - def function(self, x): - return 1 / (1 + np.exp(-x)) - - def derivative(self, value): - return value * (1 - value) - - -class ReLU(Activation): - - def function(self, x): - return max(0, x) - - def derivative(self, value): - return 1 if value > 0 else 0 - - -class ELU(Activation): - - def __init__(self, alpha=0.01): - self.alpha = alpha - - def function(self, x): - return x if x > 0 else self.alpha * (np.exp(x) - 1) - - def derivative(self, value): - return 1 if value > 0 else self.alpha * np.exp(value) - - -class LeakyReLU(Activation): - - def __init__(self, alpha=0.01): - self.alpha = alpha - - def function(self, x): - return max(x, self.alpha * x) - - def derivative(self, value): - return 1 if value > 0 else self.alpha - - -class Tanh(Activation): - - def function(self, x): - return np.tanh(x) - - def derivative(self, value): - return 1 - (value ** 2) - - -class SoftMax(Activation): - - def function(self, x): - return np.exp(x) / np.sum(np.exp(x)) - - def derivative(self, x): - return np.ones_like(x) - - -class SoftPlus(Activation): - - def function(self, x): - return np.log(1. + np.exp(x)) - - def derivative(self, x): - return 1. / (1. + np.exp(-x)) - - -class Linear(Activation): - - def function(self, x): - return x - - def derivative(self, x): - return np.ones_like(x) - - -class InputLayer(Layer): - """1D input layer. Layer size is the same as input vector size.""" - - def __init__(self, size=3): - super().__init__(size) - - def forward(self, inputs): - """Take each value of the inputs to each unit in the layer.""" - assert len(self.nodes) == len(inputs) - for node, inp in zip(self.nodes, inputs): - node.value = inp - return inputs - - -class OutputLayer(Layer): - """1D softmax output layer in 19.3.2.""" - - def __init__(self, size=3): - super().__init__(size) - - def forward(self, inputs, activation=SoftMax): - assert len(self.nodes) == len(inputs) - res = activation().function(inputs) - for node, val in zip(self.nodes, res): - node.value = val - return res - - -class DenseLayer(Layer): - """ - 1D dense layer in a neural network. - :param in_size: (int) input vector size - :param out_size: (int) output vector size - :param activation: (Activation object) activation function - """ - - def __init__(self, in_size=3, out_size=3, activation=Sigmoid): - super().__init__(out_size) - self.out_size = out_size - self.inputs = None - self.activation = activation() - # initialize weights - for node in self.nodes: - node.weights = random_weights(-0.5, 0.5, in_size) - - def forward(self, inputs): - self.inputs = inputs - res = [] - # get the output value of each unit - for unit in self.nodes: - val = self.activation.function(np.dot(unit.weights, inputs)) - unit.value = val - res.append(val) - return res - - -class ConvLayer1D(Layer): - """ - 1D convolution layer of in neural network. - :param kernel_size: convolution kernel size - """ - - def __init__(self, size=3, kernel_size=3): - super().__init__(size) - # init convolution kernel as gaussian kernel - for node in self.nodes: - node.weights = gaussian_kernel(kernel_size) - - def forward(self, features): - # each node in layer takes a channel in the features - assert len(self.nodes) == len(features) - res = [] - # compute the convolution output of each channel, store it in node.val - for node, feature in zip(self.nodes, features): - out = conv1D(feature, node.weights) - res.append(out) - node.value = out - return res - - -class MaxPoolingLayer1D(Layer): - """ - 1D max pooling layer in a neural network. - :param kernel_size: max pooling area size - """ - - def __init__(self, size=3, kernel_size=3): - super().__init__(size) - self.kernel_size = kernel_size - self.inputs = None - - def forward(self, features): - assert len(self.nodes) == len(features) - res = [] - self.inputs = features - # do max pooling for each channel in features - for i in range(len(self.nodes)): - feature = features[i] - # get the max value in a kernel_size * kernel_size area - out = [max(feature[i:i + self.kernel_size]) - for i in range(len(feature) - self.kernel_size + 1)] - res.append(out) - self.nodes[i].value = out - return res - - -class BatchNormalizationLayer(Layer): - """Batch normalization layer.""" - - def __init__(self, size, eps=0.001): - super().__init__(size) - self.eps = eps - # self.weights = [beta, gamma] - self.weights = [0, 0] - self.inputs = None - - def forward(self, inputs): - # mean value of inputs - mu = sum(inputs) / len(inputs) - # standard error of inputs - stderr = statistics.stdev(inputs) - self.inputs = inputs - res = [] - # get normalized value of each input - for i in range(len(self.nodes)): - val = [(inputs[i] - mu) * self.weights[0] / np.sqrt(self.eps + stderr ** 2) + self.weights[1]] - res.append(val) - self.nodes[i].value = val - return res - - -def init_examples(examples, idx_i, idx_t, o_units): - """Init examples from dataset.examples.""" - - inputs, targets = {}, {} - for i, e in enumerate(examples): - # input values of e - inputs[i] = [e[i] for i in idx_i] - - if o_units > 1: - # one-hot representation of e's target - t = [0 for i in range(o_units)] - t[e[idx_t]] = 1 - targets[i] = t - else: - # target value of e - targets[i] = [e[idx_t]] - - return inputs, targets - - -def stochastic_gradient_descent(dataset, net, loss, epochs=1000, l_rate=0.01, batch_size=1, verbose=False): - """ - Gradient descent algorithm to update the learnable parameters of a network. - :return: the updated network - """ - examples = dataset.examples # init data - - for e in range(epochs): - total_loss = 0 - random.shuffle(examples) - weights = [[node.weights for node in layer.nodes] for layer in net] - - for batch in get_batch(examples, batch_size): - inputs, targets = init_examples(batch, dataset.inputs, dataset.target, len(net[-1].nodes)) - # compute gradients of weights - gs, batch_loss = BackPropagation(inputs, targets, weights, net, loss) - # update weights with gradient descent - weights = [x + y for x, y in zip(weights, [np.array(tg) * -l_rate for tg in gs])] - total_loss += batch_loss - - # update the weights of network each batch - for i in range(len(net)): - if weights[i].size != 0: - for j in range(len(weights[i])): - net[i].nodes[j].weights = weights[i][j] - - if verbose: - print("epoch:{}, total_loss:{}".format(e + 1, total_loss)) - - return net - - -def adam(dataset, net, loss, epochs=1000, rho=(0.9, 0.999), delta=1 / 10 ** 8, - l_rate=0.001, batch_size=1, verbose=False): - """ - [Figure 19.6] - Adam optimizer to update the learnable parameters of a network. - Required parameters are similar to gradient descent. - :return the updated network - """ - examples = dataset.examples - - # init s,r and t - s = [[[0] * len(node.weights) for node in layer.nodes] for layer in net] - r = [[[0] * len(node.weights) for node in layer.nodes] for layer in net] - t = 0 - - # repeat util converge - for e in range(epochs): - # total loss of each epoch - total_loss = 0 - random.shuffle(examples) - weights = [[node.weights for node in layer.nodes] for layer in net] - - for batch in get_batch(examples, batch_size): - t += 1 - inputs, targets = init_examples(batch, dataset.inputs, dataset.target, len(net[-1].nodes)) - - # compute gradients of weights - gs, batch_loss = BackPropagation(inputs, targets, weights, net, loss) - - # update s,r,s_hat and r_gat - s = vector_add(scalar_vector_product(rho[0], s), - scalar_vector_product((1 - rho[0]), gs)) - r = vector_add(scalar_vector_product(rho[1], r), - scalar_vector_product((1 - rho[1]), element_wise_product(gs, gs))) - s_hat = scalar_vector_product(1 / (1 - rho[0] ** t), s) - r_hat = scalar_vector_product(1 / (1 - rho[1] ** t), r) - - # rescale r_hat - r_hat = map_vector(lambda x: 1 / (np.sqrt(x) + delta), r_hat) - - # delta weights - delta_theta = scalar_vector_product(-l_rate, element_wise_product(s_hat, r_hat)) - weights = vector_add(weights, delta_theta) - total_loss += batch_loss - - # update the weights of network each batch - for i in range(len(net)): - if weights[i]: - for j in range(len(weights[i])): - net[i].nodes[j].weights = weights[i][j] - - if verbose: - print("epoch:{}, total_loss:{}".format(e + 1, total_loss)) - - return net - - -def BackPropagation(inputs, targets, theta, net, loss): - """ - The back-propagation algorithm for multilayer networks in only one epoch, to calculate gradients of theta. - :param inputs: a batch of inputs in an array. Each input is an iterable object - :param targets: a batch of targets in an array. Each target is an iterable object - :param theta: parameters to be updated - :param net: a list of predefined layer objects representing their linear sequence - :param loss: a predefined loss function taking array of inputs and targets - :return: gradients of theta, loss of the input batch - """ - - assert len(inputs) == len(targets) - o_units = len(net[-1].nodes) - n_layers = len(net) - batch_size = len(inputs) - - gradients = [[[] for _ in layer.nodes] for layer in net] - total_gradients = [[[0] * len(node.weights) for node in layer.nodes] for layer in net] - - batch_loss = 0 - - # iterate over each example in batch - for e in range(batch_size): - i_val = inputs[e] - t_val = targets[e] - - # forward pass and compute batch loss - for i in range(1, n_layers): - layer_out = net[i].forward(i_val) - i_val = layer_out - batch_loss += loss(t_val, layer_out) - - # initialize delta - delta = [[] for _ in range(n_layers)] - - previous = np.array([layer_out[i] - t_val[i] for i in range(o_units)]) - h_layers = n_layers - 1 - - # backward pass - for i in range(h_layers, 0, -1): - layer = net[i] - derivative = np.array([layer.activation.derivative(node.value) for node in layer.nodes]) - delta[i] = previous * derivative - # pass to layer i-1 in the next iteration - previous = np.matmul([delta[i]], theta[i])[0] - # compute gradient of layer i - gradients[i] = [scalar_vector_product(d, net[i].inputs) for d in delta[i]] - - # add gradient of current example to batch gradient - total_gradients = vector_add(total_gradients, gradients) - - return total_gradients, batch_loss - - -def get_batch(examples, batch_size=1): - """Split examples into multiple batches""" - for i in range(0, len(examples), batch_size): - yield examples[i: i + batch_size] - - -class NeuralNetworkLearner: - """ - Simple dense multilayer neural network. - :param hidden_layer_sizes: size of hidden layers in the form of a list - """ - - def __init__(self, dataset, hidden_layer_sizes, l_rate=0.01, epochs=1000, batch_size=10, - optimizer=stochastic_gradient_descent, loss=mean_squared_error_loss, verbose=False, plot=False): - self.dataset = dataset - self.l_rate = l_rate - self.epochs = epochs - self.batch_size = batch_size - self.optimizer = optimizer - self.loss = loss - self.verbose = verbose - self.plot = plot - - input_size = len(dataset.inputs) - output_size = len(dataset.values[dataset.target]) - - # initialize the network - raw_net = [InputLayer(input_size)] - # add hidden layers - hidden_input_size = input_size - for h_size in hidden_layer_sizes: - raw_net.append(DenseLayer(hidden_input_size, h_size)) - hidden_input_size = h_size - raw_net.append(DenseLayer(hidden_input_size, output_size)) - self.raw_net = raw_net - - def fit(self, X, y): - self.learned_net = self.optimizer(self.dataset, self.raw_net, loss=self.loss, epochs=self.epochs, - l_rate=self.l_rate, batch_size=self.batch_size, verbose=self.verbose) - return self - - def predict(self, example): - n_layers = len(self.learned_net) - - layer_input = example - layer_out = example - - # get the output of each layer by forward passing - for i in range(1, n_layers): - layer_out = self.learned_net[i].forward(np.array(layer_input).reshape((-1, 1))) - layer_input = layer_out - - return layer_out.index(max(layer_out)) - - -class PerceptronLearner: - """ - Simple perceptron neural network. - """ - - def __init__(self, dataset, l_rate=0.01, epochs=1000, batch_size=10, optimizer=stochastic_gradient_descent, - loss=mean_squared_error_loss, verbose=False, plot=False): - self.dataset = dataset - self.l_rate = l_rate - self.epochs = epochs - self.batch_size = batch_size - self.optimizer = optimizer - self.loss = loss - self.verbose = verbose - self.plot = plot - - input_size = len(dataset.inputs) - output_size = len(dataset.values[dataset.target]) - - # initialize the network, add dense layer - self.raw_net = [InputLayer(input_size), DenseLayer(input_size, output_size)] - - def fit(self, X, y): - self.learned_net = self.optimizer(self.dataset, self.raw_net, loss=self.loss, epochs=self.epochs, - l_rate=self.l_rate, batch_size=self.batch_size, verbose=self.verbose) - return self - - def predict(self, example): - layer_out = self.learned_net[1].forward(np.array(example).reshape((-1, 1))) - return layer_out.index(max(layer_out)) - - -def keras_dataset_loader(dataset, max_length=500): - """ - Helper function to load keras datasets. - :param dataset: keras data set type - :param max_length: max length of each input sequence - """ - # init dataset - (X_train, y_train), (X_val, y_val) = dataset - if max_length > 0: - X_train = sequence.pad_sequences(X_train, maxlen=max_length) - X_val = sequence.pad_sequences(X_val, maxlen=max_length) - return (X_train[10:], y_train[10:]), (X_val, y_val), (X_train[:10], y_train[:10]) - - -def SimpleRNNLearner(train_data, val_data, epochs=2, verbose=False): - """ - RNN example for text sentimental analysis. - :param train_data: a tuple of (training data, targets) - Training data: ndarray taking training examples, while each example is coded by embedding - Targets: ndarray taking targets of each example. Each target is mapped to an integer - :param val_data: a tuple of (validation data, targets) - :param epochs: number of epochs - :param verbose: verbosity mode - :return: a keras model - """ - - total_inputs = 5000 - input_length = 500 - - # init data - X_train, y_train = train_data - X_val, y_val = val_data - - # init a the sequential network (embedding layer, rnn layer, dense layer) - model = Sequential() - model.add(Embedding(total_inputs, 32, input_length=input_length)) - model.add(SimpleRNN(units=128)) - model.add(Dense(1, activation='sigmoid')) - model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) - - # train the model - model.fit(X_train, y_train, validation_data=(X_val, y_val), epochs=epochs, batch_size=128, verbose=verbose) - - return model - - -def AutoencoderLearner(inputs, encoding_size, epochs=200, verbose=False): - """ - Simple example of linear auto encoder learning producing the input itself. - :param inputs: a batch of input data in np.ndarray type - :param encoding_size: int, the size of encoding layer - :param epochs: number of epochs - :param verbose: verbosity mode - :return: a keras model - """ - - # init data - input_size = len(inputs[0]) - - # init model - model = Sequential() - model.add(Dense(encoding_size, input_dim=input_size, activation='relu', kernel_initializer='random_uniform', - bias_initializer='ones')) - model.add(Dense(input_size, activation='relu', kernel_initializer='random_uniform', bias_initializer='ones')) - - # update model with sgd - sgd = optimizers.SGD(lr=0.01) - model.compile(loss='mean_squared_error', optimizer=sgd, metrics=['accuracy']) - - # train the model - model.fit(inputs, inputs, epochs=epochs, batch_size=10, verbose=verbose) - - return model diff --git a/games.ipynb b/games.ipynb deleted file mode 100644 index edf955be8..000000000 --- a/games.ipynb +++ /dev/null @@ -1,1669 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# GAMES OR ADVERSARIAL SEARCH\n", - "\n", - "This notebook serves as supporting material for topics covered in **Chapter 5 - Adversarial Search** in the book *Artificial Intelligence: A Modern Approach.* This notebook uses implementations from [games.py](https://github.com/aimacode/aima-python/blob/master/games.py) module. Let's import required classes, methods, global variables etc., from games module." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# CONTENTS\n", - "\n", - "* Game Representation\n", - "* Game Examples\n", - " * Tic-Tac-Toe\n", - " * Figure 5.2 Game\n", - "* Min-Max\n", - "* Alpha-Beta\n", - "* Players\n", - "* Let's Play Some Games!" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "from games import *\n", - "from notebook import psource, pseudocode" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# GAME REPRESENTATION\n", - "\n", - "To represent games we make use of the `Game` class, which we can subclass and override its functions to represent our own games. A helper tool is the namedtuple `GameState`, which in some cases can come in handy, especially when our game needs us to remember a board (like chess)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## `GameState` namedtuple\n", - "\n", - "`GameState` is a [namedtuple](https://docs.python.org/3.5/library/collections.html#collections.namedtuple) which represents the current state of a game. It is used to help represent games whose states can't be easily represented normally, or for games that require memory of a board, like Tic-Tac-Toe.\n", - "\n", - "`Gamestate` is defined as follows:\n", - "\n", - "`GameState = namedtuple('GameState', 'to_move, utility, board, moves')`\n", - "\n", - "* `to_move`: It represents whose turn it is to move next.\n", - "\n", - "* `utility`: It stores the utility of the game state. Storing this utility is a good idea, because, when you do a Minimax Search or an Alphabeta Search, you generate many recursive calls, which travel all the way down to the terminal states. When these recursive calls go back up to the original callee, we have calculated utilities for many game states. We store these utilities in their respective `GameState`s to avoid calculating them all over again.\n", - "\n", - "* `board`: A dict that stores the board of the game.\n", - "\n", - "* `moves`: It stores the list of legal moves possible from the current position." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "collapsed": true - }, - "source": [ - "## `Game` class\n", - "\n", - "Let's have a look at the class `Game` in our module. We see that it has functions, namely `actions`, `result`, `utility`, `terminal_test`, `to_move` and `display`.\n", - "\n", - "We see that these functions have not actually been implemented. This class is just a template class; we are supposed to create the class for our game, by inheriting this `Game` class and implementing all the methods mentioned in `Game`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "%psource Game" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now let's get into details of all the methods in our `Game` class. You have to implement these methods when you create new classes that would represent your game.\n", - "\n", - "* `actions(self, state)`: Given a game state, this method generates all the legal actions possible from this state, as a list or a generator. Returning a generator rather than a list has the advantage that it saves space and you can still operate on it as a list.\n", - "\n", - "\n", - "* `result(self, state, move)`: Given a game state and a move, this method returns the game state that you get by making that move on this game state.\n", - "\n", - "\n", - "* `utility(self, state, player)`: Given a terminal game state and a player, this method returns the utility for that player in the given terminal game state. While implementing this method assume that the game state is a terminal game state. The logic in this module is such that this method will be called only on terminal game states.\n", - "\n", - "\n", - "* `terminal_test(self, state)`: Given a game state, this method should return `True` if this game state is a terminal state, and `False` otherwise.\n", - "\n", - "\n", - "* `to_move(self, state)`: Given a game state, this method returns the player who is to play next. This information is typically stored in the game state, so all this method does is extract this information and return it.\n", - "\n", - "\n", - "* `display(self, state)`: This method prints/displays the current state of the game." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# GAME EXAMPLES\n", - "\n", - "Below we give some examples for games you can create and experiment on." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Tic-Tac-Toe\n", - "\n", - "Take a look at the class `TicTacToe`. All the methods mentioned in the class `Game` have been implemented here." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "collapsed": true - }, - "outputs": [ - { - "output_type": "stream", - "text": "\u001b[1;32mclass\u001b[0m \u001b[0mTicTacToe\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mGame\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;34m\"\"\"Play TicTacToe on an h x v board, with Max (first player) playing 'X'.\n A state has the player to move, a cached utility, a list of moves in\n the form of a list of (x, y) positions, and a board, in the form of\n a dict of {(x, y): Player} entries, where Player is 'X' or 'O'.\"\"\"\u001b[0m\u001b[1;33m\n\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m__init__\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mh\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m3\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mv\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m3\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mk\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m3\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mh\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mh\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mv\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mk\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mk\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[0mmoves\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mx\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mh\u001b[0m \u001b[1;33m+\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0my\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mv\u001b[0m \u001b[1;33m+\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0minitial\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mGameState\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mto_move\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'X'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mutility\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mboard\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;33m{\u001b[0m\u001b[1;33m}\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmoves\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mmoves\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\n\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mactions\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mstate\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;34m\"\"\"Legal moves are any square not yet taken.\"\"\"\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mstate\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmoves\u001b[0m\u001b[1;33m\n\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mresult\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mstate\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmove\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mmove\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mstate\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmoves\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mstate\u001b[0m \u001b[1;31m# Illegal move has no effect\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[0mboard\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mstate\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mboard\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcopy\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[0mboard\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mmove\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mstate\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mto_move\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[0mmoves\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mlist\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mstate\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmoves\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[0mmoves\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mremove\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmove\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mGameState\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mto_move\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'O'\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mstate\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mto_move\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;34m'X'\u001b[0m \u001b[1;32melse\u001b[0m \u001b[1;34m'X'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[0mutility\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcompute_utility\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mboard\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmove\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mstate\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mto_move\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[0mboard\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mboard\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmoves\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mmoves\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\n\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mutility\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mstate\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mplayer\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;34m\"\"\"Return the value to player; 1 for win, -1 for loss, 0 otherwise.\"\"\"\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mstate\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mutility\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mplayer\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;34m'X'\u001b[0m \u001b[1;32melse\u001b[0m \u001b[1;33m-\u001b[0m\u001b[0mstate\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mutility\u001b[0m\u001b[1;33m\n\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mterminal_test\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mstate\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;34m\"\"\"A state is terminal if it is won or there are no empty squares.\"\"\"\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mstate\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mutility\u001b[0m \u001b[1;33m!=\u001b[0m \u001b[1;36m0\u001b[0m \u001b[1;32mor\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mstate\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmoves\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m\n\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mdisplay\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mstate\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[0mboard\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mstate\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mboard\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mx\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mh\u001b[0m \u001b[1;33m+\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0my\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv\u001b[0m \u001b[1;33m+\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mboard\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'.'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mend\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m' '\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\n\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mcompute_utility\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mboard\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmove\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mplayer\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;34m\"\"\"If 'X' wins with this move, return 1; if 'O' wins return -1; else return 0.\"\"\"\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mk_in_row\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mboard\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmove\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mplayer\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mor\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mk_in_row\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mboard\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmove\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mplayer\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mor\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mk_in_row\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mboard\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmove\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mplayer\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m-\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mor\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mk_in_row\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mboard\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmove\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mplayer\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[1;33m+\u001b[0m\u001b[1;36m1\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mplayer\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;34m'X'\u001b[0m \u001b[1;32melse\u001b[0m \u001b[1;33m-\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m\n\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mk_in_row\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mboard\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmove\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mplayer\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdelta_x_y\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;34m\"\"\"Return true if there is a line through move on board for player.\"\"\"\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0mdelta_x\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdelta_y\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mdelta_x_y\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[0mx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mmove\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[0mn\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m0\u001b[0m \u001b[1;31m# n is number of moves in row\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;32mwhile\u001b[0m \u001b[0mboard\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m==\u001b[0m \u001b[0mplayer\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[0mn\u001b[0m \u001b[1;33m+=\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[0mx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mx\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0mdelta_x\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0mdelta_y\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[0mx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mmove\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;32mwhile\u001b[0m \u001b[0mboard\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m==\u001b[0m \u001b[0mplayer\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[0mn\u001b[0m \u001b[1;33m+=\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[0mx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mx\u001b[0m \u001b[1;33m-\u001b[0m \u001b[0mdelta_x\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my\u001b[0m \u001b[1;33m-\u001b[0m \u001b[0mdelta_y\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[0mn\u001b[0m \u001b[1;33m-=\u001b[0m \u001b[1;36m1\u001b[0m \u001b[1;31m# Because we counted move itself twice\u001b[0m\u001b[1;33m\n\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mn\u001b[0m \u001b[1;33m>=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mk\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", - "metadata": {}, - "execution_count": 4 - } - ], - "source": [ - "%psource TicTacToe" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The class `TicTacToe` has been inherited from the class `Game`. As mentioned earlier, you really want to do this. Catching bugs and errors becomes a whole lot easier.\n", - "\n", - "Additional methods in TicTacToe:\n", - "\n", - "* `__init__(self, h=3, v=3, k=3)` : When you create a class inherited from the `Game` class (class `TicTacToe` in our case), you'll have to create an object of this inherited class to initialize the game. This initialization might require some additional information which would be passed to `__init__` as variables. For the case of our `TicTacToe` game, this additional information would be the number of rows `h`, number of columns `v` and how many consecutive X's or O's are needed in a row, column or diagonal for a win `k`. Also, the initial game state has to be defined here in `__init__`.\n", - "\n", - "\n", - "* `compute_utility(self, board, move, player)` : A method to calculate the utility of TicTacToe game. If 'X' wins with this move, this method returns 1; if 'O' wins return -1; else return 0.\n", - "\n", - "\n", - "* `k_in_row(self, board, move, player, delta_x_y)` : This method returns `True` if there is a line formed on TicTacToe board with the latest move else `False.`" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### TicTacToe GameState\n", - "\n", - "Now, before we start implementing our `TicTacToe` game, we need to decide how we will be representing our game state. Typically, a game state will give you all the current information about the game at any point in time. When you are given a game state, you should be able to tell whose turn it is next, how the game will look like on a real-life board (if it has one) etc. A game state need not include the history of the game. If you can play the game further given a game state, you game state representation is acceptable. While we might like to include all kinds of information in our game state, we wouldn't want to put too much information into it. Modifying this game state to generate a new one would be a real pain then.\n", - "\n", - "Now, as for our `TicTacToe` game state, would storing only the positions of all the X's and O's be sufficient to represent all the game information at that point in time? Well, does it tell us whose turn it is next? Looking at the 'X's and O's on the board and counting them should tell us that. But that would mean extra computing. To avoid this, we will also store whose move it is next in the game state.\n", - "\n", - "Think about what we've done here. We have reduced extra computation by storing additional information in a game state. Now, this information might not be absolutely essential to tell us about the state of the game, but it does save us additional computation time. We'll do more of this later on." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To store game states will will use the `GameState` namedtuple.\n", - "\n", - "* `to_move`: A string of a single character, either 'X' or 'O'.\n", - "\n", - "* `utility`: 1 for win, -1 for loss, 0 otherwise.\n", - "\n", - "* `board`: All the positions of X's and O's on the board.\n", - "\n", - "* `moves`: All the possible moves from the current state. Note here, that storing the moves as a list, as it is done here, increases the space complexity of Minimax Search from `O(m)` to `O(bm)`. Refer to Sec. 5.2.1 of the book." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Representing a move in TicTacToe game\n", - "\n", - "Now that we have decided how our game state will be represented, it's time to decide how our move will be represented. Becomes easy to use this move to modify a current game state to generate a new one.\n", - "\n", - "For our `TicTacToe` game, we'll just represent a move by a tuple, where the first and the second elements of the tuple will represent the row and column, respectively, where the next move is to be made. Whether to make an 'X' or an 'O' will be decided by the `to_move` in the `GameState` namedtuple." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Fig52 Game\n", - "\n", - "For a more trivial example we will represent the game in **Figure 5.2** of the book.\n", - "\n", - "\n", - "\n", - "The states are represented with capital letters inside the triangles (eg. \"A\") while moves are the labels on the edges between states (eg. \"a1\"). Terminal nodes carry utility values. Note that the terminal nodes are named in this example 'B1', 'B2' and 'B2' for the nodes below 'B', and so forth.\n", - "\n", - "We will model the moves, utilities and initial state like this:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "moves = dict(A=dict(a1='B', a2='C', a3='D'),\n", - " B=dict(b1='B1', b2='B2', b3='B3'),\n", - " C=dict(c1='C1', c2='C2', c3='C3'),\n", - " D=dict(d1='D1', d2='D2', d3='D3'))\n", - "utils = dict(B1=3, B2=12, B3=8, C1=2, C2=4, C3=6, D1=14, D2=5, D3=2)\n", - "initial = 'A'" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In `moves`, we have a nested dictionary system. The outer's dictionary has keys as the states and values the possible moves from that state (as a dictionary). The inner dictionary of moves has keys the move names and values the next state after the move is complete.\n", - "\n", - "Below is an example that showcases `moves`. We want the next state after move 'a1' from 'A', which is 'B'. A quick glance at the above image confirms that this is indeed the case." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "B\n" - ] - } - ], - "source": [ - "print(moves['A']['a1'])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We will now take a look at the functions we need to implement. First we need to create an object of the `Fig52Game` class." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "fig52 = Fig52Game()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`actions`: Returns the list of moves one can make from a given state." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "psource(Fig52Game.actions)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['b1', 'b2', 'b3']\n" - ] - } - ], - "source": [ - "print(fig52.actions('B'))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`result`: Returns the next state after we make a specific move." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "psource(Fig52Game.result)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "B\n" - ] - } - ], - "source": [ - "print(fig52.result('A', 'a1'))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`utility`: Returns the value of the terminal state for a player ('MAX' and 'MIN'). Note that for 'MIN' the value returned is the negative of the utility." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "psource(Fig52Game.utility)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3\n", - "-3\n" - ] - } - ], - "source": [ - "print(fig52.utility('B1', 'MAX'))\n", - "print(fig52.utility('B1', 'MIN'))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`terminal_test`: Returns `True` if the given state is a terminal state, `False` otherwise." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "psource(Fig52Game.terminal_test)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "print(fig52.terminal_test('C3'))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`to_move`: Return the player who will move in this state." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "psource(Fig52Game.to_move)" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAX\n" - ] - } - ], - "source": [ - "print(fig52.to_move('A'))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As a whole the class `Fig52` that inherits from the class `Game` and overrides its functions:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "psource(Fig52Game)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# MIN-MAX\n", - "\n", - "## Overview\n", - "\n", - "This algorithm (often called *Minimax*) computes the next move for a player (MIN or MAX) at their current state. It recursively computes the minimax value of successor states, until it reaches terminals (the leaves of the tree). Using the `utility` value of the terminal states, it computes the values of parent states until it reaches the initial node (the root of the tree).\n", - "\n", - "It is worth noting that the algorithm works in a depth-first manner. The pseudocode can be found below:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "text/markdown": [ - "### AIMA3e\n", - "__function__ MINIMAX-DECISION(_state_) __returns__ _an action_ \n", - " __return__ arg max _a_ ∈ ACTIONS(_s_) MIN\\-VALUE(RESULT(_state_, _a_)) \n", - "\n", - "---\n", - "__function__ MAX\\-VALUE(_state_) __returns__ _a utility value_ \n", - " __if__ TERMINAL\\-TEST(_state_) __then return__ UTILITY(_state_) \n", - " _v_ ← −∞ \n", - " __for each__ _a_ __in__ ACTIONS(_state_) __do__ \n", - "   _v_ ← MAX(_v_, MIN\\-VALUE(RESULT(_state_, _a_))) \n", - " __return__ _v_ \n", - "\n", - "---\n", - "__function__ MIN\\-VALUE(_state_) __returns__ _a utility value_ \n", - " __if__ TERMINAL\\-TEST(_state_) __then return__ UTILITY(_state_) \n", - " _v_ ← ∞ \n", - " __for each__ _a_ __in__ ACTIONS(_state_) __do__ \n", - "   _v_ ← MIN(_v_, MAX\\-VALUE(RESULT(_state_, _a_))) \n", - " __return__ _v_ \n", - "\n", - "---\n", - "__Figure__ ?? An algorithm for calculating minimax decisions. It returns the action corresponding to the best possible move, that is, the move that leads to the outcome with the best utility, under the assumption that the opponent plays to minimize utility. The functions MAX\\-VALUE and MIN\\-VALUE go through the whole game tree, all the way to the leaves, to determine the backed\\-up value of a state. The notation argmax _a_ ∈ _S_ _f_(_a_) computes the element _a_ of set _S_ that has maximum value of _f_(_a_)." - ], - "text/plain": [ - "" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pseudocode(\"Minimax-Decision\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Implementation\n", - "\n", - "In the implementation we are using two functions, `max_value` and `min_value` to calculate the best move for MAX and MIN respectively. These functions interact in an alternating recursion; one calls the other until a terminal state is reached. When the recursion halts, we are left with scores for each move. We return the max. Despite returning the max, it will work for MIN too since for MIN the values are their negative (hence the order of values is reversed, so the higher the better for MIN too)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "psource(minimax_decision)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Example\n", - "\n", - "We will now play the Fig52 game using this algorithm. Take a look at the Fig52Game from above to follow along.\n", - "\n", - "It is the turn of MAX to move, and he is at state A. He can move to B, C or D, using moves a1, a2 and a3 respectively. MAX's goal is to maximize the end value. So, to make a decision, MAX needs to know the values at the aforementioned nodes and pick the greatest one. After MAX, it is MIN's turn to play. So MAX wants to know what will the values of B, C and D be after MIN plays.\n", - "\n", - "The problem then becomes what move will MIN make at B, C and D. The successor states of all these nodes are terminal states, so MIN will pick the smallest value for each node. So, for B he will pick 3 (from move b1), for C he will pick 2 (from move c1) and for D he will again pick 2 (from move d3).\n", - "\n", - "Let's see this in code:" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "b1\n", - "c1\n", - "d3\n" - ] - } - ], - "source": [ - "print(minimax_decision('B', fig52))\n", - "print(minimax_decision('C', fig52))\n", - "print(minimax_decision('D', fig52))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now MAX knows that the values for B, C and D are 3, 2 and 2 (produced by the above moves of MIN). The greatest is 3, which he will get with move a1. This is then the move MAX will make. Let's see the algorithm in full action:" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "a1\n" - ] - } - ], - "source": [ - "print(minimax_decision('A', fig52))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Visualization\n", - "\n", - "Below we have a simple game visualization using the algorithm. After you run the command, click on the cell to move the game along. You can input your own values via a list of 27 integers." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "from notebook import Canvas_minimax\n", - "from random import randint" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "minimax_viz = Canvas_minimax('minimax_viz', [randint(1, 50) for i in range(27)])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# ALPHA-BETA\n", - "\n", - "## Overview\n", - "\n", - "While *Minimax* is great for computing a move, it can get tricky when the number of game states gets bigger. The algorithm needs to search all the leaves of the tree, which increase exponentially to its depth.\n", - "\n", - "For Tic-Tac-Toe, where the depth of the tree is 9 (after the 9th move, the game ends), we can have at most 9! terminal states (at most because not all terminal nodes are at the last level of the tree; some are higher up because the game ended before the 9th move). This isn't so bad, but for more complex problems like chess, we have over $10^{40}$ terminal nodes. Unfortunately we have not found a way to cut the exponent away, but we nevertheless have found ways to alleviate the workload.\n", - "\n", - "Here we examine *pruning* the game tree, which means removing parts of it that we do not need to examine. The particular type of pruning is called *alpha-beta*, and the search in whole is called *alpha-beta search*.\n", - "\n", - "To showcase what parts of the tree we don't need to search, we will take a look at the example `Fig52Game`.\n", - "\n", - "In the example game, we need to find the best move for player MAX at state A, which is the maximum value of MIN's possible moves at successor states.\n", - "\n", - "`MAX(A) = MAX( MIN(B), MIN(C), MIN(D) )`\n", - "\n", - "`MIN(B)` is the minimum of 3, 12, 8 which is 3. So the above formula becomes:\n", - "\n", - "`MAX(A) = MAX( 3, MIN(C), MIN(D) )`\n", - "\n", - "Next move we will check is c1, which leads to a terminal state with utility of 2. Before we continue searching under state C, let's pop back into our formula with the new value:\n", - "\n", - "`MAX(A) = MAX( 3, MIN(2, c2, .... cN), MIN(D) )`\n", - "\n", - "We do not know how many moves state C allows, but we know that the first one results in a value of 2. Do we need to keep searching under C? The answer is no. The value MIN will pick on C will at most be 2. Since MAX already has the option to pick something greater than that, 3 from B, he does not need to keep searching under C.\n", - "\n", - "In *alpha-beta* we make use of two additional parameters for each state/node, *a* and *b*, that describe bounds on the possible moves. The parameter *a* denotes the best choice (highest value) for MAX along that path, while *b* denotes the best choice (lowest value) for MIN. As we go along we update *a* and *b* and prune a node branch when the value of the node is worse than the value of *a* and *b* for MAX and MIN respectively.\n", - "\n", - "In the above example, after the search under state B, MAX had an *a* value of 3. So, when searching node C we found a value less than that, 2, we stopped searching under C.\n", - "\n", - "You can read the pseudocode below:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/markdown": [ - "### AIMA3e\n", - "__function__ ALPHA-BETA-SEARCH(_state_) __returns__ an action \n", - " _v_ ← MAX\\-VALUE(_state_, −∞, +∞) \n", - " __return__ the _action_ in ACTIONS(_state_) with value _v_ \n", - "\n", - "---\n", - "__function__ MAX\\-VALUE(_state_, _α_, _β_) __returns__ _a utility value_ \n", - " __if__ TERMINAL\\-TEST(_state_) __then return__ UTILITY(_state_) \n", - " _v_ ← −∞ \n", - " __for each__ _a_ __in__ ACTIONS(_state_) __do__ \n", - "   _v_ ← MAX(_v_, MIN\\-VALUE(RESULT(_state_, _a_), _α_, _β_)) \n", - "   __if__ _v_ ≥ _β_ __then return__ _v_ \n", - "   _α_ ← MAX(_α_, _v_) \n", - " __return__ _v_ \n", - "\n", - "---\n", - "__function__ MIN\\-VALUE(_state_, _α_, _β_) __returns__ _a utility value_ \n", - " __if__ TERMINAL\\-TEST(_state_) __then return__ UTILITY(_state_) \n", - " _v_ ← +∞ \n", - " __for each__ _a_ __in__ ACTIONS(_state_) __do__ \n", - "   _v_ ← MIN(_v_, MAX\\-VALUE(RESULT(_state_, _a_), _α_, _β_)) \n", - "   __if__ _v_ ≤ _α_ __then return__ _v_ \n", - "   _β_ ← MIN(_β_, _v_) \n", - " __return__ _v_ \n", - "\n", - "\n", - "---\n", - "__Figure__ ?? The alpha\\-beta search algorithm. Notice that these routines are the same as the MINIMAX functions in Figure ??, except for the two lines in each of MIN\\-VALUE and MAX\\-VALUE that maintain _α_ and _β_ (and the bookkeeping to pass these parameters along)." - ], - "text/plain": [ - "" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pseudocode(\"Alpha-Beta-Search\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Implementation\n", - "\n", - "Like *minimax*, we again make use of functions `max_value` and `min_value`, but this time we utilise the *a* and *b* values, updating them and stopping the recursive call if we end up on nodes with values worse than *a* and *b* (for MAX and MIN). The algorithm finds the maximum value and returns the move that results in it.\n", - "\n", - "The implementation:" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "%psource alphabeta_search" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Example\n", - "\n", - "We will play the Fig52 Game with the *alpha-beta* search algorithm. It is the turn of MAX to play at state A." - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "a1\n" - ] - } - ], - "source": [ - "print(alphabeta_search('A', fig52))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The optimal move for MAX is a1, for the reasons given above. MIN will pick move b1 for B resulting in a value of 3, updating the *a* value of MAX to 3. Then, when we find under C a node of value 2, we will stop searching under that sub-tree since it is less than *a*. From D we have a value of 2. So, the best move for MAX is the one resulting in a value of 3, which is a1.\n", - "\n", - "Below we see the best moves for MIN starting from B, C and D respectively. Note that the algorithm in these cases works the same way as *minimax*, since all the nodes below the aforementioned states are terminal." - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "b1\n", - "c1\n", - "d3\n" - ] - } - ], - "source": [ - "print(alphabeta_search('B', fig52))\n", - "print(alphabeta_search('C', fig52))\n", - "print(alphabeta_search('D', fig52))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Visualization\n", - "\n", - "Below you will find the visualization of the alpha-beta algorithm for a simple game. Click on the cell after you run the command to move the game along. You can input your own values via a list of 27 integers." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "from notebook import Canvas_alphabeta\n", - "from random import randint" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "alphabeta_viz = Canvas_alphabeta('alphabeta_viz', [randint(1, 50) for i in range(27)])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# PLAYERS\n", - "\n", - "So, we have finished the implementation of the `TicTacToe` and `Fig52Game` classes. What these classes do is defining the rules of the games. We need more to create an AI that can actually play games. This is where `random_player` and `alphabeta_player` come in.\n", - "\n", - "## query_player\n", - "The `query_player` function allows you, a human opponent, to play the game. This function requires a `display` method to be implemented in your game class, so that successive game states can be displayed on the terminal, making it easier for you to visualize the game and play accordingly.\n", - "\n", - "## random_player\n", - "The `random_player` is a function that plays random moves in the game. That's it. There isn't much more to this guy. \n", - "\n", - "## alphabeta_player\n", - "The `alphabeta_player`, on the other hand, calls the `alphabeta_search` function, which returns the best move in the current game state. Thus, the `alphabeta_player` always plays the best move given a game state, assuming that the game tree is small enough to search entirely.\n", - "\n", - "## minimax_player\n", - "The `minimax_player`, on the other hand calls the `minimax_search` function which returns the best move in the current game state.\n", - "\n", - "## play_game\n", - "The `play_game` function will be the one that will actually be used to play the game. You pass as arguments to it an instance of the game you want to play and the players you want in this game. Use it to play AI vs AI, AI vs human, or even human vs human matches!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# LET'S PLAY SOME GAMES!\n", - "\n", - "## Game52\n", - "\n", - "Let's start by experimenting with the `Fig52Game` first. For that we'll create an instance of the subclass Fig52Game inherited from the class Game:" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "game52 = Fig52Game()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "First we try out our `random_player(game, state)`. Given a game state it will give us a random move every time:" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "a1\n", - "a3\n" - ] - } - ], - "source": [ - "print(random_player(game52, 'A'))\n", - "print(random_player(game52, 'A'))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The `alphabeta_player(game, state)` will always give us the best move possible, for the relevant player (MAX or MIN):" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "a1\n", - "b1\n", - "c1\n" - ] - } - ], - "source": [ - "print( alphabeta_player(game52, 'A') )\n", - "print( alphabeta_player(game52, 'B') )\n", - "print( alphabeta_player(game52, 'C') )" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "What the `alphabeta_player` does is, it simply calls the method `alphabeta_full_search`. They both are essentially the same. In the module, both `alphabeta_full_search` and `minimax_decision` have been implemented. They both do the same job and return the same thing, which is, the best move in the current state. It's just that `alphabeta_full_search` is more efficient with regards to time because it prunes the search tree and hence, explores lesser number of states." - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'a1'" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "minimax_decision('A', game52)" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'a1'" - ] - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "alphabeta_search('A', game52)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Demonstrating the play_game function on the game52:" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "B1\n" - ] - }, - { - "data": { - "text/plain": [ - "3" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "game52.play_game(alphabeta_player, alphabeta_player)" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "B2\n" - ] - }, - { - "data": { - "text/plain": [ - "12" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "game52.play_game(alphabeta_player, random_player)" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "current state:\n", - "A\n", - "available moves: ['a1', 'a2', 'a3']\n", - "\n", - "Your move? a1\n", - "B1\n" - ] - }, - { - "data": { - "text/plain": [ - "3" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "game52.play_game(query_player, alphabeta_player)" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "current state:\n", - "B\n", - "available moves: ['b1', 'b2', 'b3']\n", - "\n", - "Your move? b1\n", - "B1\n" - ] - }, - { - "data": { - "text/plain": [ - "3" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "game52.play_game(alphabeta_player, query_player)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note that if you are the first player then alphabeta_player plays as MIN, and if you are the second player then alphabeta_player plays as MAX. This happens because that's the way the game is defined in the class Fig52Game. Having a look at the code of this class should make it clear." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## TicTacToe\n", - "\n", - "Now let's play `TicTacToe`. First we initialize the game by creating an instance of the subclass TicTacToe inherited from the class Game:" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "ttt = TicTacToe()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can print a state using the display method:" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - ". . . \n", - ". . . \n", - ". . . \n" - ] - } - ], - "source": [ - "ttt.display(ttt.initial)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Hmm, so that's the initial state of the game; no X's and no O's.\n", - "\n", - "Let us create a new game state by ourselves to experiment:" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "my_state = GameState(\n", - " to_move = 'X',\n", - " utility = '0',\n", - " board = {(1,1): 'X', (1,2): 'O', (1,3): 'X',\n", - " (2,1): 'O', (2,3): 'O',\n", - " (3,1): 'X',\n", - " },\n", - " moves = [(2,2), (3,2), (3,3)]\n", - " )" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "So, how does this game state look like?" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "X O X \n", - "O . O \n", - "X . . \n" - ] - } - ], - "source": [ - "ttt.display(my_state)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The `random_player` will behave how he is supposed to i.e. *pseudo-randomly*:" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(2, 2)" - ] - }, - "execution_count": 40, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "random_player(ttt, my_state)" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(2, 2)" - ] - }, - "execution_count": 41, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "random_player(ttt, my_state)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "But the `alphabeta_player` will always give the best move, as expected:" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(2, 2)" - ] - }, - "execution_count": 42, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "alphabeta_player(ttt, my_state)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now let's make two players play against each other. We use the `play_game` function for this. The `play_game` function makes players play the match against each other and returns the utility for the first player, of the terminal state reached when the game ends. Hence, for our `TicTacToe` game, if we get the output +1, the first player wins, -1 if the second player wins, and 0 if the match ends in a draw." - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "O O . \n", - "X O X \n", - "X X O \n" - ] - }, - { - "data": { - "text/plain": [ - "-1" - ] - }, - "execution_count": 43, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ttt.play_game(random_player, alphabeta_player)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The output is (usually) -1, because `random_player` loses to `alphabeta_player`. Sometimes, however, `random_player` manages to draw with `alphabeta_player`.\n", - "\n", - "Since an `alphabeta_player` plays perfectly, a match between two `alphabeta_player`s should always end in a draw. Let's see if this happens:" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "X X O \n", - "O O X \n", - "X O X \n", - "0\n", - "X X O \n", - "O O X \n", - "X O X \n", - "0\n", - "X X O \n", - "O O X \n", - "X O X \n", - "0\n", - "X X O \n", - "O O X \n", - "X O X \n", - "0\n", - "X X O \n", - "O O X \n", - "X O X \n", - "0\n", - "X X O \n", - "O O X \n", - "X O X \n", - "0\n", - "X X O \n", - "O O X \n", - "X O X \n", - "0\n", - "X X O \n", - "O O X \n", - "X O X \n", - "0\n", - "X X O \n", - "O O X \n", - "X O X \n", - "0\n", - "X X O \n", - "O O X \n", - "X O X \n", - "0\n" - ] - } - ], - "source": [ - "for _ in range(10):\n", - " print(ttt.play_game(alphabeta_player, alphabeta_player))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A `random_player` should never win against an `alphabeta_player`. Let's test that." - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "X O O \n", - "X O . \n", - "O X X \n", - "-1\n", - "O X . \n", - "O X X \n", - "O . . \n", - "-1\n", - "X X O \n", - "O O X \n", - "O X . \n", - "-1\n", - "O O O \n", - ". X X \n", - "X . . \n", - "-1\n", - "O O O \n", - ". . X \n", - "X . X \n", - "-1\n", - "O X O \n", - "X O X \n", - "X . O \n", - "-1\n", - "O X X \n", - "O X X \n", - "O O . \n", - "-1\n", - "O O X \n", - "X O X \n", - "X O . \n", - "-1\n", - "O O X \n", - "X O . \n", - "X O X \n", - "-1\n", - "O O X \n", - "X X O \n", - "O X X \n", - "0\n" - ] - } - ], - "source": [ - "for _ in range(10):\n", - " print(ttt.play_game(random_player, alphabeta_player))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Canvas_TicTacToe(Canvas)\n", - "\n", - "This subclass is used to play TicTacToe game interactively in Jupyter notebooks. TicTacToe class is called while initializing this subclass.\n", - "\n", - "Let's have a match between `random_player` and `alphabeta_player`. Click on the board to call players to make a move." - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "from notebook import Canvas_TicTacToe" - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "
\n", - "\n", - "
\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "bot_play = Canvas_TicTacToe('bot_play', 'random', 'alphabeta')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now, let's play a game ourselves against a `random_player`:" - ] - }, - { - "cell_type": "code", - "execution_count": 48, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "
\n", - "\n", - "
\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "rand_play = Canvas_TicTacToe('rand_play', 'human', 'random')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Yay! We (usually) win. But we cannot win against an `alphabeta_player`, however hard we try." - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "
\n", - "\n", - "
\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "ab_play = Canvas_TicTacToe('ab_play', 'human', 'alphabeta')" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "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.8.2-final" - } - }, - "nbformat": 4, - "nbformat_minor": 1 -} \ No newline at end of file diff --git a/games.py b/games.py deleted file mode 100644 index d22b2e640..000000000 --- a/games.py +++ /dev/null @@ -1,590 +0,0 @@ -"""Games or Adversarial Search (Chapter 5)""" - -import copy -import itertools -import random -from collections import namedtuple - -import numpy as np - -from utils import vector_add - -GameState = namedtuple('GameState', 'to_move, utility, board, moves') -StochasticGameState = namedtuple('StochasticGameState', 'to_move, utility, board, moves, chance') - - -# ______________________________________________________________________________ -# MinMax Search - - -def minmax_decision(state, game): - """Given a state in a game, calculate the best move by searching - forward all the way to the terminal states. [Figure 5.3]""" - - player = game.to_move(state) - - def max_value(state): - if game.terminal_test(state): - return game.utility(state, player) - v = -np.inf - for a in game.actions(state): - v = max(v, min_value(game.result(state, a))) - return v - - def min_value(state): - if game.terminal_test(state): - return game.utility(state, player) - v = np.inf - for a in game.actions(state): - v = min(v, max_value(game.result(state, a))) - return v - - # Body of minmax_decision: - return max(game.actions(state), key=lambda a: min_value(game.result(state, a))) - - -# ______________________________________________________________________________ - - -def expect_minmax(state, game): - """ - [Figure 5.11] - Return the best move for a player after dice are thrown. The game tree - includes chance nodes along with min and max nodes. - """ - player = game.to_move(state) - - def max_value(state): - v = -np.inf - for a in game.actions(state): - v = max(v, chance_node(state, a)) - return v - - def min_value(state): - v = np.inf - for a in game.actions(state): - v = min(v, chance_node(state, a)) - return v - - def chance_node(state, action): - res_state = game.result(state, action) - if game.terminal_test(res_state): - return game.utility(res_state, player) - sum_chances = 0 - num_chances = len(game.chances(res_state)) - for chance in game.chances(res_state): - res_state = game.outcome(res_state, chance) - util = 0 - if res_state.to_move == player: - util = max_value(res_state) - else: - util = min_value(res_state) - sum_chances += util * game.probability(chance) - return sum_chances / num_chances - - # Body of expect_minmax: - return max(game.actions(state), key=lambda a: chance_node(state, a), default=None) - - -def alpha_beta_search(state, game): - """Search game to determine best action; use alpha-beta pruning. - As in [Figure 5.7], this version searches all the way to the leaves.""" - - player = game.to_move(state) - - # Functions used by alpha_beta - def max_value(state, alpha, beta): - if game.terminal_test(state): - return game.utility(state, player) - v = -np.inf - for a in game.actions(state): - v = max(v, min_value(game.result(state, a), alpha, beta)) - if v >= beta: - return v - alpha = max(alpha, v) - return v - - def min_value(state, alpha, beta): - if game.terminal_test(state): - return game.utility(state, player) - v = np.inf - for a in game.actions(state): - v = min(v, max_value(game.result(state, a), alpha, beta)) - if v <= alpha: - return v - beta = min(beta, v) - return v - - # Body of alpha_beta_search: - best_score = -np.inf - beta = np.inf - best_action = None - for a in game.actions(state): - v = min_value(game.result(state, a), best_score, beta) - if v > best_score: - best_score = v - best_action = a - return best_action - - -def alpha_beta_cutoff_search(state, game, d=4, cutoff_test=None, eval_fn=None): - """Search game to determine best action; use alpha-beta pruning. - This version cuts off search and uses an evaluation function.""" - - player = game.to_move(state) - - # Functions used by alpha_beta - def max_value(state, alpha, beta, depth): - if cutoff_test(state, depth): - return eval_fn(state) - v = -np.inf - for a in game.actions(state): - v = max(v, min_value(game.result(state, a), alpha, beta, depth + 1)) - if v >= beta: - return v - alpha = max(alpha, v) - return v - - def min_value(state, alpha, beta, depth): - if cutoff_test(state, depth): - return eval_fn(state) - v = np.inf - for a in game.actions(state): - v = min(v, max_value(game.result(state, a), alpha, beta, depth + 1)) - if v <= alpha: - return v - beta = min(beta, v) - return v - - # Body of alpha_beta_cutoff_search starts here: - # The default test cuts off at depth d or at a terminal state - cutoff_test = (cutoff_test or (lambda state, depth: depth > d or game.terminal_test(state))) - eval_fn = eval_fn or (lambda state: game.utility(state, player)) - best_score = -np.inf - beta = np.inf - best_action = None - for a in game.actions(state): - v = min_value(game.result(state, a), best_score, beta, 1) - if v > best_score: - best_score = v - best_action = a - return best_action - - -# ______________________________________________________________________________ -# Players for Games - - -def query_player(game, state): - """Make a move by querying standard input.""" - print("current state:") - game.display(state) - print("available moves: {}".format(game.actions(state))) - print("") - move = None - if game.actions(state): - move_string = input('Your move? ') - try: - move = eval(move_string) - except NameError: - move = move_string - else: - print('no legal moves: passing turn to next player') - return move - - -def random_player(game, state): - """A player that chooses a legal move at random.""" - return random.choice(game.actions(state)) if game.actions(state) else None - - -def alpha_beta_player(game, state): - return alpha_beta_search(state, game) - - -def minmax_player(game,state): - return minmax_decision(state,game) - - -def expect_minmax_player(game, state): - return expect_minmax(state, game) - - -# ______________________________________________________________________________ -# Some Sample Games - - -class Game: - """A game is similar to a problem, but it has a utility for each - state and a terminal test instead of a path cost and a goal - test. To create a game, subclass this class and implement actions, - result, utility, and terminal_test. You may override display and - successors or you can inherit their default methods. You will also - need to set the .initial attribute to the initial state; this can - be done in the constructor.""" - - def actions(self, state): - """Return a list of the allowable moves at this point.""" - raise NotImplementedError - - def result(self, state, move): - """Return the state that results from making a move from a state.""" - raise NotImplementedError - - def utility(self, state, player): - """Return the value of this final state to player.""" - raise NotImplementedError - - def terminal_test(self, state): - """Return True if this is a final state for the game.""" - return not self.actions(state) - - def to_move(self, state): - """Return the player whose move it is in this state.""" - return state.to_move - - def display(self, state): - """Print or otherwise display the state.""" - print(state) - - def __repr__(self): - return '<{}>'.format(self.__class__.__name__) - - def play_game(self, *players): - """Play an n-person, move-alternating game.""" - state = self.initial - while True: - for player in players: - move = player(self, state) - state = self.result(state, move) - if self.terminal_test(state): - self.display(state) - return self.utility(state, self.to_move(self.initial)) - - -class StochasticGame(Game): - """A stochastic game includes uncertain events which influence - the moves of players at each state. To create a stochastic game, subclass - this class and implement chances and outcome along with the other - unimplemented game class methods.""" - - def chances(self, state): - """Return a list of all possible uncertain events at a state.""" - raise NotImplementedError - - def outcome(self, state, chance): - """Return the state which is the outcome of a chance trial.""" - raise NotImplementedError - - def probability(self, chance): - """Return the probability of occurrence of a chance.""" - raise NotImplementedError - - def play_game(self, *players): - """Play an n-person, move-alternating stochastic game.""" - state = self.initial - while True: - for player in players: - chance = random.choice(self.chances(state)) - state = self.outcome(state, chance) - move = player(self, state) - state = self.result(state, move) - if self.terminal_test(state): - self.display(state) - return self.utility(state, self.to_move(self.initial)) - - -class Fig52Game(Game): - """The game represented in [Figure 5.2]. Serves as a simple test case.""" - - succs = dict(A=dict(a1='B', a2='C', a3='D'), - B=dict(b1='B1', b2='B2', b3='B3'), - C=dict(c1='C1', c2='C2', c3='C3'), - D=dict(d1='D1', d2='D2', d3='D3')) - utils = dict(B1=3, B2=12, B3=8, C1=2, C2=4, C3=6, D1=14, D2=5, D3=2) - initial = 'A' - - def actions(self, state): - return list(self.succs.get(state, {}).keys()) - - def result(self, state, move): - return self.succs[state][move] - - def utility(self, state, player): - if player == 'MAX': - return self.utils[state] - else: - return -self.utils[state] - - def terminal_test(self, state): - return state not in ('A', 'B', 'C', 'D') - - def to_move(self, state): - return 'MIN' if state in 'BCD' else 'MAX' - - -class Fig52Extended(Game): - """Similar to Fig52Game but bigger. Useful for visualisation""" - - succs = {i: dict(l=i * 3 + 1, m=i * 3 + 2, r=i * 3 + 3) for i in range(13)} - utils = dict() - - def actions(self, state): - return sorted(list(self.succs.get(state, {}).keys())) - - def result(self, state, move): - return self.succs[state][move] - - def utility(self, state, player): - if player == 'MAX': - return self.utils[state] - else: - return -self.utils[state] - - def terminal_test(self, state): - return state not in range(13) - - def to_move(self, state): - return 'MIN' if state in {1, 2, 3} else 'MAX' - - -class TicTacToe(Game): - """Play TicTacToe on an h x v board, with Max (first player) playing 'X'. - A state has the player to move, a cached utility, a list of moves in - the form of a list of (x, y) positions, and a board, in the form of - a dict of {(x, y): Player} entries, where Player is 'X' or 'O'.""" - - def __init__(self, h=3, v=3, k=3): - self.h = h - self.v = v - self.k = k - moves = [(x, y) for x in range(1, h + 1) - for y in range(1, v + 1)] - self.initial = GameState(to_move='X', utility=0, board={}, moves=moves) - - def actions(self, state): - """Legal moves are any square not yet taken.""" - return state.moves - - def result(self, state, move): - if move not in state.moves: - return state # Illegal move has no effect - board = state.board.copy() - board[move] = state.to_move - moves = list(state.moves) - moves.remove(move) - return GameState(to_move=('O' if state.to_move == 'X' else 'X'), - utility=self.compute_utility(board, move, state.to_move), - board=board, moves=moves) - - def utility(self, state, player): - """Return the value to player; 1 for win, -1 for loss, 0 otherwise.""" - return state.utility if player == 'X' else -state.utility - - def terminal_test(self, state): - """A state is terminal if it is won or there are no empty squares.""" - return state.utility != 0 or len(state.moves) == 0 - - def display(self, state): - board = state.board - for x in range(1, self.h + 1): - for y in range(1, self.v + 1): - print(board.get((x, y), '.'), end=' ') - print() - - def compute_utility(self, board, move, player): - """If 'X' wins with this move, return 1; if 'O' wins return -1; else return 0.""" - if (self.k_in_row(board, move, player, (0, 1)) or - self.k_in_row(board, move, player, (1, 0)) or - self.k_in_row(board, move, player, (1, -1)) or - self.k_in_row(board, move, player, (1, 1))): - return +1 if player == 'X' else -1 - else: - return 0 - - def k_in_row(self, board, move, player, delta_x_y): - """Return true if there is a line through move on board for player.""" - (delta_x, delta_y) = delta_x_y - x, y = move - n = 0 # n is number of moves in row - while board.get((x, y)) == player: - n += 1 - x, y = x + delta_x, y + delta_y - x, y = move - while board.get((x, y)) == player: - n += 1 - x, y = x - delta_x, y - delta_y - n -= 1 # Because we counted move itself twice - return n >= self.k - - -class ConnectFour(TicTacToe): - """A TicTacToe-like game in which you can only make a move on the bottom - row, or in a square directly above an occupied square. Traditionally - played on a 7x6 board and requiring 4 in a row.""" - - def __init__(self, h=7, v=6, k=4): - TicTacToe.__init__(self, h, v, k) - - def actions(self, state): - return [(x, y) for (x, y) in state.moves - if x == self.h or (x + 1 , y ) in state.board] - -class Gomoku(TicTacToe): - """Also known as Five in a row.""" - - def __init__(self, h=15, v=16, k=5): - TicTacToe.__init__(self, h, v, k) - - -class Backgammon(StochasticGame): - """A two player game where the goal of each player is to move all the - checkers off the board. The moves for each state are determined by - rolling a pair of dice.""" - - def __init__(self): - """Initial state of the game""" - point = {'W': 0, 'B': 0} - board = [point.copy() for index in range(24)] - board[0]['B'] = board[23]['W'] = 2 - board[5]['W'] = board[18]['B'] = 5 - board[7]['W'] = board[16]['B'] = 3 - board[11]['B'] = board[12]['W'] = 5 - self.allow_bear_off = {'W': False, 'B': False} - self.direction = {'W': -1, 'B': 1} - self.initial = StochasticGameState(to_move='W', - utility=0, - board=board, - moves=self.get_all_moves(board, 'W'), chance=None) - - def actions(self, state): - """Return a list of legal moves for a state.""" - player = state.to_move - moves = state.moves - if len(moves) == 1 and len(moves[0]) == 1: - return moves - legal_moves = [] - for move in moves: - board = copy.deepcopy(state.board) - if self.is_legal_move(board, move, state.chance, player): - legal_moves.append(move) - return legal_moves - - def result(self, state, move): - board = copy.deepcopy(state.board) - player = state.to_move - self.move_checker(board, move[0], state.chance[0], player) - if len(move) == 2: - self.move_checker(board, move[1], state.chance[1], player) - to_move = ('W' if player == 'B' else 'B') - return StochasticGameState(to_move=to_move, - utility=self.compute_utility(board, move, player), - board=board, - moves=self.get_all_moves(board, to_move), chance=None) - - def utility(self, state, player): - """Return the value to player; 1 for win, -1 for loss, 0 otherwise.""" - return state.utility if player == 'W' else -state.utility - - def terminal_test(self, state): - """A state is terminal if one player wins.""" - return state.utility != 0 - - def get_all_moves(self, board, player): - """All possible moves for a player i.e. all possible ways of - choosing two checkers of a player from the board for a move - at a given state.""" - all_points = board - taken_points = [index for index, point in enumerate(all_points) - if point[player] > 0] - if self.checkers_at_home(board, player) == 1: - return [(taken_points[0],)] - moves = list(itertools.permutations(taken_points, 2)) - moves = moves + [(index, index) for index, point in enumerate(all_points) - if point[player] >= 2] - return moves - - def display(self, state): - """Display state of the game.""" - board = state.board - player = state.to_move - print("current state : ") - for index, point in enumerate(board): - print("point : ", index, " W : ", point['W'], " B : ", point['B']) - print("to play : ", player) - - def compute_utility(self, board, move, player): - """If 'W' wins with this move, return 1; if 'B' wins return -1; else return 0.""" - util = {'W': 1, 'B': -1} - for idx in range(0, 24): - if board[idx][player] > 0: - return 0 - return util[player] - - def checkers_at_home(self, board, player): - """Return the no. of checkers at home for a player.""" - sum_range = range(0, 7) if player == 'W' else range(17, 24) - count = 0 - for idx in sum_range: - count = count + board[idx][player] - return count - - def is_legal_move(self, board, start, steps, player): - """Move is a tuple which contains starting points of checkers to be - moved during a player's turn. An on-board move is legal if both the destinations - are open. A bear-off move is the one where a checker is moved off-board. - It is legal only after a player has moved all his checkers to his home.""" - dest1, dest2 = vector_add(start, steps) - dest_range = range(0, 24) - move1_legal = move2_legal = False - if dest1 in dest_range: - if self.is_point_open(player, board[dest1]): - self.move_checker(board, start[0], steps[0], player) - move1_legal = True - else: - if self.allow_bear_off[player]: - self.move_checker(board, start[0], steps[0], player) - move1_legal = True - if not move1_legal: - return False - if dest2 in dest_range: - if self.is_point_open(player, board[dest2]): - move2_legal = True - else: - if self.allow_bear_off[player]: - move2_legal = True - return move1_legal and move2_legal - - def move_checker(self, board, start, steps, player): - """Move a checker from starting point by a given number of steps""" - dest = start + steps - dest_range = range(0, 24) - board[start][player] -= 1 - if dest in dest_range: - board[dest][player] += 1 - if self.checkers_at_home(board, player) == 15: - self.allow_bear_off[player] = True - - def is_point_open(self, player, point): - """A point is open for a player if the no. of opponent's - checkers already present on it is 0 or 1. A player can - move a checker to a point only if it is open.""" - opponent = 'B' if player == 'W' else 'W' - return point[opponent] <= 1 - - def chances(self, state): - """Return a list of all possible dice rolls at a state.""" - dice_rolls = list(itertools.combinations_with_replacement([1, 2, 3, 4, 5, 6], 2)) - return dice_rolls - - def outcome(self, state, chance): - """Return the state which is the outcome of a dice roll.""" - dice = tuple(map((self.direction[state.to_move]).__mul__, chance)) - return StochasticGameState(to_move=state.to_move, - utility=state.utility, - board=state.board, - moves=state.moves, chance=dice) - - def probability(self, chance): - """Return the probability of occurrence of a dice roll.""" - return 1 / 36 if chance[0] == chance[1] else 1 / 18 diff --git a/games4e.ipynb b/games4e.ipynb deleted file mode 100644 index 5b619f7ed..000000000 --- a/games4e.ipynb +++ /dev/null @@ -1,1667 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Game Tree Search\n", - "\n", - "We start with defining the abstract class `Game`, for turn-taking *n*-player games. We rely on, but do not define yet, the concept of a `state` of the game; we'll see later how individual games define states. For now, all we require is that a state has a `state.to_move` attribute, which gives the name of the player whose turn it is. (\"Name\" will be something like `'X'` or `'O'` for tic-tac-toe.) \n", - "\n", - "We also define `play_game`, which takes a game and a dictionary of `{player_name: strategy_function}` pairs, and plays out the game, on each turn checking `state.to_move` to see whose turn it is, and then getting the strategy function for that player and applying it to the game and the state to get a move." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "from collections import namedtuple, Counter, defaultdict\n", - "import random\n", - "import math\n", - "import functools \n", - "cache = functools.lru_cache(10**6)" - ] - }, - { - "cell_type": "code", - "execution_count": 73, - "metadata": {}, - "outputs": [], - "source": [ - "class Game:\n", - " \"\"\"A game is similar to a problem, but it has a terminal test instead of \n", - " a goal test, and a utility for each terminal state. To create a game, \n", - " subclass this class and implement `actions`, `result`, `is_terminal`, \n", - " and `utility`. You will also need to set the .initial attribute to the \n", - " initial state; this can be done in the constructor.\"\"\"\n", - "\n", - " def actions(self, state):\n", - " \"\"\"Return a collection of the allowable moves from this state.\"\"\"\n", - " raise NotImplementedError\n", - "\n", - " def result(self, state, move):\n", - " \"\"\"Return the state that results from making a move from a state.\"\"\"\n", - " raise NotImplementedError\n", - "\n", - " def is_terminal(self, state):\n", - " \"\"\"Return True if this is a final state for the game.\"\"\"\n", - " return not self.actions(state)\n", - " \n", - " def utility(self, state, player):\n", - " \"\"\"Return the value of this final state to player.\"\"\"\n", - " raise NotImplementedError\n", - " \n", - "\n", - "def play_game(game, strategies: dict, verbose=False):\n", - " \"\"\"Play a turn-taking game. `strategies` is a {player_name: function} dict,\n", - " where function(state, game) is used to get the player's move.\"\"\"\n", - " state = game.initial\n", - " while not game.is_terminal(state):\n", - " player = state.to_move\n", - " move = strategies[player](game, state)\n", - " state = game.result(state, move)\n", - " if verbose: \n", - " print('Player', player, 'move:', move)\n", - " print(state)\n", - " return state" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Minimax-Based Game Search Algorithms\n", - "\n", - "We will define several game search algorithms. Each takes two inputs, the game we are playing and the current state of the game, and returns a a `(value, move)` pair, where `value` is the utility that the algorithm computes for the player whose turn it is to move, and `move` is the move itself.\n", - "\n", - "First we define `minimax_search`, which exhaustively searches the game tree to find an optimal move (assuming both players play optimally), and `alphabeta_search`, which does the same computation, but prunes parts of the tree that could not possibly have an affect on the optimnal move. " - ] - }, - { - "cell_type": "code", - "execution_count": 66, - "metadata": {}, - "outputs": [], - "source": [ - "def minimax_search(game, state):\n", - " \"\"\"Search game tree to determine best move; return (value, move) pair.\"\"\"\n", - "\n", - " player = state.to_move\n", - "\n", - " def max_value(state):\n", - " if game.is_terminal(state):\n", - " return game.utility(state, player), None\n", - " v, move = -infinity, None\n", - " for a in game.actions(state):\n", - " v2, _ = min_value(game.result(state, a))\n", - " if v2 > v:\n", - " v, move = v2, a\n", - " return v, move\n", - "\n", - " def min_value(state):\n", - " if game.is_terminal(state):\n", - " return game.utility(state, player), None\n", - " v, move = +infinity, None\n", - " for a in game.actions(state):\n", - " v2, _ = max_value(game.result(state, a))\n", - " if v2 < v:\n", - " v, move = v2, a\n", - " return v, move\n", - "\n", - " return max_value(state)\n", - "\n", - "infinity = math.inf\n", - "\n", - "def alphabeta_search(game, state):\n", - " \"\"\"Search game to determine best action; use alpha-beta pruning.\n", - " As in [Figure 5.7], this version searches all the way to the leaves.\"\"\"\n", - "\n", - " player = state.to_move\n", - "\n", - " def max_value(state, alpha, beta):\n", - " if game.is_terminal(state):\n", - " return game.utility(state, player), None\n", - " v, move = -infinity, None\n", - " for a in game.actions(state):\n", - " v2, _ = min_value(game.result(state, a), alpha, beta)\n", - " if v2 > v:\n", - " v, move = v2, a\n", - " alpha = max(alpha, v)\n", - " if v >= beta:\n", - " return v, move\n", - " return v, move\n", - "\n", - " def min_value(state, alpha, beta):\n", - " if game.is_terminal(state):\n", - " return game.utility(state, player), None\n", - " v, move = +infinity, None\n", - " for a in game.actions(state):\n", - " v2, _ = max_value(game.result(state, a), alpha, beta)\n", - " if v2 < v:\n", - " v, move = v2, a\n", - " beta = min(beta, v)\n", - " if v <= alpha:\n", - " return v, move\n", - " return v, move\n", - "\n", - " return max_value(state, -infinity, +infinity)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# A Simple Game: Tic-Tac-Toe\n", - "\n", - "We have the notion of an abstract game, we have some search functions; now it is time to define a real game; a simple one, tic-tac-toe. Moves are `(x, y)` pairs denoting squares, where `(0, 0)` is the top left, and `(2, 2)` is the bottom right (on a board of size `height=width=3`)." - ] - }, - { - "cell_type": "code", - "execution_count": 67, - "metadata": {}, - "outputs": [], - "source": [ - "class TicTacToe(Game):\n", - " \"\"\"Play TicTacToe on an `height` by `width` board, needing `k` in a row to win.\n", - " 'X' plays first against 'O'.\"\"\"\n", - "\n", - " def __init__(self, height=3, width=3, k=3):\n", - " self.k = k # k in a row\n", - " self.squares = {(x, y) for x in range(width) for y in range(height)}\n", - " self.initial = Board(height=height, width=width, to_move='X', utility=0)\n", - "\n", - " def actions(self, board):\n", - " \"\"\"Legal moves are any square not yet taken.\"\"\"\n", - " return self.squares - set(board)\n", - "\n", - " def result(self, board, square):\n", - " \"\"\"Place a marker for current player on square.\"\"\"\n", - " player = board.to_move\n", - " board = board.new({square: player}, to_move=('O' if player == 'X' else 'X'))\n", - " win = k_in_row(board, player, square, self.k)\n", - " board.utility = (0 if not win else +1 if player == 'X' else -1)\n", - " return board\n", - "\n", - " def utility(self, board, player):\n", - " \"\"\"Return the value to player; 1 for win, -1 for loss, 0 otherwise.\"\"\"\n", - " return board.utility if player == 'X' else -board.utility\n", - "\n", - " def is_terminal(self, board):\n", - " \"\"\"A board is a terminal state if it is won or there are no empty squares.\"\"\"\n", - " return board.utility != 0 or len(self.squares) == len(board)\n", - "\n", - " def display(self, board): print(board) \n", - "\n", - "\n", - "def k_in_row(board, player, square, k):\n", - " \"\"\"True if player has k pieces in a line through square.\"\"\"\n", - " def in_row(x, y, dx, dy): return 0 if board[x, y] != player else 1 + in_row(x + dx, y + dy, dx, dy)\n", - " return any(in_row(*square, dx, dy) + in_row(*square, -dx, -dy) - 1 >= k\n", - " for (dx, dy) in ((0, 1), (1, 0), (1, 1), (1, -1)))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "States in tic-tac-toe (and other games) will be represented as a `Board`, which is a subclass of `defaultdict` that in general will consist of `{(x, y): contents}` pairs, for example `{(0, 0): 'X', (1, 1): 'O'}` might be the state of the board after two moves. Besides the contents of squares, a board also has some attributes: \n", - "- `.to_move` to name the player whose move it is; \n", - "- `.width` and `.height` to give the size of the board (both 3 in tic-tac-toe, but other numbers in related games);\n", - "- possibly other attributes, as specified by keywords. \n", - "\n", - "As a `defaultdict`, the `Board` class has a `__missing__` method, which returns `empty` for squares that have no been assigned but are within the `width` × `height` boundaries, or `off` otherwise. The class has a `__hash__` method, so instances can be stored in hash tables." - ] - }, - { - "cell_type": "code", - "execution_count": 68, - "metadata": {}, - "outputs": [], - "source": [ - "class Board(defaultdict):\n", - " \"\"\"A board has the player to move, a cached utility value, \n", - " and a dict of {(x, y): player} entries, where player is 'X' or 'O'.\"\"\"\n", - " empty = '.'\n", - " off = '#'\n", - " \n", - " def __init__(self, width=8, height=8, to_move=None, **kwds):\n", - " self.__dict__.update(width=width, height=height, to_move=to_move, **kwds)\n", - " \n", - " def new(self, changes: dict, **kwds) -> 'Board':\n", - " \"Given a dict of {(x, y): contents} changes, return a new Board with the changes.\"\n", - " board = Board(width=self.width, height=self.height, **kwds)\n", - " board.update(self)\n", - " board.update(changes)\n", - " return board\n", - "\n", - " def __missing__(self, loc):\n", - " x, y = loc\n", - " if 0 <= x < self.width and 0 <= y < self.height:\n", - " return self.empty\n", - " else:\n", - " return self.off\n", - " \n", - " def __hash__(self): \n", - " return hash(tuple(sorted(self.items()))) + hash(self.to_move)\n", - " \n", - " def __repr__(self):\n", - " def row(y): return ' '.join(self[x, y] for x in range(self.width))\n", - " return '\\n'.join(map(row, range(self.height))) + '\\n'" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Players\n", - "\n", - "We need an interface for players. I'll represent a player as a `callable` that will be passed two arguments: `(game, state)` and will return a `move`.\n", - "The function `player` creates a player out of a search algorithm, but you can create your own players as functions, as is done with `random_player` below:" - ] - }, - { - "cell_type": "code", - "execution_count": 69, - "metadata": {}, - "outputs": [], - "source": [ - "def random_player(game, state): return random.choice(list(game.actions(state)))\n", - "\n", - "def player(search_algorithm):\n", - " \"\"\"A game player who uses the specified search algorithm\"\"\"\n", - " return lambda game, state: search_algorithm(game, state)[1]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Playing a Game\n", - "\n", - "We're ready to play a game. I'll set up a match between a `random_player` (who chooses randomly from the legal moves) and a `player(alphabeta_search)` (who makes the optimal alpha-beta move; practical for tic-tac-toe, but not for large games). The `player(alphabeta_search)` will never lose, but if `random_player` is lucky, it will be a tie." - ] - }, - { - "cell_type": "code", - "execution_count": 74, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Player X move: (0, 0)\n", - "X . .\n", - ". . .\n", - ". . .\n", - "\n", - "Player O move: (1, 1)\n", - "X . .\n", - ". O .\n", - ". . .\n", - "\n", - "Player X move: (1, 2)\n", - "X . .\n", - ". O .\n", - ". X .\n", - "\n", - "Player O move: (0, 1)\n", - "X . .\n", - "O O .\n", - ". X .\n", - "\n", - "Player X move: (2, 1)\n", - "X . .\n", - "O O X\n", - ". X .\n", - "\n", - "Player O move: (2, 0)\n", - "X . O\n", - "O O X\n", - ". X .\n", - "\n", - "Player X move: (2, 2)\n", - "X . O\n", - "O O X\n", - ". X X\n", - "\n", - "Player O move: (0, 2)\n", - "X . O\n", - "O O X\n", - "O X X\n", - "\n" - ] - }, - { - "data": { - "text/plain": [ - "-1" - ] - }, - "execution_count": 74, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "play_game(TicTacToe(), dict(X=random_player, O=player(alphabeta_search)), verbose=True).utility" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The alpha-beta player will never lose, but sometimes the random player can stumble into a draw. When two optimal (alpha-beta or minimax) players compete, it will always be a draw:" - ] - }, - { - "cell_type": "code", - "execution_count": 75, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Player X move: (0, 1)\n", - ". . .\n", - "X . .\n", - ". . .\n", - "\n", - "Player O move: (0, 0)\n", - "O . .\n", - "X . .\n", - ". . .\n", - "\n", - "Player X move: (2, 0)\n", - "O . X\n", - "X . .\n", - ". . .\n", - "\n", - "Player O move: (2, 1)\n", - "O . X\n", - "X . O\n", - ". . .\n", - "\n", - "Player X move: (1, 2)\n", - "O . X\n", - "X . O\n", - ". X .\n", - "\n", - "Player O move: (0, 2)\n", - "O . X\n", - "X . O\n", - "O X .\n", - "\n", - "Player X move: (1, 0)\n", - "O X X\n", - "X . O\n", - "O X .\n", - "\n", - "Player O move: (1, 1)\n", - "O X X\n", - "X O O\n", - "O X .\n", - "\n", - "Player X move: (2, 2)\n", - "O X X\n", - "X O O\n", - "O X X\n", - "\n" - ] - }, - { - "data": { - "text/plain": [ - "0" - ] - }, - "execution_count": 75, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "play_game(TicTacToe(), dict(X=player(alphabeta_search), O=player(minimax_search)), verbose=True).utility" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Connect Four\n", - "\n", - "Connect Four is a variant of tic-tac-toe, played on a larger (7 x 6) board, and with the restriction that in any column you can only play in the lowest empty square in the column." - ] - }, - { - "cell_type": "code", - "execution_count": 76, - "metadata": {}, - "outputs": [], - "source": [ - "class ConnectFour(TicTacToe):\n", - " \n", - " def __init__(self): super().__init__(width=7, height=6, k=4)\n", - "\n", - " def actions(self, board):\n", - " \"\"\"In each column you can play only the lowest empty square in the column.\"\"\"\n", - " return {(x, y) for (x, y) in self.squares - set(board)\n", - " if y == board.height - 1 or (x, y + 1) in board}" - ] - }, - { - "cell_type": "code", - "execution_count": 77, - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Player X move: (2, 5)\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . X . . . .\n", - "\n", - "Player O move: (1, 5)\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". O X . . . .\n", - "\n", - "Player X move: (5, 5)\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". O X . . X .\n", - "\n", - "Player O move: (4, 5)\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". O X . O X .\n", - "\n", - "Player X move: (4, 4)\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . X . .\n", - ". O X . O X .\n", - "\n", - "Player O move: (2, 4)\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . O . X . .\n", - ". O X . O X .\n", - "\n", - "Player X move: (2, 3)\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . X . . . .\n", - ". . O . X . .\n", - ". O X . O X .\n", - "\n", - "Player O move: (1, 4)\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . X . . . .\n", - ". O O . X . .\n", - ". O X . O X .\n", - "\n", - "Player X move: (0, 5)\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . X . . . .\n", - ". O O . X . .\n", - "X O X . O X .\n", - "\n", - "Player O move: (5, 4)\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . X . . . .\n", - ". O O . X O .\n", - "X O X . O X .\n", - "\n", - "Player X move: (5, 3)\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . X . . X .\n", - ". O O . X O .\n", - "X O X . O X .\n", - "\n", - "Player O move: (6, 5)\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . X . . X .\n", - ". O O . X O .\n", - "X O X . O X O\n", - "\n", - "Player X move: (1, 3)\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". X X . . X .\n", - ". O O . X O .\n", - "X O X . O X O\n", - "\n", - "Player O move: (6, 4)\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". X X . . X .\n", - ". O O . X O O\n", - "X O X . O X O\n", - "\n", - "Player X move: (5, 2)\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . X .\n", - ". X X . . X .\n", - ". O O . X O O\n", - "X O X . O X O\n", - "\n", - "Player O move: (0, 4)\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . X .\n", - ". X X . . X .\n", - "O O O . X O O\n", - "X O X . O X O\n", - "\n", - "Player X move: (0, 3)\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . X .\n", - "X X X . . X .\n", - "O O O . X O O\n", - "X O X . O X O\n", - "\n", - "Player O move: (0, 2)\n", - ". . . . . . .\n", - ". . . . . . .\n", - "O . . . . X .\n", - "X X X . . X .\n", - "O O O . X O O\n", - "X O X . O X O\n", - "\n", - "Player X move: (0, 1)\n", - ". . . . . . .\n", - "X . . . . . .\n", - "O . . . . X .\n", - "X X X . . X .\n", - "O O O . X O O\n", - "X O X . O X O\n", - "\n", - "Player O move: (0, 0)\n", - "O . . . . . .\n", - "X . . . . . .\n", - "O . . . . X .\n", - "X X X . . X .\n", - "O O O . X O O\n", - "X O X . O X O\n", - "\n", - "Player X move: (5, 1)\n", - "O . . . . . .\n", - "X . . . . X .\n", - "O . . . . X .\n", - "X X X . . X .\n", - "O O O . X O O\n", - "X O X . O X O\n", - "\n", - "Player O move: (4, 3)\n", - "O . . . . . .\n", - "X . . . . X .\n", - "O . . . . X .\n", - "X X X . O X .\n", - "O O O . X O O\n", - "X O X . O X O\n", - "\n", - "Player X move: (6, 3)\n", - "O . . . . . .\n", - "X . . . . X .\n", - "O . . . . X .\n", - "X X X . O X X\n", - "O O O . X O O\n", - "X O X . O X O\n", - "\n", - "Player O move: (5, 0)\n", - "O . . . . O .\n", - "X . . . . X .\n", - "O . . . . X .\n", - "X X X . O X X\n", - "O O O . X O O\n", - "X O X . O X O\n", - "\n", - "Player X move: (3, 5)\n", - "O . . . . O .\n", - "X . . . . X .\n", - "O . . . . X .\n", - "X X X . O X X\n", - "O O O . X O O\n", - "X O X X O X O\n", - "\n", - "Player O move: (1, 2)\n", - "O . . . . O .\n", - "X . . . . X .\n", - "O O . . . X .\n", - "X X X . O X X\n", - "O O O . X O O\n", - "X O X X O X O\n", - "\n", - "Player X move: (1, 1)\n", - "O . . . . O .\n", - "X X . . . X .\n", - "O O . . . X .\n", - "X X X . O X X\n", - "O O O . X O O\n", - "X O X X O X O\n", - "\n", - "Player O move: (3, 4)\n", - "O . . . . O .\n", - "X X . . . X .\n", - "O O . . . X .\n", - "X X X . O X X\n", - "O O O O X O O\n", - "X O X X O X O\n", - "\n" - ] - }, - { - "data": { - "text/plain": [ - "-1" - ] - }, - "execution_count": 77, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "play_game(ConnectFour(), dict(X=random_player, O=random_player), verbose=True).utility" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Transposition Tables\n", - "\n", - "By treating the game tree as a tree, we can arrive at the same state through different paths, and end up duplicating effort. In state-space search, we kept a table of `reached` states to prevent this. For game-tree search, we can achieve the same effect by applying the `@cache` decorator to the `min_value` and `max_value` functions. We'll use the suffix `_tt` to indicate a function that uses these transisiton tables." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [], - "source": [ - "def minimax_search_tt(game, state):\n", - " \"\"\"Search game to determine best move; return (value, move) pair.\"\"\"\n", - "\n", - " player = state.to_move\n", - "\n", - " @cache\n", - " def max_value(state):\n", - " if game.is_terminal(state):\n", - " return game.utility(state, player), None\n", - " v, move = -infinity, None\n", - " for a in game.actions(state):\n", - " v2, _ = min_value(game.result(state, a))\n", - " if v2 > v:\n", - " v, move = v2, a\n", - " return v, move\n", - "\n", - " @cache\n", - " def min_value(state):\n", - " if game.is_terminal(state):\n", - " return game.utility(state, player), None\n", - " v, move = +infinity, None\n", - " for a in game.actions(state):\n", - " v2, _ = max_value(game.result(state, a))\n", - " if v2 < v:\n", - " v, move = v2, a\n", - " return v, move\n", - "\n", - " return max_value(state)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For alpha-beta search, we can still use a cache, but it should be based just on the state, not on whatever values alpha and beta have." - ] - }, - { - "cell_type": "code", - "execution_count": 79, - "metadata": {}, - "outputs": [], - "source": [ - "def cache1(function):\n", - " \"Like lru_cache(None), but only considers the first argument of function.\"\n", - " cache = {}\n", - " def wrapped(x, *args):\n", - " if x not in cache:\n", - " cache[x] = function(x, *args)\n", - " return cache[x]\n", - " return wrapped\n", - "\n", - "def alphabeta_search_tt(game, state):\n", - " \"\"\"Search game to determine best action; use alpha-beta pruning.\n", - " As in [Figure 5.7], this version searches all the way to the leaves.\"\"\"\n", - "\n", - " player = state.to_move\n", - "\n", - " @cache1\n", - " def max_value(state, alpha, beta):\n", - " if game.is_terminal(state):\n", - " return game.utility(state, player), None\n", - " v, move = -infinity, None\n", - " for a in game.actions(state):\n", - " v2, _ = min_value(game.result(state, a), alpha, beta)\n", - " if v2 > v:\n", - " v, move = v2, a\n", - " alpha = max(alpha, v)\n", - " if v >= beta:\n", - " return v, move\n", - " return v, move\n", - "\n", - " @cache1\n", - " def min_value(state, alpha, beta):\n", - " if game.is_terminal(state):\n", - " return game.utility(state, player), None\n", - " v, move = +infinity, None\n", - " for a in game.actions(state):\n", - " v2, _ = max_value(game.result(state, a), alpha, beta)\n", - " if v2 < v:\n", - " v, move = v2, a\n", - " beta = min(beta, v)\n", - " if v <= alpha:\n", - " return v, move\n", - " return v, move\n", - "\n", - " return max_value(state, -infinity, +infinity)" - ] - }, - { - "cell_type": "code", - "execution_count": 81, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 593 ms, sys: 52 ms, total: 645 ms\n", - "Wall time: 655 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "O X X\n", - "X O O\n", - "O X X" - ] - }, - "execution_count": 81, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time play_game(TicTacToe(), {'X':player(alphabeta_search_tt), 'O':player(minimax_search_tt)})" - ] - }, - { - "cell_type": "code", - "execution_count": 82, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 3.07 s, sys: 30.7 ms, total: 3.1 s\n", - "Wall time: 3.15 s\n" - ] - }, - { - "data": { - "text/plain": [ - "O X X\n", - "X O O\n", - "O X X" - ] - }, - "execution_count": 82, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time play_game(TicTacToe(), {'X':player(alphabeta_search), 'O':player(minimax_search)})" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Heuristic Cutoffs" - ] - }, - { - "cell_type": "code", - "execution_count": 63, - "metadata": {}, - "outputs": [], - "source": [ - "def cutoff_depth(d):\n", - " \"\"\"A cutoff function that searches to depth d.\"\"\"\n", - " return lambda game, state, depth: depth > d\n", - "\n", - "def h_alphabeta_search(game, state, cutoff=cutoff_depth(6), h=lambda s, p: 0):\n", - " \"\"\"Search game to determine best action; use alpha-beta pruning.\n", - " As in [Figure 5.7], this version searches all the way to the leaves.\"\"\"\n", - "\n", - " player = state.to_move\n", - "\n", - " @cache1\n", - " def max_value(state, alpha, beta, depth):\n", - " if game.is_terminal(state):\n", - " return game.utility(state, player), None\n", - " if cutoff(game, state, depth):\n", - " return h(state, player), None\n", - " v, move = -infinity, None\n", - " for a in game.actions(state):\n", - " v2, _ = min_value(game.result(state, a), alpha, beta, depth+1)\n", - " if v2 > v:\n", - " v, move = v2, a\n", - " alpha = max(alpha, v)\n", - " if v >= beta:\n", - " return v, move\n", - " return v, move\n", - "\n", - " @cache1\n", - " def min_value(state, alpha, beta, depth):\n", - " if game.is_terminal(state):\n", - " return game.utility(state, player), None\n", - " if cutoff(game, state, depth):\n", - " return h(state, player), None\n", - " v, move = +infinity, None\n", - " for a in game.actions(state):\n", - " v2, _ = max_value(game.result(state, a), alpha, beta, depth + 1)\n", - " if v2 < v:\n", - " v, move = v2, a\n", - " beta = min(beta, v)\n", - " if v <= alpha:\n", - " return v, move\n", - " return v, move\n", - "\n", - " return max_value(state, -infinity, +infinity, 0)" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 367 ms, sys: 7.9 ms, total: 375 ms\n", - "Wall time: 375 ms\n" - ] - }, - { - "data": { - "text/plain": [ - "O X X\n", - "X O O\n", - "O X X" - ] - }, - "execution_count": 54, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time play_game(TicTacToe(), {'X':player(h_alphabeta_search), 'O':player(h_alphabeta_search)})" - ] - }, - { - "cell_type": "code", - "execution_count": 60, - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . X .\n", - "\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . X O\n", - "\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . X\n", - ". . . . . X O\n", - "\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . O X\n", - ". . . . . X O\n", - "\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . O X\n", - ". . . . X X O\n", - "\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . O .\n", - ". . . . . O X\n", - ". . . . X X O\n", - "\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . O .\n", - ". . . . X O X\n", - ". . . . X X O\n", - "\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . O .\n", - ". . . . X O X\n", - ". O . . X X O\n", - "\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . O .\n", - ". X . . X O X\n", - ". O . . X X O\n", - "\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . O O\n", - ". X . . X O X\n", - ". O . . X X O\n", - "\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . X O O\n", - ". X . . X O X\n", - ". O . . X X O\n", - "\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . X O O\n", - ". X . . X O X\n", - ". O . O X X O\n", - "\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . X .\n", - ". . . . X O O\n", - ". X . . X O X\n", - ". O . O X X O\n", - "\n", - ". . . . . . .\n", - ". . . . . O .\n", - ". . . . . X .\n", - ". . . . X O O\n", - ". X . . X O X\n", - ". O . O X X O\n", - "\n", - ". . . . . . .\n", - ". . . . . O .\n", - ". . . . . X .\n", - ". X . . X O O\n", - ". X . . X O X\n", - ". O . O X X O\n", - "\n", - ". . . . . . .\n", - ". . . . . O .\n", - ". . . . . X O\n", - ". X . . X O O\n", - ". X . . X O X\n", - ". O . O X X O\n", - "\n", - ". . . . . . .\n", - ". . . . . O .\n", - ". X . . . X O\n", - ". X . . X O O\n", - ". X . . X O X\n", - ". O . O X X O\n", - "\n", - ". . . . . . .\n", - ". . . . . O .\n", - ". X . . . X O\n", - ". X . . X O O\n", - ". X . . X O X\n", - ". O O O X X O\n", - "\n", - ". . . . . . .\n", - ". . . . . O .\n", - ". X . . . X O\n", - ". X . . X O O\n", - ". X . . X O X\n", - "X O O O X X O\n", - "\n", - ". . . . . . .\n", - ". . . . . O O\n", - ". X . . . X O\n", - ". X . . X O O\n", - ". X . . X O X\n", - "X O O O X X O\n", - "\n", - ". . . . . . X\n", - ". . . . . O O\n", - ". X . . . X O\n", - ". X . . X O O\n", - ". X . . X O X\n", - "X O O O X X O\n", - "\n", - ". . . . . . X\n", - ". . . . . O O\n", - ". X . . . X O\n", - ". X . . X O O\n", - "O X . . X O X\n", - "X O O O X X O\n", - "\n", - ". . . . . X X\n", - ". . . . . O O\n", - ". X . . . X O\n", - ". X . . X O O\n", - "O X . . X O X\n", - "X O O O X X O\n", - "\n", - ". . . . . X X\n", - ". . . . . O O\n", - ". X . . . X O\n", - ". X . . X O O\n", - "O X . O X O X\n", - "X O O O X X O\n", - "\n", - ". . . . . X X\n", - ". . . . . O O\n", - ". X . . . X O\n", - ". X . X X O O\n", - "O X . O X O X\n", - "X O O O X X O\n", - "\n", - ". . . . . X X\n", - ". . . . . O O\n", - ". X . . O X O\n", - ". X . X X O O\n", - "O X . O X O X\n", - "X O O O X X O\n", - "\n", - ". . . . . X X\n", - ". . . . . O O\n", - ". X . X O X O\n", - ". X . X X O O\n", - "O X . O X O X\n", - "X O O O X X O\n", - "\n", - ". . . . . X X\n", - ". . . . O O O\n", - ". X . X O X O\n", - ". X . X X O O\n", - "O X . O X O X\n", - "X O O O X X O\n", - "\n", - ". . . . . X X\n", - ". . . X O O O\n", - ". X . X O X O\n", - ". X . X X O O\n", - "O X . O X O X\n", - "X O O O X X O\n", - "\n", - ". . . . O X X\n", - ". . . X O O O\n", - ". X . X O X O\n", - ". X . X X O O\n", - "O X . O X O X\n", - "X O O O X X O\n", - "\n", - ". . . X O X X\n", - ". . . X O O O\n", - ". X . X O X O\n", - ". X . X X O O\n", - "O X . O X O X\n", - "X O O O X X O\n", - "\n", - "CPU times: user 8.82 s, sys: 146 ms, total: 8.96 s\n", - "Wall time: 9.19 s\n" - ] - }, - { - "data": { - "text/plain": [ - "1" - ] - }, - "execution_count": 60, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time play_game(ConnectFour(), {'X':player(h_alphabeta_search), 'O':random_player}, verbose=True).utility" - ] - }, - { - "cell_type": "code", - "execution_count": 61, - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . X .\n", - "\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . O .\n", - ". . . . . X .\n", - "\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . O .\n", - ". . . . X X .\n", - "\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . O .\n", - ". . O . X X .\n", - "\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . X O .\n", - ". . O . X X .\n", - "\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . X O .\n", - ". . O O X X .\n", - "\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . X O .\n", - ". X O O X X .\n", - "\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". O . . X O .\n", - ". X O O X X .\n", - "\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". X . . . . .\n", - ". O . . X O .\n", - ". X O O X X .\n", - "\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". O . . . . .\n", - ". X . . . . .\n", - ". O . . X O .\n", - ". X O O X X .\n", - "\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". O . . . . .\n", - ". X . . . . .\n", - ". O . . X O .\n", - "X X O O X X .\n", - "\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". O . . . . .\n", - ". X . . . . .\n", - "O O . . X O .\n", - "X X O O X X .\n", - "\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". O . . . . .\n", - ". X . . X . .\n", - "O O . . X O .\n", - "X X O O X X .\n", - "\n", - ". . . . . . .\n", - ". . . . . . .\n", - ". O . . O . .\n", - ". X . . X . .\n", - "O O . . X O .\n", - "X X O O X X .\n", - "\n", - ". . . . . . .\n", - ". . . . X . .\n", - ". O . . O . .\n", - ". X . . X . .\n", - "O O . . X O .\n", - "X X O O X X .\n", - "\n", - ". . . . . . .\n", - ". . . . X . .\n", - ". O . . O . .\n", - ". X . . X O .\n", - "O O . . X O .\n", - "X X O O X X .\n", - "\n", - ". . . . . . .\n", - ". . . . X . .\n", - ". O . . O X .\n", - ". X . . X O .\n", - "O O . . X O .\n", - "X X O O X X .\n", - "\n", - ". . . . . . .\n", - ". . . . X . .\n", - ". O . . O X .\n", - ". X . . X O .\n", - "O O O . X O .\n", - "X X O O X X .\n", - "\n", - ". . . . . . .\n", - ". . . . X . .\n", - ". O . . O X .\n", - ". X . . X O .\n", - "O O O X X O .\n", - "X X O O X X .\n", - "\n", - ". . . . . . .\n", - ". . . . X O .\n", - ". O . . O X .\n", - ". X . . X O .\n", - "O O O X X O .\n", - "X X O O X X .\n", - "\n", - ". . . . . . .\n", - ". . . . X O .\n", - ". O . . O X .\n", - ". X . X X O .\n", - "O O O X X O .\n", - "X X O O X X .\n", - "\n", - ". . . . . . .\n", - ". . . . X O .\n", - ". O . O O X .\n", - ". X . X X O .\n", - "O O O X X O .\n", - "X X O O X X .\n", - "\n", - ". . . . . . .\n", - ". . . X X O .\n", - ". O . O O X .\n", - ". X . X X O .\n", - "O O O X X O .\n", - "X X O O X X .\n", - "\n", - ". . . O . . .\n", - ". . . X X O .\n", - ". O . O O X .\n", - ". X . X X O .\n", - "O O O X X O .\n", - "X X O O X X .\n", - "\n", - ". . . O . . .\n", - ". . . X X O .\n", - ". O . O O X .\n", - ". X X X X O .\n", - "O O O X X O .\n", - "X X O O X X .\n", - "\n", - "CPU times: user 12.1 s, sys: 237 ms, total: 12.4 s\n", - "Wall time: 12.9 s\n" - ] - }, - { - "data": { - "text/plain": [ - "1" - ] - }, - "execution_count": 61, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%time play_game(ConnectFour(), {'X':player(h_alphabeta_search), 'O':player(h_alphabeta_search)}, verbose=True).utility" - ] - }, - { - "cell_type": "code", - "execution_count": 83, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Result states: 6,589; Terminal tests: 3,653; for alphabeta_search_tt\n", - "Result states: 25,703; Terminal tests: 25,704; for alphabeta_search\n", - "Result states: 4,687; Terminal tests: 2,805; for h_alphabeta_search\n", - "Result states: 16,167; Terminal tests: 5,478; for minimax_search_tt\n" - ] - } - ], - "source": [ - "class CountCalls:\n", - " \"\"\"Delegate all attribute gets to the object, and count them in ._counts\"\"\"\n", - " def __init__(self, obj):\n", - " self._object = obj\n", - " self._counts = Counter()\n", - " \n", - " def __getattr__(self, attr):\n", - " \"Delegate to the original object, after incrementing a counter.\"\n", - " self._counts[attr] += 1\n", - " return getattr(self._object, attr)\n", - " \n", - "def report(game, searchers):\n", - " for searcher in searchers:\n", - " game = CountCalls(game)\n", - " searcher(game, game.initial)\n", - " print('Result states: {:7,d}; Terminal tests: {:7,d}; for {}'.format(\n", - " game._counts['result'], game._counts['is_terminal'], searcher.__name__))\n", - " \n", - "report(TicTacToe(), (alphabeta_search_tt, alphabeta_search, h_alphabeta_search, minimax_search_tt))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Monte Carlo Tree Search" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "class Node:\n", - " def __init__(self, parent, )\n", - "def mcts(state, game, N=1000):" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Heuristic Search Algorithms" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "t = CountCalls(TicTacToe())\n", - " \n", - "play_game(t, dict(X=minimax_player, O=minimax_player), verbose=True)\n", - "t._counts" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "for tactic in (three, fork, center, opposite_corner, corner, any):\n", - " for s in squares:\n", - " if tactic(board, s,player): return s\n", - " for s ins quares:\n", - " if tactic(board, s, opponent): return s" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "\n", - "def ucb(U, N, C=2**0.5, parentN=100):\n", - " return round(U/N + C * math.sqrt(math.log(parentN)/N), 2)\n", - "\n", - "{C: (ucb(60, 79, C), ucb(1, 10, C), ucb(2, 11, C)) \n", - " for C in (1.4, 1.5)}\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def ucb(U, N, parentN=100, C=2):\n", - " return U/N + C * math.sqrt(math.log(parentN)/N)\n", - "\n", - "\n", - "C = 1.4 \n", - "\n", - "class Node:\n", - " def __init__(self, name, children=(), U=0, N=0, parent=None, p=0.5):\n", - " self.__dict__.update(name=name, U=U, N=N, parent=parent, children=children, p=p)\n", - " for c in children:\n", - " c.parent = self\n", - " \n", - " def __repr__(self):\n", - " return '{}:{}/{}={:.0%}{}'.format(self.name, self.U, self.N, self.U/self.N, self.children)\n", - " \n", - "def select(n):\n", - " if n.children:\n", - " return select(max(n.children, key=ucb))\n", - " else:\n", - " return n\n", - " \n", - "def back(n, amount):\n", - " if n:\n", - " n.N += 1\n", - " n.U += amount\n", - " back(n.parent, 1 - amount)\n", - " \n", - " \n", - "def one(root): \n", - " n = select(root)\n", - " amount = int(random.uniform(0, 1) < n.p)\n", - " back(n, amount)\n", - " \n", - "def ucb(n): \n", - " return (float('inf') if n.N == 0 else\n", - " n.U / n.N + C * math.sqrt(math.log(n.parent.N)/n.N))\n", - "\n", - "\n", - "tree = Node('root', [Node('a', p=.8, children=[Node('a1', p=.05), \n", - " Node('a2', p=.25,\n", - " children=[Node('a2a', p=.7), Node('a2b')])]),\n", - " Node('b', p=.5, children=[Node('b1', p=.6,\n", - " children=[Node('b1a', p=.3), Node('b1b')]), \n", - " Node('b2', p=.4)]),\n", - " Node('c', p=.1)])\n", - "\n", - "for i in range(100):\n", - " one(tree); \n", - "for c in tree.children: print(c)\n", - "'select', select(tree), 'tree', tree\n", - "\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "us = (100, 50, 25, 10, 5, 1)\n", - "infinity = float('inf')\n", - "\n", - "@lru_cache(None)\n", - "def f1(n, denom):\n", - " return (0 if n == 0 else\n", - " infinity if n < 0 or not denom else\n", - " min(1 + f1(n - denom[0], denom),\n", - " f1(n, denom[1:])))\n", - " \n", - "@lru_cache(None)\n", - "def f2(n, denom):\n", - " @lru_cache(None)\n", - " def f(n):\n", - " return (0 if n == 0 else\n", - " infinity if n < 0 else\n", - " 1 + min(f(n - d) for d in denom))\n", - " return f(n)\n", - "\n", - "@lru_cache(None)\n", - "def f3(n, denom):\n", - " return (0 if n == 0 else\n", - " infinity if n < 0 or not denom else\n", - " min(k + f2(n - k * denom[0], denom[1:]) \n", - " for k in range(1 + n // denom[0])))\n", - " \n", - "\n", - "def g(n, d=us): return f1(n, d), f2(n, d), f3(n, d)\n", - " \n", - "n = 12345\n", - "%time f1(n, us)\n", - "%time f2(n, us)\n", - "%time f3(n, us)\n", - " " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "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.7.2" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/games4e.py b/games4e.py deleted file mode 100644 index aba5b0eb3..000000000 --- a/games4e.py +++ /dev/null @@ -1,635 +0,0 @@ -"""Games or Adversarial Search (Chapter 5)""" - -import copy -import itertools -import random -from collections import namedtuple - -import numpy as np - -from utils4e import vector_add, MCT_Node, ucb - -GameState = namedtuple('GameState', 'to_move, utility, board, moves') -StochasticGameState = namedtuple('StochasticGameState', 'to_move, utility, board, moves, chance') - - -# ______________________________________________________________________________ -# MinMax Search - - -def minmax_decision(state, game): - """Given a state in a game, calculate the best move by searching - forward all the way to the terminal states. [Figure 5.3]""" - - player = game.to_move(state) - - def max_value(state): - if game.terminal_test(state): - return game.utility(state, player) - v = -np.inf - for a in game.actions(state): - v = max(v, min_value(game.result(state, a))) - return v - - def min_value(state): - if game.terminal_test(state): - return game.utility(state, player) - v = np.inf - for a in game.actions(state): - v = min(v, max_value(game.result(state, a))) - return v - - # Body of minmax_decision: - return max(game.actions(state), key=lambda a: min_value(game.result(state, a))) - - -# ______________________________________________________________________________ - - -def expect_minmax(state, game): - """ - [Figure 5.11] - Return the best move for a player after dice are thrown. The game tree - includes chance nodes along with min and max nodes. - """ - player = game.to_move(state) - - def max_value(state): - v = -np.inf - for a in game.actions(state): - v = max(v, chance_node(state, a)) - return v - - def min_value(state): - v = np.inf - for a in game.actions(state): - v = min(v, chance_node(state, a)) - return v - - def chance_node(state, action): - res_state = game.result(state, action) - if game.terminal_test(res_state): - return game.utility(res_state, player) - sum_chances = 0 - num_chances = len(game.chances(res_state)) - for chance in game.chances(res_state): - res_state = game.outcome(res_state, chance) - util = 0 - if res_state.to_move == player: - util = max_value(res_state) - else: - util = min_value(res_state) - sum_chances += util * game.probability(chance) - return sum_chances / num_chances - - # Body of expect_min_max: - return max(game.actions(state), key=lambda a: chance_node(state, a), default=None) - - -def alpha_beta_search(state, game): - """Search game to determine best action; use alpha-beta pruning. - As in [Figure 5.7], this version searches all the way to the leaves.""" - - player = game.to_move(state) - - # Functions used by alpha_beta - def max_value(state, alpha, beta): - if game.terminal_test(state): - return game.utility(state, player) - v = -np.inf - for a in game.actions(state): - v = max(v, min_value(game.result(state, a), alpha, beta)) - if v >= beta: - return v - alpha = max(alpha, v) - return v - - def min_value(state, alpha, beta): - if game.terminal_test(state): - return game.utility(state, player) - v = np.inf - for a in game.actions(state): - v = min(v, max_value(game.result(state, a), alpha, beta)) - if v <= alpha: - return v - beta = min(beta, v) - return v - - # Body of alpha_beta_search: - best_score = -np.inf - beta = np.inf - best_action = None - for a in game.actions(state): - v = min_value(game.result(state, a), best_score, beta) - if v > best_score: - best_score = v - best_action = a - return best_action - - -def alpha_beta_cutoff_search(state, game, d=4, cutoff_test=None, eval_fn=None): - """Search game to determine best action; use alpha-beta pruning. - This version cuts off search and uses an evaluation function.""" - - player = game.to_move(state) - - # Functions used by alpha_beta - def max_value(state, alpha, beta, depth): - if cutoff_test(state, depth): - return eval_fn(state) - v = -np.inf - for a in game.actions(state): - v = max(v, min_value(game.result(state, a), alpha, beta, depth + 1)) - if v >= beta: - return v - alpha = max(alpha, v) - return v - - def min_value(state, alpha, beta, depth): - if cutoff_test(state, depth): - return eval_fn(state) - v = np.inf - for a in game.actions(state): - v = min(v, max_value(game.result(state, a), alpha, beta, depth + 1)) - if v <= alpha: - return v - beta = min(beta, v) - return v - - # Body of alpha_beta_cutoff_search starts here: - # The default test cuts off at depth d or at a terminal state - cutoff_test = (cutoff_test or (lambda state, depth: depth > d or game.terminal_test(state))) - eval_fn = eval_fn or (lambda state: game.utility(state, player)) - best_score = -np.inf - beta = np.inf - best_action = None - for a in game.actions(state): - v = min_value(game.result(state, a), best_score, beta, 1) - if v > best_score: - best_score = v - best_action = a - return best_action - - -# ______________________________________________________________________________ -# Monte Carlo Tree Search - - -def monte_carlo_tree_search(state, game, N=1000): - def select(n): - """select a leaf node in the tree""" - if n.children: - return select(max(n.children.keys(), key=ucb)) - else: - return n - - def expand(n): - """expand the leaf node by adding all its children states""" - if not n.children and not game.terminal_test(n.state): - n.children = {MCT_Node(state=game.result(n.state, action), parent=n): action - for action in game.actions(n.state)} - return select(n) - - def simulate(game, state): - """simulate the utility of current state by random picking a step""" - player = game.to_move(state) - while not game.terminal_test(state): - action = random.choice(list(game.actions(state))) - state = game.result(state, action) - v = game.utility(state, player) - return -v - - def backprop(n, utility): - """passing the utility back to all parent nodes""" - if utility > 0: - n.U += utility - # if utility == 0: - # n.U += 0.5 - n.N += 1 - if n.parent: - backprop(n.parent, -utility) - - root = MCT_Node(state=state) - - for _ in range(N): - leaf = select(root) - child = expand(leaf) - result = simulate(game, child.state) - backprop(child, result) - - max_state = max(root.children, key=lambda p: p.N) - - return root.children.get(max_state) - - -# ______________________________________________________________________________ -# Players for Games - - -def query_player(game, state): - """Make a move by querying standard input.""" - print("current state:") - game.display(state) - print("available moves: {}".format(game.actions(state))) - print("") - move = None - if game.actions(state): - move_string = input('Your move? ') - try: - move = eval(move_string) - except NameError: - move = move_string - else: - print('no legal moves: passing turn to next player') - return move - - -def random_player(game, state): - """A player that chooses a legal move at random.""" - return random.choice(game.actions(state)) if game.actions(state) else None - - -def alpha_beta_player(game, state): - return alpha_beta_search(state, game) - - -def expect_min_max_player(game, state): - return expect_minmax(state, game) - - -def mcts_player(game, state): - return monte_carlo_tree_search(state, game) - - -# ______________________________________________________________________________ -# Some Sample Games - - -class Game: - """A game is similar to a problem, but it has a utility for each - state and a terminal test instead of a path cost and a goal - test. To create a game, subclass this class and implement actions, - result, utility, and terminal_test. You may override display and - successors or you can inherit their default methods. You will also - need to set the .initial attribute to the initial state; this can - be done in the constructor.""" - - def actions(self, state): - """Return a list of the allowable moves at this point.""" - raise NotImplementedError - - def result(self, state, move): - """Return the state that results from making a move from a state.""" - raise NotImplementedError - - def utility(self, state, player): - """Return the value of this final state to player.""" - raise NotImplementedError - - def terminal_test(self, state): - """Return True if this is a final state for the game.""" - return not self.actions(state) - - def to_move(self, state): - """Return the player whose move it is in this state.""" - return state.to_move - - def display(self, state): - """Print or otherwise display the state.""" - print(state) - - def __repr__(self): - return '<{}>'.format(self.__class__.__name__) - - def play_game(self, *players): - """Play an n-person, move-alternating game.""" - state = self.initial - while True: - for player in players: - move = player(self, state) - state = self.result(state, move) - if self.terminal_test(state): - self.display(state) - return self.utility(state, self.to_move(self.initial)) - - -class StochasticGame(Game): - """A stochastic game includes uncertain events which influence - the moves of players at each state. To create a stochastic game, subclass - this class and implement chances and outcome along with the other - unimplemented game class methods.""" - - def chances(self, state): - """Return a list of all possible uncertain events at a state.""" - raise NotImplementedError - - def outcome(self, state, chance): - """Return the state which is the outcome of a chance trial.""" - raise NotImplementedError - - def probability(self, chance): - """Return the probability of occurrence of a chance.""" - raise NotImplementedError - - def play_game(self, *players): - """Play an n-person, move-alternating stochastic game.""" - state = self.initial - while True: - for player in players: - chance = random.choice(self.chances(state)) - state = self.outcome(state, chance) - move = player(self, state) - state = self.result(state, move) - if self.terminal_test(state): - self.display(state) - return self.utility(state, self.to_move(self.initial)) - - -class Fig52Game(Game): - """The game represented in [Figure 5.2]. Serves as a simple test case.""" - - succs = dict(A=dict(a1='B', a2='C', a3='D'), - B=dict(b1='B1', b2='B2', b3='B3'), - C=dict(c1='C1', c2='C2', c3='C3'), - D=dict(d1='D1', d2='D2', d3='D3')) - utils = dict(B1=3, B2=12, B3=8, C1=2, C2=4, C3=6, D1=14, D2=5, D3=2) - initial = 'A' - - def actions(self, state): - return list(self.succs.get(state, {}).keys()) - - def result(self, state, move): - return self.succs[state][move] - - def utility(self, state, player): - if player == 'MAX': - return self.utils[state] - else: - return -self.utils[state] - - def terminal_test(self, state): - return state not in ('A', 'B', 'C', 'D') - - def to_move(self, state): - return 'MIN' if state in 'BCD' else 'MAX' - - -class Fig52Extended(Game): - """Similar to Fig52Game but bigger. Useful for visualisation""" - - succs = {i: dict(l=i * 3 + 1, m=i * 3 + 2, r=i * 3 + 3) for i in range(13)} - utils = dict() - - def actions(self, state): - return sorted(list(self.succs.get(state, {}).keys())) - - def result(self, state, move): - return self.succs[state][move] - - def utility(self, state, player): - if player == 'MAX': - return self.utils[state] - else: - return -self.utils[state] - - def terminal_test(self, state): - return state not in range(13) - - def to_move(self, state): - return 'MIN' if state in {1, 2, 3} else 'MAX' - - -class TicTacToe(Game): - """Play TicTacToe on an h x v board, with Max (first player) playing 'X'. - A state has the player to move, a cached utility, a list of moves in - the form of a list of (x, y) positions, and a board, in the form of - a dict of {(x, y): Player} entries, where Player is 'X' or 'O'.""" - - def __init__(self, h=3, v=3, k=3): - self.h = h - self.v = v - self.k = k - moves = [(x, y) for x in range(1, h + 1) - for y in range(1, v + 1)] - self.initial = GameState(to_move='X', utility=0, board={}, moves=moves) - - def actions(self, state): - """Legal moves are any square not yet taken.""" - return state.moves - - def result(self, state, move): - if move not in state.moves: - return state # Illegal move has no effect - board = state.board.copy() - board[move] = state.to_move - moves = list(state.moves) - moves.remove(move) - return GameState(to_move=('O' if state.to_move == 'X' else 'X'), - utility=self.compute_utility(board, move, state.to_move), - board=board, moves=moves) - - def utility(self, state, player): - """Return the value to player; 1 for win, -1 for loss, 0 otherwise.""" - return state.utility if player == 'X' else -state.utility - - def terminal_test(self, state): - """A state is terminal if it is won or there are no empty squares.""" - return state.utility != 0 or len(state.moves) == 0 - - def display(self, state): - board = state.board - for x in range(1, self.h + 1): - for y in range(1, self.v + 1): - print(board.get((x, y), '.'), end=' ') - print() - - def compute_utility(self, board, move, player): - """If 'X' wins with this move, return 1; if 'O' wins return -1; else return 0.""" - if (self.k_in_row(board, move, player, (0, 1)) or - self.k_in_row(board, move, player, (1, 0)) or - self.k_in_row(board, move, player, (1, -1)) or - self.k_in_row(board, move, player, (1, 1))): - return +1 if player == 'X' else -1 - else: - return 0 - - def k_in_row(self, board, move, player, delta_x_y): - """Return true if there is a line through move on board for player.""" - (delta_x, delta_y) = delta_x_y - x, y = move - n = 0 # n is number of moves in row - while board.get((x, y)) == player: - n += 1 - x, y = x + delta_x, y + delta_y - x, y = move - while board.get((x, y)) == player: - n += 1 - x, y = x - delta_x, y - delta_y - n -= 1 # Because we counted move itself twice - return n >= self.k - - -class ConnectFour(TicTacToe): - """A TicTacToe-like game in which you can only make a move on the bottom - row, or in a square directly above an occupied square. Traditionally - played on a 7x6 board and requiring 4 in a row.""" - - def __init__(self, h=7, v=6, k=4): - TicTacToe.__init__(self, h, v, k) - - def actions(self, state): - return [(x, y) for (x, y) in state.moves - if y == 1 or (x, y - 1) in state.board] - - -class Backgammon(StochasticGame): - """A two player game where the goal of each player is to move all the - checkers off the board. The moves for each state are determined by - rolling a pair of dice.""" - - def __init__(self): - """Initial state of the game""" - point = {'W': 0, 'B': 0} - board = [point.copy() for index in range(24)] - board[0]['B'] = board[23]['W'] = 2 - board[5]['W'] = board[18]['B'] = 5 - board[7]['W'] = board[16]['B'] = 3 - board[11]['B'] = board[12]['W'] = 5 - self.allow_bear_off = {'W': False, 'B': False} - self.direction = {'W': -1, 'B': 1} - self.initial = StochasticGameState(to_move='W', - utility=0, - board=board, - moves=self.get_all_moves(board, 'W'), chance=None) - - def actions(self, state): - """Return a list of legal moves for a state.""" - player = state.to_move - moves = state.moves - if len(moves) == 1 and len(moves[0]) == 1: - return moves - legal_moves = [] - for move in moves: - board = copy.deepcopy(state.board) - if self.is_legal_move(board, move, state.chance, player): - legal_moves.append(move) - return legal_moves - - def result(self, state, move): - board = copy.deepcopy(state.board) - player = state.to_move - self.move_checker(board, move[0], state.chance[0], player) - if len(move) == 2: - self.move_checker(board, move[1], state.chance[1], player) - to_move = ('W' if player == 'B' else 'B') - return StochasticGameState(to_move=to_move, - utility=self.compute_utility(board, move, player), - board=board, - moves=self.get_all_moves(board, to_move), chance=None) - - def utility(self, state, player): - """Return the value to player; 1 for win, -1 for loss, 0 otherwise.""" - return state.utility if player == 'W' else -state.utility - - def terminal_test(self, state): - """A state is terminal if one player wins.""" - return state.utility != 0 - - def get_all_moves(self, board, player): - """All possible moves for a player i.e. all possible ways of - choosing two checkers of a player from the board for a move - at a given state.""" - all_points = board - taken_points = [index for index, point in enumerate(all_points) - if point[player] > 0] - if self.checkers_at_home(board, player) == 1: - return [(taken_points[0],)] - moves = list(itertools.permutations(taken_points, 2)) - moves = moves + [(index, index) for index, point in enumerate(all_points) - if point[player] >= 2] - return moves - - def display(self, state): - """Display state of the game.""" - board = state.board - player = state.to_move - print("current state : ") - for index, point in enumerate(board): - print("point : ", index, " W : ", point['W'], " B : ", point['B']) - print("to play : ", player) - - def compute_utility(self, board, move, player): - """If 'W' wins with this move, return 1; if 'B' wins return -1; else return 0.""" - util = {'W': 1, 'B': -1} - for idx in range(0, 24): - if board[idx][player] > 0: - return 0 - return util[player] - - def checkers_at_home(self, board, player): - """Return the no. of checkers at home for a player.""" - sum_range = range(0, 7) if player == 'W' else range(17, 24) - count = 0 - for idx in sum_range: - count = count + board[idx][player] - return count - - def is_legal_move(self, board, start, steps, player): - """Move is a tuple which contains starting points of checkers to be - moved during a player's turn. An on-board move is legal if both the destinations - are open. A bear-off move is the one where a checker is moved off-board. - It is legal only after a player has moved all his checkers to his home.""" - dest1, dest2 = vector_add(start, steps) - dest_range = range(0, 24) - move1_legal = move2_legal = False - if dest1 in dest_range: - if self.is_point_open(player, board[dest1]): - self.move_checker(board, start[0], steps[0], player) - move1_legal = True - else: - if self.allow_bear_off[player]: - self.move_checker(board, start[0], steps[0], player) - move1_legal = True - if not move1_legal: - return False - if dest2 in dest_range: - if self.is_point_open(player, board[dest2]): - move2_legal = True - else: - if self.allow_bear_off[player]: - move2_legal = True - return move1_legal and move2_legal - - def move_checker(self, board, start, steps, player): - """Move a checker from starting point by a given number of steps""" - dest = start + steps - dest_range = range(0, 24) - board[start][player] -= 1 - if dest in dest_range: - board[dest][player] += 1 - if self.checkers_at_home(board, player) == 15: - self.allow_bear_off[player] = True - - def is_point_open(self, player, point): - """A point is open for a player if the no. of opponent's - checkers already present on it is 0 or 1. A player can - move a checker to a point only if it is open.""" - opponent = 'B' if player == 'W' else 'W' - return point[opponent] <= 1 - - def chances(self, state): - """Return a list of all possible dice rolls at a state.""" - dice_rolls = list(itertools.combinations_with_replacement([1, 2, 3, 4, 5, 6], 2)) - return dice_rolls - - def outcome(self, state, chance): - """Return the state which is the outcome of a dice roll.""" - dice = tuple(map((self.direction[state.to_move]).__mul__, chance)) - return StochasticGameState(to_move=state.to_move, - utility=state.utility, - board=state.board, - moves=state.moves, chance=dice) - - def probability(self, chance): - """Return the probability of occurrence of a dice roll.""" - return 1 / 36 if chance[0] == chance[1] else 1 / 18 diff --git a/gui/eight_puzzle.py b/gui/eight_puzzle.py deleted file mode 100644 index 5733228d7..000000000 --- a/gui/eight_puzzle.py +++ /dev/null @@ -1,151 +0,0 @@ -import os.path -import random -import time -from functools import partial -from tkinter import * - -from search import astar_search, EightPuzzle - -sys.path.append(os.path.join(os.path.dirname(__file__), '..')) - -root = Tk() - -state = [1, 2, 3, 4, 5, 6, 7, 8, 0] -puzzle = EightPuzzle(tuple(state)) -solution = None - -b = [None] * 9 - - -# TODO: refactor into OOP, remove global variables - -def scramble(): - """Scrambles the puzzle starting from the goal state""" - - global state - global puzzle - possible_actions = ['UP', 'DOWN', 'LEFT', 'RIGHT'] - scramble = [] - for _ in range(60): - scramble.append(random.choice(possible_actions)) - - for move in scramble: - if move in puzzle.actions(state): - state = list(puzzle.result(state, move)) - puzzle = EightPuzzle(tuple(state)) - create_buttons() - - -def solve(): - """Solves the puzzle using astar_search""" - - return astar_search(puzzle).solution() - - -def solve_steps(): - """Solves the puzzle step by step""" - - global puzzle - global solution - global state - solution = solve() - print(solution) - - for move in solution: - state = puzzle.result(state, move) - create_buttons() - root.update() - root.after(1, time.sleep(0.75)) - - -def exchange(index): - """Interchanges the position of the selected tile with the zero tile under certain conditions""" - - global state - global solution - global puzzle - zero_ix = list(state).index(0) - actions = puzzle.actions(state) - current_action = '' - i_diff = index // 3 - zero_ix // 3 - j_diff = index % 3 - zero_ix % 3 - if i_diff == 1: - current_action += 'DOWN' - elif i_diff == -1: - current_action += 'UP' - - if j_diff == 1: - current_action += 'RIGHT' - elif j_diff == -1: - current_action += 'LEFT' - - if abs(i_diff) + abs(j_diff) != 1: - current_action = '' - - if current_action in actions: - b[zero_ix].grid_forget() - b[zero_ix] = Button(root, text=f'{state[index]}', width=6, font=('Helvetica', 40, 'bold'), - command=partial(exchange, zero_ix)) - b[zero_ix].grid(row=zero_ix // 3, column=zero_ix % 3, ipady=40) - b[index].grid_forget() - b[index] = Button(root, text=None, width=6, font=('Helvetica', 40, 'bold'), command=partial(exchange, index)) - b[index].grid(row=index // 3, column=index % 3, ipady=40) - state[zero_ix], state[index] = state[index], state[zero_ix] - puzzle = EightPuzzle(tuple(state)) - - -def create_buttons(): - """Creates dynamic buttons""" - - # TODO: Find a way to use grid_forget() with a for loop for initialization - b[0] = Button(root, text=f'{state[0]}' if state[0] != 0 else None, width=6, font=('Helvetica', 40, 'bold'), - command=partial(exchange, 0)) - b[0].grid(row=0, column=0, ipady=40) - b[1] = Button(root, text=f'{state[1]}' if state[1] != 0 else None, width=6, font=('Helvetica', 40, 'bold'), - command=partial(exchange, 1)) - b[1].grid(row=0, column=1, ipady=40) - b[2] = Button(root, text=f'{state[2]}' if state[2] != 0 else None, width=6, font=('Helvetica', 40, 'bold'), - command=partial(exchange, 2)) - b[2].grid(row=0, column=2, ipady=40) - b[3] = Button(root, text=f'{state[3]}' if state[3] != 0 else None, width=6, font=('Helvetica', 40, 'bold'), - command=partial(exchange, 3)) - b[3].grid(row=1, column=0, ipady=40) - b[4] = Button(root, text=f'{state[4]}' if state[4] != 0 else None, width=6, font=('Helvetica', 40, 'bold'), - command=partial(exchange, 4)) - b[4].grid(row=1, column=1, ipady=40) - b[5] = Button(root, text=f'{state[5]}' if state[5] != 0 else None, width=6, font=('Helvetica', 40, 'bold'), - command=partial(exchange, 5)) - b[5].grid(row=1, column=2, ipady=40) - b[6] = Button(root, text=f'{state[6]}' if state[6] != 0 else None, width=6, font=('Helvetica', 40, 'bold'), - command=partial(exchange, 6)) - b[6].grid(row=2, column=0, ipady=40) - b[7] = Button(root, text=f'{state[7]}' if state[7] != 0 else None, width=6, font=('Helvetica', 40, 'bold'), - command=partial(exchange, 7)) - b[7].grid(row=2, column=1, ipady=40) - b[8] = Button(root, text=f'{state[8]}' if state[8] != 0 else None, width=6, font=('Helvetica', 40, 'bold'), - command=partial(exchange, 8)) - b[8].grid(row=2, column=2, ipady=40) - - -def create_static_buttons(): - """Creates scramble and solve buttons""" - - scramble_btn = Button(root, text='Scramble', font=('Helvetica', 30, 'bold'), width=8, command=partial(init)) - scramble_btn.grid(row=3, column=0, ipady=10) - solve_btn = Button(root, text='Solve', font=('Helvetica', 30, 'bold'), width=8, command=partial(solve_steps)) - solve_btn.grid(row=3, column=2, ipady=10) - - -def init(): - """Calls necessary functions""" - - global state - global solution - state = [1, 2, 3, 4, 5, 6, 7, 8, 0] - scramble() - create_buttons() - create_static_buttons() - - -init() -root.mainloop() diff --git a/gui/genetic_algorithm_example.py b/gui/genetic_algorithm_example.py deleted file mode 100644 index c987151c8..000000000 --- a/gui/genetic_algorithm_example.py +++ /dev/null @@ -1,189 +0,0 @@ -# A simple program that implements the solution to the phrase generation problem using -# genetic algorithms as given in the search.ipynb notebook. -# -# Type on the home screen to change the target phrase -# Click on the slider to change genetic algorithm parameters -# Click 'GO' to run the algorithm with the specified variables -# Displays best individual of the current generation -# Displays a progress bar that indicates the amount of completion of the algorithm -# Displays the first few individuals of the current generation - -import os.path -from tkinter import * -from tkinter import ttk - -import search - -sys.path.append(os.path.join(os.path.dirname(__file__), '..')) - -LARGE_FONT = ('Verdana', 12) -EXTRA_LARGE_FONT = ('Consolas', 36, 'bold') - -canvas_width = 800 -canvas_height = 600 - -black = '#000000' -white = '#ffffff' -p_blue = '#042533' -lp_blue = '#0c394c' - -# genetic algorithm variables -# feel free to play around with these -target = 'Genetic Algorithm' # the phrase to be generated -max_population = 100 # number of samples in each population -mutation_rate = 0.1 # probability of mutation -f_thres = len(target) # fitness threshold -ngen = 1200 # max number of generations to run the genetic algorithm - -generation = 0 # counter to keep track of generation number - -u_case = [chr(x) for x in range(65, 91)] # list containing all uppercase characters -l_case = [chr(x) for x in range(97, 123)] # list containing all lowercase characters -punctuations1 = [chr(x) for x in range(33, 48)] # lists containing punctuation symbols -punctuations2 = [chr(x) for x in range(58, 65)] -punctuations3 = [chr(x) for x in range(91, 97)] -numerals = [chr(x) for x in range(48, 58)] # list containing numbers - -# extend the gene pool with the required lists and append the space character -gene_pool = [] -gene_pool.extend(u_case) -gene_pool.extend(l_case) -gene_pool.append(' ') - - -# callbacks to update global variables from the slider values -def update_max_population(slider_value): - global max_population - max_population = slider_value - - -def update_mutation_rate(slider_value): - global mutation_rate - mutation_rate = slider_value - - -def update_f_thres(slider_value): - global f_thres - f_thres = slider_value - - -def update_ngen(slider_value): - global ngen - ngen = slider_value - - -# fitness function -def fitness_fn(_list): - fitness = 0 - # create string from list of characters - phrase = ''.join(_list) - # add 1 to fitness value for every matching character - for i in range(len(phrase)): - if target[i] == phrase[i]: - fitness += 1 - return fitness - - -# function to bring a new frame on top -def raise_frame(frame, init=False, update_target=False, target_entry=None, f_thres_slider=None): - frame.tkraise() - global target - if update_target and target_entry is not None: - target = target_entry.get() - f_thres_slider.config(to=len(target)) - if init: - population = search.init_population(max_population, gene_pool, len(target)) - genetic_algorithm_stepwise(population) - - -# defining root and child frames -root = Tk() -f1 = Frame(root) -f2 = Frame(root) - -# pack frames on top of one another -for frame in (f1, f2): - frame.grid(row=0, column=0, sticky='news') - -# Home Screen (f1) widgets -target_entry = Entry(f1, font=('Consolas 46 bold'), exportselection=0, foreground=p_blue, justify=CENTER) -target_entry.insert(0, target) -target_entry.pack(expand=YES, side=TOP, fill=X, padx=50) -target_entry.focus_force() - -max_population_slider = Scale(f1, from_=3, to=1000, orient=HORIZONTAL, label='Max population', - command=lambda value: update_max_population(int(value))) -max_population_slider.set(max_population) -max_population_slider.pack(expand=YES, side=TOP, fill=X, padx=40) - -mutation_rate_slider = Scale(f1, from_=0, to=1, orient=HORIZONTAL, label='Mutation rate', resolution=0.0001, - command=lambda value: update_mutation_rate(float(value))) -mutation_rate_slider.set(mutation_rate) -mutation_rate_slider.pack(expand=YES, side=TOP, fill=X, padx=40) - -f_thres_slider = Scale(f1, from_=0, to=len(target), orient=HORIZONTAL, label='Fitness threshold', - command=lambda value: update_f_thres(int(value))) -f_thres_slider.set(f_thres) -f_thres_slider.pack(expand=YES, side=TOP, fill=X, padx=40) - -ngen_slider = Scale(f1, from_=1, to=5000, orient=HORIZONTAL, label='Max number of generations', - command=lambda value: update_ngen(int(value))) -ngen_slider.set(ngen) -ngen_slider.pack(expand=YES, side=TOP, fill=X, padx=40) - -button = ttk.Button(f1, text='RUN', - command=lambda: raise_frame(f2, init=True, update_target=True, target_entry=target_entry, - f_thres_slider=f_thres_slider)).pack(side=BOTTOM, pady=50) - -# f2 widgets -canvas = Canvas(f2, width=canvas_width, height=canvas_height) -canvas.pack(expand=YES, fill=BOTH, padx=20, pady=15) -button = ttk.Button(f2, text='EXIT', command=lambda: raise_frame(f1)).pack(side=BOTTOM, pady=15) - - -# function to run the genetic algorithm and update text on the canvas -def genetic_algorithm_stepwise(population): - root.title('Genetic Algorithm') - for generation in range(ngen): - # generating new population after selecting, recombining and mutating the existing population - population = [ - search.mutate(search.recombine(*search.select(2, population, fitness_fn)), gene_pool, mutation_rate) for i - in range(len(population))] - # genome with the highest fitness in the current generation - current_best = ''.join(max(population, key=fitness_fn)) - # collecting first few examples from the current population - members = [''.join(x) for x in population][:48] - - # clear the canvas - canvas.delete('all') - # displays current best on top of the screen - canvas.create_text(canvas_width / 2, 40, fill=p_blue, font='Consolas 46 bold', text=current_best) - - # displaying a part of the population on the screen - for i in range(len(members) // 3): - canvas.create_text((canvas_width * .175), (canvas_height * .25 + (25 * i)), fill=lp_blue, - font='Consolas 16', text=members[3 * i]) - canvas.create_text((canvas_width * .500), (canvas_height * .25 + (25 * i)), fill=lp_blue, - font='Consolas 16', text=members[3 * i + 1]) - canvas.create_text((canvas_width * .825), (canvas_height * .25 + (25 * i)), fill=lp_blue, - font='Consolas 16', text=members[3 * i + 2]) - - # displays current generation number - canvas.create_text((canvas_width * .5), (canvas_height * 0.95), fill=p_blue, font='Consolas 18 bold', - text=f'Generation {generation}') - - # displays blue bar that indicates current maximum fitness compared to maximum possible fitness - scaling_factor = fitness_fn(current_best) / len(target) - canvas.create_rectangle(canvas_width * 0.1, 90, canvas_width * 0.9, 100, outline=p_blue) - canvas.create_rectangle(canvas_width * 0.1, 90, canvas_width * 0.1 + scaling_factor * canvas_width * 0.8, 100, - fill=lp_blue) - canvas.update() - - # checks for completion - fittest_individual = search.fitness_threshold(fitness_fn, f_thres, population) - if fittest_individual: - break - - -raise_frame(f1) -root.mainloop() diff --git a/gui/grid_mdp.py b/gui/grid_mdp.py deleted file mode 100644 index e60b49247..000000000 --- a/gui/grid_mdp.py +++ /dev/null @@ -1,676 +0,0 @@ -import os.path -import sys -import tkinter as tk -import tkinter.messagebox -from functools import partial -from tkinter import ttk - -import matplotlib -import matplotlib.animation as animation -from matplotlib import pyplot as plt -from matplotlib import style -from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg -from matplotlib.figure import Figure -from matplotlib.ticker import MaxNLocator - -from mdp import * - -sys.path.append(os.path.join(os.path.dirname(__file__), '..')) - -matplotlib.use('TkAgg') -style.use('ggplot') - -fig = Figure(figsize=(20, 15)) -sub = fig.add_subplot(111) -plt.rcParams['axes.grid'] = False - -WALL_VALUE = -99999.0 -TERM_VALUE = -999999.0 - -black = '#000' -white = '#fff' -gray2 = '#222' -gray9 = '#999' -grayd = '#ddd' -grayef = '#efefef' -pblue = '#000040' -green8 = '#008080' -green4 = '#004040' - -cell_window_mantainer = None - - -def extents(f): - """adjusts axis markers for heatmap""" - - delta = f[1] - f[0] - return [f[0] - delta / 2, f[-1] + delta / 2] - - -def display(gridmdp, _height, _width): - """displays matrix""" - - dialog = tk.Toplevel() - dialog.wm_title('Values') - - container = tk.Frame(dialog) - container.pack(side=tk.TOP, fill=tk.BOTH, expand=True) - - for i in range(max(1, _height)): - for j in range(max(1, _width)): - label = ttk.Label(container, text=f'{gridmdp[_height - i - 1][j]:.3f}', font=('Helvetica', 12)) - label.grid(row=i + 1, column=j + 1, padx=3, pady=3) - - dialog.mainloop() - - -def display_best_policy(_best_policy, _height, _width): - """displays best policy""" - dialog = tk.Toplevel() - dialog.wm_title('Best Policy') - - container = tk.Frame(dialog) - container.pack(side=tk.TOP, fill=tk.BOTH, expand=True) - - for i in range(max(1, _height)): - for j in range(max(1, _width)): - label = ttk.Label(container, text=_best_policy[i][j], font=('Helvetica', 12, 'bold')) - label.grid(row=i + 1, column=j + 1, padx=3, pady=3) - - dialog.mainloop() - - -def initialize_dialogbox(_width, _height, gridmdp, terminals, buttons): - """creates dialogbox for initialization""" - - dialog = tk.Toplevel() - dialog.wm_title('Initialize') - - container = tk.Frame(dialog) - container.pack(side=tk.TOP, fill=tk.BOTH, expand=True) - container.grid_rowconfigure(0, weight=1) - container.grid_columnconfigure(0, weight=1) - - wall = tk.IntVar() - wall.set(0) - term = tk.IntVar() - term.set(0) - reward = tk.DoubleVar() - reward.set(0.0) - - label = ttk.Label(container, text='Initialize', font=('Helvetica', 12), anchor=tk.N) - label.grid(row=0, column=0, columnspan=3, sticky='new', pady=15, padx=5) - label_reward = ttk.Label(container, text='Reward', font=('Helvetica', 10), anchor=tk.N) - label_reward.grid(row=1, column=0, columnspan=3, sticky='new', pady=1, padx=5) - entry_reward = ttk.Entry(container, font=('Helvetica', 10), justify=tk.CENTER, exportselection=0, - textvariable=reward) - entry_reward.grid(row=2, column=0, columnspan=3, sticky='new', pady=5, padx=50) - - rbtn_term = ttk.Radiobutton(container, text='Terminal', variable=term, value=TERM_VALUE) - rbtn_term.grid(row=3, column=0, columnspan=3, sticky='nsew', padx=160, pady=5) - rbtn_wall = ttk.Radiobutton(container, text='Wall', variable=wall, value=WALL_VALUE) - rbtn_wall.grid(row=4, column=0, columnspan=3, sticky='nsew', padx=172, pady=5) - - initialize_widget_disability_checks(_width, _height, gridmdp, terminals, label_reward, entry_reward, rbtn_wall, - rbtn_term) - - btn_apply = ttk.Button(container, text='Apply', - command=partial(initialize_update_table, _width, _height, gridmdp, terminals, buttons, - reward, term, wall, label_reward, entry_reward, rbtn_term, rbtn_wall)) - btn_apply.grid(row=5, column=0, sticky='nsew', pady=5, padx=5) - btn_reset = ttk.Button(container, text='Reset', - command=partial(initialize_reset_all, _width, _height, gridmdp, terminals, buttons, reward, - term, wall, label_reward, entry_reward, rbtn_wall, rbtn_term)) - btn_reset.grid(row=5, column=1, sticky='nsew', pady=5, padx=5) - btn_ok = ttk.Button(container, text='Ok', command=dialog.destroy) - btn_ok.grid(row=5, column=2, sticky='nsew', pady=5, padx=5) - - dialog.geometry('400x200') - dialog.mainloop() - - -def update_table(i, j, gridmdp, terminals, buttons, reward, term, wall, label_reward, entry_reward, rbtn_term, - rbtn_wall): - """functionality for 'apply' button""" - if wall.get() == WALL_VALUE: - buttons[i][j].configure(style='wall.TButton') - buttons[i][j].config(text='Wall') - label_reward.config(foreground='#999') - entry_reward.config(state=tk.DISABLED) - rbtn_term.state(['!focus', '!selected']) - rbtn_term.config(state=tk.DISABLED) - gridmdp[i][j] = WALL_VALUE - - elif wall.get() != WALL_VALUE: - if reward.get() != 0.0: - gridmdp[i][j] = reward.get() - buttons[i][j].configure(style='reward.TButton') - buttons[i][j].config(text=f'R = {reward.get()}') - - if term.get() == TERM_VALUE: - if (i, j) not in terminals: - terminals.append((i, j)) - rbtn_wall.state(['!focus', '!selected']) - rbtn_wall.config(state=tk.DISABLED) - - if gridmdp[i][j] < 0: - buttons[i][j].configure(style='-term.TButton') - - elif gridmdp[i][j] > 0: - buttons[i][j].configure(style='+term.TButton') - - elif gridmdp[i][j] == 0.0: - buttons[i][j].configure(style='=term.TButton') - - -def initialize_update_table(_width, _height, gridmdp, terminals, buttons, reward, term, wall, label_reward, - entry_reward, rbtn_term, rbtn_wall): - """runs update_table for all cells""" - - for i in range(max(1, _height)): - for j in range(max(1, _width)): - update_table(i, j, gridmdp, terminals, buttons, reward, term, wall, label_reward, entry_reward, rbtn_term, - rbtn_wall) - - -def reset_all(_height, i, j, gridmdp, terminals, buttons, reward, term, wall, label_reward, entry_reward, rbtn_wall, - rbtn_term): - """functionality for reset button""" - reward.set(0.0) - term.set(0) - wall.set(0) - gridmdp[i][j] = 0.0 - buttons[i][j].configure(style='TButton') - buttons[i][j].config(text=f'({_height - i - 1}, {j})') - - if (i, j) in terminals: - terminals.remove((i, j)) - - label_reward.config(foreground='#000') - entry_reward.config(state=tk.NORMAL) - rbtn_term.config(state=tk.NORMAL) - rbtn_wall.config(state=tk.NORMAL) - rbtn_wall.state(['!focus', '!selected']) - rbtn_term.state(['!focus', '!selected']) - - -def initialize_reset_all(_width, _height, gridmdp, terminals, buttons, reward, term, wall, label_reward, entry_reward, - rbtn_wall, rbtn_term): - """runs reset_all for all cells""" - - for i in range(max(1, _height)): - for j in range(max(1, _width)): - reset_all(_height, i, j, gridmdp, terminals, buttons, reward, term, wall, label_reward, entry_reward, - rbtn_wall, rbtn_term) - - -def external_reset(_width, _height, gridmdp, terminals, buttons): - """reset from edit menu""" - for i in range(max(1, _height)): - for j in range(max(1, _width)): - gridmdp[i][j] = 0.0 - buttons[i][j].configure(style='TButton') - buttons[i][j].config(text=f'({_height - i - 1}, {j})') - - -def widget_disability_checks(i, j, gridmdp, terminals, label_reward, entry_reward, rbtn_wall, rbtn_term): - """checks for required state of widgets in dialog boxes""" - - if gridmdp[i][j] == WALL_VALUE: - label_reward.config(foreground='#999') - entry_reward.config(state=tk.DISABLED) - rbtn_term.config(state=tk.DISABLED) - rbtn_wall.state(['!focus', 'selected']) - rbtn_term.state(['!focus', '!selected']) - - if (i, j) in terminals: - rbtn_wall.config(state=tk.DISABLED) - rbtn_wall.state(['!focus', '!selected']) - - -def flatten_list(_list): - """returns a flattened list""" - return sum(_list, []) - - -def initialize_widget_disability_checks(_width, _height, gridmdp, terminals, label_reward, entry_reward, rbtn_wall, - rbtn_term): - """checks for required state of widgets when cells are initialized""" - - bool_walls = [['False'] * max(1, _width) for _ in range(max(1, _height))] - bool_terms = [['False'] * max(1, _width) for _ in range(max(1, _height))] - - for i in range(max(1, _height)): - for j in range(max(1, _width)): - if gridmdp[i][j] == WALL_VALUE: - bool_walls[i][j] = 'True' - - if (i, j) in terminals: - bool_terms[i][j] = 'True' - - bool_walls_fl = flatten_list(bool_walls) - bool_terms_fl = flatten_list(bool_terms) - - if bool_walls_fl.count('True') == len(bool_walls_fl): - print('`') - label_reward.config(foreground='#999') - entry_reward.config(state=tk.DISABLED) - rbtn_term.config(state=tk.DISABLED) - rbtn_wall.state(['!focus', 'selected']) - rbtn_term.state(['!focus', '!selected']) - - if bool_terms_fl.count('True') == len(bool_terms_fl): - rbtn_wall.config(state=tk.DISABLED) - rbtn_wall.state(['!focus', '!selected']) - rbtn_term.state(['!focus', 'selected']) - - -def dialogbox(i, j, gridmdp, terminals, buttons, _height): - """creates dialogbox for each cell""" - global cell_window_mantainer - if (cell_window_mantainer != None): - cell_window_mantainer.destroy() - - dialog = tk.Toplevel() - cell_window_mantainer = dialog - dialog.wm_title(f'{_height - i - 1}, {j}') - - container = tk.Frame(dialog) - container.pack(side=tk.TOP, fill=tk.BOTH, expand=True) - container.grid_rowconfigure(0, weight=1) - container.grid_columnconfigure(0, weight=1) - - wall = tk.IntVar() - wall.set(gridmdp[i][j]) - term = tk.IntVar() - term.set(TERM_VALUE if (i, j) in terminals else 0.0) - reward = tk.DoubleVar() - reward.set(gridmdp[i][j] if gridmdp[i][j] != WALL_VALUE else 0.0) - - label = ttk.Label(container, text=f'Configure cell {_height - i - 1}, {j}', font=('Helvetica', 12), anchor=tk.N) - label.grid(row=0, column=0, columnspan=3, sticky='new', pady=15, padx=5) - label_reward = ttk.Label(container, text='Reward', font=('Helvetica', 10), anchor=tk.N) - label_reward.grid(row=1, column=0, columnspan=3, sticky='new', pady=1, padx=5) - entry_reward = ttk.Entry(container, font=('Helvetica', 10), justify=tk.CENTER, exportselection=0, - textvariable=reward) - entry_reward.grid(row=2, column=0, columnspan=3, sticky='new', pady=5, padx=50) - - rbtn_term = ttk.Radiobutton(container, text='Terminal', variable=term, value=TERM_VALUE) - rbtn_term.grid(row=3, column=0, columnspan=3, sticky='nsew', padx=160, pady=5) - rbtn_wall = ttk.Radiobutton(container, text='Wall', variable=wall, value=WALL_VALUE) - rbtn_wall.grid(row=4, column=0, columnspan=3, sticky='nsew', padx=172, pady=5) - - widget_disability_checks(i, j, gridmdp, terminals, label_reward, entry_reward, rbtn_wall, rbtn_term) - - btn_apply = ttk.Button(container, text='Apply', - command=partial(update_table, i, j, gridmdp, terminals, buttons, reward, term, wall, - label_reward, entry_reward, rbtn_term, rbtn_wall)) - btn_apply.grid(row=5, column=0, sticky='nsew', pady=5, padx=5) - btn_reset = ttk.Button(container, text='Reset', - command=partial(reset_all, _height, i, j, gridmdp, terminals, buttons, reward, term, wall, - label_reward, entry_reward, rbtn_wall, rbtn_term)) - btn_reset.grid(row=5, column=1, sticky='nsew', pady=5, padx=5) - btn_ok = ttk.Button(container, text='Ok', command=dialog.destroy) - btn_ok.grid(row=5, column=2, sticky='nsew', pady=5, padx=5) - - dialog.geometry('400x200') - dialog.mainloop() - - -class MDPapp(tk.Tk): - - def __init__(self, *args, **kwargs): - - tk.Tk.__init__(self, *args, **kwargs) - tk.Tk.wm_title(self, 'Grid MDP') - self.shared_data = { - 'height': tk.IntVar(), - 'width': tk.IntVar()} - self.shared_data['height'].set(1) - self.shared_data['width'].set(1) - self.container = tk.Frame(self) - self.container.pack(side='top', fill='both', expand=True) - self.container.grid_rowconfigure(0, weight=1) - self.container.grid_columnconfigure(0, weight=1) - - self.frames = {} - - self.menu_bar = tk.Menu(self.container) - self.file_menu = tk.Menu(self.menu_bar, tearoff=0) - self.file_menu.add_command(label='Exit', command=self.exit) - self.menu_bar.add_cascade(label='File', menu=self.file_menu) - - self.edit_menu = tk.Menu(self.menu_bar, tearoff=1) - self.edit_menu.add_command(label='Reset', command=self.master_reset) - self.edit_menu.add_command(label='Initialize', command=self.initialize) - self.edit_menu.add_separator() - self.edit_menu.add_command(label='View matrix', command=self.view_matrix) - self.edit_menu.add_command(label='View terminals', command=self.view_terminals) - self.menu_bar.add_cascade(label='Edit', menu=self.edit_menu) - self.menu_bar.entryconfig('Edit', state=tk.DISABLED) - - self.build_menu = tk.Menu(self.menu_bar, tearoff=1) - self.build_menu.add_command(label='Build and Run', command=self.build) - self.menu_bar.add_cascade(label='Build', menu=self.build_menu) - self.menu_bar.entryconfig('Build', state=tk.DISABLED) - tk.Tk.config(self, menu=self.menu_bar) - - for F in (HomePage, BuildMDP, SolveMDP): - frame = F(self.container, self) - self.frames[F] = frame - frame.grid(row=0, column=0, sticky='nsew') - - self.show_frame(HomePage) - - def placeholder_function(self): - """placeholder function""" - - print('Not supported yet!') - - def exit(self): - """function to exit""" - if tkinter.messagebox.askokcancel('Exit?', 'All changes will be lost'): - quit() - - def new(self): - """function to create new GridMDP""" - - self.master_reset() - build_page = self.get_page(BuildMDP) - build_page.gridmdp = None - build_page.terminals = None - build_page.buttons = None - self.show_frame(HomePage) - - def get_page(self, page_class): - """returns pages from stored frames""" - return self.frames[page_class] - - def view_matrix(self): - """prints current matrix to console""" - - build_page = self.get_page(BuildMDP) - _height = self.shared_data['height'].get() - _width = self.shared_data['width'].get() - print(build_page.gridmdp) - display(build_page.gridmdp, _height, _width) - - def view_terminals(self): - """prints current terminals to console""" - build_page = self.get_page(BuildMDP) - print('Terminals', build_page.terminals) - - def initialize(self): - """calls initialize from BuildMDP""" - - build_page = self.get_page(BuildMDP) - build_page.initialize() - - def master_reset(self): - """calls master_reset from BuildMDP""" - build_page = self.get_page(BuildMDP) - build_page.master_reset() - - def build(self): - """runs specified mdp solving algorithm""" - - frame = SolveMDP(self.container, self) - self.frames[SolveMDP] = frame - frame.grid(row=0, column=0, sticky='nsew') - self.show_frame(SolveMDP) - build_page = self.get_page(BuildMDP) - gridmdp = build_page.gridmdp - terminals = build_page.terminals - solve_page = self.get_page(SolveMDP) - _height = self.shared_data['height'].get() - _width = self.shared_data['width'].get() - solve_page.create_graph(gridmdp, terminals, _height, _width) - - def show_frame(self, controller, cb=False): - """shows specified frame and optionally runs create_buttons""" - if cb: - build_page = self.get_page(BuildMDP) - build_page.create_buttons() - frame = self.frames[controller] - frame.tkraise() - - -class HomePage(tk.Frame): - - def __init__(self, parent, controller): - """HomePage constructor""" - - tk.Frame.__init__(self, parent) - self.controller = controller - frame1 = tk.Frame(self) - frame1.pack(side=tk.TOP) - frame3 = tk.Frame(self) - frame3.pack(side=tk.TOP) - frame4 = tk.Frame(self) - frame4.pack(side=tk.TOP) - frame2 = tk.Frame(self) - frame2.pack(side=tk.TOP) - - s = ttk.Style() - s.theme_use('clam') - s.configure('TButton', background=grayd, padding=0) - s.configure('wall.TButton', background=gray2, foreground=white) - s.configure('reward.TButton', background=gray9) - s.configure('+term.TButton', background=green8) - s.configure('-term.TButton', background=pblue, foreground=white) - s.configure('=term.TButton', background=green4) - - label = ttk.Label(frame1, text='GridMDP builder', font=('Helvetica', 18, 'bold'), background=grayef) - label.pack(pady=75, padx=50, side=tk.TOP) - - ec_btn = ttk.Button(frame3, text='Empty cells', width=20) - ec_btn.pack(pady=0, padx=0, side=tk.LEFT, ipady=10) - ec_btn.configure(style='TButton') - - w_btn = ttk.Button(frame3, text='Walls', width=20) - w_btn.pack(pady=0, padx=0, side=tk.LEFT, ipady=10) - w_btn.configure(style='wall.TButton') - - r_btn = ttk.Button(frame3, text='Rewards', width=20) - r_btn.pack(pady=0, padx=0, side=tk.LEFT, ipady=10) - r_btn.configure(style='reward.TButton') - - term_p = ttk.Button(frame3, text='Positive terminals', width=20) - term_p.pack(pady=0, padx=0, side=tk.LEFT, ipady=10) - term_p.configure(style='+term.TButton') - - term_z = ttk.Button(frame3, text='Neutral terminals', width=20) - term_z.pack(pady=0, padx=0, side=tk.LEFT, ipady=10) - term_z.configure(style='=term.TButton') - - term_n = ttk.Button(frame3, text='Negative terminals', width=20) - term_n.pack(pady=0, padx=0, side=tk.LEFT, ipady=10) - term_n.configure(style='-term.TButton') - - label = ttk.Label(frame4, text='Dimensions', font=('Verdana', 14), background=grayef) - label.pack(pady=15, padx=10, side=tk.TOP) - entry_h = tk.Entry(frame2, textvariable=self.controller.shared_data['height'], font=('Verdana', 10), width=3, - justify=tk.CENTER) - entry_h.pack(pady=10, padx=10, side=tk.LEFT) - label_x = ttk.Label(frame2, text='X', font=('Verdana', 10), background=grayef) - label_x.pack(pady=10, padx=4, side=tk.LEFT) - entry_w = tk.Entry(frame2, textvariable=self.controller.shared_data['width'], font=('Verdana', 10), width=3, - justify=tk.CENTER) - entry_w.pack(pady=10, padx=10, side=tk.LEFT) - button = ttk.Button(self, text='Build a GridMDP', command=lambda: controller.show_frame(BuildMDP, cb=True)) - button.pack(pady=10, padx=10, side=tk.TOP, ipadx=20, ipady=10) - button.configure(style='reward.TButton') - - -class BuildMDP(tk.Frame): - - def __init__(self, parent, controller): - - tk.Frame.__init__(self, parent) - self.grid_rowconfigure(0, weight=1) - self.grid_columnconfigure(0, weight=1) - self.frame = tk.Frame(self) - self.frame.pack() - self.controller = controller - - def create_buttons(self): - """creates interactive cells to build MDP""" - _height = self.controller.shared_data['height'].get() - _width = self.controller.shared_data['width'].get() - self.controller.menu_bar.entryconfig('Edit', state=tk.NORMAL) - self.controller.menu_bar.entryconfig('Build', state=tk.NORMAL) - self.gridmdp = [[0.0] * max(1, _width) for _ in range(max(1, _height))] - self.buttons = [[None] * max(1, _width) for _ in range(max(1, _height))] - self.terminals = [] - - s = ttk.Style() - s.theme_use('clam') - s.configure('TButton', background=grayd, padding=0) - s.configure('wall.TButton', background=gray2, foreground=white) - s.configure('reward.TButton', background=gray9) - s.configure('+term.TButton', background=green8) - s.configure('-term.TButton', background=pblue, foreground=white) - s.configure('=term.TButton', background=green4) - - for i in range(max(1, _height)): - for j in range(max(1, _width)): - self.buttons[i][j] = ttk.Button(self.frame, text=f'({_height - i - 1}, {j})', - width=int(196 / max(1, _width)), - command=partial(dialogbox, i, j, self.gridmdp, self.terminals, - self.buttons, _height)) - self.buttons[i][j].grid(row=i, column=j, ipady=int(336 / max(1, _height)) - 12) - - def initialize(self): - """runs initialize_dialogbox""" - - _height = self.controller.shared_data['height'].get() - _width = self.controller.shared_data['width'].get() - initialize_dialogbox(_width, _height, self.gridmdp, self.terminals, self.buttons) - - def master_reset(self): - """runs external reset""" - _height = self.controller.shared_data['height'].get() - _width = self.controller.shared_data['width'].get() - if tkinter.messagebox.askokcancel('Reset', 'Are you sure you want to reset all cells?'): - external_reset(_width, _height, self.gridmdp, self.terminals, self.buttons) - - -class SolveMDP(tk.Frame): - - def __init__(self, parent, controller): - - tk.Frame.__init__(self, parent) - self.grid_rowconfigure(0, weight=1) - self.grid_columnconfigure(0, weight=1) - self.frame = tk.Frame(self) - self.frame.pack() - self.controller = controller - self.terminated = False - self.iterations = 0 - self.epsilon = 0.001 - self.delta = 0 - - def process_data(self, terminals, _height, _width, gridmdp): - """preprocess variables""" - - flipped_terminals = [] - - for terminal in terminals: - flipped_terminals.append((terminal[1], _height - terminal[0] - 1)) - - grid_to_solve = [[0.0] * max(1, _width) for _ in range(max(1, _height))] - grid_to_show = [[0.0] * max(1, _width) for _ in range(max(1, _height))] - - for i in range(max(1, _height)): - for j in range(max(1, _width)): - if gridmdp[i][j] == WALL_VALUE: - grid_to_show[i][j] = 0.0 - grid_to_solve[i][j] = None - - else: - grid_to_show[i][j] = grid_to_solve[i][j] = gridmdp[i][j] - - return flipped_terminals, grid_to_solve, np.flipud(grid_to_show) - - def create_graph(self, gridmdp, terminals, _height, _width): - """creates canvas and initializes value_iteration_parameters""" - self._height = _height - self._width = _width - self.controller.menu_bar.entryconfig('Edit', state=tk.DISABLED) - self.controller.menu_bar.entryconfig('Build', state=tk.DISABLED) - - self.terminals, self.gridmdp, self.grid_to_show = self.process_data(terminals, _height, _width, gridmdp) - self.sequential_decision_environment = GridMDP(self.gridmdp, terminals=self.terminals) - - self.initialize_value_iteration_parameters(self.sequential_decision_environment) - - self.canvas = FigureCanvasTkAgg(fig, self.frame) - self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True) - self.anim = animation.FuncAnimation(fig, self.animate_graph, interval=50) - self.canvas.show() - - def animate_graph(self, i): - """performs value iteration and animates graph""" - - # cmaps to use: bone_r, Oranges, inferno, BrBG, copper - self.iterations += 1 - x_interval = max(2, len(self.gridmdp[0])) - y_interval = max(2, len(self.gridmdp)) - x = np.linspace(0, len(self.gridmdp[0]) - 1, x_interval) - y = np.linspace(0, len(self.gridmdp) - 1, y_interval) - - sub.clear() - sub.imshow(self.grid_to_show, cmap='BrBG', aspect='auto', interpolation='none', extent=extents(x) + extents(y), - origin='lower') - fig.tight_layout() - - U = self.U1.copy() - - for s in self.sequential_decision_environment.states: - self.U1[s] = self.R(s) + self.gamma * max( - [sum([p * U[s1] for (p, s1) in self.T(s, a)]) for a in self.sequential_decision_environment.actions(s)]) - self.delta = max(self.delta, abs(self.U1[s] - U[s])) - - self.grid_to_show = grid_to_show = [[0.0] * max(1, self._width) for _ in range(max(1, self._height))] - for k, v in U.items(): - self.grid_to_show[k[1]][k[0]] = v - - if (self.delta < self.epsilon * (1 - self.gamma) / self.gamma) or ( - self.iterations > 60) and self.terminated is False: - self.terminated = True - display(self.grid_to_show, self._height, self._width) - - pi = best_policy(self.sequential_decision_environment, - value_iteration(self.sequential_decision_environment, .01)) - display_best_policy(self.sequential_decision_environment.to_arrows(pi), self._height, self._width) - - ax = fig.gca() - ax.xaxis.set_major_locator(MaxNLocator(integer=True)) - ax.yaxis.set_major_locator(MaxNLocator(integer=True)) - - def initialize_value_iteration_parameters(self, mdp): - """initializes value_iteration parameters""" - self.U1 = {s: 0 for s in mdp.states} - self.R, self.T, self.gamma = mdp.R, mdp.T, mdp.gamma - - def value_iteration_metastep(self, mdp, iterations=20): - """runs value_iteration""" - - U_over_time = [] - U1 = {s: 0 for s in mdp.states} - R, T, gamma = mdp.R, mdp.T, mdp.gamma - - for _ in range(iterations): - U = U1.copy() - - for s in mdp.states: - U1[s] = R(s) + gamma * max([sum([p * U[s1] for (p, s1) in T(s, a)]) for a in mdp.actions(s)]) - - U_over_time.append(U) - return U_over_time - - -if __name__ == '__main__': - app = MDPapp() - app.geometry('1280x720') - app.mainloop() diff --git a/gui/romania_problem.py b/gui/romania_problem.py deleted file mode 100644 index 9ec94099d..000000000 --- a/gui/romania_problem.py +++ /dev/null @@ -1,672 +0,0 @@ -from copy import deepcopy -from tkinter import * - -from search import * -from utils import PriorityQueue - -sys.path.append(os.path.join(os.path.dirname(__file__), '..')) - -root = None -city_coord = {} -romania_problem = None -algo = None -start = None -goal = None -counter = -1 -city_map = None -frontier = None -front = None -node = None -next_button = None -explored = None - - -def create_map(root): - """This function draws out the required map.""" - global city_map, start, goal - romania_locations = romania_map.locations - width = 750 - height = 670 - margin = 5 - city_map = Canvas(root, width=width, height=height) - city_map.pack() - - # Since lines have to be drawn between particular points, we need to list - # them separately - make_line( - city_map, - romania_locations['Arad'][0], - height - - romania_locations['Arad'][1], - romania_locations['Sibiu'][0], - height - - romania_locations['Sibiu'][1], - romania_map.get('Arad', 'Sibiu')) - make_line( - city_map, - romania_locations['Arad'][0], - height - - romania_locations['Arad'][1], - romania_locations['Zerind'][0], - height - - romania_locations['Zerind'][1], - romania_map.get('Arad', 'Zerind')) - make_line( - city_map, - romania_locations['Arad'][0], - height - - romania_locations['Arad'][1], - romania_locations['Timisoara'][0], - height - - romania_locations['Timisoara'][1], - romania_map.get('Arad', 'Timisoara')) - make_line( - city_map, - romania_locations['Oradea'][0], - height - - romania_locations['Oradea'][1], - romania_locations['Zerind'][0], - height - - romania_locations['Zerind'][1], - romania_map.get('Oradea', 'Zerind')) - make_line( - city_map, - romania_locations['Oradea'][0], - height - - romania_locations['Oradea'][1], - romania_locations['Sibiu'][0], - height - - romania_locations['Sibiu'][1], - romania_map.get('Oradea', 'Sibiu')) - make_line( - city_map, - romania_locations['Lugoj'][0], - height - - romania_locations['Lugoj'][1], - romania_locations['Timisoara'][0], - height - - romania_locations['Timisoara'][1], - romania_map.get('Lugoj', 'Timisoara')) - make_line( - city_map, - romania_locations['Lugoj'][0], - height - - romania_locations['Lugoj'][1], - romania_locations['Mehadia'][0], - height - - romania_locations['Mehadia'][1], - romania_map.get('Lugoj', 'Mehadia')) - make_line( - city_map, - romania_locations['Drobeta'][0], - height - - romania_locations['Drobeta'][1], - romania_locations['Mehadia'][0], - height - - romania_locations['Mehadia'][1], - romania_map.get('Drobeta', 'Mehadia')) - make_line( - city_map, - romania_locations['Drobeta'][0], - height - - romania_locations['Drobeta'][1], - romania_locations['Craiova'][0], - height - - romania_locations['Craiova'][1], - romania_map.get('Drobeta', 'Craiova')) - make_line( - city_map, - romania_locations['Pitesti'][0], - height - - romania_locations['Pitesti'][1], - romania_locations['Craiova'][0], - height - - romania_locations['Craiova'][1], - romania_map.get('Pitesti', 'Craiova')) - make_line( - city_map, - romania_locations['Rimnicu'][0], - height - - romania_locations['Rimnicu'][1], - romania_locations['Craiova'][0], - height - - romania_locations['Craiova'][1], - romania_map.get('Rimnicu', 'Craiova')) - make_line( - city_map, - romania_locations['Rimnicu'][0], - height - - romania_locations['Rimnicu'][1], - romania_locations['Sibiu'][0], - height - - romania_locations['Sibiu'][1], - romania_map.get('Rimnicu', 'Sibiu')) - make_line( - city_map, - romania_locations['Rimnicu'][0], - height - - romania_locations['Rimnicu'][1], - romania_locations['Pitesti'][0], - height - - romania_locations['Pitesti'][1], - romania_map.get('Rimnicu', 'Pitesti')) - make_line( - city_map, - romania_locations['Bucharest'][0], - height - - romania_locations['Bucharest'][1], - romania_locations['Pitesti'][0], - height - - romania_locations['Pitesti'][1], - romania_map.get('Bucharest', 'Pitesti')) - make_line( - city_map, - romania_locations['Fagaras'][0], - height - - romania_locations['Fagaras'][1], - romania_locations['Sibiu'][0], - height - - romania_locations['Sibiu'][1], - romania_map.get('Fagaras', 'Sibiu')) - make_line( - city_map, - romania_locations['Fagaras'][0], - height - - romania_locations['Fagaras'][1], - romania_locations['Bucharest'][0], - height - - romania_locations['Bucharest'][1], - romania_map.get('Fagaras', 'Bucharest')) - make_line( - city_map, - romania_locations['Giurgiu'][0], - height - - romania_locations['Giurgiu'][1], - romania_locations['Bucharest'][0], - height - - romania_locations['Bucharest'][1], - romania_map.get('Giurgiu', 'Bucharest')) - make_line( - city_map, - romania_locations['Urziceni'][0], - height - - romania_locations['Urziceni'][1], - romania_locations['Bucharest'][0], - height - - romania_locations['Bucharest'][1], - romania_map.get('Urziceni', 'Bucharest')) - make_line( - city_map, - romania_locations['Urziceni'][0], - height - - romania_locations['Urziceni'][1], - romania_locations['Hirsova'][0], - height - - romania_locations['Hirsova'][1], - romania_map.get('Urziceni', 'Hirsova')) - make_line( - city_map, - romania_locations['Eforie'][0], - height - - romania_locations['Eforie'][1], - romania_locations['Hirsova'][0], - height - - romania_locations['Hirsova'][1], - romania_map.get('Eforie', 'Hirsova')) - make_line( - city_map, - romania_locations['Urziceni'][0], - height - - romania_locations['Urziceni'][1], - romania_locations['Vaslui'][0], - height - - romania_locations['Vaslui'][1], - romania_map.get('Urziceni', 'Vaslui')) - make_line( - city_map, - romania_locations['Iasi'][0], - height - - romania_locations['Iasi'][1], - romania_locations['Vaslui'][0], - height - - romania_locations['Vaslui'][1], - romania_map.get('Iasi', 'Vaslui')) - make_line( - city_map, - romania_locations['Iasi'][0], - height - - romania_locations['Iasi'][1], - romania_locations['Neamt'][0], - height - - romania_locations['Neamt'][1], - romania_map.get('Iasi', 'Neamt')) - - for city in romania_locations.keys(): - make_rectangle( - city_map, - romania_locations[city][0], - height - - romania_locations[city][1], - margin, - city) - - make_legend(city_map) - - -def make_line(map, x0, y0, x1, y1, distance): - """This function draws out the lines joining various points.""" - map.create_line(x0, y0, x1, y1) - map.create_text((x0 + x1) / 2, (y0 + y1) / 2, text=distance) - - -def make_rectangle(map, x0, y0, margin, city_name): - """This function draws out rectangles for various points.""" - global city_coord - rect = map.create_rectangle( - x0 - margin, - y0 - margin, - x0 + margin, - y0 + margin, - fill="white") - if "Bucharest" in city_name or "Pitesti" in city_name or "Lugoj" in city_name \ - or "Mehadia" in city_name or "Drobeta" in city_name: - map.create_text( - x0 - 2 * margin, - y0 - 2 * margin, - text=city_name, - anchor=E) - else: - map.create_text( - x0 - 2 * margin, - y0 - 2 * margin, - text=city_name, - anchor=SE) - city_coord.update({city_name: rect}) - - -def make_legend(map): - rect1 = map.create_rectangle(600, 100, 610, 110, fill="white") - text1 = map.create_text(615, 105, anchor=W, text="Un-explored") - - rect2 = map.create_rectangle(600, 115, 610, 125, fill="orange") - text2 = map.create_text(615, 120, anchor=W, text="Frontier") - - rect3 = map.create_rectangle(600, 130, 610, 140, fill="red") - text3 = map.create_text(615, 135, anchor=W, text="Currently Exploring") - - rect4 = map.create_rectangle(600, 145, 610, 155, fill="grey") - text4 = map.create_text(615, 150, anchor=W, text="Explored") - - rect5 = map.create_rectangle(600, 160, 610, 170, fill="dark green") - text5 = map.create_text(615, 165, anchor=W, text="Final Solution") - - -def tree_search(problem): - """ - Search through the successors of a problem to find a goal. - The argument frontier should be an empty queue. - Don't worry about repeated paths to a state. [Figure 3.7] - This function has been changed to make it suitable for the Tkinter GUI. - """ - global counter, frontier, node - - if counter == -1: - frontier.append(Node(problem.initial)) - - display_frontier(frontier) - if counter % 3 == 0 and counter >= 0: - node = frontier.pop() - - display_current(node) - if counter % 3 == 1 and counter >= 0: - if problem.goal_test(node.state): - return node - frontier.extend(node.expand(problem)) - - display_frontier(frontier) - if counter % 3 == 2 and counter >= 0: - display_explored(node) - return None - - -def graph_search(problem): - """ - Search through the successors of a problem to find a goal. - The argument frontier should be an empty queue. - If two paths reach a state, only use the first one. [Figure 3.7] - This function has been changed to make it suitable for the Tkinter GUI. - """ - global counter, frontier, node, explored - if counter == -1: - frontier.append(Node(problem.initial)) - explored = set() - - display_frontier(frontier) - if counter % 3 == 0 and counter >= 0: - node = frontier.pop() - - display_current(node) - if counter % 3 == 1 and counter >= 0: - if problem.goal_test(node.state): - return node - explored.add(node.state) - frontier.extend(child for child in node.expand(problem) - if child.state not in explored and - child not in frontier) - - display_frontier(frontier) - if counter % 3 == 2 and counter >= 0: - display_explored(node) - return None - - -def display_frontier(queue): - """This function marks the frontier nodes (orange) on the map.""" - global city_map, city_coord - qu = deepcopy(queue) - while qu: - node = qu.pop() - for city in city_coord.keys(): - if node.state == city: - city_map.itemconfig(city_coord[city], fill="orange") - - -def display_current(node): - """This function marks the currently exploring node (red) on the map.""" - global city_map, city_coord - city = node.state - city_map.itemconfig(city_coord[city], fill="red") - - -def display_explored(node): - """This function marks the already explored node (gray) on the map.""" - global city_map, city_coord - city = node.state - city_map.itemconfig(city_coord[city], fill="gray") - - -def display_final(cities): - """This function marks the final solution nodes (green) on the map.""" - global city_map, city_coord - for city in cities: - city_map.itemconfig(city_coord[city], fill="green") - - -def breadth_first_tree_search(problem): - """Search the shallowest nodes in the search tree first.""" - global frontier, counter, node - if counter == -1: - frontier = deque() - - if counter == -1: - frontier.append(Node(problem.initial)) - - display_frontier(frontier) - if counter % 3 == 0 and counter >= 0: - node = frontier.popleft() - - display_current(node) - if counter % 3 == 1 and counter >= 0: - if problem.goal_test(node.state): - return node - frontier.extend(node.expand(problem)) - - display_frontier(frontier) - if counter % 3 == 2 and counter >= 0: - display_explored(node) - return None - - -def depth_first_tree_search(problem): - """Search the deepest nodes in the search tree first.""" - # This search algorithm might not work in case of repeated paths. - global frontier, counter, node - if counter == -1: - frontier = [] # stack - - if counter == -1: - frontier.append(Node(problem.initial)) - - display_frontier(frontier) - if counter % 3 == 0 and counter >= 0: - node = frontier.pop() - - display_current(node) - if counter % 3 == 1 and counter >= 0: - if problem.goal_test(node.state): - return node - frontier.extend(node.expand(problem)) - - display_frontier(frontier) - if counter % 3 == 2 and counter >= 0: - display_explored(node) - return None - - -def breadth_first_graph_search(problem): - """[Figure 3.11]""" - global frontier, node, explored, counter - if counter == -1: - node = Node(problem.initial) - display_current(node) - if problem.goal_test(node.state): - return node - - frontier = deque([node]) # FIFO queue - - display_frontier(frontier) - explored = set() - if counter % 3 == 0 and counter >= 0: - node = frontier.popleft() - display_current(node) - explored.add(node.state) - if counter % 3 == 1 and counter >= 0: - for child in node.expand(problem): - if child.state not in explored and child not in frontier: - if problem.goal_test(child.state): - return child - frontier.append(child) - display_frontier(frontier) - if counter % 3 == 2 and counter >= 0: - display_explored(node) - return None - - -def depth_first_graph_search(problem): - """Search the deepest nodes in the search tree first.""" - global counter, frontier, node, explored - if counter == -1: - frontier = [] # stack - if counter == -1: - frontier.append(Node(problem.initial)) - explored = set() - - display_frontier(frontier) - if counter % 3 == 0 and counter >= 0: - node = frontier.pop() - - display_current(node) - if counter % 3 == 1 and counter >= 0: - if problem.goal_test(node.state): - return node - explored.add(node.state) - frontier.extend(child for child in node.expand(problem) - if child.state not in explored and - child not in frontier) - - display_frontier(frontier) - if counter % 3 == 2 and counter >= 0: - display_explored(node) - return None - - -def best_first_graph_search(problem, f): - """Search the nodes with the lowest f scores first. - You specify the function f(node) that you want to minimize; for example, - if f is a heuristic estimate to the goal, then we have greedy best - first search; if f is node.depth then we have breadth-first search. - There is a subtlety: the line "f = memoize(f, 'f')" means that the f - values will be cached on the nodes as they are computed. So after doing - a best first search you can examine the f values of the path returned.""" - global frontier, node, explored, counter - - if counter == -1: - f = memoize(f, 'f') - node = Node(problem.initial) - display_current(node) - if problem.goal_test(node.state): - return node - frontier = PriorityQueue('min', f) - frontier.append(node) - display_frontier(frontier) - explored = set() - if counter % 3 == 0 and counter >= 0: - node = frontier.pop() - display_current(node) - if problem.goal_test(node.state): - return node - explored.add(node.state) - if counter % 3 == 1 and counter >= 0: - for child in node.expand(problem): - if child.state not in explored and child not in frontier: - frontier.append(child) - elif child in frontier: - if f(child) < frontier[child]: - del frontier[child] - frontier.append(child) - display_frontier(frontier) - if counter % 3 == 2 and counter >= 0: - display_explored(node) - return None - - -def uniform_cost_search(problem): - """[Figure 3.14]""" - return best_first_graph_search(problem, lambda node: node.path_cost) - - -def astar_search(problem, h=None): - """A* search is best-first graph search with f(n) = g(n)+h(n). - You need to specify the h function when you call astar_search, or - else in your Problem subclass.""" - h = memoize(h or problem.h, 'h') - return best_first_graph_search(problem, lambda n: n.path_cost + h(n)) - - -# TODO: -# Remove redundant code. -# Make the interchangeability work between various algorithms at each step. -def on_click(): - """ - This function defines the action of the 'Next' button. - """ - global algo, counter, next_button, romania_problem, start, goal - romania_problem = GraphProblem(start.get(), goal.get(), romania_map) - if "Breadth-First Tree Search" == algo.get(): - node = breadth_first_tree_search(romania_problem) - if node is not None: - final_path = breadth_first_tree_search(romania_problem).solution() - final_path.append(start.get()) - display_final(final_path) - next_button.config(state="disabled") - counter += 1 - elif "Depth-First Tree Search" == algo.get(): - node = depth_first_tree_search(romania_problem) - if node is not None: - final_path = depth_first_tree_search(romania_problem).solution() - final_path.append(start.get()) - display_final(final_path) - next_button.config(state="disabled") - counter += 1 - elif "Breadth-First Graph Search" == algo.get(): - node = breadth_first_graph_search(romania_problem) - if node is not None: - final_path = breadth_first_graph_search(romania_problem).solution() - final_path.append(start.get()) - display_final(final_path) - next_button.config(state="disabled") - counter += 1 - elif "Depth-First Graph Search" == algo.get(): - node = depth_first_graph_search(romania_problem) - if node is not None: - final_path = depth_first_graph_search(romania_problem).solution() - final_path.append(start.get()) - display_final(final_path) - next_button.config(state="disabled") - counter += 1 - elif "Uniform Cost Search" == algo.get(): - node = uniform_cost_search(romania_problem) - if node is not None: - final_path = uniform_cost_search(romania_problem).solution() - final_path.append(start.get()) - display_final(final_path) - next_button.config(state="disabled") - counter += 1 - elif "A* - Search" == algo.get(): - node = astar_search(romania_problem) - if node is not None: - final_path = astar_search(romania_problem).solution() - final_path.append(start.get()) - display_final(final_path) - next_button.config(state="disabled") - counter += 1 - - -def reset_map(): - global counter, city_coord, city_map, next_button - counter = -1 - for city in city_coord.keys(): - city_map.itemconfig(city_coord[city], fill="white") - next_button.config(state="normal") - - -# TODO: Add more search algorithms in the OptionMenu -if __name__ == "__main__": - global algo, start, goal, next_button - root = Tk() - root.title("Road Map of Romania") - root.geometry("950x1150") - algo = StringVar(root) - start = StringVar(root) - goal = StringVar(root) - algo.set("Breadth-First Tree Search") - start.set('Arad') - goal.set('Bucharest') - cities = sorted(romania_map.locations.keys()) - algorithm_menu = OptionMenu( - root, - algo, "Breadth-First Tree Search", "Depth-First Tree Search", - "Breadth-First Graph Search", "Depth-First Graph Search", - "Uniform Cost Search", "A* - Search") - Label(root, text="\n Search Algorithm").pack() - algorithm_menu.pack() - Label(root, text="\n Start City").pack() - start_menu = OptionMenu(root, start, *cities) - start_menu.pack() - Label(root, text="\n Goal City").pack() - goal_menu = OptionMenu(root, goal, *cities) - goal_menu.pack() - frame1 = Frame(root) - next_button = Button( - frame1, - width=6, - height=2, - text="Next", - command=on_click, - padx=2, - pady=2, - relief=GROOVE) - next_button.pack(side=RIGHT) - reset_button = Button( - frame1, - width=6, - height=2, - text="Reset", - command=reset_map, - padx=2, - pady=2, - relief=GROOVE) - reset_button.pack(side=RIGHT) - frame1.pack(side=BOTTOM) - create_map(root) - root.mainloop() diff --git a/gui/tic-tac-toe.py b/gui/tic-tac-toe.py deleted file mode 100644 index 66d9d6e75..000000000 --- a/gui/tic-tac-toe.py +++ /dev/null @@ -1,232 +0,0 @@ -import os.path -from tkinter import * - -from games import minmax_decision, alpha_beta_player, random_player, TicTacToe -# "gen_state" can be used to generate a game state to apply the algorithm -from tests.test_games import gen_state - -sys.path.append(os.path.join(os.path.dirname(__file__), '..')) - -ttt = TicTacToe() -root = None -buttons = [] -frames = [] -x_pos = [] -o_pos = [] -count = 0 -sym = "" -result = None -choices = None - - -def create_frames(root): - """ - This function creates the necessary structure of the game. - """ - frame1 = Frame(root) - frame2 = Frame(root) - frame3 = Frame(root) - frame4 = Frame(root) - create_buttons(frame1) - create_buttons(frame2) - create_buttons(frame3) - buttonExit = Button( - frame4, height=1, width=2, - text="Exit", - command=lambda: exit_game(root)) - buttonExit.pack(side=LEFT) - frame4.pack(side=BOTTOM) - frame3.pack(side=BOTTOM) - frame2.pack(side=BOTTOM) - frame1.pack(side=BOTTOM) - frames.append(frame1) - frames.append(frame2) - frames.append(frame3) - for x in frames: - buttons_in_frame = [] - for y in x.winfo_children(): - buttons_in_frame.append(y) - buttons.append(buttons_in_frame) - buttonReset = Button(frame4, height=1, width=2, - text="Reset", command=lambda: reset_game()) - buttonReset.pack(side=LEFT) - - -def create_buttons(frame): - """ - This function creates the buttons to be pressed/clicked during the game. - """ - button0 = Button(frame, height=2, width=2, text=" ", - command=lambda: on_click(button0)) - button0.pack(side=LEFT) - button1 = Button(frame, height=2, width=2, text=" ", - command=lambda: on_click(button1)) - button1.pack(side=LEFT) - button2 = Button(frame, height=2, width=2, text=" ", - command=lambda: on_click(button2)) - button2.pack(side=LEFT) - - -# TODO: Add a choice option for the user. -def on_click(button): - """ - This function determines the action of any button. - """ - global ttt, choices, count, sym, result, x_pos, o_pos - - if count % 2 == 0: - sym = "X" - else: - sym = "O" - count += 1 - - button.config( - text=sym, - state='disabled', - disabledforeground="red") # For cross - - x, y = get_coordinates(button) - x += 1 - y += 1 - x_pos.append((x, y)) - state = gen_state(to_move='O', x_positions=x_pos, - o_positions=o_pos) - try: - choice = choices.get() - if "Random" in choice: - a, b = random_player(ttt, state) - elif "Pro" in choice: - a, b = minmax_decision(state, ttt) - else: - a, b = alpha_beta_player(ttt, state) - except (ValueError, IndexError, TypeError) as e: - disable_game() - result.set("It's a draw :|") - return - if 1 <= a <= 3 and 1 <= b <= 3: - o_pos.append((a, b)) - button_to_change = get_button(a - 1, b - 1) - if count % 2 == 0: # Used again, will become handy when user is given the choice of turn. - sym = "X" - else: - sym = "O" - count += 1 - - if check_victory(button): - result.set("You win :)") - disable_game() - else: - button_to_change.config(text=sym, state='disabled', - disabledforeground="black") - if check_victory(button_to_change): - result.set("You lose :(") - disable_game() - - -# TODO: Replace "check_victory" by "k_in_row" function. -def check_victory(button): - """ - This function checks various winning conditions of the game. - """ - # check if previous move caused a win on vertical line - global buttons - x, y = get_coordinates(button) - tt = button['text'] - if buttons[0][y]['text'] == buttons[1][y]['text'] == buttons[2][y]['text'] != " ": - buttons[0][y].config(text="|" + tt + "|") - buttons[1][y].config(text="|" + tt + "|") - buttons[2][y].config(text="|" + tt + "|") - return True - - # check if previous move caused a win on horizontal line - if buttons[x][0]['text'] == buttons[x][1]['text'] == buttons[x][2]['text'] != " ": - buttons[x][0].config(text="--" + tt + "--") - buttons[x][1].config(text="--" + tt + "--") - buttons[x][2].config(text="--" + tt + "--") - return True - - # check if previous move was on the main diagonal and caused a win - if x == y and buttons[0][0]['text'] == buttons[1][1]['text'] == buttons[2][2]['text'] != " ": - buttons[0][0].config(text="\\" + tt + "\\") - buttons[1][1].config(text="\\" + tt + "\\") - buttons[2][2].config(text="\\" + tt + "\\") - return True - - # check if previous move was on the secondary diagonal and caused a win - if x + y == 2 and buttons[0][2]['text'] == buttons[1][1]['text'] == buttons[2][0]['text'] != " ": - buttons[0][2].config(text="/" + tt + "/") - buttons[1][1].config(text="/" + tt + "/") - buttons[2][0].config(text="/" + tt + "/") - return True - - return False - - -def get_coordinates(button): - """ - This function returns the coordinates of the button clicked. - """ - global buttons - for x in range(len(buttons)): - for y in range(len(buttons[x])): - if buttons[x][y] == button: - return x, y - - -def get_button(x, y): - """ - This function returns the button memory location corresponding to a coordinate. - """ - global buttons - return buttons[x][y] - - -def reset_game(): - """ - This function will reset all the tiles to the initial null value. - """ - global x_pos, o_pos, frames, count - - count = 0 - x_pos = [] - o_pos = [] - result.set("Your Turn!") - for x in frames: - for y in x.winfo_children(): - y.config(text=" ", state='normal') - - -def disable_game(): - """ - This function deactivates the game after a win, loss or draw. - """ - global frames - for x in frames: - for y in x.winfo_children(): - y.config(state='disabled') - - -def exit_game(root): - """ - This function will exit the game by killing the root. - """ - root.destroy() - - -if __name__ == "__main__": - global result, choices - - root = Tk() - root.title("TicTacToe") - root.geometry("150x200") # Improved the window geometry - root.resizable(0, 0) # To remove the maximize window option - result = StringVar() - result.set("Your Turn!") - w = Label(root, textvariable=result) - w.pack(side=BOTTOM) - create_frames(root) - choices = StringVar(root) - choices.set("Vs Pro") - menu = OptionMenu(root, choices, "Vs Random", "Vs Pro", "Vs Legend") - menu.pack() - root.mainloop() diff --git a/gui/tsp.py b/gui/tsp.py deleted file mode 100644 index 590fff354..000000000 --- a/gui/tsp.py +++ /dev/null @@ -1,342 +0,0 @@ -from tkinter import * -from tkinter import messagebox - -import utils -from search import * - -sys.path.append(os.path.join(os.path.dirname(__file__), '..')) - -distances = {} - - -class TSProblem(Problem): - """subclass of Problem to define various functions""" - - def two_opt(self, state): - """Neighbour generating function for Traveling Salesman Problem""" - neighbour_state = state[:] - left = random.randint(0, len(neighbour_state) - 1) - right = random.randint(0, len(neighbour_state) - 1) - if left > right: - left, right = right, left - neighbour_state[left: right + 1] = reversed(neighbour_state[left: right + 1]) - return neighbour_state - - def actions(self, state): - """action that can be executed in given state""" - return [self.two_opt] - - def result(self, state, action): - """result after applying the given action on the given state""" - return action(state) - - def path_cost(self, c, state1, action, state2): - """total distance for the Traveling Salesman to be covered if in state2""" - cost = 0 - for i in range(len(state2) - 1): - cost += distances[state2[i]][state2[i + 1]] - cost += distances[state2[0]][state2[-1]] - return cost - - def value(self, state): - """value of path cost given negative for the given state""" - return -1 * self.path_cost(None, None, None, state) - - -class TSPGui(): - """Class to create gui of Traveling Salesman using simulated annealing where one can - select cities, change speed and temperature. Distances between cities are euclidean - distances between them. - """ - - def __init__(self, root, all_cities): - self.root = root - self.vars = [] - self.frame_locations = {} - self.calculate_canvas_size() - self.button_text = StringVar() - self.button_text.set("Start") - self.algo_var = StringVar() - self.all_cities = all_cities - self.frame_select_cities = Frame(self.root) - self.frame_select_cities.grid(row=1) - self.frame_canvas = Frame(self.root) - self.frame_canvas.grid(row=2) - Label(self.root, text="Map of Romania", font="Times 13 bold").grid(row=0, columnspan=10) - - def create_checkboxes(self, side=LEFT, anchor=W): - """To select cities which are to be a part of Traveling Salesman Problem""" - - row_number = 0 - column_number = 0 - - for city in self.all_cities: - var = IntVar() - var.set(1) - Checkbutton(self.frame_select_cities, text=city, variable=var).grid( - row=row_number, column=column_number, sticky=W) - - self.vars.append(var) - column_number += 1 - if column_number == 10: - column_number = 0 - row_number += 1 - - def create_buttons(self): - """Create start and quit button""" - - Button(self.frame_select_cities, textvariable=self.button_text, - command=self.run_traveling_salesman).grid(row=5, column=4, sticky=E + W) - Button(self.frame_select_cities, text='Quit', command=self.on_closing).grid( - row=5, column=5, sticky=E + W) - - def create_dropdown_menu(self): - """Create dropdown menu for algorithm selection""" - - choices = {'Simulated Annealing', 'Genetic Algorithm', 'Hill Climbing'} - self.algo_var.set('Simulated Annealing') - dropdown_menu = OptionMenu(self.frame_select_cities, self.algo_var, *choices) - dropdown_menu.grid(row=4, column=4, columnspan=2, sticky=E + W) - dropdown_menu.config(width=19) - - def run_traveling_salesman(self): - """Choose selected cities""" - - cities = [] - for i in range(len(self.vars)): - if self.vars[i].get() == 1: - cities.append(self.all_cities[i]) - - tsp_problem = TSProblem(cities) - self.button_text.set("Reset") - self.create_canvas(tsp_problem) - - def calculate_canvas_size(self): - """Width and height for canvas""" - - minx, maxx = sys.maxsize, -1 * sys.maxsize - miny, maxy = sys.maxsize, -1 * sys.maxsize - - for value in romania_map.locations.values(): - minx = min(minx, value[0]) - maxx = max(maxx, value[0]) - miny = min(miny, value[1]) - maxy = max(maxy, value[1]) - - # New locations squeezed to fit inside the map of romania - for name, coordinates in romania_map.locations.items(): - self.frame_locations[name] = (coordinates[0] / 1.2 - minx + - 150, coordinates[1] / 1.2 - miny + 165) - - canvas_width = maxx - minx + 200 - canvas_height = maxy - miny + 200 - - self.canvas_width = canvas_width - self.canvas_height = canvas_height - - def create_canvas(self, problem): - """creating map with cities""" - - map_canvas = Canvas(self.frame_canvas, width=self.canvas_width, height=self.canvas_height) - map_canvas.grid(row=3, columnspan=10) - current = Node(problem.initial) - map_canvas.delete("all") - self.romania_image = PhotoImage(file="../images/romania_map.png") - map_canvas.create_image(self.canvas_width / 2, self.canvas_height / 2, - image=self.romania_image) - cities = current.state - for city in cities: - x = self.frame_locations[city][0] - y = self.frame_locations[city][1] - map_canvas.create_oval(x - 3, y - 3, x + 3, y + 3, - fill="red", outline="red") - map_canvas.create_text(x - 15, y - 10, text=city) - - self.cost = StringVar() - Label(self.frame_canvas, textvariable=self.cost, relief="sunken").grid( - row=2, columnspan=10) - - self.speed = IntVar() - speed_scale = Scale(self.frame_canvas, from_=500, to=1, orient=HORIZONTAL, - variable=self.speed, label="Speed ----> ", showvalue=0, font="Times 11", - relief="sunken", cursor="gumby") - speed_scale.grid(row=1, columnspan=5, sticky=N + S + E + W) - - if self.algo_var.get() == 'Simulated Annealing': - self.temperature = IntVar() - temperature_scale = Scale(self.frame_canvas, from_=100, to=0, orient=HORIZONTAL, - length=200, variable=self.temperature, label="Temperature ---->", - font="Times 11", relief="sunken", showvalue=0, cursor="gumby") - temperature_scale.grid(row=1, column=5, columnspan=5, sticky=N + S + E + W) - self.simulated_annealing_with_tunable_T(problem, map_canvas) - elif self.algo_var.get() == 'Genetic Algorithm': - self.mutation_rate = DoubleVar() - self.mutation_rate.set(0.05) - mutation_rate_scale = Scale(self.frame_canvas, from_=0, to=1, orient=HORIZONTAL, - length=200, variable=self.mutation_rate, label='Mutation Rate ---->', - font='Times 11', relief='sunken', showvalue=0, cursor='gumby', resolution=0.001) - mutation_rate_scale.grid(row=1, column=5, columnspan=5, sticky='nsew') - self.genetic_algorithm(problem, map_canvas) - elif self.algo_var.get() == 'Hill Climbing': - self.no_of_neighbors = IntVar() - self.no_of_neighbors.set(100) - no_of_neighbors_scale = Scale(self.frame_canvas, from_=10, to=1000, orient=HORIZONTAL, - length=200, variable=self.no_of_neighbors, label='Number of neighbors ---->', - font='Times 11', relief='sunken', showvalue=0, cursor='gumby') - no_of_neighbors_scale.grid(row=1, column=5, columnspan=5, sticky='nsew') - self.hill_climbing(problem, map_canvas) - - def exp_schedule(k=100, lam=0.03, limit=1000): - """One possible schedule function for simulated annealing""" - - return lambda t: (k * np.exp(-lam * t) if t < limit else 0) - - def simulated_annealing_with_tunable_T(self, problem, map_canvas, schedule=exp_schedule()): - """Simulated annealing where temperature is taken as user input""" - - current = Node(problem.initial) - - while True: - T = schedule(self.temperature.get()) - if T == 0: - return current.state - neighbors = current.expand(problem) - if not neighbors: - return current.state - next = random.choice(neighbors) - delta_e = problem.value(next.state) - problem.value(current.state) - if delta_e > 0 or probability(np.exp(delta_e / T)): - map_canvas.delete("poly") - - current = next - self.cost.set("Cost = " + str('%0.3f' % (-1 * problem.value(current.state)))) - points = [] - for city in current.state: - points.append(self.frame_locations[city][0]) - points.append(self.frame_locations[city][1]) - map_canvas.create_polygon(points, outline='red', width=3, fill='', tag="poly") - map_canvas.update() - map_canvas.after(self.speed.get()) - - def genetic_algorithm(self, problem, map_canvas): - """Genetic Algorithm modified for the given problem""" - - def init_population(pop_number, gene_pool, state_length): - """initialize population""" - - population = [] - for i in range(pop_number): - population.append(utils.shuffled(gene_pool)) - return population - - def recombine(state_a, state_b): - """recombine two problem states""" - - start = random.randint(0, len(state_a) - 1) - end = random.randint(start + 1, len(state_a)) - new_state = state_a[start:end] - for city in state_b: - if city not in new_state: - new_state.append(city) - return new_state - - def mutate(state, mutation_rate): - """mutate problem states""" - - if random.uniform(0, 1) < mutation_rate: - sample = random.sample(range(len(state)), 2) - state[sample[0]], state[sample[1]] = state[sample[1]], state[sample[0]] - return state - - def fitness_fn(state): - """calculate fitness of a particular state""" - - fitness = problem.value(state) - return int((5600 + fitness) ** 2) - - current = Node(problem.initial) - population = init_population(100, current.state, len(current.state)) - all_time_best = current.state - while True: - population = [mutate(recombine(*select(2, population, fitness_fn)), self.mutation_rate.get()) - for _ in range(len(population))] - current_best = np.argmax(population, key=fitness_fn) - if fitness_fn(current_best) > fitness_fn(all_time_best): - all_time_best = current_best - self.cost.set("Cost = " + str('%0.3f' % (-1 * problem.value(all_time_best)))) - map_canvas.delete('poly') - points = [] - for city in current_best: - points.append(self.frame_locations[city][0]) - points.append(self.frame_locations[city][1]) - map_canvas.create_polygon(points, outline='red', width=1, fill='', tag='poly') - best_points = [] - for city in all_time_best: - best_points.append(self.frame_locations[city][0]) - best_points.append(self.frame_locations[city][1]) - map_canvas.create_polygon(best_points, outline='red', width=3, fill='', tag='poly') - map_canvas.update() - map_canvas.after(self.speed.get()) - - def hill_climbing(self, problem, map_canvas): - """hill climbing where number of neighbors is taken as user input""" - - def find_neighbors(state, number_of_neighbors=100): - """finds neighbors using two_opt method""" - - neighbors = [] - for i in range(number_of_neighbors): - new_state = problem.two_opt(state) - neighbors.append(Node(new_state)) - state = new_state - return neighbors - - current = Node(problem.initial) - while True: - neighbors = find_neighbors(current.state, self.no_of_neighbors.get()) - neighbor = np.argmax_random_tie(neighbors, key=lambda node: problem.value(node.state)) - map_canvas.delete('poly') - points = [] - for city in current.state: - points.append(self.frame_locations[city][0]) - points.append(self.frame_locations[city][1]) - map_canvas.create_polygon(points, outline='red', width=3, fill='', tag='poly') - neighbor_points = [] - for city in neighbor.state: - neighbor_points.append(self.frame_locations[city][0]) - neighbor_points.append(self.frame_locations[city][1]) - map_canvas.create_polygon(neighbor_points, outline='red', width=1, fill='', tag='poly') - map_canvas.update() - map_canvas.after(self.speed.get()) - if problem.value(neighbor.state) > problem.value(current.state): - current.state = neighbor.state - self.cost.set("Cost = " + str('%0.3f' % (-1 * problem.value(current.state)))) - - def on_closing(self): - if messagebox.askokcancel('Quit', 'Do you want to quit?'): - self.root.destroy() - - -if __name__ == '__main__': - all_cities = [] - for city in romania_map.locations.keys(): - distances[city] = {} - all_cities.append(city) - all_cities.sort() - - # distances['city1']['city2'] contains euclidean distance between their coordinates - for name_1, coordinates_1 in romania_map.locations.items(): - for name_2, coordinates_2 in romania_map.locations.items(): - distances[name_1][name_2] = np.linalg.norm( - [coordinates_1[0] - coordinates_2[0], coordinates_1[1] - coordinates_2[1]]) - distances[name_2][name_1] = np.linalg.norm( - [coordinates_1[0] - coordinates_2[0], coordinates_1[1] - coordinates_2[1]]) - - root = Tk() - root.title("Traveling Salesman Problem") - cities_selection_panel = TSPGui(root, all_cities) - cities_selection_panel.create_checkboxes() - cities_selection_panel.create_buttons() - cities_selection_panel.create_dropdown_menu() - root.protocol('WM_DELETE_WINDOW', cities_selection_panel.on_closing) - root.mainloop() diff --git a/gui/vacuum_agent.py b/gui/vacuum_agent.py deleted file mode 100644 index b07dab282..000000000 --- a/gui/vacuum_agent.py +++ /dev/null @@ -1,154 +0,0 @@ -import os.path -from tkinter import * - -from agents import * - -sys.path.append(os.path.join(os.path.dirname(__file__), '..')) - -loc_A, loc_B = (0, 0), (1, 0) # The two locations for the Vacuum world - - -class Gui(Environment): - """This GUI environment has two locations, A and B. Each can be Dirty - or Clean. The agent perceives its location and the location's - status.""" - - def __init__(self, root, height=300, width=380): - super().__init__() - self.status = {loc_A: 'Clean', - loc_B: 'Clean'} - self.root = root - self.height = height - self.width = width - self.canvas = None - self.buttons = [] - self.create_canvas() - self.create_buttons() - - def thing_classes(self): - """The list of things which can be used in the environment.""" - return [Wall, Dirt, ReflexVacuumAgent, RandomVacuumAgent, - TableDrivenVacuumAgent, ModelBasedVacuumAgent] - - def percept(self, agent): - """Returns the agent's location, and the location status (Dirty/Clean).""" - return agent.location, self.status[agent.location] - - def execute_action(self, agent, action): - """Change the location status (Dirty/Clean); track performance. - Score 10 for each dirt cleaned; -1 for each move.""" - if action == 'Right': - agent.location = loc_B - agent.performance -= 1 - elif action == 'Left': - agent.location = loc_A - agent.performance -= 1 - elif action == 'Suck': - if self.status[agent.location] == 'Dirty': - if agent.location == loc_A: - self.buttons[0].config(bg='white', activebackground='light grey') - else: - self.buttons[1].config(bg='white', activebackground='light grey') - agent.performance += 10 - self.status[agent.location] = 'Clean' - - def default_location(self, thing): - """Agents start in either location at random.""" - return random.choice([loc_A, loc_B]) - - def create_canvas(self): - """Creates Canvas element in the GUI.""" - self.canvas = Canvas( - self.root, - width=self.width, - height=self.height, - background='powder blue') - self.canvas.pack(side='bottom') - - def create_buttons(self): - """Creates the buttons required in the GUI.""" - button_left = Button(self.root, height=4, width=12, padx=2, pady=2, bg='white') - button_left.config(command=lambda btn=button_left: self.dirt_switch(btn)) - self.buttons.append(button_left) - button_left_window = self.canvas.create_window(130, 200, anchor=N, window=button_left) - button_right = Button(self.root, height=4, width=12, padx=2, pady=2, bg='white') - button_right.config(command=lambda btn=button_right: self.dirt_switch(btn)) - self.buttons.append(button_right) - button_right_window = self.canvas.create_window(250, 200, anchor=N, window=button_right) - - def dirt_switch(self, button): - """Gives user the option to put dirt in any tile.""" - bg_color = button['bg'] - if bg_color == 'saddle brown': - button.config(bg='white', activebackground='light grey') - elif bg_color == 'white': - button.config(bg='saddle brown', activebackground='light goldenrod') - - def read_env(self): - """Reads the current state of the GUI.""" - for i, btn in enumerate(self.buttons): - if i == 0: - if btn['bg'] == 'white': - self.status[loc_A] = 'Clean' - else: - self.status[loc_A] = 'Dirty' - else: - if btn['bg'] == 'white': - self.status[loc_B] = 'Clean' - else: - self.status[loc_B] = 'Dirty' - - def update_env(self, agent): - """Updates the GUI according to the agent's action.""" - self.read_env() - # print(self.status) - before_step = agent.location - self.step() - # print(self.status) - # print(agent.location) - move_agent(self, agent, before_step) - - -def create_agent(env, agent): - """Creates the agent in the GUI and is kept independent of the environment.""" - env.add_thing(agent) - # print(agent.location) - if agent.location == (0, 0): - env.agent_rect = env.canvas.create_rectangle(80, 100, 175, 180, fill='lime green') - env.text = env.canvas.create_text(128, 140, font="Helvetica 10 bold italic", text="Agent") - else: - env.agent_rect = env.canvas.create_rectangle(200, 100, 295, 180, fill='lime green') - env.text = env.canvas.create_text(248, 140, font="Helvetica 10 bold italic", text="Agent") - - -def move_agent(env, agent, before_step): - """Moves the agent in the GUI when 'next' button is pressed.""" - if agent.location == before_step: - pass - else: - if agent.location == (1, 0): - env.canvas.move(env.text, 120, 0) - env.canvas.move(env.agent_rect, 120, 0) - elif agent.location == (0, 0): - env.canvas.move(env.text, -120, 0) - env.canvas.move(env.agent_rect, -120, 0) - - -# TODO: Add more agents to the environment. -# TODO: Expand the environment to XYEnvironment. -if __name__ == "__main__": - root = Tk() - root.title("Vacuum Environment") - root.geometry("420x380") - root.resizable(0, 0) - frame = Frame(root, bg='black') - # reset_button = Button(frame, text='Reset', height=2, width=6, padx=2, pady=2, command=None) - # reset_button.pack(side='left') - next_button = Button(frame, text='Next', height=2, width=6, padx=2, pady=2) - next_button.pack(side='left') - frame.pack(side='bottom') - env = Gui(root) - agent = ReflexVacuumAgent() - create_agent(env, agent) - next_button.config(command=lambda: env.update_env(agent)) - root.mainloop() diff --git a/gui/xy_vacuum_environment.py b/gui/xy_vacuum_environment.py deleted file mode 100644 index 093abc6c3..000000000 --- a/gui/xy_vacuum_environment.py +++ /dev/null @@ -1,191 +0,0 @@ -import os.path -from tkinter import * - -from agents import * - -sys.path.append(os.path.join(os.path.dirname(__file__), '..')) - - -class Gui(VacuumEnvironment): - """This is a two-dimensional GUI environment. Each location may be - dirty, clean or can have a wall. The user can change these at each step. - """ - xi, yi = (0, 0) - perceptible_distance = 1 - - def __init__(self, root, width=7, height=7, elements=None): - super().__init__(width, height) - if elements is None: - elements = ['D', 'W'] - self.root = root - self.create_frames() - self.create_buttons() - self.create_walls() - self.elements = elements - - def create_frames(self): - """Adds frames to the GUI environment.""" - self.frames = [] - for _ in range(7): - frame = Frame(self.root, bg='grey') - frame.pack(side='bottom') - self.frames.append(frame) - - def create_buttons(self): - """Adds buttons to the respective frames in the GUI.""" - self.buttons = [] - for frame in self.frames: - button_row = [] - for _ in range(7): - button = Button(frame, height=3, width=5, padx=2, pady=2) - button.config( - command=lambda btn=button: self.display_element(btn)) - button.pack(side='left') - button_row.append(button) - self.buttons.append(button_row) - - def create_walls(self): - """Creates the outer boundary walls which do not move.""" - for row, button_row in enumerate(self.buttons): - if row == 0 or row == len(self.buttons) - 1: - for button in button_row: - button.config(text='W', state='disabled', - disabledforeground='black') - else: - button_row[0].config( - text='W', state='disabled', disabledforeground='black') - button_row[len(button_row) - 1].config(text='W', - state='disabled', disabledforeground='black') - # Place the agent in the centre of the grid. - self.buttons[3][3].config( - text='A', state='disabled', disabledforeground='black') - - def display_element(self, button): - """Show the things on the GUI.""" - txt = button['text'] - if txt != 'A': - if txt == 'W': - button.config(text='D') - elif txt == 'D': - button.config(text='') - elif txt == '': - button.config(text='W') - - def execute_action(self, agent, action): - """Determines the action the agent performs.""" - xi, yi = (self.xi, self.yi) - if action == 'Suck': - dirt_list = self.list_things_at(agent.location, Dirt) - if dirt_list: - dirt = dirt_list[0] - agent.performance += 100 - self.delete_thing(dirt) - self.buttons[xi][yi].config(text='', state='normal') - xf, yf = agent.location - self.buttons[xf][yf].config( - text='A', state='disabled', disabledforeground='black') - - else: - agent.bump = False - if action == 'TurnRight': - agent.direction += Direction.R - elif action == 'TurnLeft': - agent.direction += Direction.L - elif action == 'Forward': - agent.bump = self.move_to(agent, agent.direction.move_forward(agent.location)) - if not agent.bump: - self.buttons[xi][yi].config(text='', state='normal') - xf, yf = agent.location - self.buttons[xf][yf].config( - text='A', state='disabled', disabledforeground='black') - - if action != 'NoOp': - agent.performance -= 1 - - def read_env(self): - """Reads the current state of the GUI environment.""" - for i, btn_row in enumerate(self.buttons): - for j, btn in enumerate(btn_row): - if (i != 0 and i != len(self.buttons) - 1) and (j != 0 and j != len(btn_row) - 1): - agt_loc = self.agents[0].location - if self.some_things_at((i, j)) and (i, j) != agt_loc: - for thing in self.list_things_at((i, j)): - self.delete_thing(thing) - if btn['text'] == self.elements[0]: - self.add_thing(Dirt(), (i, j)) - elif btn['text'] == self.elements[1]: - self.add_thing(Wall(), (i, j)) - - def update_env(self): - """Updates the GUI environment according to the current state.""" - self.read_env() - agt = self.agents[0] - previous_agent_location = agt.location - self.xi, self.yi = previous_agent_location - self.step() - xf, yf = agt.location - - def reset_env(self, agt): - """Resets the GUI environment to the initial state.""" - self.read_env() - for i, btn_row in enumerate(self.buttons): - for j, btn in enumerate(btn_row): - if (i != 0 and i != len(self.buttons) - 1) and (j != 0 and j != len(btn_row) - 1): - if self.some_things_at((i, j)): - for thing in self.list_things_at((i, j)): - self.delete_thing(thing) - btn.config(text='', state='normal') - self.add_thing(agt, location=(3, 3)) - self.buttons[3][3].config( - text='A', state='disabled', disabledforeground='black') - - -def XYReflexAgentProgram(percept): - """The modified SimpleReflexAgentProgram for the GUI environment.""" - status, bump = percept - if status == 'Dirty': - return 'Suck' - - if bump == 'Bump': - value = random.choice((1, 2)) - else: - value = random.choice((1, 2, 3, 4)) # 1-right, 2-left, others-forward - - if value == 1: - return 'TurnRight' - elif value == 2: - return 'TurnLeft' - else: - return 'Forward' - - -class XYReflexAgent(Agent): - """The modified SimpleReflexAgent for the GUI environment.""" - - def __init__(self, program=None): - super().__init__(program) - self.location = (3, 3) - self.direction = Direction("up") - - -# TODO: Check the coordinate system. -# TODO: Give manual choice for agent's location. -if __name__ == "__main__": - root = Tk() - root.title("Vacuum Environment") - root.geometry("420x440") - root.resizable(0, 0) - frame = Frame(root, bg='black') - reset_button = Button(frame, text='Reset', height=2, - width=6, padx=2, pady=2) - reset_button.pack(side='left') - next_button = Button(frame, text='Next', height=2, - width=6, padx=2, pady=2) - next_button.pack(side='left') - frame.pack(side='bottom') - env = Gui(root) - agt = XYReflexAgent(program=XYReflexAgentProgram) - env.add_thing(agt, location=(3, 3)) - next_button.config(command=env.update_env) - reset_button.config(command=lambda: env.reset_env(agt)) - root.mainloop() diff --git a/images/-0.04.jpg b/images/-0.04.jpg deleted file mode 100644 index 3cf27642178a9417922ca4c5c36426ed64f9f3ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16933 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

+Wxbu#xm8>9rF1HnSUCh7t6irRP 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

G%fsIpkYcM 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 diff --git a/images/4.jpg b/images/4.jpg deleted file mode 100644 index 55e75001d92ab790c824e4647f035b200519d4ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21550 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 diff --git a/images/IMAGE-CREDITS b/images/IMAGE-CREDITS deleted file mode 100644 index f8525eb92..000000000 --- a/images/IMAGE-CREDITS +++ /dev/null @@ -1,17 +0,0 @@ -PHOTO CREDITS - -Image After http://www.imageafter.com/ - - b15woods003.jpg - (Cropped to 764x764 and scaled to 50x50 to make wall-icon.jpg - by Gregory Weber) - -Noctua Graphics, http://www.noctua-graphics.de/english/fraset_e.htm - - dirt05.jpg 512x512 - (Scaled to 50x50 to make dirt05-icon.jpg by Gregory Weber) - -Gregory Weber - - dirt.svg, dirt.png - vacuum.svg, vacuum.png diff --git a/images/aima3e_big.jpg b/images/aima3e_big.jpg deleted file mode 100644 index 1105a5e14adf0074dfad807b8a8db0018a151881..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57178 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


yN*;4>2Gf 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 diff --git a/images/dirt.svg b/images/dirt.svg deleted file mode 100644 index 162f84582..000000000 --- a/images/dirt.svg +++ /dev/null @@ -1,291 +0,0 @@ - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/images/dirt05-icon.jpg b/images/dirt05-icon.jpg deleted file mode 100644 index 38d02e97f84973f98b2b98ad5ca3a7a752986174..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1772 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 diff --git a/images/fig_5_2.png b/images/fig_5_2.png deleted file mode 100644 index 87248579821631ff1953470e3e80536f2edfe0aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49045 zcmb^ZcT`kq&^-#%G}s`a38KUXL6YPQ(j+Ar5HmTeh~y-VWK=)_K|!(vLBs?iIS438 zG7==`C^<-O;MQ^8_xr8y-gW=Gvu4&fJ#fx*o>NcNuDy5l(<_&?XpXWTB_Sc9Ij^mL zjf4cPN8O#A@xQRO4apRH}6&IC|l13XnBq6CJKd-KK zgJ8P&+DG+9?QXq9Q$c&^?b{~YQr_nqvZ}@{D@J8R1Q~M951+c&(cZxz6?&oh6c6L| zw4cY!93Q(xNs7=PS04j`rd_fbu?Dk>QHh+^C#)&CswQ)H{+SE^1T z9|aPa1xEjUq=u(H=Jf9)F5Ho$^8Z~9i~j%aay{$oZ7S=PaI-;@f7kEnEODI~AGgG* z(vdmK{9A_cr3Vi-WqORI?lv>yH2=@X%`I{x<(}))IHiXR!`~7)&%*x_{O>m!8ea)H zR_<@k&CNA8H)mxD_#RWEt9kqHNu7C>yf%g5FF`?t2MhYk!{4Zm9^IydXY2X5J2iJQ zGBclZC>DPG%0R}x(yF*T=sEM62s;=u|8LXASwG#fEpiyzTpnrbVq4jnNip-=-{AE5 zOJ7L}chUIoE;M50D?k4J>9lWh3>zFA9B{0BZ59CA&HZnai~U_^T1{LUc&DbOjEgDR z6(87*Rt0c+ub?X71=TS9cMX)T^3LQZgFIRs{^yg#kgZ`a$JzEY;u%=0oT$Tez_ant zkU@=(KTh&aBXMWFsj;#6w%4-Ynb@Pgb4tFWkFd(ci-iN*-4I(kN63xWue@Mjr(@Qh zG%&wLsltcJUR_^L|5jn&a!Jj-U)AM_p82>b$Nn7=U7B~Smn$Z%MRX}QIA2_S-cO@u ztm*0L87pe?;p4{=eXHF?$BGJ$^6Z4K$sF)@dsoJ)iHy4*i1zZNDVE*-6&UKWGtnyR}dF?%A>s2=;m>L5)pYnV>`you@A z5Nvat!(#=B8RWR2lDkFl@OJQ2%cyZO_rMgF>jf&=-$ZpxM)7F$a zyuZ4qbe1Q?uDMbK_GanhQoiO4KO8nRilb=J^hz^UyL$Dis%q7r&UYo3(6@Bwrl*(^ zirr@}rjDLbFVBzSP==?@x|;s=>(}kq$nKKB?pBc{eQ9d(xSwnnh)oEiWho`4<+kux zyT@M6fbti<%^<3vsL;iaXF4%Lr~YI&NiJ{UI$Ot49?8q=kvvPK^Vu|Pvg~KvLf+@U zd^!F%*DrmS=D-;L;Sqty_`I*LueLTtC8HW$24$+hEw0!<{X)3FhY;%3ITizhP($4# zbR4MqAihcRqR2N?3Q$bf>i^1nV(YenGpdnylJ#m6^TAyIb>x%vzLsL#pW zpCcGPf3l&F&;H%@<%@OBhxUk|$R~1pd(_*srvvYGUb&vc(u3)LHbIj)(>CJPsWVXI zI8z$-UF9%S{nMWd50;0Aa?Dh4RDoRD>8hw6yf#@9VdGNa*G$pTpPB4a59G!?*z!%| zqI{(@xS4p_1DOL_zmPI)t)-rE{I+rH_U*~1jQqs{>FsU7ZWOPhxh+~voNf?LSN}@a zst;$|noe|FD~3Frgn@15VsiRXMs50?p5FH*le7#?T=XnyI&)j+yQExX?1BMZG1 z)F+C%e|^MKbi|y*Ugw}JPFC{rC9c*Rzi^(NIj63Bk-WDw2_l4YaG=b?5qAR8=Qez9tz6*tJ(OC;}qE1ewQ`!kvH*j7M?cH@@8{f{H8@3xD@0=XnN`Hsvw zit6a-_>2Z%K79C4%$_bVqW48@#4b|143gKu-pJu)UELW8Zi+y8%A>{8sc9~PKMO`Z z$2sNi^j~~a{;8l(;zoo4cg(Ghi)^h+=V=QFJ9T#QX`4-NfA4y)HDyjdZ?ExQ`}l4_ z=FD2>4oYgBsYp7ymGQyswuW`g>+aoeH_2>_>>{>~`*Iei@u^&`Ac)l7FL*Hjd$B42 zZ5-+xr_HD&z?4pSg%S`IUHX-di9kxt`72c=Y=xP3`DJ5MW+E z8)=BF|5U72`tn^&ApQcGP1KD~tV53u2w!UJRfLuEZg>RjJ~?3;5*jKbCN^{SQ!cxL z%k72U+>5cIQ>(~hqW=}j^dv=(rI!~)6}-2_^(=I(ppKzXDExh>4c7n4lw~x3iuc<4 zcgYO<4n9%xE|WjES0~JTHg4h+;ayn#D?`lVlMPXe14W0#^|q1&7kWKo=i0;lk;7GK zh=j2J$|2qL%uDAlUUcnVW1E0F5yh|TyE7H*$qGlZ?!S5%cP^OL{ZGf+4n&BYVK`c>DVUQ7H}^!2`4w-v&qry?pud z@#Dur*~ON=h>`aV*8cP}$ZmEzZS`w@r|ehkf_# z5gd|n_1~6Aka?Zzhn?D6uJnWKN6cbP@!2$}^xY?@Hp1f-`0np2E)}QS_GAO_+5X$9 zyMthq|K9DJ`WHM}$)3~kOG9N?c6o6nrG2=}41fOrAR15AM-%lC{Jgvy3w`S`Mh*sr zc6~)7zD>HYU(6&3d3|J4xIk zFgCWQ@^IgA|A`XZp6wsLIyE^prIRGT`X*Gg6hMg_0EdV()libqq@;u@=8cVwrdTm7 z6%`dVH4>${R`vhzmCU~_r-NfW-ICbzQ7@;xy`A@BjQ9RV5ApGOl7j1WqfpKyieJHL zv}z(k#kcQHY&f%oq{4@&&M5D( z#9mW}4(AmTn$Ipm$mPQw6uK{R(=#YHT?o*9?Qv+cP_lU{QAwCH^ZJY9KKyl z-djT+CZ%p;0h!KglMN@#yjP*-mF-L?UcY`l@vCSEm$vPH_YJ-N?y`t+@e0KD@<`=j zlUSwq?q3_tn6u7%FxR9=T$*j;(0ufzj5|5F;a_%HD#MFR5Cj>_6yj zr~n5iQQ7BVPqqn^#*zn%{jd#>Qk>XecV@^>7+0Z}#zwzC%DdZQsWJ)mX9qCnDkDW; zJ`J+(9cSKu{CH7EhlY~!4}>L^Sh*8%+u8Sx0SS~6u}Fvhe4D?szlMj0;kY}`f8`G3 z%KZ1xpTj*yd^{lkaGY@?tbE77AHPS)iba-o-=9Klxx(`o=8DP7Z@+5+1Z&x@d3NkU1|ygI2w_+ zFvwfNCoWg)i7F{6;qgg}^Ep{rqx^=)I5|0aDih}TkmOS|{E+JLr^?F1>$*xeO-)-N ztUC;mTx1_Js4u3NTSCmjpYv!vZ;qFm z`S3BD6_)voNyztL#~OB<4vT^Fk$?X5wZIaWya_?pCFoH6Hv6o-{?4vO_z|sk)}}^$ z_e4}I__B+~pB?Tm`{B(=0XyTNnFy_wwCTuzJFKOPMAWx&(`CH{Rjh*<0G$QlxDd2I3A!4i92EW#p6|{+0J! zJB5vlfDqThc|P6`>#YlC+xc}@!}|D10mU1x6mMu?pKU_5amJLrK^LPailI^3S)a*E zLHTTS>$N2*RO=E*zj7bU zxJ77@>3JL+TnVKDATwHJ?D8>RZIXJ%VV>6Tg0fSATrLo|+D4C_CteHSQ|!7%nw^z( zZ?5aTva<4v7cZc_lU13EA9SjwN#0(4E@D(T2!RT<%ny*l+S=OoRk_qFjxP-!kFTEo z|6Pjq^_v13<>(6$(lfmVMn;J*Uox<>vmZMaos?vJ{W?6fT;rZLyqjBt5YrCIq4g+iT(q{&J$1qTpM^} zFD2tWA-ak8K92r2avUmhZ z5f##~cxi#K*M+W2Y>HdUBZoDNy4yQDG@Q!bu>a7|vZ?%fhICHPo;@Q}RqxE_RQ6`q zKoMz;lbGn#Rhi;X@UJ!?^G_V5Q^z1tBF%_o_Qir8hmxrnNQJGh6?=$cHnLCB&IK2K zmC;E3@Zq$eAms<_Y3IJLcXak1f1MWok-6x!L-XIFLIxUIS~%n!*auh-p^~kpe@=j` zGW1ytl`qWcyFK=pl2O%a9}f6%p*@?*GcIi@BogR6u9})2bY0gqaqqtQ=m<^YPrx4a zoI6itt6qBy_szZ1@$uPTn`)~5@q-kNHrjuAIxvm~S#EJ0a?xFC6P#ekSw zXS9D>1{ncKrUAcO1JD?pA91xww9Kw1gns__=RG)}NNpVamnMzt02nZ{u?;}IkBf_g z@)W^oA4O=-@hyq`^yyRCQfX6ty)|Szug!%q$j#1Zq@>xL2Hfrgc@&LCJHl20%t(ej zk#es(j7?5dQ85wI&kU8(d$smN4qPHKGP0|yE2r`xAqARg_kY>_h5qN?KsJn32b)2T z(#5aVz)H8D-U{57Ip24pk=^xhf6KA=O8}<-wBmz>IChZC3a?@tERX!}G?czW0(Bn(QSn#IM6v;?L7AH5H{@93JZg@a^=KfwGc(F_hs$Z?;k*b=RRDv< zCCS+SX3{g3u^?k7N{-4PIL$?$p%OOitd$sV0p9D*+EsGWX%*5iG9Uvi4bu-$6V?k~$fZ zQp&vd7K@rp^MasHyj=Mtcq3Um8`&vtGyMNPYC^!#{6hFTXwmd#*iz1XljZ=j;k=%~EY{%fmiE zRsH$%2daXSNXkz{KPbWB|usc!O+m#5J;R={%aU0oAn`jrTh+v zg_|2T88k>jG(-dLEL>dnoq6rCeKliBzuQsYT$&Rd>LJ{6V2ltUsvmMe1xT4pgwIqp3sCm0w4M=CV&r0~?1M++T>9>R7M z+4eXPw^xk{?V!9w+yN;62!owQ)wm+PLCsS}gco+6sQY$!utyXKjKjk3cD(ckfZ3+J zX9wGJ04P(~tb)DLx&3}`p0zH4Adlrru8RP$4@YzG!GOJ;2z$REyy;A&XylVr64#m_ z>jcxVJ*Z{UYfg~)n4ce=qH0LBx3$bEZcc*b!d)~lV9CF7?_Im0l$4a;-l7};T|-vn z&Yvb{W^@yz-$UDMRTtLK&@iU;;ueOQC^zKB2)Av^)JfEgz%4E=D&1*}hBd@-YDC5$ zZ%G=%e>o{m#qR+2!DGEeu5x$oBh>3L{>WR6Py^xKZD?)VF^D0m6QbpS@g6;TWac^b zDyL%iS&C}pT?Azpzfd_Oy6*38Kuvg;le26Up%la^cu(=hty_VnGpLO2TPb?!NLnP~{gCZgZ^|TdMJ@bDOG{PPJ zp9EcmG^Md>eb<%d$^ zfVAAwPxtq>R90&kp_1&t4fJwM!_8P!nc*DE5Xj+I!=PRX8|Kgc-xKhEvP1aTLSG(a zyMB?P!HzuZHssJKJ%sm6*9e`x7o_Vol8#$~r%ykG%0~S^0J|7bqdF9rvI!OGCNZx!bN8<#C zVsCeMbFO>-U~k#1)J;(3ejGf+6aFAB?ZnCd>5sI+S!=5)I>->l7{dz;&2tvV9(9nzp}!_#KhHJ8yyql;@F;9UY=y;v+Z=}&J?hzzPo?kc`bkQ zSRJp$)6`h)Z1kArl+JyCW5Rqt=B7mRIH6W90BSco`!e9(u?DUXgzw5lzg~uJ*>kiC zHS8fvbHzQC+?n6&<4H&{P`h>@c0I|wSQ?15IgkPH zC^C8^6i?yTe)0fRfG6TyR<^fG`ZaK|uC}6ww)pUsN9YcdOJieW5SB9;$mn!Ud`d9x zp@5*^dw7PP+@x`Pp=4I6QNxkYMcS|8??O^;AX1i=rY1r{;2+eiBjmf{a(VjV$=0hT zCO(}ya!Ag?KR|As?fG8p@ZR-@-hPh#Wk%eRA9kE?&i&Rhn0*pG8Xc{F@GfL@)coMY zD59b)7hHeAT}n!E`TeLholFI!0_Z}P`|`9ZXtl@(M|KaS`s;q8^gQN9r@Bu{uPXV5 zhrl~^7%FA*$j+C%oT5CGb`G;KRzesM+A^l4b#`w19yOCe;>w3zIv<_1oK@>dWEBJ? zw9u2o8Nq791d(q7iH573z;W?PJo$rJH_yYXQZY7{&}vlAnI!_X!nv+psVX4bm`~Rq zpt*Ec50`)40pZWVSR0N;$_M{>B`Y4RVywb%rA(Z;-PqK3vQf z#^nPHex#^pD1aARFtnCHWCw9-2ZGTP+FH9owI4Ee1`Nb_V zqgp+$_fIH`uZDU?UeC8MRB^(Mc*QJDYB7Jj^_f-ap)^q8$AI&vSFNhed`olc;l+uk zcR|k^d2iEj$#_+M?%6fXt+kV%e-4NVE5Ey7Rl5r$_g@!&+84OiOXI1S^*1@xFt;E<(nUEsN{>&Mdf0YFWwZbF0euA z#m3T|)w~m`oAZn1ep_5OGpK_fb1LrpB?fGKJGy(>^c{OXaHL_1diaQEQ|bJ-aqlr0 zo2=%rpqPw`Bpnt&lfXaGaw<39$J_Q7%n9YP`WJKJ3E~k{s}$59yaJ%zgoCfm7tl}o zyp2S&{72yrVB;vtsYrqtY^zDL zEj_&(m6>0CE_m|PoNXvPm>a+_gd9Jk(+4pLw}|s6mQ4jkM4sfbcw`gU$yr$5OgR+_ zsTJP*-U>wXnFkAmzq40w{R!1lOTUgc?->Os1I28l)LjUcNRo7QD;ltQs&0yMhwig` zRK+jlED!E(r2_BfvDm)>oFrb9>?#_9l`Bi|%6)aa9UU<`TakA6fTvz#+E!%jsio9C zcgc-?S`!Tzr0zvD90gK-d}2an|L^sVcO4aa%IYT^jkJd?SHAg?tB_1iPmj00`c2{- z)83Vi&zSu4E+tvPm9NvOOOg6>RY1iE5HTDcgWs*x@TBj$zEvTC0r)oH_l$cE|LDU0 zMNiKi5N{{O#|gp|Z%{{zkAKh1{F!&{Ui-KQ%g?Br6?{F~sCWOCH0b%UJNx;^&Ld}b z387)YpE!(EnDl?Y@S-`XVP)`}m&ag9$5Ae^(0S3G11OEqq;Ax6`cZF~mJ@DZJ}WsX z&S<%nmLFy?J&|?;w$BoE<(3X`?EKJ8b|C&iY`5>J9nUl5dq2V>?6!!@o}|JnU6hKEM4bMevy-C&#q43 z9z~X9ROOrwZQ7Pc`Huc&&>ItEY^BNA_vi*kEQh%QIyyQoihVlH%PH}qJ~A; zdmGp!K@~tS+V{3~`-}zSn+^z!sAdPqQ z@p4t|Z5(l-WF|RL%9<7gayK=2nLlHyx67z2=;^;NERtW2B4>A#DNwjkZ6F*|C^{xW({=8NFl<{Dv@Xd2K%lw! zp`Vnua)9bFy*zw5W(PAgKqeJ{@MZ%LXe{nxRlci*pX?Z!oI1=bQ**vby~0+EEiUdu zE4Vg5r+(s?lL#qAaUAXHk{vC8q{wo4Z@)ZJwwt&?ZcQ)q3*8 zj;-`4V0%9x!klNG)mw?^a&S2A{W)W6Keq7axtXD|$5K*61lEI`#@x>I>+J?;jklFT zw8qO}d(i&D>?#%EN98F`?3pT>Q(xVA_39Nulp!1jSTwYtR``A@;Ji%rcP+f(_@TI< z3Cm00&Z0Co+^hR9N5t*3`smL2nKjAX*Wld~xpDT~R0l<<-b(qky^|6PS5F_6H+Qu3 z?|&D?fo7Zqk}i~{?g9`K*9S|+SEZvfAA5DmT5DMuo|-A>F%5nC^! zRZkBg5=6UWfpv|s69N_@qsMCQFT%-vnV8t*bM^v6wx#7bqb~ltm9c-I|cE;JA(S&7td(l9HOw+0QGVNhf*C@mB=wMG^>;>Ku4J zijS9{f56WybhEtkoo@YWAqsJeACKW!80@ac-rlhXdA1F|PF+c1Q%%h(Ex^zJ4xptX z287`IgT>A^Ha0}=|Gid!e?NGt0`KvpY`!%b0Rm`ZW@ZZ*m^GnD*-P&3?m#rCtGrf6 zq|=$!*OhxqioWz6L475z*8gL6alLYsiVC>bGrr`3%m^bTuXW)2<`Wh{}eEVl3=&<&}Q_l6{q3gL*|C|HMai)fB5aB-{ z&91vrj8h}*feolYgOz@VNVZJ&S~?HD1TFfMw}|LE|u zbo>Z27(Ur&oigQjG9-{cneby^AQ3~S{vD2k*T!5enqnM}5O)$F{7pas6~l6c1R_lw z2pm}Wa|lTOuq{iQ10eVND5^Z>YJCL#NYXU)IiT{}0t5C)#r|p58W;;;&!!+LN>KRt zQm6?WZuuPoZ-R7g@2|gu9(q0fzkAgvoIZWJ{2SuND+Sicyov<+Q!?m5=$M)1VWXh1 z5<#u|@cHu;Kiwp82Qb{_L|K{x68-?sQNS{N&ScKVVLQgzK^~k3(SH=kl!sv)in7Ye z$sAgA=7$ISCrk-r$aR+e4)>6987fvm0NQKaRXcG8S~3>ETzh3e<1Lr3w}PTdqFnu) zE95%DIq=6x+jKxO>m3;?^T>Jso&_>JC>VY88R6?dGya|Lahz&=wIavpv=9M+u6T4I#cFF|8@ql{SRQpY)sRuYgVv z|Mlw^boh7u2FQ}S?|=J~nK(?Cpn1Sp<{8I=!z&8Fkcn0jT~-MosrG`2vyyPN}Wm8<{PcnA@ z)0OsXAg*nINCpXM%mNjM@&)Y@?{wg8VUbpA2{a%VmM4S$gbxr^R>V6V{u;UUtH4%om7yXWfl~*>9lSqRKN4Z? zAZpJX?C;GB#}F4C{r1L!ISH!jXV3olwl&;@)}Fsp`;2Myq@ktB#VQm~ZHq%?Mcd(+ zj139L;c_saJi>IXY;3#|8I!tiYl|=&pzy4U2i`+oR#yq=D9MCzO5Bxn;QI|9$+-=- z`>d06unGzbF97p){yZgCsGZ)aN~#V2NX32R8BlGM6ck^+z0H0W5fR}+nF5)PcGeV5 zJ%L%R3*nkhGw+aRK+Ngy++{(ZahR=;a~S+ttvx>u$8`i8!0Cs-Fg_?u7)}X@my~H# z2GdmogPo$veGzc=1k210mgLPbC|iM&i9SNT4ba+?8EHVz(J3U#IaWZZLWj~)&8jba z{PkAt+WNW$?LMTyRq>8z%;2%Qc8vjhZ}du4cTdmOpH7TlQ~3rx&_K5v7;x=%0|RAg zX#tq7I5>eo;(C(&cVS9k(PK>?{wcH{Am}H89cC7|v>B94jHt;&P>X<)GZf!WPCbXh z0DFgA@|A?=+9Xh#xc0Yj<_s@x%Yve`3!Kk7NuV}zco~k+u;$(Q(T z&4X3?O9zasuAyN+a9Vbg7fm$b7*yUFPViSS(${Ck%D;i6Ov~{H_%aYspwMi=zN#aS zuLv*52fQ1eRrHJf1$$6-395+$4rPmg5dUnX22X~krvi4~@=6tAJ3e&~<0(|t zXTk{QG3@|06@*rJP@9`Knc!3*G}c(g+qX}Gf>;M-s5@xL*s-&g#Q0CLCAp@irnx2f z$N6OMbW=9Bw&V_+F%zV;Az@)PBa)7M+Ezy|J8$g0hLR77w5_#u+5&Ct^qrhGc7+8B zBTn9l3(5;zzvfYvHsu4Yk&6Pt!sWot(uii0fbfaAlnPH#Qc{9g)u4b7dJP8k9cl!s zgJ_Jtn4_@FRf4E3;Ni@`k+p3!-9lo2DLaKaoK@!j(qIYRoH{O=#o&iE{?b?g-)QDI zj|eGpC#RmXUBIV;7X6x48R+pMT8=X-{-~ExQBWiN*8KB|ty@SWTD#s~=Y;MECmwX2 zl(q_<=J=o_3y{n2;OJJP>yUt>5gi*~2K8yYHqyU`o)X;c;ko1-o z><+eoAUvy>AyN*Zsq(C1dF*n1|3Vd|TOI)BmtY<4?h|uS5E}K@Jd7!6k)oL8V7ND* zc4cUM_dHVQ_Wu4^2l90Ni^Ks)UqIHZ`%3_}3QClqlYpAt7NCo>SNdwp_cDBs?*Oof zH#ibj{3U#W_GeC(l9VL$3fQ%9=`#lj$Ok)!nwKv?GkoU`FP1Hno|KjV7S7j15!W)+ z+<@VeTvrQKo$Q2dE@kKG+SvR7DQ6oDJu6=hd`Y#^pY|@vz6B(goc`$2>F%JD~>eu;JhMKi32;0TOoAnKtxuImaFw1!Mvas@x`h)Dod??~-YFCD#I48Xu)b3)}YVJz^g>tX# zsqc@>+aSX6VHK<4cg7bWRzWj^qcDZ?u_Heo63%=4`_h|k$XTn$CV3dUB-1(L_7+oTmU*n`^wEVK9j%k7+ z3IV#jyiYJm8NW!EKw77!pb+0I6%r{9BBg+2|DoaH(BWO~N9^FritkWt131?o=sQ&M7*mckF04-dpnojRqY^g8(UBsd<{ zH#VkF{LV{hB7#Nv_qrHzOMd8@%+#IHTf2o}i&xjAqgK~?ugNw8>zCa=?{kw?WRxVm z@=hyN<2mkjxr`z7I~$XrXpm=V*<`~oNi%?a>}nX4Cm<%ur(%piQmd=}aAhR&c>4p2 zDIXz#pW`RnEA%>sq(93g%R9dbF!;nb;=Qf|Ru<1HPt~e`unClj_B$bw_^iRdZL-SY zzY7979Zs%*YwsT^-7Ww`00~d!9nm#1Ui%@ruA0x2`sqGsL?lFBr}gHWh8@7!Y(wx`?0e^Sla7Faf-LL%3nR;%M6i}ITUbsM6Y1!y{NE*Pk&sNkHEK^QHBHv^8M z84I0gD`}C!Z3+dh`S$~K7tl{_2D$cu)l-{-RR;#MX)uzri-SzL?-)B9`?@{I=Uj)< zm8_D5&HG7?h`*6+3rI#Rq4;W7Pmjl+jwcw_T9CQ2p}xT?Uk3ALl>}`w=V=Tq${JE4 z%ToQt(e#ju|KWuFK%qMjTEOMv2L-?~1=e)%8;&E!z1cUR0J{nL9EJ`JsXUa|N6iNo zpT3&NXXYO~i}aXad;t6~HCET*hQd%o#|bftPkrne{O#|WlhG#4?;DdM@0?A7j>QtI zh=}fi2s)}((9aw|quz>Uxaa(~_WBu&LWkzJ^jAnQQxLXn=k4{aPtEy+ZPvlDDun{a zwq=?Y2Rf1}9^bAHjUBu9R%o=*=J@AwGrqcegQ{JpQ=d@(o#`@8*mEJAOlM8 z`gQa=nZ3u<;@PmS zY)E8-%=hCR438+K6KTg$P-*a_9ftys!-|(B`q{9Y%7gDY)jP)Fko?`+nhD?&_t|x0 z{^O~N;z&u0d*j@1dT(I6D|65ME^EUV;iGKsQ~`kL>+0**RXd%Y`lF$yPS4MKE%Zv@ zVtCeQ%2?Xv1Uep^Q=~6>lH?KrMDRprqJ!ib)nD2jaK81_@OmG)bZE{%!7^dNW?A`# zX9F`xHZz8-3Y9ir5PtEiZ;!d-0#Wapi~?A?p!Bt%btX~{iPkPIl31?GRvt%DWo+`i zqp8Qaxw#3c4aFC#P*9R+u~?8IpMdHl`DNz20OFwTgkl8-h8u_MFEh$A0-yhp8(1wA zSvEomj7ApzKoU4~frvmBoT#az12#9~YPc1Y52R>;_tlfxnKd_vk>>|g?v79(6pZat}S}oxxNKrlDn@2lxu)HlS{LOoDI}Dmoqz^>&LM)Fx`k0e;Vrp^m zb|94~qWoj!;vph|#)`otPK9<+fGMNZFG5bA{n1Bg*|))S0l=hO zT}!JiUMd)4jJm``iWqm9@L-`x*9;#=W!OW6+3XXcz5oa@`Swr-TNVhfeQTjF3VuGU zMTfY;+#&A^2OGHQsixTVFQHB){%9XR2wU0x4gDGeRkk5ehVi4^pj`cvRYfhKmxN9Q zu1@ps>Vp7LM3;M@bp1vq1f1vr;k5s=QrL*9+Q{r;UbrFGgoFJJLWl^k1|L?Og4l;Z zCUf5DY=Gy54sXRjbQ{nhG`P32jT@@9Z9!S?Xp9HK9U+0y*)R&T27cZNRF5+tGEtM# zXbjyJdP%~vh63j#xJ2hv1y{%4{z->Z9lWHW@ua9|3-l?^UUzorQ^dt1F~;?Ppv8(u z1OJ2D9{{E0-*s_ufjz4L8U^=&^xzwc>)Fu_vPVzpz`nw*9K3G zlAQ3JC;L^us{33v2B07G>Y*6pMyTgt3^Xw_YXh814lBR^{?n(wtEuIF zrsPhZ48YLoby82efAmMgE`hn+*47pxo&!Y6t<_b9hkpgIWe7hBfxLkqJu(Mpd~503 zgGED}rXdfUpj$rykRT%~I46qz!H;<(r^LXbNJ%+{lB+TmFeFmKh!vHi;@4 zb3kDbfCyKdLDgt{F>Ba^^VC#*S?vttxypTKAid!M12BWt&_WvTtzN9LgPdTZ;oqsUW(Cpv*Vk%ozh2^c~0^71@; zNrGmY8347-)Nq?w8GL)_4g?AyAuXI{!jXIb+D&k;j9GYe;7MEW7YxJf12~z^V0m<` z!2dT<7e0Y{=WHpdf9;wJ!aeyb1~7zkD8^tSe}f-2<0d@|i-O0JF;4ukxOL%vQf6-O zdoViMB#)f%TWjDy+{p1;CFvlmI6UyWQXNh>ZSP7GIA*=r!ZYfR3~?;<{_@G`EaZ@s zlG@vtpJ{%`w5TL-qfjB2%?cV)@WSFp?`np#ZUCzTo!&D5dil6yK)@1Kbu0dAy-5oC zvq6HIne9L_wrn=(wI7~&e}SH9sbmH>x!Jcq{o1}BIjH|2lC1mGAczyt+BKq=-le9FB7-_E zlN4B<)-U(FKS1k_q)xouu{o;7tHs>BF*u&qbR|u>Jb&~`r&RcK#okgPNLpBCwLa%w zS{7Gua&s5?T3>E}_;Lmz-r(~soF<<0m{UkS+N1-_puNQrUtgXy>~C;E)t}2}yT#~~ zniWLDR)=o+0W1}Unt26AQ`W>SsUtVQB7F$a?b$2uqIcybn=Kz|3n&T`IE--Sj$?W1 z2*6YV+$)7aW~zqoU`*uhr}$W8R!xVrdZ@^#_NQzoC6{kDU<) zdUIrq%NIroaI!%Og?j9r?h%mSXjmj4V-n~iKdjHR!O568F2ZW|F<0W0Gpp{27y9z3=2Er6noohp7{I zwwPdgdr&~Zm=4bKb2!p}(SqJEf zd<=de{DN>kTcJnkC+u;LABKpz6QE(i&*W9$B;5cZ!U)Kyg?eJVlr>Vl@a+_FUcE}H ztiL%^j4oH9fHS{z6&9K5FX1Bj)9I_njS{eHA)F*-fodpV0_+>^arf zFALtN;;|q$WUc|{KwaqEN6VQuM(rB?Ec)0$oXA@!HsWw7W-8-53PU0wz7c-FCN3fN zq#N$YpcPPKtq$d`C*fvg&@4Ee`}__V-qjm`jX(*ygS$uVMhHR~NM9P@Yk!$Gko{+& z9NZy@g9a@T5sHH1TL1>MkVZ|3^q*H=;?2P@$C+W!7DW}$w; z(9jSpdQr#1@<+HXe`l|W^YVtCOyn!3x(+at^Z(pg8wWE4h}x!lF)}gH3&ySBPb9T| z;Hmc{p?98cW|8ui&ACI){ssC3@b1V=Zw&mtY+*503*__miUrPr5*&JGz@z$D95-sbq16_E!j8-2a4xM3Qw1`P468+AVYQr$!{L_h=AvYPCoUxaxE^?s);* ziYO$gnsdmijv!P#0BEELtUF!IgQ>U}ADUZXp2@;R$Dm~S0N^B4vBv>ccLaR{Nrke0 zO~k{4FDhA>?KnTz8j>(EDJ#M0sOSXKw)?=y)JT~PylOSZtKLcV=G@M^+AF{ zWARmJKEys+vhsuK;)M%@Vv*IKJP~m#p||cbI#q?SNYzDfwxR7Q?|taZ)R{oJu7CoP zcpDoO4m17$6UI*bP@+JRg%g4`!FY{n{yx|JF>!^(qX;oT55u?$FhD}sBARP3aPs2^ zq3Ti`FmCoMMa_si5=zUuzYRR*k0jFU&k&{rZRp%}ljOfwXIemo&CSiloAdEq zPLc=jBp7L72B@YhZj)&XoOdv>5|3%F0S6$sU^H;|x&izWzcz__L7DRGy&ZSG3I#(8 zvv3@Zwnf%~#4&NMWhyB#RI%=U3C@E4q{`bHP+^8$nndn;jR#}_|W5+ ztosK|?~ViEg^;;A8_Jo9BzGziqEnnRlgWvMx(zs6aHrp)jfzKX^5QIDB6>KR7EGwR z?O(h+SRzH?gVSsVcDyFzi?tG>KG;dZfPj0a^1W>^P+t=AHmLeLP($f=*F(e1mFftvP#x`b=2a=n^v{n}N$L@y!Ap(9& zS1JwgK|*271%oRvp7~&02Jl3TG%zS9vCBMZTC1fI_y(F1oeLKv+jRSd5W>O(I)~p~UDWLIPS6Vyv#ejn#cjh`*1L79 z(6)y*=`p8_(E4->IuQ%(U9e6AkWEmv9s(o)_?WQi^|KC@Qw)92JDtSioSbdgc&6Xt z7E2zGcN}2Kh*O4Fe9I{BE=_Y54ElWj_Z27-7W1c8B$&b+{Ihf+5^J9`OA8qztz7n4xb z$?dc~L52s0hlfY&xFXDZC$w7XK~ld0e;FF?LMTN`|sPZvv=E)_Xl0uR)w0?p^1i(kH0^J zKSKPn!&n$7vyHlmK`=0XEV^c_I@mxNK;!h{A`NRu$|gI|J>(anX$WDU&m-lAnBQQo zTVK^5smr_r)|U9l$f~yZr(kbDzBH$gkz~j!S6`K6wKKU6svpUawvCNoG7k_{kz?MzplzYS;>=M&u3nePW%NhX7{1(bAZ3U@M|Dzt#dQT;EZ*^8Fuh} zGK0{KFknrG4~WgkK)i6^;gFokq4@I7s&MeE2H34??KofQ=;~HN2vvm%N0D5LKQ3bU z7wFtIA^g#whfpp>H#gyqU2Sd4(45TZ#U1%A4t@;RV`Sa(oDnxOwXdX0KaNn-X&qd&*%sZO%v;!_f)$#1eI8Wqe zB;i9QWz&kL3^G&;9m^IAVZRd1CMo@Y&O%bqzb_7UPVZkDCw!opBA#)r!WrdF$sK9F zbO6x)-}ea}b#($_@YsnH>%vEq;BEBV<_v+8qVlIJiA3rB?$f5!N1NZ@y|T@eX#qp& z@Z}G$-gDoJ`^S3fByMZ)aR~|80<~eO(@avGZCuhZsS?%s0BOii*_9Q2c!*Bj^EXKK zM3xV!iQDw(SJWd;>Ss{IM`H^GxEw%O{xMAP0vWKVs#5iR%}?UOas=P^lAlC*9hMTm zIMdtLDN(4`rU^-wK-fmUg+)U|2gp2Qn%S{N;>H2&;Z#q&f1+arO9s9z>DUUQMuWSjjCd_$>fdU0uh(FY-G;U+ z?w#4APcRF1v4oYZs>TgcAD7(DTagQPb_)>jAG}Y~_%kHnJ-;f*oj8qpH9awre&31Y zuMhb2TGsOn8|#0|DnniX$|iBl=$~%tG4)FCnHe(!Iw}fKH5AU3k4gcvv-jdA8h+<9 zI}P4Yi6vd9`SSVxtu%Bze9^&qUnb;B1%LpBuc3)Txkw2JgqVfrvm=o`0W=<>gg$?W z9$kRS-qN0<<^cExo2Q#BMecN3Qql!fXJXLtap21!1Lb|QN}J4UQ?^Q(9F>cU16~_( z)qf=yVH2nGg-#0!%cx$FbZVHI+(*&&KsKnX7(NnWN6Z97uz1gIpnRAfjEqUk%&gm#IOSu`Wd`5J(R9#{ZTd`bEj`^n z54pk#dJAIVUFi9g09u@Ba-?o&fzci~sYKc9KOSV-id6QID2y*I`ap*W&%IiO#=>}& zv8^D5e<09En+QoNmro{c_7Dg%j^{1nrytGs71*ArZ29C3z2#`#?!#jbBOo0eKlJpv z7Y82Sg6gFuWVC2^16u8^ZF>Tp4BAU=B+7ewup248-nL|myR zw#JZrO*`yO0K0>Nd6hrHYK{CZM~2ma!n{^N`-V)t4XUc*y>>3&cLqB%Du+8D3a(wU zMQcDElREZn+2I)JGl)`<{t}vW0EJ)yZ7RhDglTP??%yc zaC~!_x{$1=rP^%_36h+goH%`#pO5b@7)>&su`P#uXpHQ+sFYJ&Axpy zCE7n|eQoUw;`|(u{^Iz0c7Z?Ys-a;i42i;s;o4r}iOt^rpOz;{0?~ue4LltgH2%UF zCG+*M9YTgesDIAMnYkJlruOIvi-E6|s@^($Jw*CjUs)XM-CMVgxBXwt{Z&+!-y1g$ zN;gP%cXxwycS=h)NOyO4cXxLx(kUqoA|A^c}#)!W8EwFditxz+`Xf9)$WRyZ0F-s8!GqFO>~k#0ff{oF)_&fZx9ui6Sdzzde0;j+ z7V?intYBp3w!vojwn5MAmqH>M0i)S3e?aW}viz_CeJoIFi1>~Gv%Hb_jwfqRulf`~ z>j0qbXM@Y#68!Hk1ls_o!#7M`l#A1xPvDH~;Y6G}e$En|^#$CB%`eO%f*QD-Xds`7 zma`;+#2AEyK^G}mgltHR@%@`0C*H21hgtcp!oLF+EBTe)wwjyUHJHjL8FbbmX5V&! z2sB16f(Jq@SVsm{&i+~EBy_O=M&rE3cj4P6pp8w`V}XT`P+-8oadp+RjU?X<9%7N%MSx-jZqjLLd%X2!PMfv2L*<}~S#bQ?77X@o z!0>%vNrHnaXv>6+18>LPok|1S;OVOyC!_vbN^yt9}LX$5=mgl25XtnsOvubreGV z@B^k|*#v@52X6ELRo!m0LQz{+F!dk=nSzRn$jS9GzMzSR@F@pB<0oGQVubbA)Wpbr zw>G81#KAfIb)=;Oq)?DoLY68FWdRoc;$A(gqNyXi0%R?d6(RxE>FU4P26V`GczEz6 zPriisg(G39Z7Gz%fQTJ~-vI{@oEIp$BSw;q&R((dv#=z{Me{(YkK+Rfm;&s2#Qb|3 z0)YGRN1UPdBxdPOG+}`S5G=&h>m7{vMp)P%%zf3tC1#kL4xru(eB?=PJt6>yT{(hC z$-n?f111p7m%DRA?4E_21#Iwbk6$~*u?Y(g44`wE0~_A{%3pa}4vd7j zIB2zlRH`{352|<|09K}(j|0HV*Ve{$vbO!=AO>WxYUR;3#22_S-9d;!Lm^NGV!}?Z zPx|rMO`ajuD1l)N5XF86 zAFHe*0}hNhSO5E@qZ6K8Q_4R=xhyvDkfb|nlp)bW;?kWP#qZy>zKrn}ib26Y5<6Ce^T-UQc z0Ouaib%P**J@D+HtO z_LcNCNNEUlKGx_D1qDb{WF+s=l@N@FJJ4xv->^O{EolO2iF_FSDy*ra3Fwr0%*Z@Z zpxjZb!LTFez-g!U2lEy2D$B=LZ|YG*f#sOP`pd@{jVB$bxyJ{sOJO5|Q2wH;5CiOI zi3EaJ13R%wKn67gV{$%Qqv!_x^q`V;Wr9wtGQOzJLGzyMc%B7Y_g+g){IsA&vY)noL(E~U|Lt>eq7B-z4(TMoUnY{te^021!R8 zYOh?mA?wl<3=~Irv>9%dpGp9<`N3o=HK=^u3%sE0!NI}mha$`>@KvJVqccF-jMRgZ%|8qF zG9%Cuv;EUauv-RycC);|${$$ydYb@L^MAmyKT(j%=hH2OUuy%AW(k#tu$^3kKSaIe@Pb!^G|ZGgN%uo*D6-hgO^WKk$9n!RZUxHdQ&n@k3UxVf?E zEGUoxx4k>8B?$@K8NCdlcm=$AK!1en{sEHU0;K`kei|X8?X2 zK_8S9AKwp3%fZ1xNWMZ*8Z!W0#5aDGe!(63g$f7jG`eidr5*^XM!1h~>Cjy1!?3Zr z87grlv7G5=J#5^k0KE+W&`{_5uVgr6YPI@*0O0}ATUG7meb5~Z0fODXAXXqOYBt>! z6PU+o*L?x53-)Km=b3e8b(R*nJ#0k{4NPp!R~<$m=z&Rs6$%1Z0TQ@mAEIvjlqr%+ z2h$13)&m7A8kvX>IB&t33WT%7z$^pEb#$_z2~uzI--N(559lm7zZ=jRffyp5S>z#e zpjZK#aeoVQ^C3b&fnc=TF03xt050L`69PFbe^eDhDgqqbRmSW8A`&hvZER*TXeYU< zSR`sfpZx$Ml-mY-3J)NNP>$DOZLkUmnlP5M2}va^61rh4Fjh#$f~W-?VPVRlP`HPC zU?G8h{#Du^(8wSSvU+p^(9P1=$qZ0(nfOq*;7=%HeIF;6u0`}|N9ymOM+neq} z5y(QC?!bl^wu{$iK#))Fdx%-pVm51yoL_wyGdDT^-oJ05{0P#(2)C~a3 zFkSI0!$?A0{8a^dTTZM+%9t`0cOZ*lhiRMMfOBekdOO&EAOf7~PeTQnnPXX;6eAS9 z6ih|R%dggSKF17s<|=&h)KNihno)-Q*t;8BYvwHVj8vdQkwdH>pF%&q&*edAMQ6pC zMns2!>zFHfC4e}FAiggp1#bgi9E}Hc32lHdiD}CMv95qKmrWoe zOHw7JrKyrAM~sw+Kzc3lIy^+y(xP2YbY#7uu4rS(QEMI@!TL4r+_SJL*(b=k1J*1^ z?G0Ii8$_wYKV*+FO&KnUl^_g%17C{jM(Dv^W3#Y8Q6-@nPQ=E*unvF#AXfl9+zT*8 zK!hSdGs4KmwkwxC0ZF;e+J99<5cVJY2>xvl(D#2i6&%(sNHGn15SC?8|Mr<9i~y21 za$?>nrkPU2(U7fX#3nY}qI)zN{otEkv{t=#l2IlUMB>WpDZ^Oq|DZRtv>Rl0C8(nt zL}GVf%c~;1Iv5*j@`({w#Fp!6i`#}GfeJ3$E%+rzGWAIP;@!|!diCNA%kLqhKz z!s^b9HXt*XTyF3yfBGc(FZyM~1QTYo* zb-HM+B!l}FKi#0MI0lkHgBoBqyz}p5R>dUQw^-{f)^quxOd7a6M}`J@T7TW=12=nO zd-r|GyDwBp9Lvm8pF67ioNo*8>>%ZkcM{m%s0uJot!yeW`R@5Ex zq(6)~(Q1xtLnm1@&c)tx2lCCW{rBd6iwgt2Kydq@eGU6w1m%{|3U2CLgvstM{~Y7p zIzK@L;yDvt)E`ME(wI5cy%;&e$5E^FZmEXbr?gW%&n(w@$qk;^Y-M)SxkYMN5_J&V z;9%bQe)SDHgqMts%G;mqc~c_%9Kp7ZbAl+~;Hzj^KqwR0Y5!8uYC-)H%PE(0(zz?E zl}(Iqcg+bK)r&ct&f$(CutBHL_Wl!hcg;*b-DJ1zlVoZ&qCnbW$mpPmDWCGze~-Q_ zfq<>$X_E*2xuFcYZ(IGN-Zd8CNe{tmSF-C%G!+pu)LKJwVu#>?bA4#l_etjVhYwZO zZ$E9zv>&S^a@5b>gv4rX0sV;i8~N%BDCj0O{veOIOBe^VOlI@%d6sbDANH;1-y1tO z6w5V8*_!_65#AcJX=E)B-H9N_Dpf5DV?_JN`25# zdNG%uN1Y&Tn(vc91cc5b_s50_s6NiEmTJ%XjB zgPU$Kuj1U$i_?k?G5e;k-HiH#5%At47x2EXYlZ~K=g0e;2uCrgXeGqLZIe9SAwIaK zA{kBPqPgF@A_DQdIds>AzyE!5wQ!x;8(@BaUxpBrX2TW0A~0xIKrTi_Wj|;)F7}AU z^e=^dr~JodDY=H&FX#-3ZAV^=?pc=xqqX?+q=?Hcu$M{?)H-h9# zFv9Hxqqxx+-qZM<5Li zFOgf?gfnt($mWyO;>i4|TLJs~0uxMB{RbpMw8~sd^+<<-mti`~EWTd{DkFXTu9lie z7(URqI&#x|qklG;v0dZJYfERBI}lYiT`R83bD@4!J9H-VzPGnD;Kk@EEbr%QD3UeE z>IKmlstFutx;D~!ETy%3Uv7`cofMPLr8fK4#GTT0s?liPs;?MG?L403H29IdF1?_R z?5_+=B{p2oO}pnG#QBn;+h8v+(ev?KOkZC&_l@R!!1(o^02!e(z6<@mqd_6haB@%7 z9fwSw;0m)`<5lkvt4!wCRa+Qlm(@*2t|2ATk0AP-lSiPp06_)D$Nir${gw~g+w%S< zd9>S8F-oi3DwR`?_mNFIASI{iOH_hZF|N~9n{<6AJ#K@q9pShT_Pr!=$70ajAy2mo zv!xwMYd7G6xh;mXZu)OM55IU#+99Q2ovUN{osd|R@OSJpF4y!25K zyc3EJpFD)J{NO&bX%^0cjeS@_C*1H{?XbF~be-AMy7Z5igUTZZyHat_1$9_*Py8|= zri$&@W)wG6(^*L#L9*~;*7YHUxzk)MoYQd#EmOPhmr$c`S!L7j9Xev=Y8rxYlisCe zShg`mtNKW{L6KU|CC1}*M)z&&?H_5JC!Vr7<&=6ize$%c=3lS`8|47O82%P86duz9}P8K3(~9kw;KADj}qSoV|==Bh!EyrblFmg1mX z8C-4c65-75Xh;?Q0=T(@U5GYUBznW zW9{3I)1k11KE_UcKdqqsox8p&5bvXzMNC|fCbz~7jeS3DXrrLHH`F1rIbVy{BIIOh zYK|P3Q)%IH9Aff;Q_!O!!qmsdJT-9JgIxv7MJUR_*XWA`FD04xEo(~UI!WIjhgbvl zdz{VL-)4NPTE76^z`%%)FFJi>DkfBtg8!U%n* z6wPbcQ(EOi{q@2)JA2_Pv9o+-I;?{Z`bHq~ntp&^qUz!q=8Ucyu^7u_G5tAdk>$WS z4Q+%aX$)JSt;ME8rJ4q5L&6F^O$(`D!Mfh3*Rwc${jat!hAGJ$Yi5t>N)7)kdBiF5 z{rsF*_MUMCw=#i_Uq3(+t83#eh0IHy;`G2H)R$5;H!SjFId>|m0KrpLdB1Hm`8lf= z#&;tdZLEygdt@>5S=9gJ{d5aPL^N{G;+8Ii@ebVUGI%Rn?7XPAr(C%n)qlql$GsAT zLf7qQ4ITfvLv6xC$#?b*de6S%qjgi&J%Ns`ruu!J!Wtg3Ra8ebtvm`VmwfW#vPBq; zYKa*ugR+RI^0DT~FxJWd{DMmoofq_K0f8CgH(Pt#6x(zJOcz{7xzqvA;YINrH%_^? zS8iOq)FaG+MwJdOZ*&bLwG@@OWpD7C{TS@rE@Paq(l|UTM(;aN>3BG6I!esK$C3PZ zI?$?P8_xOFNr=mWqP82BE)k>U)lW)@6qkK|azqG5QemJj{-M57F7&aC5mG^9e8lUG zuQ`+)nRTO3a>3XNV)SO&o#hq&-@8rZ`>HExh~u*Q82CG8jq}W&Y2#RZ3$rhO6e~}8 z7sa+_iVmfxYXWa|6L-lWdC>|MtEpMkl_{9dbu5&+YP34#vaq6@_QQAbLWQC)QvJ%X zVjdlzvUtAASKoD}(puiqI*z1B{#HmixRa*5T(Vw{B6_5gXtud;RR&i%Q1g-Z4zsmS zr-$dN=)2#R3&}oxotNM0Pt4QRnuDpG+s8G+}s9H9TiK}*B&2TqT}EvS{*ywyNr<8tm9?u0nd#Y_UpO7ZSmB zz!+AZp8WYwMAnYMs`Kvgr>*CNr^v=rdjpj1ul)9Ky$B-a3K7kXjY?pKRCz-mO|?f> zMl`y%3VO|`L(zL!r>!EvRGwsTeN1^PW^F;;&i!|C+V$u1=%(PiR*`K(ftdvJdr_6} zR4mwex_j}ptG_Ga{q6Qds@QgGKYIks3(kJoj=@Tc-EBiJ8RD?x4mOo?J!e!$`G>Ey zwb{tV_R$pjRJ`V|u)-|NyjkPI>0RJ!N1ep#jTS}D%!!+2GIytJ_)^=m#Cn9>P!97#aQe;6dVzns1Mi|F!b@Kbx@+mWd@6PaQ1#w#M?0?SF`%~oEy9ESBbw)1bu6{ zI4MW6fYq&ogT+r|rx%pvDT@4Op$Wy)o?7#LU`8(-V`jcnpI2l)UJ{nze2h--f~OK~Xz7Z~FdCrmwdK8tZF1ZTIH zS)#q|7hoc|_~k=YW?Mse5gYeg{Qkh9@`Qqnux;QR4=%-ExF+`-8|8P8h1atZyC!>c z1vCxv8&1xr+P`lDe$m2*t$4>a|1o?vZ{Ik`#MR(P?s!jJ^@G8lXQ}0xMU(ecCVb%6T2zaJK~6tLmpPl;2*4KiWv*vaq;db(IDAOrc)+HeQTo=!RnIMt}0y> z)^>a{w@kk&T(c&N+xG3Lx@$!U{lrPS4wSj_7H(F|Q*ER(G%i_cON>yh(%%;r8D`*& zkyXiNRjarof7el6lDdfb&`HG9O_PcyzAGwQy)YqfPvDLIUAZFCc*ymO5_v-?S=V4@ zoi&D+a_st?jCk5#-~NFN6nJB`?UNM!p6SqEvl8bpAFmx~~dN zi?`bqW{c9hmeV?D@%?Jou6^ktB3&Y85E$L0=X!d%}I;E|w z<8L`wGic1*3eEAxy;$VQoVgl~($Mw;)>8jcGy6MnT$t@_nmITwrI*#95+pd*#b0&n zJuAp9`$)f$SYS&Mk`)puieVtqFWaYR&vTUN6QU0Pd_X!%EtTahC!>)(n+oRllc?iQ z6;t!iSdVwm(KIY78!ygCC%j)*f%HEtKtWjNJMqUhdhUzU;!BgWhJ9Ue@+JL8 z8|pm5x|}h!;N@5pkG(>(nUAZMDA}b;SoJ}eB9yn#VK8;WIDuro)sFE9Z3*ijccmosxP1UCTpBadB~*+-nVhB&c2I%%KOSIg8OZ z>ide$_=~w_*-8gdFP#KghjsFCd-c`TWNfVvdM~Mr8w7WmbY^JU`q{t#HN{OeU4u<# zl7?fyWy=_L`($w2Y>iE3t>#42{4?bg%J8#=GhI>cg5tL{)h&Zwg|gB}zp5T+0aZac zY#}Jj-q!s%Gro4cb%!X_yAaI`4kK81g33>|l#@5I9&rP4i^U)2ETYv8E+lmnz@}Z8 zk+6TL%XZpJYOk+Ymy85KVaxjtxqrrT`UkArQ$NGYsg%9CM z9`n6Bg#c3=4Sv)ds{ZTS;sA5A)}PhK4=LL}bpM<57*66tAf4_thi|+e|L9ki&cIIv zkEz}7?pqlC`Xd5`CP-VvOV$61m6xNoJFb)`K%cZtEb?A$BbA9c7&msXV4U)&R%&kK z7=6Sj{+F+Efe+b^CbvJx)x=oQmWwWWBrZm93U-jBlMwr>rYdM${%m(Y2;tI-nk@*V zGH}8APw|;re{l2ou1hJS^Dc^x6q?b;DrgCSDOuve){8Klo8(jD)@6A)Xs1&4X$UX8 zuB&a4{Ou=Cj%AEyQk1@56(4Hf^HnY{M!sT<0G*5Nx{vN6cxvU1NiVep>Bu+}4#8RS zHV&>q7Mr;&?&lqgEoK`x456VVn)yPfs+&`3D{=U-<28}*v3 z)ye+zSC}(wIr3LmNP-?u#Bul8YYv9Y{Hy!q>H4zPN*6DhodKr;a#})APPPsEaix6N z&4zs1Y*ea@K9s?=1{&G0tL8O3HFlq~tS0X7@6JT7KDGsk_o%nD6ws}p^T&Qge9S;0 zx_u-tAKmkP7^|f3M1zmIM^~E`li*rbN5(u8rFk`J!p8pduRF3fdm671!kEUGYxKlB z+Rl#=I@t=?N0L&zz6)c<0z)L+OrsO@Lh+s4FFuwGeloXz4aBoh!mX<;>Mj42K;#Ce%Z2 zK(v9NrKl4X;xlgcZ-wBa92%v;lHDy)7R6W37Jqd832U+Y@kbdrp{JM?v%VN=-h^3a z`(^gNz=WHYG>oEDg&fPArujIHhg#t$`W|g1=5T8s3Z^7N`A2QT%D=FtKfX`WtzOf@ zygc`zkbgaBIg$WCxZ8IB1ni0Wq#DYw{Hw^!Y6hh6%0siXgv$|CQ})82?XivqD~R4p zicy2pRZqgvSnnv-wK6i_y3u}|j)`usgcHrkw4$(k`aV2K{R_!%el4j!_oMYC;sM}UX{SdvTr1bwY<^t=i_*G3QO{47rLt^ElZjt51naBV{1&* znWM{xn^0Cm!Jl(C#G-F2hL7Dn!*wdqukiDjd*>wPKLveTo}V|o^mNq!i-seIhCo^* zLi8fNA=;&e8b`7$A#(GExK5{Z_nj6_Dj{e4A)O&!$)CmH{lXh$@#jzKxhk~!@I>cX z<9YAvOI1W9J=6NOPnS3Ni=BonO=Ywryr^Zjk)7I?yzF1)5IYP8GQGln5!lc~e1Q6} zQ5HxFZfND>NO!;X7ed^}ED1@M%IenklKFC^T+F;V8_GkUh~@I-LU>OoMXr~L_=ETt z74JKJo-m4I*iCoKf%JDBvJgLE0ZHG+Z2!NAjKnc8+L>d->9WaQ`_YZBvxoUP0S3B(;Z|CLhFO2xSb5kue2)>yE z$>#nK=={HP$L#+HbdiV1;UyI`?T`M#&yl_%#>D#;oNlde~fR}BTe)3W4YV5% zNxKLdn~hM9WjTJ^ge4aQxaG=l-_&^Pdt-Z8SO?2a?W0x~v|S zw|)M|6>8gDxBrs2(mj}lYhTM?UAtU9|wtr<00n~SIp>Hl8h z%6mWApsM81-eeXNcDhj2nV-B8?)(!xhbk~KD7+nf^?(lV&>QVy?1>H$|)&fPCe_wjSKT=qp#+UBperEUi`IXGy4 z@|Cfi%ti+J&So5I`nqn66(YxYE+7+pU;td2Ib7UPwO*XDyZ~ooAZN5DPzP z*@@wI@p@LuCf7C3_J$u5h~`c1j=pMUpyQtm7yC<3$p3wti(+13b2PM-S5^TI;bApsTKbRj151_ zO9Fb3Z`LzADYr+ZCS2)IZSl+vR8u5v_a;`Z&>dn zRgL*H=(J=L9#KEyx%?e_j^wsgXQdLt>mQixgxTkD5e0tt1frsJ@|_Pgo5|h0jX5Bu z)E4!@gujr!9u;P6xdt&wAf6IQOHT2TyYU%C2b~R@$8kZR(^w}YC^BX{=b>K0Lf_py zLZ$+M@e)%CtAFJE~TdG*#r9{+J8m5(t6be`yRqa$RcX-t@PIUP5+3qhA(EJV8^F8b-dJ#J!GU)zkl z{>keyn(-%t=9ik%O5F6chug^HDT)o-x~A8e_6BkrlCHyquqUF%&a%WbyHI;uXwUl~ zD#BLnyT9UV_q1yM|AAmB>a_g=E}LP3*y((DZ*}pi<)p%|0FV8HqMcmH*4(Ty^Cmy{ zuz&-HPkX6kZQap~9!tH`!_<~*CtCXYki5{hg6u~FD@|?9&;Be4KHJ}o%B!0sT(@Pq zw1U-7R^jHyvjJ@FJy>pUh!af7zx{`OIS#ecb)^#YzUYM$349YIa^JvfdmxEGa*+It zFI~D<6STa!EaPG%QW*D&DJ$9^#YUg(aY-CL@r{yY= zMJD|`9$sqK_}KBf)5sX^`7Mn~381e}GAi8kvl#?o-?nn(4=Wi&M1?pA_$z*-JnQB$ zCXX=s6HRxVPHO*L@NQez{FMv-yA!CG(DQrN*k74Ak`Yy(c+^|5CU}3aImi(4uYS?i zZHj^BhLcIiPsxzWv%ENnqx03+7-Xr;Og{P)E`|sOc}lGzugSp*c~l3$YXrck<3Z5 z-oMh78p5IFZ&M>4+7Ms2@r$K*b@xWuT7Rku zBNKHf8FnMJW_ZlF!XsNetur&m^e#fFw}W&h!dKqu@O7YnP9VKRY| z598hDcS@uZ@Zp|NZ>wr6UN6UI=A!Q2VsgtK$3NE=mjk!wPS>h|`w{ zI}dxRm}%iHc#^a2uDN55ut=0ZXr~6`95$X;`tbN!|C|Wb+c`0o52fo?2%n(1@&W5$ zp}SW?q1}c=TGr6MBHi!vi2Et(%@j3nuNBV1^Rf)gzsU+#%dqdS=8#h@>tj1Vx5P7_ ztnGR2dJnrSWdDpUzoqX)n2Wo4ZA6Rgjy8c$NrEJ>m{`W~qUBd!Q+fJGah`sp9xAzZ zIq)=L^MgL!Z%slgJ1>H|zFW4he?{GoziwT{SNX6V$BwQtb}BrMqvWjhx@<;$1_p({ z6zNQRu$8Xnl%j1o=1gO3e~D9qY2&QD=mJGWMV*mWfx5GgIkL3#_g(_~lzD1YW@f#? z%l`gmqgpB)lwY({GV96D51XVsmqRaA_=sysF_=geVU%x|8O>2V(1EPDVB6tRetvPX z;>T2z`bXoUF8g5~p)c~5wTqltyb+HL1pPMYGur9ih&!wM2VxAA?LBmcX>YNrx5rr; z(zJYAM;Sg(IZ-Lry26#dQ2S?y=YRBZYl_qwJMg9Z?i9R^DI@cDW%gsIS1{d%nHeaX z=U0iOZkVO9dY#Q>F=LtgT0T8~j>}NrGOT5~E74CS3#+g2HA~h!eB~g*~DraS9 z%Ej7I{JWxj9Uyg-Mbm~m-9K@H^C&)tTVokR-OP{0x6h_2T?upJT=BMULnS~t11XLt zeQESiLSJvo!m4#z1B~M`>>>ZsQvm&@va9Z zsE1Cc8qzB!%9fQ+`l)#OnR~x^UW@#E@BLOhb9hken|sG*6(mE7MNGwzB#n3 zr&ErXTuVJX_c`=>N=Hj|&!&k)NyiB>qVuP5Qz1>0D$e#&Wf*b$kU zGt~77YRQ9!F;$FM>vd^xg&m_9b6J?z)eUo)sz)V#;f&bEBDR!QHvRg!+K^c!!^JwH zg#uR%R}1(5QqHQ=?HH?kQ!DA{M;kj7ux^SXLH=H@b#icjf65#f#Q+N3MEX zK<}?Vkqba;f`d+a8>5r-PRYwvhNwS-;BJy*P_9W%Y{O3_3cD zxRE|Gu>SwgbX^({tnnM9vz7ZnaXq}g%)>>u(91u|QqMh}svSvIFTyJMe4-Pz{Y%KV zB$()i_Ww1m4JNKQ`Y94N(H~lSDU4ru$ci^#uQHysnad(B%hMaH;Ne8u-Q{pDw+OILE1zNF+h`B~#(SX&?wps~RrD4=ARQk>i*e`cOBYmtYUlD34Ut}vbyrK*p zxGk#FA7@msbVw7`D&@|ZiV{o zA}hPiw3em`rZ_ekRt%Bt2)Y{M+o-&fuJB0|>glFb&d|$CM2zHPgj3O=pun4zgzaB` zzAnSr9??oNd2a931=9aWut{VvVqT>01qB7c-*vYbyO)+?njZ)p+55>jDt|Zi5>X%W zg`3~f$}R4oK=5-s9w?1{IQ&vj5$nD`Da_#V;X*z$^W!ab0AJDYT@L&#i)C~Pw1VDE zt1suuyFd#*?JTP|y#*|O?-R@Cqy9Ls@NOJ>G9EGW!v4LBzf7e5>y;o{8s+4=rz|PU zqtMo~4qV|??&CB;+j^aEl?<_cD9W{A~JF+=& z9Pme>D#UI;eDkR>>rH&MA?9%35@O#ldiujH=cx0i-`DX+xGJ?ZwBce28 z)KzTHv}5v!`8W0WY#XSTBa5;3!pjAKt}8wU<@^N;M%+++Xf~h{+T2(B?mOyBRL$1X zO`y7Z(ynM!VzG!XfZ&2nf_q!>{^iWJwYy;WXC@}oSHDdR2}5B=6-1dA$dGo1e%ssM zfNQraAN(iGi1F_!iXA`9H_7Y$lDQqLmyChzrFt6DWSvp!F((!E_A@kI308!~W;tpL zXeWcRA5%ll82Xj{)7dvsO1^p11{uQ1A`JwEa5?0s**POcaPpN!T1{1k($&HUzYoly zKN}Pw5Ayod{X*k)@P&UF!tix7)<(dE@{}UW$WBx2{uG6Ih6wEv^Ozr!x8F3A_`5r$ zhCAZU^j{q6i)8A!GqUe!T8oHT7XMRp!1_eQO3`q*dvx6&9VsiXfE@DPOybbtph*zl zZFt*DweE`eRIm^+I}LxG?{xvA(N-|SD*K~hhcDYIqe?de>kONVQYO&5Wj!d#VwE9A zYJESI^2M40yAO9!J#VUxT!iCIHB+>2e#@1P=s(V(|+9yzy;?(wVmZy$W z$;UY*chJ~XaG+(HK-E0sF>P1xPhbrd$}%JqImGxu)*86s=eb;?AMH_d< zX1cq{lW*}X5BjH-_C9P7+qJZx*^jc5xKiKjA%&i)QAfY3;@uC;skVW%j=tA2Z8XeY zs03A4kRBwFS3(DYGsSqqB5dFw%h5u2LdCdx)kUG5#g)g`lekXc;e^F>E|!z;BYa)v zd{&_w?+%sFmS7G!2DVF#yZ8)e2PY~-F>It3sN3;*t6E+QTxk>63gNhxF>t8>>?7Z< zRmiunaG+HIkSvGFmF$5`0bwbBPEyFnwxNBO?EZ&A$@Pq9iBy~d3<0K^DB_y1M9Y^Dii^H0=b>iy>~ zO33{>6)EHjUH`yD zCeAEk;;vof4b4KD4~w%QvfCRz22?85f_)AnXLh3})@1raX#ma%_!6if9r*Bfe=hyg zzN)tlJ@d@ntV05!k*%1h=Mv4kuwk95SsI?ohi<`H2B3U`Ha7GIN|a5y&PNy^ z*V=sN1LRuvdlNJ(HZq0-EQ?GpP|ElK7PG74-(eMXiqPWt!7A09 z*!VYg3bwvjxEDT9LXf5X+xz1aiAJDK9aHGAY<9viAg7xzzhbLd3=Ar-pEka8NMoN0 z_}U=qLtIAN4_)&&6?hjaA63}ZF>PrT7A($LmR7!xFWm}W(uz=vdc8a{us1_=y0#Ir z{MKlejlLznR&)7h z_=Rc8MXhHnz{~xiLQcV&6dLwPuG!oAH`%%7D4cgN#xxhJY8kD+Q+bb4NDt14^Y+P` zkBd4-WKXnY_N@>|oinFx`sz=3)C4T?pk-OWXY!p1ru#D%H6rWaW0xnxVDC8CX^ zE~!>Q%ZWQ2`NU$|2zI2J#}B3-qLz4^vnbQ58trlW61R&OCw73A9d?6#Ctj#(k8StG z?s9!Z6t=o#tNyzz($k7l62?^Rp;i{L&GOQ5jon0YQG#}-q@~}xYovr)Il?fPdhraJxef<(6%L5D^|{WjH_sq2gcQ15oCU= zndmwmUB}yV)T!9YPf?aADsY-*O0Dlg#zeE3>8el;=?lm1I((+CO^->#U#nRaC~^EA zN3>dJOn63CzbUw`A*`|-{jtFQuV#n8%TB7Sl)V6hRQxw2W)}~tef&cG4RL!~u~e2o zsr-6j5YfM{{nv3x5g{oDt60+OLme{<)1J@l5*}J%=t;&vs`w@c%3->|#7k%k+kAU< zNUXTn+*>Z6^Y4_q@6ii>ZM)|J;$pfhW$^o6;_Q~Z=HJC!xwFPm%2*Ya(z8P9(@K`o z*vL*7tC!SS+h0;o;V=fyuC2tW*2XGUN66Pb)C}g^5fwOXgVNTt4lmi&Cs}tTIfC4F zvzZTo;P2X8nxnz}5C)^Ylzyi?Quwzt)?*o2>^pvU<|y**5pieOwngLDZkpk@`n|Ay zxltcDVXUSpUj!SW(AKz|J!^@Vjk7**Zdi_}NZE1qs&O!N`ao1>W=N;`y6N{)lp0&@ zL32w`9d(YCOOWX?8d7@l`L+g)16ov(UTk*V+pPuIjj2KyA{ zT3leUEZ*yvb$67mjKVq=6C${Wmcq5RI36wdzUZj->Ynp)2!fO@YZI$z#BtSn6UH@p zhi$6Z90TZ0=-AXp&KacMd^&!&$KhO>;_7MLlmNG%*}0Qb9UUU+qoe07YXh2C9eAHn z_g2-1j6X30OlarFDh545n$U`;Qf@G>IMqIp{W>0f9j3~6YGadMj!O-t=Rv{tC8E%Q zC65Zz7aBDctCI=BeE7pW{!CY)JJ0LsAcMs@&9z6ieu7P{Xbyib;g*g^>odRg+~iT? zF#4%xu6uIAJ09Uo9xOgC`2RQYT*S{CXs>8hd}e`_b;nc;9ad6;JmrD;UwY-2txSdC zI1i_?yunBYjqfH<8!GBF!}m*2S;G(z1+cPshQSs++GK>V=q19XWuZ8<2b~1`5aH_Q zyQ3ditn+Hx-1gvW#EN+GG0sF~;q2d{hR4$wGE0lM3p3kOa~;lQ;<3`n#mGAnXkuOM z|6LW(7D={w7Q%n8+C*>1n{RuLK<&&Ek{82f%Q1`ulz z2F8Xa9n0LZ`%^EB>kL~Ds!vkyLfb~2jwCkljQzS9g6zHhukGo$a5{B^y>ZLj5gPYC90_ExItwn_miqoR+Y^V!-#puF z2(2r;;lwXl1L}p$@RcU_LjHoX;MW{pYWhXSc-!#2q1~aJ9T}#C56D<~emH+UIM7=@ zscb80SIbEWk%$=g`SrHY^)q!}7@6tvQI;bD(DI6*EOSHcLJ9d$Hzhy$5hh;gD^r^h!ATGvj=`$oYPYYJZI$*$=0yWaUjsJl+JD z*54WW)yx7EzTnQs*zyhRt)y3P{p00KSHH$b#^Q{Kc758FHYpw_YPUX&JE@o)lsR@P z6LRB0AHwxGrenbyZeTYecqll%MXV!Zp3g(QEZ|1v4`y_OIn9?SVi>ARRzd>>5aulV z-pVH9U_`#AiJbj99Estv)u6tNV$Efvwrc{kZS@^Hazxt`ETio%38X1_A%yV>mz-++JcPJJP%sJ8&T7&3YI95;3Q?d;Y=d( z$d63^R}wM1pXZoX!^)Zm=Q{0&mqOi+xP^GU91O(j)K6(+)rVe~J9Y1b6z+K1WvSDP z%Az}FBqsd%Tx$*gjfP=yA-4J2DQMRCFl3CC$LKnXSt(pj0!U99K{_>Eth147CQ<}L z@sN?RjVfN!&mgNnqydkoAgjxUYkf2Iy>e2yb5tA!iq;!ig?)Ad`~J#-?dyj4kwZoO zUBElu+oYkHSc>U&X%Hf`qF^rJTGFwW$o;VJXU?=%a}*A-R)jP068wC-F6)Qw8yI&X z{WrzxZG_+9^a+i;LrgU-#`06HnWZO9I|XjPqhq@A%A{3ZC$r3!#gTq`X`y@6iO7T2 z1Ra((8qGWq@^Ja9k9x;&nGu0EFqtoY=L;QfGF<)YT1ZohX75j1A1xDi{)fS# z1dBMYc|4=anT74en&;xzVYowa8*3y%E5D|tUW^DdH} z|2JX$FgoMupXix4bI-|5le5<^_jKPw+0R3u7QUkJU`r`0AvR1`jH^q+~ z)80@}G#cO{amo-94s*}2QL4l9<^XR*3f`<8bm+rg;zsh9C55)?T;9N^TFD82&>En@ zAstMjMl<&f`f5qZSbU@+lj(4KVpOu13sSYGRye#-Q>mYHqnr=N@>Ps$m@G>v%A%#m zsE13etUS+s<-wWiDj4~!P*?6OOHgnQ0l?CA1G_Wm0pf?A&P>{Y()N`hYT#=|$({ad zxYzxIEi3;h?gf=jwopj&L|gx#;?626j;`I-xJz(o+#P~@aB19Kg3|=IAPK=8LO1U2 zl3-1+KyY^_Bm{>bK@%X5Q{?;pea_Xn*?WxLmo<8H*LbVeTD4|9bH2w;OZA!NO%=~! zLk3Q}_;69;d=rym!I{KrM20xKw&5cDjJ zb$~dpz$&7-vUm@K0;*d!_qrQV<4}6M9FXmHL#VxKK05PxDzOPvi9YBF7jH9HtpkHC z^P=if+@j8xCC}#Uy1=3wLN# zleh)_w&LY{fmS=Wwrb8?W3-vgnr!z8XL}DCcSgo#>Ngs*9&PvHS}of|69KOPAO2FI zel-sKraS5cWE}W20&>NlNT#IC9mu$Cdm5g-Ra{qU1-9 zuT=Vdjr3brO18^62(y4qD0Oyecb<|u+ERdj{UM#SPVtPxRDOq{_`s#RUuNzHR%Vvf zyB}CDjdC`RytpgRh|s-@inoR?)@5WEO%R|>Ml1EF0v1mD(;fFO>G6w>W^c}@U| zc*FVGRFIMdqgQ3zF~O3wAh{946SPH|w|7E5CI5_3O%ELhhhbbTVC^^RX z3(PI$OdV`zx7|78I5qIBI+_Q@bsJx+Sn#H}#57*Umf%1C#gt~(?*B$Cs0M@K`uv2? z1?Xq7g?@8)apz^r{lJ%HZnz>iBP`sp>yRjxBg%8ocl>17=gSX|B8tD>yCw%w+b*`}rb^ ztk-SfNrkhMmQcjKSKy@ip8>qj-`uzGq?8W~iS-%sO-sFBVn1dFbKt$FF_XJRD5a)2^YnG%V2 zCC>%B!fb67l}p2NgxMrMeS!rkE{*b(?k(dp-rfYfIR4X|UeP;^HNixW|0?yXO3Xys zHjJ#Kh(G5|U#v^+bO6D`0|D(dgwj*lDuWU|kK*pPJ}`*W4Sb_)=p4G#O<%N5*zY-2 zE3y|oqbJghcs;YYD)(?j|1|GDN2cv8c)bI=;KS@^xSStfidk2XddNxMGd+f{yBxYd zDSMI^?01+Ql2~tAf8l^RYF+7)=w3C&4rV^(ictbfH!@9B1|H0FRpvcTySjO#^aq1w zW)=FX7@`Mig#90RyN#K-eQQ*B)n{tuDbE4=Hvn$W2S@~?C+RzLp_o*qX*J)nuJc1p z6LGdRvUPzBd@xfk0dZ^fkDeqfy_*ikW6N?0i#KKXOvgPsaqokAQ8Oc@k%I36CT3!`qJzu{4$;a)weloAie6xQvJ#rvv_b)aU z6a7CT0`|!R&8jJ8hJ`8uK8Q8^$0e$N`VvhFwF2iL2_`a6?8t(1?#^zDrPv6R=(j>vv&Rx8S7GClnmB#4J1p4naNvWtJ71$FMd??l zM8J*a#N6$UJfPrxC?LwI`6c#>Ah@Bekv7EW_i`ZMRMEuoWL1lgC&P`9kg8{VQTQl;_Lf-BC!Rb zt{kU0?ovhXME4KVedZ^%8eZ-2ILdaMmqlMm(pb?6Tz7G!yGvRcfy zOkOm_3Z4Oto*kkAs9i7fNpnOwTQG7*k&os3M=sxXg|=oaCVaeDou zBEx9@HjtDbNnw{*_Aj zk28Eq()7Y_eSd>6pku?4T}qBBt9VtqeUnq)3lx_7a{5UL3-p-d>gw4NkI#l54FFcwtA`(CkN{EcwNovXr6Vu}($gk?evbn7UDoDiXz_BX zZ}BrjO6=(XL^=nTe%K{P8+P?>s`=1i0f>wKtx|<`psNVs`v8o1OJZUM0zA};RLV*> zbodi(?(7Xp+%ia~0S=gCp`B0SaG==bmq#spde_mfbE~ya44q<@|J_VA@r(!DMQs$N z(n!?$J245?(O8YgRV>{DYN!1L!UvZ7z4b~Eh8}=EN z^-wg~N>oolNjx)B|ICf$Jp*kmnsM{wNs;RpHzCWM_7+g8;b#i^c}jlSs4QteN^nF~ z^J{03zzomr(+4q;@OoXYnarYWAx{CbVFaouNrrxCIclQOhvkmw=BxwXg?SYCv!$YL z@3$>7yBCDFK|ul0-Zj-_^j^;!!rh2y1TS(07)RD;{j%w%luKF=z^FE4_R71?+enJe zG$E`QAKJ53;nF5gJ;1t!?f{*Irdx2AuJEgxGT%+-IVDbQi&!ZT3P$o1)F-4=j~^FH zDaA$qdhRe4bK}zn3ITiK*Cg4LWvmn$iXK&Ivbo$`t-8^_%3t||j>O?$F&9EhMPxc27gXc-_#)1g zK&h)`xB>g1>7SjdSF^cYN`t)Fd8)c&6~WY^uAg#a!IbfwobhvD!jE&!;)Vu z?hVROb$XF6c2K9q{~URY|(IbXM}K4_Z5ZZ>)d^fvW|zf;fC972+v3-gF6_>@`ezBG%o>%xTc zz4OyIocj#tXT6Efmrd&A-AhRe?dPa^OoZY(=fi)bDp#V;eWFJ}4)1z&FQ(PB5ao6* zY-P}O4l90FF_-U;##th7GfOSKG6t=5kCJwNitOk73c%9zWibhJdsC;HKZvx}{iXm{ z(Jc?1bzW!e>l`|~lx}4QEN`y0biG-ofgD!&pzN;y8y;mF6`GDDiqf_jo@&3)%4VWd zWMOSOR3^C&4W|r_e4>;*i)lLLTHPQ4u#Q4@MKGrAsgIbQ3WE7+)BoO_nWLw{Wyu1&`c>K0`K@(N7Mxx82sh}5Rf2Wn_QGc0yBF_>Hs^?I*bXQfD>*nY6c>tGet(uEw054&;xHbe}m+te=b|y zgY`Or!ZQp~v)!&{YEj3zh$WkOqCbA7zr?(3mg0WOCR(P#KonVfbM4O9j4;u;FFt~x zNiU{bg*msyj+C_c;rYgG-Pr@_U+d$DU@v0tPp_WWOhViGiR`Z^9Wb8I9`I+ajW+bV z+IQ&srf84ljJK9qi-%u6>Q3cU!cMGZJh_f=_wYAEsc(og~8Cx=$#wH~~9WrSK5ls~lwrsZT>dSZ~e;9K|qEGQG-#c#u zh_Zutq^o@!G%sD52fGI4QA6_;!&-U*C}{D6HbVPG{4Qg}i(v=f7={=sE9l1n4XyaS zz_WK@p@z(u68mw)J#~@{s~axdNu6CiKl^8TRTv5nMmC8tMMG8!-tn%?J+bu&Ny$hH zlH@DQhqT<9TiB{_Bo*aE&0`{ngRp#SL^beHSWfH*P|GGr8bL4{O2M>ZmutjaSq6j0 zT0@cWoGL%V6!INXh8}!`jB(rXd;jCD{CuBV%~$3=hXa-0#y?<3j2w!e8PDOiN#b&; zTQ30T-=tLhTIocEMI?|$Dmiu=lLD2_Lz$1qaw3ia$p)s(XF8+m(zQkIg7YD1KB939 zvucWe6)xXedf9bUW--)d7S@6XB3(EY5F!mktXZ|g)B2(e#cf+oGy?g*Gf_O>&!)l= zA}D4?3;34T5Q%gn2FltGVe?`=sszeS%9KOM72L3LRD~NLr!kWvEJLATwrX1AJy#}te4EiRtB~PQ?x}V*_4?Gk z334T~G$wVu^m0~#CgKkUF)`1Y?QP)CMBs0abqe`av-259Aeqvt%wrzKf~DjX8{77% zDBodv*{E~--oA;}Z&#x%L4q$}DVH%G-RFX@t9u=>86s=Zx=d0D7|V6jHPTTDQ?q9U ze&{0(0iu-_R&+LHgQ}o|=l;(Jm#=lFIB62|B{k>F@AL zg?Mcjbk;jZsMH9`lM}7@9!TTgARVX<-xpt5|HlssJkX?~lBnobATAU;lf~2z#E`8n zB(U=)BaLux`*H{5USe4XvnuK+=$x<>504ZmagQW-6f#v@hS$RJrND{oV;OK)gChCw zJ=A?$0Aa%8=9gIR6hAl6wn-u*k*An6VS)u^+CMI_COK#kC zK|9%iMMdktGS7lm>rMl3FIoo!rALhv!vl}}zs^ijB|=0EEz%0}9>iXLa~JhwwkE7g zG*Nq#o06A}wF+8dPwP6T7KEZoH^~Db)849m7=V}cQ!mg@(cOh-T2E8t@*LV^`qY^v!(W@)8pNdM&2_W#<05r z=u~UN&eh?_=ZB1VwH#yFT`;?^Vp9cd@m+?Q7VQ4~XEEvEWs@&&orzUK=O4H-g)q3fYSLKLdAk zU;4a{ELaobbKRZ_(o5&nSgY<6?u`WOqvJY?dwWaD4#>(2b+*{3=ialMDhw}s8GUW& zhq04EAg%xm7A0N|*9%aMDzn$z2tUtMVlCbIaGCW@iOUw`p#5_I;1AAJDPPTu(7qAO zLVCJCQBQ@BC_Q&|(0B zWVU;GaY5wnZYVno!^u{)6h8Yq!FSDV`$vUro$>=jMR7gQw(soi2$uvl;`L~WX`&u& zLj(Yxw|*y8$GeEeQ2Hwy^`;}13MtW+nf+!os=DK?dZQxHwS3*1=yW|QlI9=qlUz9X zeETf?_kE-#RFmYJWo!O*Y*J02?p_$PL+(C<^Esf9!6g?aqaEX>^`kO zYC8&23UXH6o0QU#lOfE4V%6Pm2S1xSsN@sHbTx8ajO?f~HomkuE&wfYRBMJt?4dI5 zp9_!QE)FF({Y#yZsNfw-hV30!jcb`EBa`)rYHn`76I(nDmk^3(Fd$zSMu2XD+ z5SUar%mXV6+X#DRynV{z&N#HI&;i*YxY=>x%{8aSyJMy5X&RkUld58((`hs+gVvAS z+bW!h;@{cWa$lEtS+HotUsWg_SJK88BMAQa61?80Qku|qfO1-ZMeZ$lD-Kb`M;B1RLggZZZ)y^f$7G+ULRx08}?8s2Y_?4 zLVU}}_IKL0b?b7$MPPkHKO(9|>4Xhm3I4nUDt_Yw1H15YHC5|6`rm++KcnlotFRpM zjpyo_(bCtOwG+6nR-9jkVw1yZ;Yc)+f|k+tGlm{#t;N`pWU+2pJ!m5YZvzEp-RIS# z;2#!JlEf^NkV|>G)Yb8Wgl+=;>*D!5{WduMEFGmsu!A_FDxAg6dLVqC(T;r2M6ISzo?(ZDGvY@#aBz{}X0N5%c zj;=z|wV~qu-5t_x&@!e~0f#?da+&BcvE-3_^a$Em<;6Z$TfEcJUq=#3b!hAwJW9_s zcKU(ovs9%S$|Q67?aMaS8hXXiS8oPdy6og~0gTvqHcrCtj-s!k9Qt9aJZxhS3pdG; z(g8;mU29k5fN7j{B$1Zh%T>41C?F=Q@tuWDo}(;sMeE@HN3uOP&rhhe&gDX3u29$n>$5dfP=0<8>r2 zX-22^7RjcN7Rm404?B_AS5%isv!!43x=_`jbMI>2k}pkP}&KC+uJn9At=>T{QPr_mH;*_8mC*3e6p~b#mVJCW8F^x zz%W!$+{bv*Z~N(CS+58P<})o+{fDZXNMij!izO=I+vW*9q@`4RQaV77KdIOOLpk&+ zpCWOMRxrg}rVZlx>kHlERu6N0{QBU?F|Wp($r*W06j@Web88pCb4;WQICk=j^-0~; zK~m!2EisYJhUagNMt;8=RC@%jbmzP=;$YfQF~ zmhCIwcMVo}Qn~^?LDhHrog!;RKK+F?ejn%u_uruO`sp4$nA=M=R3FJsFsI+*-%PDc zgx`KB+6KH>X1Xkw?tFkG=XGm)kRNO5+fz49tXVDs1RgYjy0KQ7Hdk`M1MP+4Hii!&#n%VCkgR# z%Xj=Nqpk399l!S(FH8pxzN>dQAI?N6rO@-B(s9(t66hOdyS zZ7XejBB_!!_B`e{=hW;_yNcrkmTWICGwB#n2`i0-kRrlytt*{?5Uv}#5e*f+dnwrk z1}sKRdC000VJI;EtADkYCK|)c)8tO0;=`hFK^a(Wx)bbeNelc!#%LPgzDrYhi|x-R zpe{Bx1se(CoEL@d0at)B&pgc#^fPA4K%mrg#@tq!glw+T)Xes|QGD3vdAPh}B@~e) z!+V|>G@0%S&O$iBWsQhy{iQrR+8p^>4yB^P?5<+jav~&fdHCgR4TY(x#$~2NG39n^{2=l#e-VhZ+ZfeHe_sEz%Wo z{R{v;0hZ`S2-j|ZBq1tvlGp8pRPK9H^`94j6w1;q{zW?*hv*e{LfSTI<|z=Tbf@S@ zQ`H&<8%qfLW$XhaWZAiYa7AgLF=Ge}EoNe$7I9W&F17myMf#vFfK7P#LMyj;ZBg-_ z{lHsM7PVOmzE>{EJa0AZYt6u}!v^IERJ4~~#j$5z*=_SSrlXjDDE9VgQ;2C~DX{Aw z<25u0WQ$i}#EuC*YD0aDvm)h9By{f;b{M$;bjtLNmCK*ol+IrYKu#S%UdLeqM*O2# ztJ||m)fizv70YFn4NpUGD9(8(5q_@@XuKmV=OI~<$tZo;HT_T8 z#y3ax?9GPnn6Kkf=-;6jEkg@^_!6sKD~l+1gQPm%+P^PK&9>Rbx|_PqU`3B+A$sw` zQD$yu8{S}B_vc*y;YbE%_?Wp>`hm+fbdGd9E3>)bLt~?89@968t`Ku8BfSyJvqI05 z4v5s>>?~Z1Ea@C_aq;+VWy8m-ICmZ~xcI`7y{pl~0iiVp>Dz3>N^z5c8alu2VT;=? zns5ieI@t&SQW#NNB#~t(T_7;P667VSpjpD9)5#)fJ}-5?7hQxR($jhJN_#&1o|)Gc zC4zc_+IMrw-N#}Kek%%kD!&X|z`#E3hInX{wr0Fk$HP?{5`d6D;AL7c`Q*X5cUDcb zJ;WL1K6f7`nBsulVqA*scU=<0LnHB+Ru%2@{>)3#&+P#ykw->w==L>|X6#$jqZPsmrYT@=vSWNvej68$ zAAm-XZa5L{AwEkAs3d~Qd}4>;4LBw<<~GV<{TxiXdDV5A;Rou^bun?Dmc-`O05(1J zW&wnest&4=Xu}o6Y>kd8W7Jp_tpKm&3?rvQ9h%gxYWWjVX0;1jE%mx=obs~ubBv=; z?*RvTGYcyZzm9KKw!8+XTcw}vVR;d4YDC@{7Rtk-+rcPTwYu0wf{xdqC6hw`Tlr^QOas8xmdWkv*e;s4yeFf7H)v>MlnXY(CK&JR!DT0(ku3-1nthb-@ zGfOJPA*3?REEQR2nf;y26Da^pAB4Uv44EE+>CMvUp{$*6{s)6`mCEW&NufLKwEy-O zqM^lE0eby?YuFcTqEoi7obE7!iDRnNJy(8LIh$iQsL!5^biggB)u>)m%1Fn{(53Gq zLo9ZqHw6OXKkfuZEIHz}R9?X~2EpD~)6_Q4{^mlzXdDvwrcWuG4aG_ffN?mx(d6lPGs$y5s*V9}tE2^mjccSdo-r#clD5_oBl} zk=_ZAPgVk6-|^ucM=DUWz1f#tRNiNwnKMuwIp689&a@Ef&2bMwQjnss2qlubD%N+j zo35(tyhx8`#}&E(e|w6QXpHK)Zzmi3FkB=96ecDgS?4bfQ(~bn{GC*qQlF27?r({J zS4P{OjhypKHQS2BJ4p<2xet(e7%`9lF;4y_en2|ZH70d8HFz@3od${Nu{vvTXAEqe zzmN+I)5s_2qC849L&GjIV@)obaVLOpwzzFFX;YHC%GCP4LEM&#uf1@8bdKTZt!1K} z%!yZ^J^FSzAxVZ@-}RmSzmiHg1Ok^#0*G>co{D5?FiE#vF_JH*+Wc)htkmOUUq)e0 zRIoNx`5W4Fm-bc&0r?J~01`rIiF~%^8IFH25E9k_= z9BmM&daIT+EtUD0r|+uG!4IFVJc1{VN$ld%(rX~%J{?~*?@~!#B|}V}21Z#JI-|kZ zytBW*ptQ>A*~NE8%fR``kn*vEH0tD>(NHl3{8Y@xO?Qhke|oy+7;>$_cUy)mXIm{@ zp|6+UlC|zbUFGGE*Vw4b=&@%ha_(&$(1T6Ca)KuFNs<_2kROLpQC{lHUnyosrx>dp zavw+f$2x}IpQW(ArQJTA(rj424W7x`rtTWgVhoZ!C3$*LB31LyRKPv4d=iUwb{0Fi zInw}@6yz)DB+V4`)TFu}C=Li3P11*w-`nz!sVEOwI&a^#wKNunbTK)^juP7;QFG8; zkNz%2Jz~b<`<=Jkv!Yo0!ak^&9_f)4Nj`me=A!$~NIzXftw8iP7s?yte>3R9_QlHb zox$T`>!D_EvYRqCGS^t=$)x!$5}tizEPV{Tp(3yzj|uBswOXqkD^=VsX_r-#i|Xu4 zIoAr2c>nV}BJt;J?rgGl#v>RaKh8Ke=C$Y|R`Rqf-L>TjX|aDYhxi$dPgwXNS}ca= zvei~Ikam<2-&}9`zbpVRHeo+GkwLu(ncGWM`HdD1^oN--OC9~y7wEDf= z?|(i+_anQpaa3ID-Etm+VJ2Oee*Ek8J;Pl&YuJ5?o1J{>{hE?* z+u2c#hCB@G1!ar_(X)L8O)OfBlrP8)X^zuxrOw_?>o3A%$ddM%Dt9jDV;w4vx*AS z1z?RZvic{rthf280~Jf}Q6P~jPsnsEnZ%v2-!tPerb}8q?p`Il(F3!j0w9|7$MoAA zr!++ToRs?|Y^M*O=T+xkEE|S9p9#qKe2gskR@rWEZ&c@sSzMgfF`DEYD_(D^4anaE zjnrm1i8xN}xte;(WLkvjWYVI{ih*q(i@d2bXJt)EOu480sB7?s7RI1!>4hupJ6UC9 zdox<=o+U;<7B$O1hLjr}<;yc%^?bchHbwbg%ftEa`=|cDBnI1L!Jjv>TMFLX(W P-~(3FRH&DG9`=6#fw6m- diff --git a/images/ge0.jpg b/images/ge0.jpg deleted file mode 100644 index a70b1870321307b9e1ff7ffbbd2d6fc2504eb3a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20226 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 diff --git a/images/ge1.jpg b/images/ge1.jpg deleted file mode 100644 index 624f16e25b914c6ef9b1622dcb2b0c2a44b8f6fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21080 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 G_x}$8gkLNG diff --git a/images/ge4.jpg b/images/ge4.jpg deleted file mode 100644 index b3a4b4acdd107d05d25958003b6366f65c29a922..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23605 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 CQl0+* diff --git a/images/general_learning_agent.jpg b/images/general_learning_agent.jpg deleted file mode 100644 index a8153bef8b4e10ff4cb0a908a62153ea910ac351..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32599 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

E$fHB1*xXl0UuWi#=)7h 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 diff --git a/images/knowledge_FOIL_grandparent.png b/images/knowledge_FOIL_grandparent.png deleted file mode 100644 index dbc6e77290705d1d5b69638c3ad7d2a913f1aa9d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18034 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 diff --git a/images/knowledge_foil_family.png b/images/knowledge_foil_family.png deleted file mode 100644 index 356f22d8dcf197626d0bd1251dd72ccc0a700e40..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35686 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 Ap#T5? diff --git a/images/makefile b/images/makefile deleted file mode 100644 index 20297a8ef..000000000 --- a/images/makefile +++ /dev/null @@ -1,34 +0,0 @@ -# makefile for images - -Sources = dirt.svg vacuum.svg - -Targets = $(Sources:.svg=.png) - -ImageScale = 50x50 - -Temporary = tmp.jpg - -.PHONY: all - -all: $(Targets) - -.PHONY: clean - -clean: - rm -f $(Targets) $(Temporary) - -%.png: %.svg - convert -scale $(ImageScale) $< $@ - -%-icon.jpg: %.svg - convert -scale $(ImageScale) $< $@ - -%-icon.jpg: %.jpg - convert -scale $(ImageScale) $< $@ - -wall-icon.jpg: b15woods003.jpg - convert -crop 764x764+0+0 $< tmp.jpg - convert -resize 50x50+0+0 tmp.jpg $@ - -vacuum-icon.jpg: vacuum.svg - convert -scale $(ImageScale) -transparent white $< $@ diff --git a/images/maze.png b/images/maze.png deleted file mode 100644 index f3fcd19904cfe1ae6e57f38897ee1b924745e6fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4576 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 diff --git a/images/mdp-a.png b/images/mdp-a.png deleted file mode 100644 index 2f3774891c89262f6f780bfc9cb1d2f8abbe6ca6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31989 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 diff --git a/images/mdp-b.png b/images/mdp-b.png deleted file mode 100644 index f21a3760c7644f91a79ac72c81ef8f8648682a80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17560 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 O2!p4qpUXO@geCxoIew=A diff --git a/images/mdp-c.png b/images/mdp-c.png deleted file mode 100644 index 1034079a2e355aa54c96d8abe8dbe7679a7f1c90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18293 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�e%Vf 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 diff --git a/images/model_goal_based_agent.jpg b/images/model_goal_based_agent.jpg deleted file mode 100644 index 93d6182b4b884fc446709229801225fb7ca0d846..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61937 zcmeFYcU)85x-J@|OYa?2K$?IeT_83&tteeXH<{IMrL5|}fyj4|HwJkR^){KxqmfKgjRO9Mbc z0sxQ@e*ou`fO`Pa3%|GDucX9{jDqa^fc7ebWC*g z42+CSj2CH{S(q7Fh<`Kwz6i~IX66=lPwk&MI666ddU^Z!`uPWhg-1k2y^fAaN=`|IrM-I(&&kcp zFF+I)6<1bOqiSkD*VVVSwRd!OeeLcU8Xg%P8~-tZna3{tTwGdSSzW{L{My~yKOh_) z{T>$yfb_4!BEJ50VEsjCIAp{ zYV`3!=tY1i;J@Gg6H{=3W_?{!rr+hBVdJZzv1!_5eU(>=3wK7}zX6bre5Xu@w%sQ% z7{8Z16Zqkm&{ZyIdllE2C^;JI8Fmg}p_s65p-cd(czvWo&)Ww1jWh?d?EAjyU{J>k z#BNFoov0_-NS~=Vk_=#hn9x!ehL+h#F8kh6G_xGJ_=F0r<8ua1r9B~^Zh+f~5EKPG zWkN@Q2_Aa_X9kZ*&H>Z{oBHQ~`)>1~Gu|f6b3lqQ0NSc~Y;+D7<0d-=c4KUNymj~~I*pe?fzJ=tc9YC_Jm zI*&Iwl{tAcE_i-XTFwV3oUx!W7uyct=#6tg-i(HFS;T^4nLY51uZuGR?|z#BSS=9c z<-5~-g&@({OmSJE@u)Ly*!;fy&-c=$aO}`^rEdR}7w&Mtt|Vo245Chi#+Hr0RhAtqbbA5h61k$Nl5ceUsQ2Ucv8&;P)SXFBA`DP5)bWpVLExjw| zG;L_bB!Q%dcgcU> zp=US0G*x>0QU!r+{!|a|jgG0$pKVt)G1KB48>CNn{1PefYrA*@#ZO^nL z=};oGtl7e&;*aEyt^@cY0LuTfL`#y?%gR(e+>_WDcCG&lK(+fLZSOWa0rYUh>r}uH zFQ4iJEpfMnsBXCT`JMx;-o71ze!26J_81tAruXK9SmI{V7n&~o0^vq9T%NT~8pK#; zDgn9`m?YR^6ShfivjXQmPUPJvpsg*n_)87Ab3oR5?ea&ZoPR)nwdg=hHW^HCiFM4I4QhnWqD)w9?PUVer8_vh{E{`B(^Efbh8HvXFl1xo_5Eqa@`8B*04xn?T#G8c`i`WtiK=l*!$evmp*O zb^ikY<&3X+j2?Bo-zoC{F!{fCfPea*{|p+Z&{BJpG9!$OOKYaY3-#M4o8cyfOKX{V zgT^1FLIV3kp?T_8Z|rQUd?$Ypa>WlZKb5Ob7>7K8TWWv85ZZK2tyK@0S;2QFAe17c z{tmTv2{Rh~6^|$p-~a4>%U!C0#zT#K4mm3U;YT6a*giKs+>}Dib|vI~eWsy*?sH!4 zxBlOvcoiSwlW+4CL}WXjaSm>J(UI!M^y*i}sgp4=q=L#rw1kqhx{1F+Z~*!b?`DlqehJ?%D)Cd^Rv-7~+N0BK z4H(OvuiJJA-kHuX-FT}n`1lzptlL4cb3f?mSM0Ak?{s$nyNjFUwd%vy)xaxpD8~&Vx$u0`^3lZ;?7c? z3Y=&O$g`AIbA6oGjR zGJy(|F!1$a(fbT>WZcA*d$D{q=TuI8jege)yJ%t-N*m~6hebrI@OTH>&8yyOnYkSJ z7G{dsY+a+~<$BnyJn@wygf>(oDKXUuodKY!4dKQ|<_6Cnubv6otgaVakuP${cN(jh zbRGsY)COmZz&NAn!rwfalcx=j`%YG4Lq7a`@6@hc2BLPkAx$*2{#OxFVG+D&*dCd>n>2T-~wlFiOWB9f9b-Un-@r^&;R#H!I0t zc~mtSynj(vRrT3$4x{;3$+vQij~@#;aH*4i`tp(HRQb_`e_sr8z_T@eF5C<<*sj>Q zSzy>rTDI%gwK6G5!6Zx5v)zYZQq-8Xk^+ux+h61QloxqM|0qy zEsj=ki=@b1p`8cHvTC{y_jwsOKOxz(=Ide8=N3#hZx$6v!kYLk?(PMoko_IIv@eDv zHUrqJNt&UJX+sr0+T2dpH+mQ$9~ zlO4WJDxP;_t|fN!P-xzj;d(IlivA8OiSU2Mr!`d=t?vjUM{e}dezi+dVwI^+e3i#f zB^dXJGVNhJj@o8l>{;?WY;(AE!;0{bzw)xmIp7(6DI)ex5B7&k4Pfu~JwVSL%D0*U z0E<63)=qf>`j;MXAe6iytKtE<0Hgn83s*ud62^ zBE@!vZZY@UTIpp_vUnX&*3*2plOp+0yM(AgLhhYGWQZhj3JB?jLtFhh59Nm}&4Tl8 z$v(B@;#GXjM!l4FsW61+Bc=TxaprGe;_qXrjN_Bf(Q_Y!lEheZa|^|LG^j4^kv*ck z;XB9kK;tDxxOeOTHO7&H|B0C+zJ)Dygmyl^7Df@DZ1;Hn?X}ltskX4MWEFl0qv1U| z{~&PAy_^+{VSY#1=L5W4eqSA>f3mO*Wn4mr@&?8vb#mDlu==m2;SX+1!ex?D0=UC@ zY4=K~3c7_E+FFVa2UEH(y{m@8X$u+w!WS*jdf4u4BeT`LvJ$-2r5+6 z@Q0xCT*#4mzna}`{`Y@8$v>HQ3hRUDY92ZZ26~-RGdhob45UF)tZYH2;d4&cyTQ(H zT&X&ju2Hal>gM`L3y!S+iRq90L|K!}R}{$$w^ZZ?H2nTQinAp9SI6iMhXhO_}LcDFYefi#s3beFpB021y5g zTsfn!7<37`Z123U!0j0SF_86sUxUSS@{3Yr8W&i}pFZ{8iSr0`Syiq{EnhVaSc)jZ zI4is6y77%>F6Q;haxgx~PI~au&}1;>6(=**r5Hf%Z7R<<p`4$h(d5;o5+2WyG zi}d~IPAP;&dc;zasr%3L$|ZgEl7`Rtv3!drfyjRC^i|=&J2ksOM+y*&Bgt#0C7rX? z(C`zEB0|nLKX5x{G3})!whsRck#9NKR1?jc=s(-U{4lAfmtOd3?Hf~L@dv#C&xi*- zYGZoemwzq=dIlCDr8Y8hGLSv#0mqdnZRTa;>}}ny^i(%Ub!}y1hJ8=DuL}ya+-P(R z_5-&bEywH{;TpOy#e`d$D7^6L{(Fi{xl*|7x|k*5-OPo-mt^nbiu-T(w0~hHH_*fc z+IMfP1uD&M=xCHfYT!;YDq~;{iSO?$s`3ied`)?AwHO-^Dsy+NyD7aMt%Vi9h_qSQ zlpRS&o(N*0oKu#50ka(nVRs@&F_RB7zFtnZZ^vuhfL=9ZW=lM?Vk3VmUm2clffOqV z6cg3jO8HPTw5?v^gR0+tzA_SdC6hZP^R(C_W}+HdR-a%Iq1pjygn5EX2Ct3daV` zYvUGM$yK#FE6U{)J?_&j9oo~pbzZ)x&2Qz9{E%+c0<`+zgf(}LV`CN?JV%fc!Dq#9 z{Ajxxo&WibggLaq+viK3bqke{H_)HL^Y(x)Zh6!FSb5qnP^TUb+@!-rwwc5GspWWd z+;~@q+uS@JaoN4OCn{BZ9QvF#l%B%Np z`EtDAj@g8BK$Szh3Y$A*9*qf{m#dAIt;-qRrFpO7fFO%CtaX!N{HdEI_VvaC%9$8* zjwXN?Kl^DF&>qd==b(jW&8lW-i4^`Gc1zX^`!%o#|`HsEuB)1yDK4awp;pjtn(m_R>1f7<9G zNI0DKU8e8@{00ACXG-7$3*^B|j6admsA1NRGiF^>#H94P~ z(=zE2}3JUB?(;E!)#CPiX` zEY(u|aEXb6EpCWu|NFSRx1syiShAro0u9Ge`+Hh$9T-=E=tt=rV= zGrS|Z`)Oru3)31~517WEfA@#}7)+{kiH@eHa(uK)#z>#L4V)okOxH0+f{>!4`P&bv|s=mOror4O8mCu$#m&K^4DQE zvE!DTC2a0O37nMrx5-6{zcajV494ACNa$psbeyFR5wSQ?X;8MQatKjzBj0Qpeez~z zQ-s;lJUHHvCh9@EI&9r>sxOk#-iECcCPEhruP*Yab@9(IEk3fi2}7Ds$R`EJJ~;>Y z>#*E~eJbfsf>F>-daZVS@Qgo54F43$_+f0-tT;~OEfw!Y?+>h@zCn}NUAu)#a*kNG#OB8!AM@|ZhhL#*ruk< zCx^l7MMCRcETvgOPq5QDhtfU679|BK)#!S7z^X$#_(HRkPWg!?lzvr>l3PDMhy+2n zdHM%;LE-~?(ZV=(TXS(P5 zed(9$_|Uc$+k-j0net>YQ`MkEvuiN(pv3A=RPDr#AopY0AU%B7D_K4o16)E|KAt^# zUPqPZ0bUOA+M9+C)CLb1#iROAQ|wPH-z99>GgiFx6_jwL`y61lR>F~hjLVx=P|ld@ zw%%z_pw?K`9$Kz)?bDf$wZK2Vy!TL;SJJpx<6^(`v#}VhHSEtMy`D9Uyvw>k)oce+ zN+5=tGE8op-q}Zh@I>xgtBGW#q*dvCT1th!AtIX*ty2 zd^2}k_Z$!orU-J!wPDXHiaYG*4{#5gnTS$Tgx5r5g$f*AkWzbD2uA8$arSFd@zO(| zL;u5C+W~;|blfm)Mn?L`rNS-n^DEJ%zcRvT% zlM-norkZ5!Ka~Q&jA*PqeqsJD#MM_` zj`{JOCWDa|6Q>y6Z}WQ|-&j*n?%J5ZWq}$mO@aLc?$)Km%{BbE+c%Ot@}VG9Rq9Xl z_@D6xQBq*LGG9XUE}v!_JS%fwS8vQxD^8}`P+U1xnD52cHYHlBOQD)qLT?5!Ay+M6 znVvajgve#{MqJaE?|YW%pBo#({8?`_aA}NM_a}8-HMo2IE!$iSV5RV{cl%WyF>`6m zJBv5y@i0nP!!q54rV~~llF9Qy5;@scuiB>3+zE-ET^D>rne%5l_xFU>pIBRn25&x; zC$1E=blb0`V0+A@@5V4$UU z|LQs7@G{QxEyF+7c~wgGiRx*RcOG=&HcsR$-@^LemYwqDx&XI|TltAEUb97j!ms2@ zGs}pILc!_*>@6Wp@5BDOje_XbfD11XGTXlX82|o0!e5Cdlt)=@2z3!vH1S!tE3NEp zcyjVskJXrk>Xqr4UhOqj5p9;?4=UrUcx{y;Z%Eqvwdy1-Zy~(?CL5L^@(A53Ky#vw z)BUMD{wAl6`-EFQ6N8xcJxQw+9`H*KA!!M zVHhmA-Lw64#Hd!*jTxcrr|))4VUtyMqD1$XFUTNPYi(Ns3^U!5BVth?&52~0{`_g6 zB^vc%NXN|0l|DLX-&Dpb;ySVq)9SK05r$y?n&)P<(!lPm18w1VRchi7_u5GRpmaMj;b}%k}ay0=G z1ZV#^s4Lv=+1UJiMn936LHO>2e)hX&Vo#`w+ANvwdiyM9X7qIrji09G zr8ioIlqf%%g-rwz9lHBr^ zkbYgOY|PITDJfw%G;WY)5pmneEjQ8D@!6Nf#$@WddN1B6i+-g4@K=v!5GN>{1B5vi zYEM&WfT!wS+<#KL{vn1iT*K28hm5F^#NAEL$1%jd>rVbmHWH-za-8#Uz~BP~)$%2N z#Q(dPXd`$INJbF+&jC-*0iEC@ciiGXjf3Fo+LL6Y;8_plOW>aP(8|Bfk6Hj>b}m{? za9w#jN=+oB2R6&nsQBq_(9I&JU#p2T7O>aULt4^OAK}yCxe~&4N=9FMPNs(Q){N2< z8cergph{GlRPm0k4t%Z8qEDn)S!q=1Za=QJ5sq%^lb8T{Bj_z5fip*DOY;O1eAkyV z+S4qQWfS*0mLWQXn`a(5d8g!dEpvLj43?_G-3MP9%hPC3mE2e;#g@Rf@=g6La<{7UA-v_A zG`On$NJ2Cs$YgL^g#^3Jq>q)jbz^REP{oZtE5~W@6wc)C;_W)_(}^`u?r&LqWt?bn zRFQGlP&>i?;xmJ zIu1;%(%m2)S|~`(xP!}6rhMg@d^05i=JwsscoUzxu8 zz_t2R)$K>=5apf4ZV0aWmIrJ0c-O6ugBT})6*Rl)qb zoa((VM{Luhvr$3!3Y{2acg*e%2)!C|9MgCv{0286w5;@zL5GN^fOwh*hmDty)d@pn z;5w%=^HmJ;^HG&$e)owhurriFdOz>`+2%m&Ie_cRE**RJe3$K3OZm9k{B4m>D*y(9 zC77i;M8)!0$*;um_`rsLRCd#F8agMf!a-DUNkY$9i4wW&@Tj_!%r-{xz7lof<*W@3{PO-M!t}8g zVY}_ajp1D=trItU<jy zD95j%6;_*x5;g@mn>j7;(vuU2vbli2FL6*X6r|~iuu?d#8D}35SoQ$& zfBb!w^`ccPzwtT!_Gv2V8ThPLlx5s;;m}fDN@?#{sUgc|EwSQ{3CTsQjYUKA!ILwV+A_(OJ(U`56De;UFZBJ@Hu>4| zR)NeR!a-UD1T9b?2r_T2(Aq3oJt#Y^aDRCB>MKQ_yF=St@5^P^qu*m76VX>6+BpKA zgeo%-jG#==m5mUhtTk8Liasg$NP5OP+YUauB@lxqNaD)R0b;+Up9lp!$Jv`MZ21{Y zki9;9 zO)E07Wiu9N8YK0Gbcv>D7;*uv=3ZwUO6T_f@iSaM0UpaZpRtX~O}n*aRY$eQE1v_} z4@wHx4j7%(*g%bSW=WR?vo>7yzK#SqxUYSCK(TxxhJKCS^#KywI4tMEXGXsjzl&~I z=~KRh4)6)Fe}UMHMil&7(+ROeY0&O>_Xl}18?hNpj;Q$+oLwPysQox0YGo~M5zs?j zqKNqa$Mr~(KUxOe#wm2o()me%2m@F&*Glsx9Q3uf77{hd#}B-+)^niwhU-co50Arf z+5t%zyHTnl*|Sj9vOn+)Uf?7X*fwx1awc;Q7*2@#cjWY6s`;suv_p5i&H)U-jVwa% zIY3X1_iwS|PuNRF#d6+7pmT-?jVnXbblVknENU%&wM(SB47=~%qx{L#l($4wF!46; zEvt|r3-V9Hr9nX4ai<15HGh7gU(EJBxL@de{wqGURk9`pR(lPhw}sb3F9;AG5KC0h zBS9!ppIux7p5zd1n;D47I(t1!lzWu|h+$6jw{3?f>?6(rISRi8UwWHdqIHWCty}Q4 z=p3*Te?s((wlrc4KnKoB%rFzP36^d(or%BG#itG-Oo z(K7csIM*zWhe?gw(@tKfnP4Ry+C5e4)%sL3v^#0GS-LT=6X=+r-$1*z>#p zk>>BI94iU=W;`s{MHrUtL_XS>`}}PmrEeLVwl;6q)wn+N%s1D{k6*n(u!Kes{U$3Ya1i?Q>1o!cx3^9Cya4;; zbQOa&JlyA!fXgyJ0tpCe!lTbF>INUHoejbjB2_$zB8+7%PQEt#j^tKmumdZ1f3ly* zd);rALVjhBy{H;|Pk#!V`=q{L$c8=x@(@5+y>fh5R|wUZ?PxWhXXls#j3ZG(ypP2X zbf*RLMJDm9_?PRKUXc*qRIXcaj8KFU8f~PGzqIk_B;fH!g zO=U@=VauXbV`*8U_Lpi%d>juX2o<;9$tnJB86}ThXe`Ug8--=j=8V-(TkQKxJj$q$ z{ZuhJqSdiml_p)@4iE6(81|CY$2hdvTqF3;F+{6f!~tVY?%3j)*Ea&Zksm+Btc^WR zszSC-S!)zOx+A|CN7$L1R5dB=k8m7xJ{errb#Y*mJ19U79ocMx;i(TsvkmKqldO=c zv*>QG22aaCHBcW!#I`X0tqQ?sk?(asj}~cY4~1udi)#-v<4Kj!lmwz9G%MBP z`98e7wk;Cj{oadDv+wms%g@*tQ<|*ChG%*q%_-`hgAv}iUij?(#v&z=jNCav@!elF z@v^TsfQqSWh0u}B0C5`vOp+lSTG!42leGb|nB50g)W8#0;EGmhD?C9(T?M+V`r4J_{Y2g2PoFd zKRPoyKbiIHmz>Yg;(Fy|lIyr7cqxgeP@JkLR}RcT`_Ly%rq*~tgj!@+OC8Ch@6}qo zuNZARgA{Gpb=F=jYk(AMLX0o{8@!1jIN|jl64Iq(T%Mn(madG4Fpk^f&az#KVuP3F zFGsrI-(5}Rme*Ri1fv^aYL(yxy7h}&pUs; zMSa=ob)0mEs&rR~7#*kTvPgJ|67`zIhe+=0J$va8V`jni^qUJ$ZqPBW1Nj{? z6GNME`U;8ri=vao?gp->YC{vv1)lK8%kwiQ6`4nJB8ug=W|*6XR_icB*N9k;LHu6@ z^8bSvP$tL-i)QeXP)~2?7ae^vym8raLFV%{8!cWT_Z(44p*I`Fg&(VK0!V}|0_K48 z`OUnsN8JeX>uUP%Y zACXza17*bc&TTnAeoB)?%;Uqq_ox1@(&+>d0YJ7V5xa0h*`Pc1#5nHc76smw3L<9g zHhtoL&|fNilDPG=hyfz(ar&Lgdw!R<@|*df-|K#-dpckY`p}w~*=1|n%8xkIh|e&O z_eE{LC{6IL<+30S<(d+={lm5{?k=v^ z{Z_Zxn2f1jg;I`%iU)C%gj@;oHUW?<9A5`)o R!fx{;e`_oxI|`f9xz0!Wn}Tzn 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�>i>{sQT zK_R-5-D+?aJNx#ezjSsqC+kNOYVp1$!QP32QyTr;?&0Wuj!h8Pjz{xpaXzLeVGf4l z?})J*V|~@D`c(lpG0)9d>OZP>p))M7icyI<2a)Mtw8Z!Z^c6I;GEJZ8C+}oY#+JUX zqBSI+NQ?~_zQBA1a~K2)9uyU?U_mWNlAho$=9xE|djDrh)jW2b?AX4ZS4{m6_RR^A9jljVjnWyAZ?4uxpO zTB_hpGzcgNm@3_I87XU08hOJ0ics9}I!+};@fwXToTMeR6j;2%qNqoxz0B>dH&PKE zicOP~gy%a;dG<1Bs0^1#^DEfBN#2d6MIX)liAgf4)fRTe3I>{f)suqOwh_t`hJ?1A zu450(oV%T!VM$EcF=|D`%p3KD^qH|-toy>VMM-Wn#r4dH7l4*R7-s4TxyZ#Xiw*3n z{3GIirN3&vc?C78>_R&XJg#~z`18Jta7Ezx(NqW?^mHK%Lh=n&1eR=-#0>I6$}gMA z)~P>v2NuACc;uSiF__{vM9OP;&2BgX;QGfV0L?0MQWC%?RFo{<=I``iZiFf-5-Wkj zpz#%DdJ?#d8?Rxd9;@^amBT{Gj<~F$hO)gRj28Q^Oq_BG;Vw%o-9*&#r#?TdYb;i1 zmSlswR*LoVfU$d@tS!zsw=BN|*;MCNpOwUj69NfKiZdQH4g3VA5K}wnWt6?9xgmA3 zN!jp~gv83Sx14g*FTt+#HK+%ozi?n72IiET&3$VlCV(2MDKV4;(%Y$Xz)pB-iUq!? zh+yp)k@#cWtnqp&dun@;_~Y9u{f41?szKcTzKxmS z5GFJ#?~5WQRK5<^qGIuXYva@z?eG~54vJuRgFpjoLQ(JnVW$T9uP2#ukZHj{L)R%U zl@Q8W7gK37%tfd74f2^NK6VXg@ao?_R|SA%0&Zj;N#vjNHRdU^-*gAb2KpVJOwkvk zZ2$S-%FpM#W2B1LqBmpGfqAVo5A*Pfx9>B>0%0v=u?I7d)nbxv{6XpX*M}M%NWuN* zRRxM9v`G%h5S7v$ZsPPPZC?d%TR>v-5QeA~09o|gEoZ9yMe^^rYigf|O;LqUaIGr% z!Aw}Y?Br9S$)T7cFSYE;{CJ{dc1sIAB?(|Vy9%=`eKj%u8)pqbN>UR1y45dfOtB=L zbVBj9Vn8=u*wtaOB!zqWsv&X_dR`$pjwNS%%qE0Ri7v8m}&Dl3!_P z3TR&(+%?jcLn%H0+EfmM8L{Tj_}Rcj{pJI6{q+|^w)G7IyNmNu!A|M?if1aPQELh@|KZsee_81H4bRE3|$eju|(u(YpOgM}w&oqOz)G zH>=@D6Os`ve&kiZ{ToVbD?11Lj>8q8Ih8cUd65Rp8(@k(P1401R4 z5vu3!!Izpm>L8uYd&am)_`Ll@x|++Q9yY)4mF@x0Ptl*p|7E$_5AVd;#>ci=E#*Uc z5j_zVMzpJ@gP3M2>rv+6JGYL;cFFT`T>GyPiC)yUV32@ImVaC0h z!C1(XPa67EGI~4aGJKucRtXa4mqCt!24y#Ln~bPx&mp^p@r?mq9@TRtKIa_(`Zx6Zj6yn zMSy^&L^)k$Sjl2AF?3#@KtxKLzDrH!^ID_fJdjTv=VgSd0Fu9L`kxjzvAv+{?;Y&3_h>eS;u0Hv2kD53@F3%x zgfO^@;J>Ibo*BWipSSx*@5r3{n|!h`dNp{19i?5s=}fb+*;3bnr*_swaKSMD9%~02 z{TWI?SZ(+nmc(>Lt0?m~!Bp#&pIVcPYar=KOi+xMaGjC=V5#5!-b`97bp+P`z*1VK zOXNf{mc`>k(Y3m74doy#SYaw^B%hp*9(D$+(6DAYJlW^>8TW??bf;yQ%N(gQ;EjHE zJ#=1v`^Cb2G6KsxS|lXfW_PpvABQq$U?E4rMwXpH><%kvk)A+)>oeS(n~)M*dg;S3 z8y~x|rd}9I(ewD`sHH2Lc1v#bJT4T52(5j8@vVRbUwHT({dWf&{@bX>Eg&zxM$LKr z7dcH^LM8>7rb|DRLh=AXwzRCY%5KO48(LrI@j9793K%FRfBG7jB;v3;-lk4C!8Ii( zZ&8(SQRbEBjv@8~s7^#Kdqbrt^KA`}3J+3ZgS|2rsya|?=<_u&L%;l1@@qPf4@TI>Q;&t(B(A1!j}P$#}Biz%LvvKTYd`9 z^DMoYIJMRe4%QBFQd4}Uu`bKiLSvu|Fg+afDx4wv@oBl240{mY8#nv&>}K({21Ns! zs#7Ts=8eGQkL+w*J$*Z)b;R)@Dzkqs?WNWnn><c!zT@N8YYqI6aKq4{tqVCFauQ}%D6@nMJ?3l&nycA84`6mZk&_C)@!ok{_5+)}AlSQn-ZQKEz3k=!-J| z)Z%Q_XGS~RZ*0urrujY)0zJoTFM9V~XXju46$CGseDPYEF@G4635SwDCC0WWTbU=( z+c>E*)5qOC8{rnK8+(9WQ;ndlW1#;s;qTcz>!T;v&xi8F zl{45`GNW2{1j=ln4@>p+PkGR4Lhs^F$^P*{TRa$oN24H{6rflnQi!^$#q$iyWL_+J z1z(LhiFcoL(HQofrG5eFBe{YgmrEtm(@!~ol$!GDOF~Vh|XWf-i+Lk3rQ-ubw2381=h8vykUMugH0U@wi%bs-}#nFZ^ZjcTGYP~LHm~- zbd`k3))tleZ8DcXsfX-bz=_~_pw}Fw;rb8VB}U+hgi^4b#Go(!y*I8GIIy}NpDhff z!xEvUb{HtsK1)m2#ox7ch*YM2b&1m`<&juM7$mlIV7*P;UZclIcu z!#IL4h&{2iR1{HcP@uB_oWP)7Hb{7MT|{YL-7}7ralL8eLk(t#eHz?N-5GNcdYz$f zBN%F%8T1~l?~nTnBT!Q=K4nI%EV7%|rqha!;P&9ZWji^K>VBzYoS;sQ4Mp|AJte|)B@ zg~EpZlKIv@(3OPY6oGCIWki$xD`7_HoP3m0&xsH@H^c~zniuoHR*7JfSew2VP4etFPwx(UHU`*~dAZr*Ro zK+`>18^Sic7?*jsra4MKufHTOg>D*7N`US1(^9@fNzPC3x~t%{YNx|py?XS>4f1%S zrZ^**Lc5HLDe6sbeLhT2G- zyTR7j+MTL20R?vzzS=_@c6XAAfGr%KdvL9krvax9p;ZYR3Tq03Tr?k8|9$>Ik*7AR`vF@LuK3TM=r97q|l&ZL&6+p3b5UTM(nlX=rpwFcZc&Q zJ|Qzw6r!%s|9HE;yvM%gxL2y@4Y3#JO@6ecWZ!~>PstyDh$7&&yq42^Z&g7FX2Z(Q z!aH;SH|W9_LmNl5+>l#2m&Ox?7g`iofreFHjxRA_|w_ri`vIQK%#J}tVj zC9`tY)13n80eF}a0N{ixLO*lKucstP9IGWCJD$Cu6E97pKR+}#Vn=``GEuGDZ(BR* z0Gh8MdLytqBK={4kA++~qwz1K{`?@*;)ypwOB~@%+n>EkQnaUO6Tou~0yV6#<{k1< z*Qk$sL^OC5lXWZ$2%TkapI85xn&!}AdccxYl;h_Jptx|etgw6#&bkG7)9|}C+zlS+ zZA7ws6}b0!;EepYXB_YW$3EysIv09+*&*NLbD|6lylK=&foPW=(ja&v;Uk0{E^}zw zSz8q6s6bwmWR!-*Cw!iJ%E&h-W;NACSwFmP=aT#+j zFCXg$JWLH`_4=do7H$-hCW$Xshb+e}(r@Gc*_H>8{KjqLpPfg|VNcO_YT+;mfJpR= zaNXw)kNwFO>A<-0HoSQ6@U)>>_TX@ozYsZ?vsc8t5w*Y}hUjenSOBo8U2<2&($<)L z9!VS!*S7Qhu1wAI^nPZ2QK#lh&pHEbA_M$w$tQdfU?#Z1%JvO14cz_&?Z+Z@(!*WF z+dsAmL^4$IKTQs5RrxI?3;bkUC`2B~+W8RP3Hyy5dK&qZD9L$OXf3mPYr$rT`nVCz zXgKEjI%}z*?v&|dST#2`Jx?w0Fg*N&e6(z@G?=7B@sEW%hD!|xnKLrp*IxUfYb@cHaz8eZeFIO5*!M({Oa~hdT2i@5DbotcX@55Q@)s-= zP0IPkXq(u@T&|cSe|6YP z8CeP*P0#j4vW~J&W#FUzRbzhHIiWXEoDNh(Oz$dZZou`6y=TlELi25HlIFYU!RCP6 z^jV*+8%J1s?mzhp!rzMP_y3h#Rwy7u$5_XXafjO(djTT#^?d0QSWZJTBai(wUrn)@ z!Xx^g7NaGV`!_>}1Zgt%-O}KV=sXLoo+DYI;@-QVZm3Q#dJ3RY90R&x4hJ&T0|3e2oU&Le%#Z_(20~Tt9;+pH z4o!W9uYse6sKgaX!j3O>pGWe^X~_LmpO#5KNbu_2rjY*AfxTfseZ5f z3+$(2gEJ^vz1v7lM19LK-85ZU&8=rRzvwY<8tZ~7f2?0kI0ox+Tho~%x@FroI{|WS zbcu^BTB7V694gUb|0z%&&&Lno3ph0oYDVfNNIi zTM>dx79_~FC70LpN4C6ZW}{)1(#CwO`HpA_Q;Q!;I-?<;f;9gW)it+wr5H_@fiqoh z{2yPW0$iBbxfrpSo4;#;`8N}0XT^uabhR|m%nEU`ge7>{|0cM(veyYI-Oju+5UnTZ z1^?N9Lop{Yge6DswpJjPaX3{?3SayLErHk>r#TaJsgdBsAOBrlB5lI$1S58~;UYWK zYr#hSI`HS&oKi132Fz{-?j7#)ikM<0z@@TQW%{dtm4doU`u?9EQv65@c-N_R?1IO#^+C;lunh9kQm?qkrD*&3*X`yI zcH%ncbzaY~AvnbimH$y9Sm`9~lmB3D9}Jc|sm7N8pz#n~hb?epEr(J}L0YUu*iy^j z)&&3JJZp2onNkE$yx0}rCk&s&^EmMn1;4ev3GCva=cA8dQjT?8RJ11;_V|tT%5$sR+hd(BDeETh|3k?sCHvE zBD`pV)ZM4B(vAKi+qKx5#6}=%zKXKJicpY6TtXaxbDD_jVN2urth863k7j z9|NDhR=o4wt+N)q3&IY--rW;b#bC$L1_}5MU7OQfopmhmeH|p27U{NmP zA2RXj(D7NqwUH73xuxV9oD#w2B}t!~MaO6FVj7&){D%C;B3CPfwL6%EGeH#NN57MT@T<&OiF?Uc6o- z!{QfOh6RaN@~vPgw4Qlq$DLC|gmPnE{nBi*O%3Hct9^v&@_S; zIM|!&B*_TnqE0vUNJ%d1=Dv%xBUiOSwZ9`XAa!hUa8rwd$Lvq`XBr0kmOT~CG8%LM zPj;Hg0MfO-#B)u%7rl;`BY&%Y1j~GWv5xOJi@M>hNp+{8C#dU&(#*=FrT^b%iB*H+ z2iXLi05YnE!G>FPQ&v|aoop-{yvGB;tLh`GM`wkdZ6>xEA}%IhK1km!%F?Xls`aY=#Hp#zpuS(?KI4KjmtAPY*}3}Y_U{u z-=`!>M8Zy$(F<(WR@MIQKmge}RUT@C3L-fK;Y$sc=0(L61zcQ-+hDbRPg@%-%V)=~ zTTw`gD{03>6Gt^glQ)@qd=R`|ualkly@&TR^2{35PAUQ|@(wXyG#9+TK9yBXmu%d4 ziV}Y1euR$g$BuycGu(Zw#(#+xsMsO#1sf-nH~hc{9AsKyBkCQEHnw5c; zST4Sq)nloWAr@{$3-R6j#$at(Juz@xl6&1j?^kMr_VS*ITC64W>AG8orG?1-&8Y?> z_vg=-p;QdGT`N_mkcCX#G~I*NbCK@#pEqi%t5F;ESv>&Gl|#ZvE6t*Tbr1Hg$++;d z;^VUnaj0mhv%RDE^G{h^zQ~vGp78Q{v`!_K{Q2CRNg5+HxdtPL*<)3~ZCb^X^c{s% zAGg-=yR|&G`oBgU%-UY`cssaN_j5Sw^_lyG-t=l@FTi4ZXLMgYZR3<{1GRXO4^seV zSOc@h`OJY~c}7tq-e&T9a>@G9cDGj1!xw)XX!Bh=<6P(RVZq4!k3~CP*MAsV>2#p} zToTWX{4y zRbAAbU~Jy}mfHzyA@3AhxSB9Xq3gQt;$eqd%q z1#g)Ltn^tsa6WrKv0Yje9vh>d%DId6%n`-&qBMT8Iqtm(K8)#xmeZaQiiBiMWx5_O-fi!Iy<@(uaX#x~ zsc7=&4nLbHyjrz&1T?oc&{9lvUU&Y=hKFZ!Sp85*jpU!)2P&xusC^ED!k@?W4}t0z z=Fg|e2RrHC_d;U;C8oF1eL-FDdod`azkoGOfiY3yT-*@9x+iw@5Y z5^b!8Mp%o(ik(|pKwA&nZcgR=ab3eHpcKcJJQw3G0? z;UGM7sl;q)PWg~Y^W3}|)&{b{dk!a9k=D+gE)4KkRAf)A#4Yt{W~*zT&2Bcnl_6$B z>?`$?Sa2LAhBgQc`>Qm~WRU{bRH=8I%KD~?VY`$+viRq9)Y=?8AB8xd+>@;-lkY_< z;g>vO#)rEb)>13SuG-jBf|8nXFls$3^GN}?xYg4~KRZLlgfy1sI3I@vgDphio7jV@ z9B-yEu}5rQwH26mw!EgU_DiXe;2x9YO2g_A;=Zd)w2ic6hf`-DzPtw`!1NJa=c2N zZFW5s2Q6&nYk!hzKJB?Y1O1BV`oQo|_dUo@J7p37{#iBwjLR=?70CCPSfO<8WNrdM za66{04vylg+R8`YuzBLFUz0lF5 zCcUSs<*|}+jJh1 zU$t5%qv)u{G^RS$2FSJjFc-LHVkSKUzU>+HgtdRSwz!ZlPf+IZI9^t&v#L^W6*#{g{%{|8H|sZC3`XA{Vr zr3DAf?Ml$E0?h1xBB;o%cv+w}fMoynU-ig&Bz7MdhpC~qGWjEj5J~4lh$x&v*13Lp zeDOe_v(Tw%OP?UBajR`Dc#JXRWU!}IZwbimmX|u@(Erk^Tz=lx7=U^)XUYG;%fY_> zTX30ZR0oRC8a3AtP`1T~`iDUl@lmvD$3i1iSmUSEG;F5MT;lZsM&6a|LS&sUexmXY zki?deJsOD$NVE@VTu67+l+%kTZ3Pyfe@jK$**RHOv5v`X?pFaEG{gAX80$no!h~P7 zA45pcHAX|C!J!?W0QAV2_TWHl?5KWmJ)qXk$Hy&H;KTT;fT;XrNHeH~Ypgjtg4aXS z;Qbawtp3fl{@4B=X<>&-8XTG#dXw=)jCkX{>;@a zO2Yaj#tYDu8kF`?_C1jy=Jv+YM|^oDCv77nA4!o2pd5vFK9`ry$N@pt$)_CF-aigyUtUJUxgOL$ zC)dY$HOf&(?Hak29CLZ;^xvi70RSH52#xv~OOuFjk9KGc1hzbB~c%svEAZkAG@QFShAjRXb4$7e~6aONiJUM_jBDxuePkRj(*~VkM|p zhIn*Zb6=hn2fDGH;@*UN%zOS6zrzF5)N4}5rs{o52mEk;r;s`>U^aa!5=y$yw zxNRMIA86|=gvA1YE00LimOnu*SS&c8sqy%cr+;aVqq+Hld>W&hEVKh9%$QG7s7Lm2 zEXd1}Q1fR={gTjbG#nmE$mi*rXkU`-m=XG}Q|t+;S1OINRj_3P6&c>YI!2P=(KHTF^2@Mp>g$e3PT0=RQ)yql;wnafo=}6?bPM z|7h{PBGKlm=W?@f5QWDjO>Zpwk#S)CPe!57Nz^#VUR@IeYa{X^g#!`%+mK>fIV4P! z4PzE^A(~4Ly8^h2+pNaDM=G3*?$?99FZ@k>LynP$Ng)q$$L{E=Q!W>!Lf}n>g%3VO zpCx8u$14hK;R}D`-;rauM3ajYwwJ2<;8x9*o8hWg$RTeNGW^wGDvA+9#mI3@6Nqjs zbwI<5i@x2Q0PlcoDq0k*wWj#7i+ybfswvOiBqyFjQ?_@|vP=!^53zVXss<_L3$`JH z*Gre9K>Flf1vN|c7f*fy{bom~f$f!ealpG{+Vv=L`yi6wsaQTqGbkqkCtjy#JNZ+= zjCx(|A9}XUYDUbNWP@WS2&HZ%ACE!8?tMN|Fb96tgnUhRv&9FzWiscg_zGUsM=iuN)UP%FK7XYkjsDjiZeNAy|y<4yyldA%MlL_YU3og>UhQ>TemBROaCX8{m zfbhRPeBq&wbr|x3(uz3jlTIq4QLY0O9ss6&?CaH(KpRDB0_b=qyLd;*crNf`Q?G7AL(g}{ zm#7wiL_cnWD`UEUN21m&BauDuD==tYP!&mzu-s^4^?kci8@~0sP#x;c%nV?gsj#X| zT{s>LznW--R-;c~1P1Ex2wZgOxPy-5ZDGLAYCZYw8Ua+GrdXB+~U7$qoE;)e-8a4YKdg&WJogTw%t z{~(wF>DWZ(|9_2oi_Ox{jtI3+5x9qgNNj5jl19@cu<~dukr&#Ctj+mKky|TNOhey5 z0a5b{KrKbWDQCwrXN8>AZrIcExgYi!o3wlq_hu7(t9{1qBxWD#0B|08{lWrM!mCmW z@@C~U7vHrUKb{Cc5D{!cQX+Go7}qO2a_PsLjK55i1eGJZEfD!5-CM;kyZ+izgV7n_ zDWa3pFLV2JDJ>jUTxO1Jws6^U^Aw8uB1}v_a$MYAyg30XH z+BNfjU*(5foYWp+!`|^PH_UJT7Oc)kQGQucTH?P3U4uUU6ERb zKUa_Kxq>T3ICXPb223AX7nC$398bwyZB5wAoE8l@j2vj|!ZRZ`Eoww|Z}HqY866>V zfAxJvK_i7w#pTbUn|z}@TNVJNB z{t%e=211qQinK`tjG$O&22{~fqUD4xnk+H-1~EUNk=WMBb(8t_Z-JiE^<7~LT(b6h zgj%$~cALv)zD+BAXP$Mzt_WezC5RDEa-?`08VVM?cVvf>^62akm{?Dn3pyGF3{Ocfk$|Hz$=HG3=Q#i^wU`? zx?S}(J>rez$h;TQ_npqJMgZIVA~AGzbddI|@BCn@Q`P!!9&a7f(x|PlWFj<6(_*Z=Asc8j3X<`Wz~!QqgzyGPexm@^x^`JR@SC;CcbC zb#xm#0}_r%mk(%F6yfNYm9fc_FZYHlC1i6LoQ^Yuuyl0iz;-&>DyGPo0wzPy+tHRA ziRHJpbYw$gN!g_}v)Rw*fH5cpTxM2JlYrgT5p3=Ob zO9-&$!MXXO)MEjsno~76S1{^JM6Vi1lld3hKykS7gMz6IxGc*Xd*u{keU8hOG)<2( z%{~eBJ3kYDabRPo!1S)!1a)iTM!zNm41i>)!Ln?$XVoOk5VYQatw>WNm^7&$LA#~k z)`Q|mA|OnZPd|HHEGtuRh}m$Al^|imY}^239K){9QN;Ct;#o&#gdRaTTgB&napBjx z1fDNx5Y+U8xR~p`>=A2btQ;qN2V>{1KV$b%kR&v!^sW&PJ5FuD%_y>W(hOi&6;jj3SS#`ta?B7K zkdPr{*k}!ss$$*{K)KjUCE8#41tORPsG;wKpUlwTJsOR6z;fKfUgbLv~01X^T2UGeLLp@^11u$@&W^rb8iK(_J zc_Sf%b~zE0mKy1JN=JFz;SHX1@oF+bS^`KYdL!s3bmW&l*n^D3f84+d~o z%A{vMQxgI{Pdxf>5O1DX+vne{rjl_IIig_@z`SoRH*ytKbluzgQhUCxNzlMV2^fPt znBH2jPqvKg(_DPWBDklVZ1J^>R0cWqm%qYR7m(5C9?bJ{I zd2;4rzEVGz9*ip;x~~O37Q$qpzQ1+yTq3x{~gOeZxXI zO6F~DaiIDYcX~XvI4Oc>z^ohSQz~G05*eqOXo%@Q3Pu4fL=oL%SuoM7ro5}nbPMo{ z!xZT3N;EF{vvkOBcv`$X1zfh|j}+mFz4vO;2nN3&a6i!Jpm`uRwX?HKfgelm{&V~u zur~ugkyK;*drdY0r!j<3i6v7v>yCiL63MRL2JviqsFEMMRHyJP#W@y@>ci29sM*~H z^+@V}BIyK=-sZIytiFKU#?(<{?5 zPW{g`>C0bk;IsK(8b1H;tfc?9E!SKh_zUseETv^{8jl2wyg^!Ox`-N;2jTw@J>m5m diff --git a/images/parse_tree.png b/images/parse_tree.png deleted file mode 100644 index f6ca87b2fb76fe83e5b90453e8513eba14ecf24b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13655 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 E0q&R<=l}o! diff --git a/images/perceptron.png b/images/perceptron.png deleted file mode 100644 index 68d2a258a5bf59760897e11b64d4cc6d882bc17c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19756 zcmeFZWmJ^m`vy3ufPe@Hh|&s@(kU$^{E$k#ZEQ)^-fMC-4*>U~3B%e5&ggyC?|`BpSn*!_0z z7@iwnAC&Xu6}fsDX`yaiqN9AEU-O1c9TQFTmr-4Hs_=OX=aaB{LX~H1`>fE`?fzO^j6AnH-{IlM$QSC$ofrK8uet-yB zLFH>jZ(z!-zS#A$Hqe1rqH7+7AGN<_058tH<{rNTE-9V1-$u^_?(}e>GhcMv^d zs6#BHj`sKW|CBbYlXt|jIJKQd({O|ZY&2n*QTaRk;E}oCIN^}BDoiSMCMrGn7`tyq zXiLtIWl_p`lzKAwWUaM852+QZc)W~!wYa$WWPP%ZIR$JnrPcOq+p{kIGI8rO#IxA1 zn&7?A!?#9=veMG(|NRf!J&zmsP;$M=o+Lsm$FoRp)?7m*!k(%-{0QW|UOT@Ur?9z8zU` z|4-4QaKEvy&!C&Fq->*_W4vgq7wz=>*9f=rN5hZIdC)qU3R9MZv79E33Ws2GlgIyc zGxHkLqEOxZwE)75Z_-+`68_Nr=a1pjw$n7X=9_Xy^9gyp=*)oiy4F+)C#{R%nZQJZ zaL9K`DFk)q^zk0fu1t@a-?;d4wabL95LkLhzxwkO7;1I0PV9!beY`_YPfzRmRKps< z_GGz-AKf0HIr^2ro&Wp76(-5MkIJ9Fwx9sF=pu!!F1Wb3+z0>ohA_j!#A|D7-U8rG zJX>2JnSfa(&kY$bdvFVbAx)EV`_DF;q+Zn2g72)nlXd^2M7w-)u)&5-mFOPA5IS1N zj!u5Pf@NZ448!kF^oAc778X8f4I^#^`^c`0(ADQqgiysE4nz8^N4CJtR>JvF5~W#`&mzlfOVGw1NNdSR1RZ)pueZR}a&PAq38m;uWB6WS z*#Ue2_3Eljr(En$wvb6dvamsI*`B)rvk?sF-die>qZ0Qw$DPVjY#iNM@YNQ;UlAJ7 zu}SsP;Fvv>#3pLkc%AP>s7?p&z&uS~TE@!nKk_t%Z+rC0A0WE_{*04K2CMYpo$y9o z43m_1ikIWz=BzE+->Se+?I2*j^Znv>xlK2E!Kt*a!`#)`Sv=XUH^W6RGvw@Oaht_w z(pnJg4=}k3T;i(FdlSQ4pPr3Ai%Z!nEuCgT`5-5q$I9Ey zfg61&+7|e(;D;^PM;2V^sWNcKb{!cB*GXy55VxkiktaW*X<8LdRulLb{Lk?RuY&Q% zDSHP~KAA^;z#68)2{R2v#NC2Nrb{>(C#&bX*3L%0N%zvYBUYd3de~F(Tc*1dJKxsK z&#h1T1UyZ>_zd>lcm#t=iKmeR9=BWzFNI zVE&_p+5+1OT!Vjqx`$HFA5u5|u6QhiO++eOsG0IkJFwt%Vr0jB!1cw0}U z!=OIc_LD`DQ#I=OqWypC=HBqH0xuAHcpJ_Ai7VX$*ONrXs6CKg_?#4Mh$dAPJc4T;1wyAc7#70SGq?2Nzku5$)f}t zxAg!4mBNBkV0TAHCMi~!3T&D%;W$ zv1$q4Cm6de6$DgU6ec6_tmDcCcRJ|nCXF?#A9i_pSrR+c=(qD!1Pgp(sLWwX_Hd2JbX4N8Cuszn_V| zX3hG3qRPpnZ)j-9Wq?CeGZW#30Y`%&HsK?A(QqhLX@gv0$3 z->KE9XL@NMXF=oair_*bSNeeOE|@QeNq=x{K2kWYT-VnmS_eF3O)!B$U`VDYwAzAX z>29QYKDcrmD;)QxZ)C()rlVfB>}rLU42b69S*%&?c>>+YdSTQ^>A^A_t~f}EcfdYv-f_gSSU8QK$*#etPk zE^Dy>KJDgfb=b?tHK;|6R&lqm$9ZB}>-EQvt3H0b?io;TG1YvglXt$6x}LvYc4k}y zOtv+vrM}&0M@NTXf_6`eSd@BxAJS!_npiVgP+~!ZFF>8Di|=*+X2IUx9@i6G{etxE z_21OX=eXeIv*lpyS?-LT{8f2Y3zIl1NW5IQpRdc#Vo#p!SOgPGo#7Xv-FEFed@`N} z78X-?E)`)ZvZ{gCDckiZ*~E{S5)q$jEhzeb@^36DDGB^a92(A!=C}?vZk7L@W5adz zY?u4cqQSW5MFxc$rd}jJYg|;I%N7)aG=WL!*cZ8qmJvbnR4b1t{vE}q52}95s^@!M zN*JFz9DEP&c@S^uS^7SXE|h-rZ*Yzo{Fr>*zj0Qm+L7;P{|-{j6xgdaXNe8 zu6j}>-m2$6RZGuU>dkah3nn8q2}&^tA!n)5E(eyL1o+R@ed7Gm(%*^K`yH4eb1#MC zM)jk8M|JzzoGvc7-aD}#;kNV(B6_nUU8kGG&Msp z#xHYMNFMS>woUG-j`baIDk2mP+ar7rWC~+$ighF!w+CI>-+U$*p200|*%&mPgp<+gm!-uD;@)X~SZSGhX7ct;h9W$klC1=@Q@q3k z`9swvckRI)(!vVuOs_X0_55+lHiz%tDCaxQCLEg4>)Q@8$!Gdoe*bLQEBl!ha;k)Y z-bRTP%aDp<4Hwj@w)|ao&9)+nYIjdpx|MxT{gve*h6&{mJ|^h5t?eZ_ypuATQP2QlPoliNJUE~UI6we=e?o1(h!fz6^3!K136UE z+m1r2IFejU-0OTu)+ur!CmwhMSdL)iL z&&H_l?Yho0HO2bN6G0YK5TyR^6|jbIxCHe5P8PD3abiY3?l}D#mm-RePj0`(QZsho zqLLr=;!6dy=D<3#ZNYE$*I``gD@<@M?;sj4aT8kK))0S|Dbwps&0dV8p#vP~i}!S2 z!!$KD`Mwogf>wRMGJz3`iJsF)Qj1}+rChG(TY z?Z%HLba;8{vXMs$tbVtgY0B<*Cq!ur4D>R#AkcS!m!-<8#?@lQJ~vg3=rsp%_2%eS z;xMO)|5(ia#cE;*&sDIZB2w3D(!BT#-afADDYaK0M7`KB$)WkA3mFw62n;4ZY08*3Iz#9Tb`?y_$5m*Xcy}=q86E(Z9!OhA|i) zvaQ)Xj-+M-Vb5n9{9oGLe`HXt_Lh^oNhu6?&vx}zHgUQ<=Z5freW=S>WKy<%txZ${ z{%+66U+Jwi6mwpo*e%%DbI6B(n`vuI0-*z5n(j5f{I8Kfff}-8?d2ExGJ56;$z$OW zn&p*i1|Nta5n$mSWNCi^nL_J8t|rXRM1rA1yzA!>$^e!o{UY0k2u6g4J2H#eUP)(s zpWtriKxt7&@T??|cyJy=6(~skBAHa1+rA_C`aHu~A=^*{X&-mtd!Jkh@@*a#ALE}j z71B*9k}j!Z8N0+U{&vK8^Fr7e!u=pk`mjdaYT*E5Y-jSv3?Iy#>co5gx_*ZC+AA1x zNG`xI;*%UdP4RH9G(L<8#I{SI-(G0K(G{(|`#l7SX97RY8UbayWuK&D-tElnVkaRX zVJrKWf`i~|so0Ub*P?I4a>S8eV~q-K3nxqTAW~wZStNQsuf~KbEPUFbo%mz1C(R(e zSi*}RlH~(BGzGHJpO^T!_EA?}2vv{`GC-wHQPnCCC2w%kf~V1G)hz-=&u=`M%fsDt zz4T6NR}z1ZWao`tNFOkMp^34vu|w2}si^Bow;Zf3y{;?AnM@!-8mwds-sc4)7bDW( zc#~LgagKDKyZoVkN(^#M$CJ@MUMv&UV0~VFL^|A)Uk^ zjf8I(JeocB!(W9g1EXGl4bK(qJOQabnFD?XQxM8 zmnqp4R zHVTg%-lv49gS~a_DF}tQcHO-gUSzMCPE=L9K_1=)QwUivXk1zFS)X)BZevIs+tr$= zz>&7~`~ByoP~>*-pwkj#{oiG|P|m*zMA7$RyH4VSGg+WZME`n=h9QJo!#|~n*^S@X zq_mN28r&~gGoO%!aFSWGMt=nfa#|>oMp3*&j@o3rd8$)#e4U7$7fjf@x)-%fOiXLn z*qbZUodWDwi6QFB2-2r-klS1LQ(!ahUaU&jXck{0JfI8t+UbtT-%R{jEL6P5r}yLt z(HU45UqXjIgKhYv1-~!$*%rht-n@Yi5F4^C8~z!Ucqc_jXzjmej&_#Pl*DY&HySP} zAkkb>6-|4u^wH`hx+CAqAEunZk~Y z4Q=pVE7yEE-{-v{)244r!oChhffkpLNTC+9>7r}M5jT7MxTn|Z{20^PbTG|SY*y7} zt~Se4@hiPLWQ}y34Z{AL@WvGunW1n5;auHmKL|NL2w4o7CO}T1L>I%5aSAern^B6) za;KZ$_ZfM@Gah65q{h$o0x6j!(S#w-fg!)Iu9l>ILPEvL+;}h@;O($gC#?ANNA#1u zmEqR?wTV|0g0<|2Ke!dF%U&wivX@0R_wSeCm3mDB0vbTRy!D;?A~gpkB_&s5qJM`8 z!y^4W3o(ztM1@_PMOdJoZ33GVNAW%g$-oJtrfu-qxC(+|`!-FKU5l6X89*$mH1~fi zoh+ugjo(pnsB>}e%errS4hfY8r$^)~u$8ptYO%}?$%$93S(7wQURA4L?lVE=fRXy~ z0|eAs_PkJD66@w#Ffo}KVlGkRiV*f#Ffm#L2&FGu`%A7GLP$_PuJo2vsX^^N6(pKN z;pR21R@}$Ou4LyX7!|yKukIG_5<2BsGQ_>o%KrRGvIy!t zb`~j%=oktGF z?{Np)G0?#$!B=mJ{wO621Id5SU4wv=wVE~k#O~||Z_!R7Ae(C73>hbxbb8#izl@9< z4+zz2>!sgD;#GPx|Fx@d^NEJd?ky?LMJ-QL6|$A`3r)-ct6vw(`J-x=G6K*GTYrD1 zb@P;gj4l;}1bCU?uS~Vvy2Vr{^xEE#m)Bvy%!y^@I01i%hB^|!&CM9MK#oJSodRv( zJO>-rBaHx=G?8|4o|@lM99P^ubqFB}m7Yx?$}?1B^Kf0%l}ad3P8XMyOzp0)>y=FI zRXh*$Jc^ZF7f#l*{2oOmRTdQ)_O1;8eGH#Gx_B2Q#j45z7x?#6k0!oYtGJ^@e&)FD zj68O$a*8JddtmVFvkUBm0`ddcyF9~=2tIgd<7#;~dLvGLA7Q$&vNHAFU#g3;Du1EI z2_v{;c7<8GPw;gI@Wrn*s9k0dn#RoUe-R?SsJ>nU9r@v66~8)DV<$())ep<|`odG* zdEVcMND;!8JVCspJ~KhD+=6hAy~%Xt#&s(3jx9u?we0Bcy1(8j%meG!)B8W@(HTPI z8M=3I(YAqPVO}G91&3Svu)I1}!CgE5K@+`Z=ZKwnsNiM1{Fm+AR~Wz(4VO}MZD}dj zxW~P#W*|!D)Qi@&vy>K^RJfg`-i`9JqovFmr~2c}^CPywm)CPYW7Nx_UzIa#-Q}@4 z3H6Qpv&PGuMlv|hV{E>d)qSD1-h12mc-7upq#R&MGp{_3;>GgxVr z7~IsZ2iEfvcV?i+icG5MN7Ue3x2{Cq#UsHHPdq@f5x)!9;V?JGq{W&Rd`XjcaB1_g zqng^vgTs5!v&zindqcq&Aun3FFV>GX2L)^b=yg=n0>!C}6YKAvXgNP=(dnry$lJmZ zoMPF_r|vd-?WIJ`Yt<9_WlsLGt6#o{#l~I@=$V`XTV%I&nb=0M-#tjHat0FJ!FIMu zDz-HP(BD@fN68^%8G+ls{z$bP#aO)62bu9TY_0?&8IRh5}8Ds8x&4(WM1Y=t-C z`<7o*7PRKH$P=s}9&*2QLFU+sk=81`(x?zQ^K!bjKQkL4aPwh3!CmO=<#!Jav8|-d zoaQx2zIiPim;I>DBX=xikCLVRGji5HHtH&iV=`TG^A~K-y;EBjSBmR*zhLf`CR+uM zeIh=_wVXK_jOV7FycMjErqSr*9=ED&y6z!K_ORY>XAypKWf_$Y>I`{?HKT?`S-;4J zgYh`4iQM4Yqs6oy{D|(KBX%^B$F*^*;}4PzZ$Axn>TlTJ_uf%Mad6~jH`APKw1m`1 zIaR4p$%`N2H$vRXOqpfiC)^?1+^BQZEdzZhiW!$jc#s7-!{P1Vq`H)b^QTHEE)VK`lIrT%UTaI9kqk7(-KJ`F0pd9RN ztd>1{rrdfyWW>E8+bL@~^Z#PolltUmEQ>c;;2v767ZIb+@h8jIi_^T<6BPwFRDT!n zSKTdSiy=gBDEL|?e$}q${N8-LO4vrwMnEfYz>XSq&1ZXMY1ZO@`A(TlZnMA#No%Wr zZ3HgKwt@}iQgN;bEOToJ9uqR=WJIzi8`nF?=iZXO_F!OAv z6ze)s?b4dBu!kDj0|2ynL!NY-^%Uw*_#JYhpLvuWBU?qo5;A@oEltN%e1AK*~*iJGw8rHM_aF3?qR!7 zFwJSt%qeX1Yg|xqH@a;dcgq!R*){Q)aS>4-XEh-wHGfi_O39kRH0Q0?T#a1u^FC-Ov(o5d zT+H-e;q_cHIw&0Dnyu*#IooNafimlD*8W{ii;N_xIKOLF*(t~?5FuewmN6Yk#pbI0 zRZSgw3ZL+=Q1M%Sbq8Pdd*2#)JONS<}AR%7)?X6jxBoL+y>pl-Bzh4U{FjJR!mS20kocO8 ze!-VzXZvpFBaI)=H>u94<#zj2P#t}V?MMz%|KHui{ZKorJe|x8|3P&(nYqHx9LQ`A zu6hfWu?JX(8SRi5iR=e%UPE{B8=_VEFy_U!#{Ep?oSE~C)W}w5N#{p7umyT@SG{Ub z#YqCb#fvC8r!@kBPlf4HQfyVNEX z@wHF546l-Dmw7tRZGeNf6crW01VRKvd{QiFjMKd)i8rE?PjvC#lD+ZtC?{vGnJ0GIJJIn>C>}hPN+0G@fBB?dPtDs zL0#`y)fiUG;&^7|mBq%n<4Wi0E4I_D=T@gxEz1f#jn{AEMf&ZNMs{z~497Rk*1HC! zpp&|sCTChU+bFyp@|C|g?tEuE6RtYTJi}(L4xr5uJ}~GnE58N$hU$c_r<49km-G0= z(XwfhE*d46n+Ji3chE)E`g>)i%?_Y;WPAM~3!%c@Cna;7jnDsNZE46R@BZi8P?}!t zgR%4WVfw-h5r?*32NZU-s~^fXwV+UdML)Kpydj*`J@e7C!wSsZIo<73U;9c8S3TxS zzM#&oUz6NRM4wbu*P_Ellz+q8(oZza9bp1J%Lpg6KLUn>s-eC2#t{)@rzacsIy2pATr9!zQVHs~czQ8|az+2nBob?=DsyeVBg!Bvx!S+)RdVcByJ;h>ZXAeApu> zbL124Y>VQb(2J|71CMK5)9a`rB9EE}bW2h+xX2y+uN>=NvoRoT)w;tIAx`;>Nuh}D zfdP+}&=PMYsv@U4iYM)uGB+7YKi+ntYh{**oLb)VsySH@3Kw(phcA zfe+dh(}jjwnBl{&rlS>;7RS;e#!j9Sitz7RC>zE|L#y)Rt{%fr)4P)&U+pvCL)H{S zbp{STXQVc3smhBc+H%2b%C^(ZgBJL$)bULuie&sgh+Z|0{@RHl)koItmv>Ao;7Jy# zY31R5P?am#-$h7fYEsuI!?)#@A_*GgJ8q3zYVM!_opv(V5)$GWE<^4!`6B8bap9Q7 z)Ec2YoM-viiq$X*HNIrtAvh8h8W7`E$(#1rweAkwBI%;-4)AJuw)w-PCd`p`l!_*^ zAG?QE8Od(rH@f|vX9!bSUvuebV^$ zuJEfNFe%G{hN=h*)|36}xcy{t%TERKg0*syJO+i!es+J&X|*>kh7(s| z7UnLl$(M@wo!fHiM%BV>3OsZ;;j-5%@y^Gg!!#8Rdd#YXdJ9o*HyzKCT)^7W+*{H?HCN}SwppKQwmOov3iXV z=B*9bCl;aA@Dy!vRstA~@zg7Pc*$eY92=3k6QV=TMk-X&?H^GQ+%E@daLpcg!=a%i zUJGfo9lze10D30m9FN*-itsaO8+(kv+^t!c9M<8#%e+{DZ}|~^6c~ArFK?67?iP$? zX+U;-e!|PkMAnrKW~aRSlKFur6MM-9Y(kBWZ?-eg_uA)O^?TWiZGm)u(YVAdsKPdl zXMj9BV>nqk-9h({B1j&4;KMXE-0Nox`Ykgi^%fWnUb(TiPEAQn5hzzF{Kl}zm%iBk zh(DcjfeZV$7Kn)F^$mU@8>skVutl4JoGA+DLwe&S=OBi$PWE0}tkCPGTbv@IuPSH@ zJfsLy_8SF3+4$f3FVk&}tZyH0*dQ=9%u`3><7N#xqP5&f#`SqmQnB623IbhZMs$6m zL3JxA8-M3g?0&Y~o9v&36T@TC9+!QttgKOrkPF_0iiqb%4xSDw;tf0l_%8nX0sD~C zFD7pLHFyJiH@jK4Zp>Y*$&^8(24{w1@#?#8an`a(wajl4Oz&EE#liH-xRsY;1RDno-A{%Wj65XHkl$t)*k#O)Z6c;$jtQFwceejwx-Y zy}|nxL&ty-^HZ?ru3W8hb@@Ze@7U601@c}HttFe~zZ#S$3nBZpdqgd`(9e(=m?(k9 zF-5Nj8gf{v-U;+-iqCUPOVJS7c3`yZN(!bM_tM}t|ET{^#l$u0id0Zt-<4N-{B{To zQ@L&7;5lIzz`h7cGAv5GGpFOyLOgNZIQ$z&wZA&{EO|Zm9JyEceW*aHlvQCcs`ERQ zqVos})Oj6e50dmLLi*}ImP~e%vAKA{SW>%TCvVp&tXVrP4wp~46}DdgF=;tYvKUNP z_V9gV2D_I0`q;D%_grSDu=P?~y4A2~6IE2VpTBHdx`Mu0o)TNI)%lL%xhII%+%IGP zkfwx3%^QMM{$7Dwl%@4H{oYuVu%a0ynf_4#qid^VRmY+)&?OQq_QFjqS3w^sN(_H8 zbZ&g}O|!Gw{S)76Gfyz0F>|_IV$B+#&RbDl0d9T(;6ckAoUS} z1@wpSyY+eT86}EIzy0fRjvhQ~`TkZT!nOIIJl>d=R)np~q_hRr-qp2xyJuPQ`2{?4 zkcu-W%CG8QeCaJQ9(#2zyjNpiJk9U0;3QuW@31qvH(hYEgd3KcXtrdgW9LeMlJZND z2VE?(-UvUZ<6{M*5n({_!lcP&l&GXBxPKRONA0M(Rp~0#*)s`vNBdMJ;Lfqmn!G_f zX){`DaUhqgvoMn;emdo?V-DQ$98ZC`TK*e&n*U!)&#LJaNRgB+%S{h4V;rR{UIkk@ zs4a#Qzhr8Ttr~ge1%noP>vfg*qvhZtm^+Csl~Er|&aN0Xjr{CdMj6Uix6tvte~< zEH(1lh`sdKbD4`bTp1%rDb2G!@}f0WR8*2%JO!F`Or+6KQ9bA(LBIq%F_}X3CY><< z8WMk_Q(N7fFB~%AQUgDd#dwi43V}$Oz@k}q1}2q}H$Ct20nbRyot{Ec!&LonU+7-K zIGYAQ?Cih)Jya7>%|VJXq{q5AI|E9Tr?q9e9&&Ew7W~qk)yFf(A5BYxsbiUhERYr9 zI0gFsy^I_W4winQNRN+W;Q;sl(%qVrks3RRy(i!k6v!orb_%`#IU0QLmNcFNVzR=x zbC6?FgGf;ED`q`Cvdw7h*`c@B7+jDN^W%VS(PwRZcr7$6b$al78{SXV?z-2 zlLijDqx@x!Pp@u=pBqERTef1{5Em6^Jw7=H6;2YZyPupcDY{{7O~5J+!lY7U(*)4@ znP($3;&|BcdvSIL^QehCnjZn;n=8ecUO#khxH;0FQec1S;*_gDDN>kW(Fn&%FJ)At zR;|Yy<2hn#m$ESXt6(=mCC)0}|NHlRtoWDGBE4*nn<4TH^+6cE){Yn^1Gc&2zL8|% z80VZ#OLge1n4T$O-RJNvW9TU!xU78MuX=YPf}25_;|&YmwJbjPpoMQW)EG?e&G4D_ z<9<|O8&jv4qER{cy%Bj3n4Z$Jv;*5Xmw6QLVEbaqt!lbp$O}X?dFI^7C%XGOB*VlD zq6XPa2ajg{gmQZ3(;^E^du<8XEeIuD&N3a*0gS&ztV-86$LulzFbftg|1mQAJb%J) zFfD%>zYH)giCYr*D_JKHcLP_aaAK3E$XM&T#^i;zDQK04r=4M(?7FnrQ`N7F^gP!Y z76TY1E-Ibw(JcloOd)HxI+%L&TAv2lUuf3-6)_#{<^N^WtFX6e>w)}iTx^*ABWTQZ zbEt+y2 z3kRtf!=rTn5!nJhG)LP%D%WCZ6n|T+J#oG0G|vz~+rNkY3U=f?$~An0CsDEiGZ>UU z_bm+^8NT$9raxg6tJm1ayi_gS)Z}6QhCIZkG1_yH7Y*{&DA`a8N8&*ueV0Yas|#7Q zGM{U5TnNXF4A#xkR7Cj2_!Xy+d7>nSez1|xI~GUSJ%!G(&TxfP!d=oH689pNs%90t`HIp z(Q|Zjlalo_RFTLt;Lg~TZXo32Fi3B{!{if6%DmWIJ}a^)6^!_*bM=eGshnG5ZGj42 zyOZ!$qnnww{6qbz8O@LE#aS#4-ddezr!<+h;NB^5@!cBu;yiYIVK*Z7c7w5F>D@b% z;`*;_H_wiGLo!~d{nS{D{5*JeG0O*gqFAz9B4ruwH;i+P&T`KG^D?LZ`Hk^k{}3=$ zsLI{?EVIJA{wL-A3>PefKqSP&&zI1j!&c`WXJkj}H7`F=JhZZl!m)afTBA-f9CpKa z>dukIj;V5YPS3@vbb?k4S}`qWaItco+}?h#{Q zr$l7lr3+$nZ}zETN|@+lw6Cpif*jOo6b-d02x~ODs=!Gx| zay^a;carfZ;Y^p!W*#1$E_BG0^>MAim(an|?^YZQBsV_?@kFb^qh@PM>wrJsUZPI2 z$+G>kx0y^#%J$dXLMBSF+SbMxKY+}xeK<|505K+$;nM|Hw^CRy&L-Kyn8wbyDsx%E zfdCP2W}``zY)f~aV+V4*)vf6whiSx_J2ZxeXe5}DelHiBSL-6&5DdifQrOp5Id@f| zsqk?FOwj4p&x#EC*L>*Yx6PxdkXK!CUi-={Z;dp>0G(7!*5_~!SK{zg5O&u{8;s8C z-{`0piQ))UD)(!{G>>5|ELWf8I!AoWet65e`9>h+&Pr_nNJmpof&o~we;Bb4BQ-6I zJYMcRLFH$p`U_M@B=IJ_-KU)*U6X=PgL?b7XWbtK#Aa1#`5xToNH{$^Xc5wUt8D%~ zkhj};z2!XEGjo`3-t)71HEZzU>>nqqlhm7A9aGx1F>H#{mJPd;Kc0=dLD&T^?}Yv| zr*tQL%#K&$!xms5t;s}t%>$-!BQ@oJd07e{`%$sH+5WUjP<<VfM>;>0~<## z$R;S@5bM<%_+n_JB=FixMY5%cNtZPr7g`Lc!*^ufyhVd~qRo461-MlD zc7Yx)04;6>k-m|b;{7{)!JkiZ@t6Kn$qkjE=PTynVR-iGyrAtAK>g3x{}SS(WG{V0 z+|heKHr+bQG(90k$!4F~yFA0OGj<=JOleY7zea z#Hal@4|p?i=u<)^S+{aSiKm-9SWZw~^fj@H`To%HNY zxt0b9-xF1xs%1q^oiY2Q@@|0nNT3Q(0CtAf>U5K=5mV!fziJKQjCzqrgz$c|G}UQp z#z6aC?!+<=ptEGMtpOxeyrc2IrR~rgFH{Tx4|)((1*w8JFN)3o$&e3N{m_QruW6CE zBl-EoX#d47XHY{`I=QH#e<4~7)a5w?=rOQ)4GPlVfz1o1<<=H2BYoz~p+0F&k-)73 zs7CD5geTHoh)-5tS*QVQ+#UY{4tBBP;~3Gj=CNv*$Ay23szV?TFZ?r5WzOr%a(0@h z*QZO?w zmx)vD6x((2As_TvmgcmqF;S7h@b8|&&Cqan=+dyBA8<~9{i1~E z)tdOq#F~uUhJ1LVL&AO^RB&ON{W^!Q09|M_gD4d6sor$Vc_V|1&FcmLO$fPWG9hA@ z3gHCI>xT#eQ-)eR@X%f6dzb8MNiWD;oyuLfq?WNcfe`EY``I4*t=*cOkV`Tj=uPsz^=MLGdN?S z&~|D$Zn-Ddhoy(efQ`dx2!%p*jf`x<^qicE069uE1;*`?KW>TLC5Hq6+jZ%2t@~#( zDEVGEhoNZ9k9k}FbSbwCz-Ix?l1Tv(1#LX22RyJ-Hso|k2AUj^2~==-`h{;GIHXf$ zD~ySWS*)x{4PJURBE(m7Q^u=+OryfKr(9D{{ez_~@@L7K0dx@#2z_4w=Z9F&7Zc@N z>u~dQV0xN$6~xJldyl_9jR4)EnQr-@#xY_)Vfbv95wZ*@>|x9HfztK`;9=x1pWS0U zMJvCy6O#|&xcP+XBL;{+ps3%!ytAc@546#EnnDTRhV)5+K0P0=bg&3(O#RrZQ<&)k zRYqk(@9A+<{o~2s_g)*fX={k>D8l*(ylOFzDG#ID+u9*YAqV=uzL*toI5Ix*dFp;sK3aym3;Z718c*_bI6-Q&Li_;} zE&hGj&~iT#_GLhNcSs;v=UQ81b=k^_bY|#F(s7;N4q!@*YKk?~uc?055p|@5s747>8B#}N01_XZYy%7YLyu*HXb#(p zI|UDVmqgPxzvQJ-zY&v$Pz!)ItpRJSA^gCdz&>pGrsN-5 z7t-AlNa!4xS$Z`VivSs!vai$pNnPQ2fEBl%ug2T2_gt<1wVE%}=1WVTrn7hcmmuv> zu<3S*O184$yD(VG&gb+N5Ow5Uh(E!mM(*si0#l-Y5QIjEBpRuH%NJ#8n)aWXl0+xV zKzIa!shr~qCX*6SaW&-MxDcNjnK?vre1<n4Ao02ds7ct<7bs>FfC-az6M=POG) z6SiL5RY)$7iQG4rC!CsN?Po3~Mn)-1+Cst_sdc>RHnVE#P?MX z1^ZBNs*Ief-M$-ya&UCinB0jk(%`M=#|=$RemWK{#OQGd>k&E!T&;%E0;#JP1Kisv zAHzAgEDw|xC?QF}C89Deeq@cwzUII*f}6J#YYO&f0ep0@ncqBw-nIMvDTQ1qk;5xD z^pS-{x_|Hx*`qtm1XuFvtK88y{53Cq=`}P`li7Njrct z5s6m2BQcA4pa@U-zz8Y03;KWgx}Z6N{5~J-QA==>#jA`QHX>GWd+N{A9=)&4zG9Dz zEgG3})nW*bn*)EOOs+huG~Ut1}bUW_`uK2+@hN$O= zz6pU|DHYx_?)0em6w4^_M*9r^X8E02B1ii0!A4K}6!%@=>4e2mjzU=5F}cvO|Fju_K|j7SlVgiu1uZ35_C>NZW)9# zVJj;ug7-~e)+SX4eE0g_2eB;&3qJbtEzvvT=PMsroIzX-pg`lqXdt1@U=B=q=s>8S zl9hAqDx5PsQ#_+yMgV7Dl}5!r>Gk~a0xx-&%!N|iN~aGB+SPwPcs_iN!S~_&@fwQT zrFlO;|3u=r{PYF>MFHg5978M41zDf-X8yVlnL#D&(1`csFqtsTs8-+pFWD_jC#m_w101^f4e z_z&WT@WV4Jl0?AkBiYF}urF1*1M_tAViWxD7FHO$tDM$x%<=W~2NE%M=>>6!CRNZ? zV9&AVEC19^iGQyULB3G|=gT>W3K7^zicPHlT5B|(HH(L&C+R`;gT4;F_mW7eS>~zx zJ^qeWeq4(+ube@mhSI^xz1xdLB4(|$#lWSZp#H20BhbYs*_224f9B zvnnXO*e^jKKraa5g5{^uokb2QIzuQUT1sqlQ3VbV!w6#L&@MG#(F}hU{l`R2C68Oe z^@pyctZPQgu#4Wl4CH$NR0eAOc@n{bF3VAeujTVOmTfw0=)K1 z1ra3$a(t~&llU?eicHdV(jEh@a{|3Oz0MtRS}v`JNyCIFM4t(?1VUV7Hp&3^r}Y&q z+QbgC(49O%Xa?-G+YY|J0K+{mwgY6(f}_I^a*Cb)--qoXK%i+r0vh^ls-a>M{lXcmYg6Wc+?8V2~i zv~%=}X=!P&T7rgi2Dm_vfBHXh@@;?;P#Bk4x)8=rP@*Khld04OhB4f?>iF1SrVg}3 z7b+b0;So>*34_R=c1~h<{=*&3RYIo$XF4uhpM{Wo{AUqiO>*EeIoMDA_RmvAo^>Fo z%Y+sGnIF)QYBYG<-o=Fy=;gKIF*mkBp6U%WuaImI2Imlx8(TM{XcG|ZJnif6w1I#=(=6@FOpK4VkLOg7UyA~;hTS2xxN)vI58`)>Oom-SbOK%->!XVA`}cpP)#T64S=vy<%CIH zAY}{u^6$k!@S@gtO_0fp(L4W)VPbHesO~ARxN8STrd;;pViTm*AR$)?H0+iM7hg`MF)q6h#v0hVfOv-|5P6ptVHRJ&)X1ZxG z;Qvk#zJWmq^)d;9mv{QeJ~NPwsg=D({?pHQ{J+%C>w=!|Is!S@^XiI~gnqIH6xS8Y_yMxq|M0ZI@8^PrH3pcQEs06QFbH{x0qk1g zG^d#>>fgvHX0?le9|7{5NV3G!I6)vYpDMdIk(- zSu*~+%TEZItV<)xP%X}M4Y2aa1shgHcTS$g$=i-J)cgD7OviXs*mPg_ya|qgA<$B* zeI9}@8zS6XT_tA~)WwzKSkFsprWxP;mo2T|+X|pNwp|>ix0pccLH~y?4GtI2oi@4p zzSTUwd_5(g!g=(CVCT3@4MmYlS=H4er*gRBiq%wY!PPjR>^vP}0H3)C)#m`L>8KF^ zp&*_V8e3Vh;j~Me`p3u)%%79v7(a+L{)h1lW=11QIPS?*J$#X;Q5p4LqnO~#m;S;U zkIm1l)|72JoO_Fc^Le*nU%6LChXEq%*(f6Q);V1U5k)ZvNILee2$yM>GiF*r7fedb=vNyynp+<*SUe|u%mU;@ffuT(t4Tl*z}4w=

B& z8c6i?5CnF|TCO$_i?nY2WOEZD?A2J|O!k$&!m-B|V?Tiq3Fab|4brje-r%zym%ygY zX#)O_(4ca$Rm(KmzL2_1yOh8{cGA58CJ%2DSsu9m=#2790p?{|OeOXdw{%glW zrEj5sMmx?L(Uwt{G5QU6ft|tLe0fLYbH9VQMod^B9A0&^3G7wKmKx&VQ^#w}U1Vvo z+TTtmIX`gm2b;CRh5rljSRG6F;sf)0Ht-FTlrehn%&+?hp>KsoMPY!6^nc8c!nC z`!lfSL%0gKM+vwMe>X63Flgu=s+kuv16U_RPSCle1oX(WGc(oBT)%b=afKsd;(4(=4Lvi4qKReHMw|`2Xyj z|L_6L5CIOqE}xyZYb8(#aFgUg;D!R3n7W@&pZ&^GpHtxU;mzjrw?HiphM$UO#6gS5 zf!hgc67*A-8QfnVzdzyAlatR@`~k&d?f1LpJ6W4`EFk^t@<(sBkX`Yb>PFI3c4d{HEiNGmxQx{NG5Wpb>q8?}-0#(tY g6vaWXRN+Vcq0f8km}2_5fg#G^>FVdQ&MBb@0IfO>4*&oF diff --git a/images/pluralityLearner_plot.png b/images/pluralityLearner_plot.png deleted file mode 100644 index 50aa5dcd14c138e342d8cdca63d70b1ada73b9c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12658 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 P1V~j$^J$r))$9KPCJ%a| diff --git a/images/point_crossover.png b/images/point_crossover.png deleted file mode 100644 index 9b8d4f7f585e319750684e76f5652c089b3d316e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5655 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 IRqWpUA9haQZvX%Q diff --git a/images/pop.jpg b/images/pop.jpg deleted file mode 100644 index 52b3e3756c63f2102aa4d7345f09e2b320673989..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 109930 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%0D_!m~REL;%r zdzJz;eEX+{IlC!D0O%%aMsLpXLeYfDu{yf`jv!ocdfIV%W~sw!%7J_>TBsKhLMTMs zx8o)uA>$o$rcl*rpB8E5Q2l@y* z={=HkmnAw1)cZ7_wCapuN%t(UuWPd=b<@sv30zl^OA~v{_1SEMYf~l)=?R}K{G6{~ zA_o>=nxFAPb%@wmvu5cfXanB+J7aMk&B}AV~ zHF0L@JD{(m6K6AseJ4D#m1@VackrVwCo=JOV(<4nOV2IfN?@oXer#Q%*|p;*kR-Fz zJ819PeVU1NQ+V~;X*+^;dD_a9b$0#L+X_qok>4y%0@lnR8e-xVYZe z30-lW?TZ%(>O$!;zn!0^B&-Q+l>Tc9*meRV#QDb2{xDz?K!+1%mB#c`&86P|&I}>E zQnvXZCN3W0p^y87@rNWxK^06ZY@3;`?*tIPn>|zoHQ=Df%Sw85rPsx}mzHV>rSWUN zc|SisZ~doB^7pPTSmo|sQgH`XVwN*t#zhBrQHm;*Ojqj+%Sa3HLnGWmvK$`fXizKd zE;q)vl)Khn^UbI(vgTHeK-%CvZ70V&n=Cs%DU*WRauo<1H7Kjn!|i6;qq}5_AroY= zz-8^gfS-5f|Hytw(R0`=W_j+VR5bNa_bg5pGNru46EhI?_>Nwb0+7_TjR(e+Sdoys-2|om zgBzKnN%fOKuj+@|4xKcqmw4&YebPnklN;xUk|dPQbayw?gIe-<###)dD@dnk#iZ7Z zM?MuL$GjQ_r{-2 zmiBrN~-`@!RB5TMfgAB;1_6mMtF|~pgxsO)Vl|{r(ERr&7$f0${ zf+yQUbMG`TwQuun*?SkEB{GlgX1bBaQ#3HDA^a9}spkfnj4_xL%?S4XdMZi|>7F0oDhC-5=VBciVlnc|Pk&_@r9KJt%JHc5>8lO+T2@tl zbmY&;#SwYb1QB01WeRF1`kBI_mv%R7Kxz&h2<(UMIunSrp&l z_u4O})Dr0V6WttvDld8=!vcua%*meuj*2Kzba;suM!9K7m+j!Ky=5JMoG1(#aSKlS zfUDF}?`b(iQzK`AM>|}|DD)JCQc2wan;G)@sBrl~Us0zc4;(x9-PQ?VXJDlJ95S^=7sg#cSn%|rb9VY!7g>T986p~{oZ&8Qzthb)c& zf!5Hz13pLPR3~U>ILZ?t(OnJFV|UhdzpMrFjktK+O#UJ!ZWxbzm<=%go%yuusj;mR zP$xJ~nmW@zSVw5RQ1p$F+eiHN>vCM*bX|2FynVzm$SiOZhaATG%uU)|qXj>1RcWII zwAtkgnOq7k{^I?R9pu$7>aeusenBzVh_FzK9z{E(j7jW{0?YAKIVhT> zT12)%N}{iEzR)e|W)pS3pbuAd-yLq33OE+(XY%60(EK>?V{UWeu3{IpD3)=0@<7%t zh8$03FJ7V7Kko@W`uGSK;waYoeQi1W`$^Q9IAjO~xXU(>G+ELzBz!!_5N%FtNI;(| z4Dmq-LoFeeR+^HlByHE2I}bE_z)uT{Bv$i$aIl_mWYS5w1&M~)u0u!3E$RtB&FLno-28+*&Vt$|alN0`8;jY!8 zJujXa8jD=DtAK(Te?S15lV5UD9L6X^m$z<=&Ah3qPuRAf{_@G0e{Fr^WUx|us~Nk@ zY+ne4F*G_wc8ftPlf7(X=XiDdPTA8og6oet%tCXwGKXwJgji4~(~111&{9v@}}-dEnv5YX7)kQD`+ zZanVS=ZB(sBB%%Gwv04(vYrRpuR^t$l)vkyBNR*s>UHM%=ez8Fh1iXY-yih!avpN+ zbiW!r_c-m<4&Aokzht@p^R-n1REvXjGJJx-`Rbj@Nep9Fd>5rus&7w&U{Q$lL8PK; z`l%!mN@Pi%UQ4^4J?5lL`#S9*U8I4#rr#`Z&h-^vzmOFJNQ%UAGeNL?cx9ySV-5c2ljvZDiZ!#HpT5j3~))lYOh`DiKmys|xzr#r6a75g#$ z{E(iy$HQMYQXG4&sq@dwRp<+%#$2fKs~7nJan}4ejh~Z{-`USxw*||LFjh7ATwt%A zf)N0p{3PovO(dC!mki18sGmJLeD70k-D^Hb?!du+UOYRaWt_li^4cB&ub9ElH?t&x zsJ-wU=eazL<;s59D&xR4$g7;l`RWP}YUPqeu6`dU=8kF13IENO>S))h{Q- z7A|JVsne_?^AqPJk-Lsyp&1MxsAI76Y|bw14^YGdC)KXqoJEN>IG{)C|3cAR5vx?M zhsh-@8>l-}l-a}kJ(tV3W3m-_n61x#0_GcYaVVNCD#FN@fQ>aew__Lga3S=?^z^5` zzWKFaYu#!CJLi7b!Cz$sFw>v}*uS>khfT}XB~r{gtuMX5areyZ0fhH zzT%rauriL^wYfo?SsL2xU)|3By4WKTdWGkJ$Z*@di0R5UNHaMhX_!(C3Un(^j5x?&v!BZ-4EqO3$l9vV(!BS>cKIS=#KhQx*VB63bV`%F?9#rlS zzAKNnDWU)J(7PB-o5}bwM>*?+t9xn3ZkYiA7;xLPiLnlI0NXpt4XqwUzN4EJcCn>> zV@h4-qGbtRYjIOuq<(768R+;=3yc}Itpqf*{ax_MRN_|r{gx{@hZzX**~9m(`}H1| zs+OA)wT&xve&b{KySKAEc2Co{O1SDX2Uia$TUCet(9RAw>QU{h*rZ;TZP3SN@SaS7 z#q6J)n1O;y&1Vk@nG8|f3wX3BIOW->GalyCVFR}dcpemCTs5eZnOgb}-oj6vcJ_4$ z5VsEt1}p?Hf~XHZxYNJ7Y=u_q$T3}2Q1Fk7-o!QE&p1#Y^Q89;>;$zF11jpaAE^4Q zF8Bn6@tkHCTg$e!jcYRyb|WY6=c~D*YfxWFz~*e#XYs4Q5<^uYXg2snl&G0LhJX?= zait%qP^G)Y*S^55E7wJTu?kKqqxQ@TfxllEDLBPF`%<^8@HKL6u%%z-tT;j=v;cNG zeeVIIJ;~G0HVS2#pNucZ^()m$C>A5eA~gO>>Fcr-&&JYFW&-TcuIb}NZz4nwa?8qY z6oDt;koNcRo$*B(f*@iN&-lQ8W2Upr5o5orFxf}M^P*3Vv}hEE_+bC>XrOmWHDo?; zJ6MCjC)K3?-o)9^gIDQH&l?^J8@7|`pR=}dYJSdyh$}pt;?ROPSGgFuQZ!*Oq^x6x zLCdqo9#~Hle~6Cny8OB|O)6tP1-tmtF~+qU9hsd#V2HCn7I0&!!;0PC-`lX%2l-&g zV{}m>2lJe3D=x_d@eX1Vf*sCOxo1s!{}ME9PLsYUtHsZ=$3-ZG4VQY&BjELqrTk;7 z&(|&up7^Cs(QssVvuifkQh2b7@UZ1wwks+0okVl_?*6!W;3kD8)isOh0g7uW(~pW7 zHME8(llB*f`1+!Gyi7|pD%$X)b(^;ABuxwmfTi-Q)%Fa8M_8Tc2VQ=_)ZMM|B( zb=8EF*@{E!WSJzF;jX8^vSib6-B;s1Vg2`hF$>8{rQXd6U2^qD$$n1Mo5g1fi<=7@mwf`D-cQg58q(Z8`N9 z<}Od=B!`OxD}Kply})+;H{@+ z74FsuoH|(gqt91Ak*R8OrSQyhUqnq=Yy4iXU{*6XEIK>hIvdzUbD#rF94J0^pw%rQq)`*K7!|H3$@D^HOD zS#L^{@~HKh%oDUR^Wd#_aU~XI4qTNhl-@j(RbS{26?9Zv#JQ-~P&loD(4?|UT=8(1 z!b6y|!bOq%n80hlk2zsxo|SN0vC|u6|H7Wm;=xk!`TGBH6Fu^^KtBVN>8S=zo#Vz&lxi;f()|4UbhO1t8vj_rtDf8Eb& zk>6h4;s~3u8v->U=mUTlgl*?(#@B3T7hs8lzEcPP!oJ~&Sk@uxFK)6Xq&7Ik3`dKp zapKtge_v%N}7hH~^#;eFN{S;EkDiJyr{c8~P=V(OVMs{)KsI#bUom zpav{i;^PcAs0diRbj`}sY`Zk$kFhS(TXPrm#yw?&q4u=b!d~mHqKb5$+XW!hb=~KSk-;vTfBkK@5sKIRi&A6xP-g+ z*&a8uS}q1NxitI!{+leOA4+ZoBh7B1*4{|YNYiS(WC&Sw$T})$?JW2}cRNsh6nrH1kQBHG03)rdc%2hQS#=db$BA&*AkvXw)4* zWY$`nR;R1){#MP-#rk05@(kz(31~esYU1uXif-ND)rlVrY^?aH)lsFn^Ks%ifO7QZ zn*+VI$2F&(!w_e!uI;p%WzZD+32^8Te~MfDrsk9U8vbaLN;5BQ*rRci`?kHQ9YbGcFQ+;{Ssn67mZbdG z&j4%;#WBu~Oh1&5jl)gGDsJ190(3+~|PduTvYCs#DMuSw%^vZd_$7Q1K9% z#(u?Mcra{A_Z~nmx!n8y?N7tf350{nR1ExZ$^3B32cxSp_Sb~UWEZ*BB2P$UO>6D? zekcKf(8JtCi?NIT!o26E#yc>^O^|mPfKu#-)=P(1YSg}JNGm209?o4 zn@WuUu+nh#=BWVR5~%rl^T<)L*xk>cw&Sx4kja>g(4%ysvlI>aIdvkDF~iPBEBF?; z&xs@5a{4rFQ+w)bTWCIS;{Tb?6S5Oaf3>CBgco&3&@L)?Yv8L|Y?-RFvymM#d3(ky z-mq>ueZkVd!k7jUyzSnsrGdA(j#4zCd_f?!W2T+OHYRJXej-xi_&H)!_;viBNBxr% zevlnM(|TpD!EV)@hP?pkxmpn-7iNPQ3o*v@r_-eigE?{xH>z%fe zZ#jJdbNuM@eiVGHymU>tr0C3Yrs(w74^g5z1pLNIT!aAN^J^{ZnoN(aS z+BVn)lJK-ke__e;A2|z%WltY&EM^F1IJ|u{Rm-kjE2{Qq4=#HZZjZCM}@{R%07=V6J< zb3YbV80obBHsLc}UE~ECRE7}w+9PM|+!QF7#?>YAXG3Xprc=8cH~Qs_K%l0umzK6^&HS`CD=or|l&o^5ySF}LG%;Z7Q8`h9roh>) zST3duB&9e!OU>Kv8fZj-?xEH9>v)7i^BeRocI&EUQaaijQYd+Q);1mJ#k{rrvi|cd z*s`Zyf^B7ifwjAa!hdjx)TrU(1<-Pq6a}R@Ze79-ttT zA3f!V#ydc+u*@lRr64A2tQrkJ)k8~U$FZbW8L^=mWZ%N0!VmKs##z!5q+*stD%mm? ztxfra>})WKOY)wj*l@mnkg<7itv>X&4?o7Q%Xol)40D-Mj2>_no@|u|QcNmL?ct7}WG8JzKR!y-{Py6YQseQ?M~{N(zJ$rZsQ%Cjk9ru-pX&?D zhTnLb_;_d+EG4-{cwr9<4odx0GGLc)ApSw$r{zZ$)s1Otwm1u=-*B32KTv%!_f$`F zbpIZ^P_@*D?wi-DjK06peEC%nTU-3Xv2p6vLWDkpY1f6Np#r;E;)`VX7^p`rE5cIS z5YWMV!dx<5$|Qg|b<4c=lNV{Nl$~CB^vz|SwEJ#i;&TQLe^Q~NUGWC-SYl?rbcv zu<@vkoFCjtTGmI%uKlgT;fntkS<3$H%Bx1?UGNgzwlNd8he(G>gdEV~UKmDhWE*XFlaVZ$^>!eg_r?TE8zPp@{)N+p*i37nx*0Rh61#1} z4}^K5yPBGokRG(w6g|O5fM>e_ zBA}-!3h+^l^t?#VhvAUfOp)}Dqk=uV-(n4vZYEV@Yn;|k@JcOU;rRRTxO_>_@cYWM z4iD5Ve4;NB8ohl?%-`jjE$q9Sb=W~%HKgO1&+d@qA4vfT8{Q{58i(7%UrxD557t)e z3rvj)lB|kQsPDcP~;>sh1pY#o+!{0?+Pq_AbG3B_K z-F3OC=%gr1y@k2mNFvAwHCtWaQ~)JY8B)GtYa!j{MCP&}RrZ%d(myiwx6|RZ*8hB- zvZtu;fmua%I_95{II>LQ z+dKpux(BbF?GeH_zmd7hqlvj`*Nx}H5{Yv$cttZUcO?N@Lj*?Gso_bb`0Uh;oOX^= zX7EOUx|Qs~&8ZUz?AhMtn41sv_8;!}*j}&Q40N8id2pZ?1c3&JN4d`z-t*8lh_>!K8wm$A@lz^-kP z0A$)68ou58!fz~OW8&qlx0WN`aqhh2iL3)VLbrj?$jv5~w9%>5=K*WRZZR4& zP;ez%@A;$Ay_@7#LmHkX-9WNTY*m_pDmB!|!g=ZMJoR^O0)13k-)Kv#3$tD-IqOKF zM~|ZM_}FzN<QI6YQzm_AYKn2iPzfnQ`^9!Sge+8liEWsL4VC@Ebe~ zS+)m{?eu*wqTG9S|7~q`D3z>DF>^`K$_*cXbN<1BJGBM(_J|WIV2;YwZo^RT_;Zxxyc_&ZAUUfYTnBWV|ATR|pW@!dgzi`Symhz(`RHBAA%ebtT zE_-rjzk0^4A72O}7Jhiz^>XbBU@~i_{khQ$8#f;zw0Yz!5~wY}S8tTslyJTPVB5RQ zYkAHE6Kfe^R_LN$ctu!TZiM#8_)AXLjt&qQOpSOy%^U8`_x%`GztwZQqHW86BFsRR zkLt76SZ7HfDSOg{6cBKmKyIu*I6T0M-@yGyVjo@Q=4Pfs`{lVVtk3BU`2)cn}bh>koownkm79!7jS?|fUQ~Q7e z-Ml*jGMpmvul}Tuci@FJ3+b)RAmt0p^}M^aG-;MFu47~35^LY)3Ln^_I;Ar;ux-~_ z2&Ns>OxV%SAlk-Hs?4f=$husg?l>eqW+;AK{#f-hb;-L|p8{JI{;^%kf`jf!hxmWq zyyn(;A*WDo>5oWj#sY#D3;}#aSPub+tDkS_foJAUF(GmNgXg>DK~l`C-|y6J^CX-R zu>|L{*($zE#`nY9_`-}Fn0L3{BB~Za4YK3f_}D}+)bEK=m_&aTkpVrYd4_s;)eKf$z!n>ZA}1V^AC>N;NgxX7GkTf zR=2^k0}-O{eJsDp-Y{=KOQ>owbUU2`-id{o#v zRRHvm0qhi$L!`b3ke6etQEunElKtX2Y7M9SnmtJP(T92r1WVkj<8nxj9lQ9bs!LED zB`f~^NEzj43_0EsRIk}PZXMWNU|5j9$HPo@WaGTqmeYWNq7lcP+t#g7%U7c*DYmWK z0mdoVe!gOYfL)~Q8@f1xx_>;-qlQW4b)tS3uKEvgHfBs^&xsa{4I{F4P ziLJ*|OG7DMeV&|N()XB!rR&;G*1|1zVw2~3j*gmq&_2|MnG6{wt;NvQ&Ls@r8d|Lj zcXxGsQrP_XZ0Y`2<*@MRfl*UU52K+8nm6N$J3-UQVg%r!h16 zx95+1^ia*VzbeE`NBLMX%|iAIp1&(etADbO&XaeqShnUI%HVx8LVIWYTR!dPi}cU= zG*Dwb*$GM){*?Q+UTdj*_i6o8LTQIZ3+wsMJuHBO$}{SeqiH@%yn*4LaN2!7l~f<` zK1u6pvYC?bBPl0y5WQJ6GK6GEL#9Q_GUtuknyyt>eYdi)%EAwQ!bJRknVSFSXWM}8 zs}9(>{gZ;6-e5qh*;v$gj2HzKt#h$0{g|d*meNo=yB=e25N|w>)rR|a~Or}=O$cCch-SMnr6o*SV&fT zgPrJ1?_FOX4FekqpX8P=Dko9LrZE)xv1+Ppz1w2i?rEm;0QbOSUD zc>=VtLcV-Zs*0OFj}O()z2B>Hj?^L0@@?q-KKXloA308F83qr#*-RIGkuI~!?@ZQA za5_Gkb(!9fq$_;SS}%UI#lq`eq<1C=c3eSUjC9*_Ow#Pru=iQ~z?RGa0tk1gnA{ad zs&b}tchyUW-K#5Ow=US$Pfeb#ax6~!Eqmqe;iNZ*40}}mI0ex9feQ=M7_Eq>@s7ut zDOTnp+o_lT!fwzASRYUD57(JFZ1>2E@K|wQ&T8{0_VI2Q%b#9Mm7>oP)w;cHD7X&a zWUPE8Mrjg#MxUW%0QpfKsdvqZtR3lC&~XkV{i@uj|KzTrj!Dr-^b?`RJIe?FHNA%u z!;IkT8(5MG7Y8}I=*!TxJEX)ffhz&T^VVPiahYMPUi^4^`o2f&_fN#+f#d%6KQH2b z&BY^$kMY&EiFo%Ky5mLY0I9U){?i^q0VWD1i6>g$Z*8oQ|@K z!Cg4^$+=6(X!PfJi)|?B1{J3#_gugiok-fPWUzV0!cMT}Ud*OnrRSL@c19Ds!zl;u&ea=leFi#logSblUSqbT?H#LO|L+KXRGb$cRf z`s^+m2*1^qVmech(HMZXYwPpdqyvdV4=};kWaVu7f`4lIK|S%U z%eKj8Ms$Nzj4bQ4FW*uo421Po-BFex1tk>vpynWL{?FdwN`+7vg#RyntttT(p}(+C z*YVZZ_FmAg_*%!2iX-+7wI~GnZV0N-Hs4JB3O>*vSK%y1jXF8Ko^+`HcnRhhryDPT zbnnCTUV~z24W#~*&GY(*nn|aSM8b84qR#i>iL1$r$rE;dYOu&OTkuiP>{6E@Fq=RqsZe-+n}j;D#~o!FB~%FqE~ zzidbiVUklpLI`$3Cs+cv%&OhS5A7JMN!AynOTKJaY-&zTTKb9GS(^yz}wE1Xe;*!T^DdyC3S zmOn7In)l{DeGiyy?E}wA4CeEk5(i`{AY}$ehd_tQSo`a-abZVx^frr=-;Ka>)m~1X ziPzYFe80iAjTPSDqQxU?rZMNszk$q^?cC+i5REpLjw@%K8J+7eQ_VD9DbE-Ql!J+% z;~6qc+Vf~+ck2ij&5o)-A0`LK;)(TnduYj9Np*<|GVJ`i^QcRMwcZYE8e(;)GtC(# z)ZWNXR_#{3EwJOb$E!GuaR`dDs|N5ir#SLC6n1w?EmB4=_gx$^KJONv*MU*B#IH?{ zQ;#k6z_Rizxv)Vp?l&>ika30zbcZg%h)pEd*N`GZDZkLh$QX%hoPnlPpO-q)X>(t1 zoW7Zf$7S^A6N-Ha@zUisHm zQ8OuY_sQ<0@f>iLwf>Fw>>TWUlu(Eu1(}LVeb&k{3c++-)3?RSD|NVxX%YJ^$k*7~%;_4yHB z+YNWQ_eIgs@gV|?W4<4rH*dDun8B#p(?Wc@q zR(RaK&(t10#y2GG?0N)1{a1sgvaY;eiCPf zc~y*6UWeUQs^!|*_isai666eI_x)QL!lTB-kvl?W@X@1Uj}+ftQ~NErZ8sxDv!yy3 zuz-Y(BW_}OZG~+ak2Ze4l=(U={;q(!1T~5m76_)%Zw9b!2(#nIxYFNr5`>~TS-z7k zc#eP~QxhQb;gB1R(A9c`T~OOE2JNO0=x0sfG7<0ZQ|j&F(RK1s9~+$!awto+fmK=mX9@dw_OhDu)cOg zrnMH2jIYVWA@BOeI&lxNkgjh+)GexNX&KYwJ4dt~BeKzdv^^C0?|$px=w;CbIRe|X zL~=%4qBqEBTpk8h(Ds^@qC#717Cxt81iy5cx_ z1Ud0ki(n~UDRnjFM*%zmNu2Q&oo#5#PvFRB*^dXB8nj__@k0;mMsZ4O_TGj5V!;h+ zML}RJeR3$8)ZaOrG3Q5DyP@*WvH#K9l?OGIbo;Q02$(?>M1-rNphiTHMFes|1Vj+V zWsHClWfc$*K?oQU7?nkq%$Na3U_e-#Nc0x#lTP ztG8Kd1KcMvBksw%n!O7d1`gE&0riz$Euk1Et4(m6IR)Ommp)ks2aqhq3WDUB9V08F zAnhp)(&nDfFNF*judHnvgt_rX6U$?6m;wRB^AL27Fe$_{qi-~uqx-RX$kmW_l$5a6 zp69`P+O>}Ac-%nA)qgzNp8)HSREV)i+9*Sb)PjD9l>X>4ec#$ne(9FQrANm;*dDgC zX_~Y;`cs<4M)e#HRtXTk06#Eo#*4#Vi_HCm+`g=sN)NuUi?j`K8Qlm_#{AUm*t%_b z{Z_)Y!~{197mm3h>8z3@W7l~aC7s2~PLbSyF3Pq+Uw(4#?Bj2!M5p2?Ysh1Vtm0N%Y9V^U~Fo_1z?WymJ{L=QaIi z+k>G)ch3x2ZS>ojzFScT^F7Q1?1xoiOTl+mNTHrxkLgR(2F2!lZNpN}X5)3031#Ur zQ+vQMN|xkOJ0BECvBR}UCwPf3JrBBK) zG6biTG0HSVpWW_!S=%l~ftECx8={+T{Ig9{1<>4I2BO)O>=wPac9#OgDRli!QO9eS z%!^i_;=@=euS9_1GTPAyCVb`wNk!};pf!sWgvHscw?$=0oXsVP4B|ee;~o;c zT>9wF5k9Qr><-jkvxkAkR7o!t&{vXFKS8Q=djWb8By=>wr-(lSS>%#85Z*Ff`+S}a zOkQ!U%KxO!>(t=LqTCfLVk_!L0li0Ry=T|VcqtH8|I(|qc;r-FPH6fvBPHpku0fz- zU{H+Sqv*Lqwk&7mnms_NT9gBRW)-^K2wDa4<~Qv>IIJ!3Z}y(bcGMdWn%k^Wan*Xy z*_DsVf$D7#;Mzh)`7`0kIjiqNl(1t<_#3nOe_Xcgwc7TJu^yr0YZBU22B8WxM*;OO z^!~$QkwCwU!_Xn_7ZxI_wW?08xy&l0+O^NcMD7yrhnkpOZl{zYx;}bmea0&=0!~V< zGA@t@?}1nv)&@ztNWyr<>TXRw(ZBU+U4vc7)BPGVz;hXQ%mb;sF=4@1|L6T695ph@t{sqQO#qWO(E<_&C%{h2 z$8eKqF$l;mKKq6$vguEj&`*iPDC9Uc2VsF+}$>LTmLG$FwWh{b8#BB9g{`TpEHgqDcc#Y91Y>)5979b4p3D zdBw_*D=8NWGY@V`xTJMxESeVjKT}S=qvrnp{Bx)u?=>(H2(T=E2$PeXPCkD`{h%bD zw1;^3F+N?o>-P{{?a)mgd(BIB7*lG7TlB}LNUm|}w$QyO9Ef=cW(!i``9QcPMzS=* zmU%2fKek#0NBkaqc)6d^G^mAZ6t-`Cu&j;rVQ({IGe@-kG}=T zIV#=)^nDf{*Tn0Rc_6`Z-njxV)jcjWkfu*AW&#MB*a{HI92NljHulUn6c@mG$W1m_ z<4>CG$22BQ)iW5owy{3@r=QiRYtClgb((Pgyn{a^re4p_*hH1K96ka+m&l4GW%TqOlH@Wg>CWW z=^3w9qc`Cm0O#f_64YyLJ%|?nCI&9=B1=gTgU58H*5R#$K;h9|*SN%Zt)^3r9Wj=#X5_!D!k$Z? zOF+Nd|Cb`7QKXS5^y4>BS_#j_oVn}M+Q0e%)(@)XE; zPbcvCPk|wPCci6?4gu2OAb+r=^D;~E>wu`h$EA;eikSqn>0$)xtJ4VID-u(X3u6QB z;+^PB{3?*q^x7U$v);Ol2H0!1kpJ|L7_6%2lihQXe|vrFu;HrRi4NP!_jirOQ(k^y{-Y zK$xiJJW&xRlcUhpm5yuGRRo&u5%GAR&#y!~krt^t&h0Hugza>vgYS$VYCE;W5a7bo z`7y@b3?Czw?rdkQTI1dDKwm4FA?D;BXz3j)e$kIvZd?ky{~Hh)GN%F$fuZNFN2cqC zM_VC@7A~p)!I0a}mt@q24^kGB>mJMB9&X1dm;Jdq*LUt#?6R6IM0h!!nYVmwvs`6Y z2~ic)8vTBqcp5@hB>}`(ZS5N#elIx`Ibf)}@rvu*P=frgQPz5?1v>gGm|lhZsu$fBX?>8>vfP7T&Z@CXtfBegMV zi%kwam9rD1?|WS-bC! zbjf$_{xwq0X=5-uIID;fwB3z!n6p5O2}dw!rsK1hk`%0!BsWIIzjAKX^32?7G(c(a ze{vHA9lQfQaq7dhnimLg_>?%a@;7gvi`Gl~B0Srq4@DS<-UTi8fN@$)_)D|1Kz0?{ zgzhO|`&(Oy){)-N1-p_Q`iZhRXQ~!n^DQ03pi#a>&M|QmoJGWdl5rT#wohjmbz~n3 zYiGC9M|1OK|M&2Z130u-SW{rtWE7 z)$JYob*NtEw ze5R)1h{Qx$DJ*oXy7iu^@)Ny%dVuH~DiI!5vDe!e!*`pD5bHCn&D@b)rR^d^FOjLV z1+FruJxmhvUp^dQ9G;#)qtWwnlswwdE#bPc~-@(s20h6zh8dC zw)W0b0M#H9Q+~{>L6Y2P(-h#fTIhVvG$E$BCIvl#tw9wCP6W)soD!h_f{ymKFMn~8 zG#`ooqCd*8Fe7IUTS^|ooV)DmEFiR|#ESym0*;|O?%DHqMCZE)OsDN5&R4Z<${&u+ z(q6hyN>Y4loHqcD&&g1fN8yd_sDH;py9sk{GG}t)yVUJ~0x2N>RexQv zv*7>6{uL&eg@B_P*`+8hoaS~(QsXGnRMVrjI!VM|h3fl{iIcQ;4{`OnO# de>f%27bal&|Bg}py^Z_%#?MOtP~qGAe*t;3`cD7= diff --git a/images/queen_s.png b/images/queen_s.png deleted file mode 100644 index cc693102aec1e78cf865bea5249941886d48cb89..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14407 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 diff --git a/images/grid_mdp.jpg b/images/grid_mdp.jpg deleted file mode 100644 index fa77fa2768ec47d9f1ffa609650e862c38b24a88..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13536 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≪%ac>58Zc1p=1NXs&le0v|8# z3u@^bL)Aw}zaL*qR4c@cxT@iTONBQgULBEb(pgu0K!WLlKp@UJR-?F!03Cn|HD^pp zKKh$=-Wk$(vit;X5IB86T|Mhi@GZX!^|EuEqL(inao&7$Shy~ifySYiv4Ml(+*&37#ElO#AM9v9 z7DIjCCd}=k475)>M*TbVDO>08n%ni7l=v1v*x1mr*!}rMj~_iUtr=QyVhMcoOTFwF zcTI6WZ!$l0Lygb^;gm4!w7;@-V*!$C~& zvh+fL!RH9Z{%L8xvelZ52rLiTIy&x=yUVA2*M|18YNcUNl67xukM?a`p2sfVQ^Ci| zg?7fe9bXD%k4wMoD|5?}$_iDFsCxNwvRNtX`$J0+jTu3_&&5Z=y!I0KAq&=|!^59C z%aLSxNSYhL7<-Z`Zbr7O?DI9t+N~Z_!B>0;@sXORJ_Y|+Fg0$!G#fuS`-tD~ z@TQLk(6ddJ7dmq0%E<~$9JI9?G)45ixk4JOqD1T)JPAC_Ue!e&X_>Hu`cr@l_b^-c zM+mm}DkTPam@>f#&Nef}?D8D9D)qd878QC0gPVZ(5reQ4kr-VbR*| zYgl#6@_Igf3gc1C+hK%!gp?a|A5O7H`v8*OTH}7PF*GB zp+AoolEOw}$15ZB02aO_gGzsrtAU-p6gGjZmzY_Y>Si-K13&)hCRpq-AF)h4YzVm$ z2Xd{q68nWkJaE}8&GE`vGJdO};@ppQ?_pH;$l!gC0P z&!jj4ISIZz+Ypq8+LHiDWuc9ye@;ne17%_^$AW-XTx*GdosSxYA5c-bFSw0!<8E^^ zCoeTWH3bTy7Z_bqf$5Tx44;}) zN+4H40CvG@A%R+=Vx*`4)Zo|*S-Fryyu9ij(8iVwp6K3cMlE(097J)gnXZCR{G!}b zyWh6=*BONl>2n?fg?|Qi0;f9}aqHUi@KWC&A&NL3%jQQXCTu`0*UewzOC2=(dMdC_ zhDS6sG{lL|rm+8j>+fEob=qLGnXhJPQ75C724hYt9aeza2lx%fRRsfEVEU?BCeazY z)VHWH+RL1VO}^R5Aw%Deu=&JP33=oC=C{g9;zQ8XrhlCSjr5kPH4a>yt{@ryRLicL zL-Lo$twQjNuwrP(QUfo#;d|^5{GT;}Y8)% zUUu9zg9upBXfSI*XR|LW0WPv6&VqT*w&8gDr;FKEcVN7p^l$h5+p`^PwZf;ZD9tDk z%Oug9D`D3XIyyQm)oVQ%+Yr^=+%3@O&z$&h1UcKXXYgnr#S9#^2+^q$vkYlDQc<#+ zSTZnOAi0XIy)hgq%EAD!w$kAv`dAOgL(g%f>g{HIMn;+*3>Al?DznYfk9$;j4J?vs z7*PzPbDZ9IR{?he{BUt$;Y=PTe6zS{yCvt~!Gi)#C`RrcQ_MMNhO^Y6@U^K% zp`l2I-_$3)G~i=1P(EYV$zuYOJ33zdej^Jy^V8i%2XD^fBTIh!D40Q1KQMG_6cUIG zKDj=H}!zlQ@{+<=IV7mH{P~4o8xX{kZ26kK>Ms9MMM4 z42BRH5~4mJXQQ zT99rtM?4X90c98%L|k(@KUyt<_jiq(s?YE_DyeplgMX2XUgW3E%)_UkqRTZbx=BMG9KG2p_Df*79jH=&*t?_Z4*OjDpHz&HF zIFEwTPZHp!<5odOJ3-z%3UwYl9bHZ*psORwdP{G1CRrqAmz~TKc7=qpIa3YsH^_BH zB&Qc=5D4t}NW3}FtFfk=5;2*+K*!BkIy0U%yta;~Mj_>he{M_R!P zUXz?ryK?0UrSEc(wX}7j1Y4SgF$1kWc6p~QUYUa8AE@ROTh*HuuHGa*o8)9`yTj#} z8j{SJtNx9@tR%UA(7al9==Bde8r2FF{^@qs^3|jHMZ+ow5++mI zo6tLc@YHWWA6Lj)4m@z(0NIu?&IF|SRAHTBwc)FtO?TqB92zFu>QoNsO?4^vs+o(D zsXsni?wzQsqz#>?!ZQQt{auBBXr`3|y8#pyy~$0`xqo!@HmfcE+>-+u=DBPkK?lW8_1&*t*m&`FqGc!)VpO^QJ6d6P> z8!xs4jYjWyZmH;dlarI6Z_uc^;Y8qG(Ao)(NHFkm!5kWrx(YJ*RCmFB zooTLDD`=>aQTsXQp6^T_tx+cF7De#JAmhcO$AZcLIshEmrpg~$*vQKrPfJVvs2jDP za^Fce*bEiB-r>-+p!S#(n;yD-Iqbp0MQEzW_L~9AfNB2<&jH=@<#MS+;{3Joe$d{LlGfdA|PJx)mAu&Dcink7G?U(T4tNx4icDLxjP58@ON>cDM-T+76&@yt)nq7#kZ`!8IV< zp)b@NJJt&>Ni{&pRT!=;Jt; z@5Bz2RKLI(`k*Paq_M~kr@?`5oExz(xRA;_=(r;Vm@j^3KLlW~qTmhuw5_uM1Ux>C z$C;Bq_2hSs&xbMwW@&(HqwzQ?sZnNeQ+jp4WXAd2(3x7$aU=PdrwVklc_v8=Qs#=PcOcd?=}=9;jN#a`#O!^rte*quy%U87Gby0YFL3Cl`>;!LANK>~ znzvL>C}llb+x@)(GlQu?>EyR~UfvmyeWr@k#syr<#Kf);pjrYXtyy=w1J8p=g6#4h zs;?l&335_3H!d%-EKWN{@RZI`KKq`=2?}iw()&tik+dxFz*wK*v$F&6_*BqCaX-G?yv-PBA7M2^;Ch; zqen4kb(fYD|NJBtm1 z%}oIw9vs2GA!vH@YAkB=8&R)C)$!45?J2lyofB)9H8Bq(L&D75Y7 zM(vQeXTr*d3+tquG|V05tZ2_D<`kIT}^$*P90r6eS`gmM~)sdH9Ky8;>=l_ zbGGL%Ty(nXe9gtx?Yg(mZC^kCfIDIL?uSP_co-R<@HjCk`PY=x%;#AzUS_|_$$e8) zTvA$AUQzk3zM-+Hxux}eSNG?hUP@p80Bv+^{Oh-g$*F0^;?nYW<_c?d?T1`E0N+2v z`d7*RNiGRQE?z_j{6atE;^Fl}fKP&7VC!B%$wO8`jyI*YX@>}JJRJ9|uuepIpEX_j z%B@aO85JFxD&vP}zf1P_1PlEiN%pUT{hM3^z&bu2M0tD?00!W4G9%T2pW!_tIaUXZ zNaY`RS)F^{b%D3{zlNB|7uy=qXGSUE#=EC10%_m|H$|ml)4r}gdzIcE>!rClGIc}%9wGlZ-z+1>|TVF2)-Xw-JSgNf$o=FDt}SNt@1I?_C3 zOKDi@oaU^ zI(p872SV?CFix2j2(kt1Zev_<4-^HtWe^Y4JuE;^${V{2M%+4 zJk&(NG$0>0kk*VXMsZ~JK_X!cm-=pwd{2!W>v?@;%xHK@E3EptKCUr-vU12-_$r- zzum)oRnMF>jWxe;=47eVo2pS&N$urpwXNtF@E~;yjX|25V@q?^aZ~XqwvIpPUAi&d zX6T80O|{<()sjqE&vX&=CpJyRjlWB7Z)h0lA{1i0iFIqGj=H{hy_$8k=Siz>ok>lv zg2DU`Ir4eO!C@t0Q^@fl#2i)BGb4e&13S~nqheZOZu_v)`ll~k7~BzXE#=)do-YXw z?(Aa_WmuZ~)aRSsObGb8^4k`}p^(ICG4OWa#~^%A2e!l|lI;5QLYhsb-oO>T%iS4Q zl%jpxSJJ*ffQ@?T$wWd1`8t}lBW*|_W)qF+bjm5&HZH)6T6qQro}p{~Nb20DWE^1= zN4n=={)tgg(lud!Kz_lC?dRJzCz&0b=wmFCL^6xNo+~8o!(6Hn4eD@^Wv$X^AdP!y zyK`-NKV&{P*!g&gwX8d6JBACz-_GM0FgD7UMu0b8PRmT}(9sNAR(__~9LY{#I>10^ z!c>p}TQ6!1)HvP~+c#Q+Wiczgi29r*jDr#TtU+Ii#(bdtF>SGXmG`ec>^=U)`NF9q zC@0HTyZ+0AEYKJ$o0A){?2o9Uv%*HvQ94?Jlgaw-j?&D0pVAKV1Im>Ra^+vn=_}pY zu}o5dfrwhDjkxSkBMXi&(TogKmO3d7255B5n+fhFQaGAr6v08<{h!c$UGlG!i;_c1 zhD`0=QrEfJ`kg6V-JYtsu=TsjlhoBHNYssf_Z?#XHL|Xo3>71?r@Y&9WXI!&jb2dN z)PxwMBmcZ5X&v`1*-I-721?X|eF8OTlm>#Zf46n_LQK!c(zsX6-YOCv8r7lcg2&}n zvbVIxcdTBIRL}o_vgh8f(#ZCwFw^PtPjmb0KqrIpC8ZQU<WHr=n`#oy_~+l*O&C+W=*I-PqeKbOcg$n>&l{@vc`g7%4K71GQI zjb=(nsi`9pL z`Vr8%eN79y4nx0-Vs*j*DukPinXJa|fq}YN%-CuBl;!)Gw&Pa6E>%O!{d02UmLlK?W6o>Cc&vdB2O9kRo+1w z2Hrf(hJh)vH7P@f%u>ppeQ2EKHAlBJ*~QS<%MM&o34sBNnF%BqAMk^$UeK^?^;8f_ z`@WNF)JYykxx>IE#9a<;l z1zxId&xEm#k}dTL!3RaTXwqZMNIrV;colNAjtCE#sZad2TlBHyf9PL)iRs4TK}ZaM zW4jYah>EVhkTSirKvh2#zi2LR`L$v342AXGT z$s6^St;PzSmMO~BhRl$+%RBI;M-DRsSur=F{plqA4F*01_XBe_`;^L*Es#TO|L@W==M>xxG+XKKpS9_p&oYHBonos^oR!#(0C(Tvm%ZUGFqv`4q* zwCDQAk1jP{^ayxldF8^~90jUCReV=wyi9D=L}?>V@z8h|%Zb^{jiSC&l&-FZtt=@F_*vu8C4Ht{cY`)qC+*b{t#HZOH5)8a+?7&R! zdkK!50AtYfLLb!Hx+x+{k~oHajG?!u8z8sQ8G9J0MeJM@Ln9u%2?K{;zJ-Bc9JH~* z_Qu2_#+FRGGKpT6>&DPkF->q`BQgx`#jf_P)SmF)e*PJ_-ib zt&S1aq;;trK9K&Jypf~LK!waH6VG>+Y|)dmyJFO^UcTsdty;CN^v(UQj-AJ(pQX%F z>6Y9RRC8`#m9Ej}PP=ze-j(LEI}1F=Hz#0U{71G4l|m7uDx2J9rk3HOT1d>~7 zMlbJlC$j{Rd+t*BtL&qUYtNq{=l*=g&@7obxWo9u9KHdi_IcMc*fA ze$6-$j&t|@=7`&Q2Vh{~DB7cwXnLdtbN_bF>JB;v2|)y7CI8U(;tM*--tNFj zc15b&K-Xoq#M7E<1B{cQ<_1c>IlG&uJ|1y-b?DV|-Kx%0xr67MXu-x2TV^JZ{7H9V zPR@nC*Z{Q?M&4d%ESZ@}PM!ZHDKbyuetwgQCIPd*<elM zG<&#}*x-HAk7ioh{k1&m+#|7P8@@yyerSFE_^lgz`kORXN(-w_(iiF>or-Wzr^B7! z-SV5Z#V@|!Kd`lZXjfKjc6LsNTOS9HxCn-GiUAi*QLr$&ooLU)PMwP8h#S!t#x zzN{sC%8!|`-zD&8lgunHay3}3jO|*nAl+hNlYePb6Z1VvhGT%JXLkNx-a|YO%2$W#^JtR zw5xNM@$(4Z6GglvT4r6eBLib~eykRJYWVt07Hb3Cl;Am|2y$H9|UU!YD z%^UXUjue-F z%bZ?mS}|OS{eDmR2z~KFX6ubRa?V>@W2NW&CNf${Y2e5cY*}(WX%NLkQj&X8&4w?U z>r-?S!;J))$GhC`=EY~2<1}P=#EkJpo#jIO!8ge+WY%_E1A(Q!@{SrsEs2;D19Q@Z z@tS$l5V|;RuX(QJ`X}vT+hCyW!0{B*4r8YA%PKM?l7d)75SngH>N`1#eQ;3I-)AAx zSeU^ZgZ_~0S(7bNYNl5JhD6;W^u?oucCMy4eA2@NU|f*YLCqqfmJpfh5}CoU8O~a} zk>G*4TKGC`>?*sieWj?oBv1_-OQatqu`~;cXzg-lY<;Lp(ta|1U#A+>+W9@^yzGml zqXz^M`@Q0$9XE3!o(Tc+mBg}jv4_SbhLgq@2M-~705lfUXbvISoKuLwJb?jMwD3%+ z-db$<@Vai@dj8-gZ=7@1F*y~*vzi~C_!%sddQv&RanoSnE0U}cV1Q}i2`&>&GF-XG zI+yJ*C^yEy`HO@70}XrP4#^(HW^A^}RnIV^wa>1yO{b{zV*Gx?;E_@X8GMpwb~O z&o#+mXUDvk<8Pni&dq=EjPotGHVtxUuEwKbKrqF%ELCmRma$h$bGPRfNa>RH>rNf# zh`wDFKy2b#n!BSwVn$iGY-WgQr@YcxzHYwAYiU^*T|0_>eM^~zMPAO~dxDA9z)Wq1 zZC7KedS-~gMk|v)0iBGY`z~;vpL|DVS|PEHt3PeCcK12hqDXSuIB?Al$yddx zU!tnDPQDcoFF*Sguv~Sy_LP@UO~@g2V+R!=VK&{HIm*qf+QiUk8n9_>DxqmBmxu4z ziz_fmaeY?qFdchKxK1f?KflxT`hCBYcIx!)njH!6?dsJHmvuCWYlz&Fn`?md0(nD8 z&d$Ew&H-uMHNtWO?kUs%<{Mq!ycNS>V)N0~C4 zTY!P>nvCaAg9VbrSu9b$kvVc)WUh_j4mJG>F2@`4;CHRySej&xgt8f8SK6aXyU7ar2m{6UlJBTR zFPkI9h)c-ts? z-KRJ93f9{Q_Ax^9W0iah9+$K9FRjm3mgO;yUVCbHqh(z2(3UB;B<7TxSDfivrdc#v$08?|(UO(z!-Nl%|A8`ByzozNNR2_%-g6ssOenR2#JU_X=KQCSALCuFBgP z)QnBMPLXQ%Dz%;LN_6<6gm-WEKr+`tu=MteEGw{H#J_yiRSM%)HNl5on#1P$oIXHI zLep0)HxKW_J4aLF}=bplVsq!e5 zBZ}Dh_;n0z5iIrN$`YbL`cA}U;_?s^(qyd=!3JmF_DT+7Vhid9FX+mXO6B2PBpk?JJGmdJ@Q`-x6acBjcD z&TmL9-3s+nm#-LWB2`abJ7ijL7ZS0dfw7<*I8ur@Jj#y diff --git a/images/hillclimb-tsp.png b/images/hillclimb-tsp.png deleted file mode 100644 index 8446bbafc45203f5a29feb1218a793c9583e8866..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32028 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

78PC4N0xYj@ZRDuI@`lx z)33`M)LyAwWtB^dd!v9YdjL7NJl@zPj#NmJIl?M}BvnIm(!?I3#^>+A2bj(72xe~+c`ID_4MnGV~@OP3@Btg7h-RF zbOVl`w+5>jovm_=EgGIVKBuSO>3k|DW%Aloc!&ht{PCjKeTX8sESyn2oUal>UT5T+}_*+&mSx~Sy7b%-?d45 z06@PzKlSB-H+v3AC3F<~Q1@ky*un zJ7WL=W7mRkPVFQhNbF7a@T3b4zaDTs*puPvaOOIh)>dL2UU!F!B z(@2q)V7ss8RFmu17|N7tNoV2z0K<6JbfEHaCFpflZ4G=moD`I@PYryTony?-!mf6> zP~(CTL9kKD^}}jCMO#Bxl-3w2WBRgLrHTgK-AN?Gm%5&dV_|N7IE|>=B!S?5>Adf7 z2=q8_S-xKH+Gk-z?9Mn03Fg2LOjgESC{_ll z7l(Di?PFo{wiYyrx=9Sl5;B3{UA*}oMj>HUlv1+%-sSeaT${X}m;V6Oi*+`-)GJ14 z^BhY{a@Fr4fE{w4i03EA)-1M;q*rkG@Yqb4Hc-qP3 zO<8#sy3K!_$(YwyHd&JUbor3X=^YkOGTNaU#onL|XJU$^_nU^`2pnQ3_*+p$1IE!& z&LPPkB%^w;&auNQv&}IId71YSbH^itY()Ds;%)0vHi2dV2tJ^LZ=YNRpr;X7SzM8J zWjy@<09WCK*eSm3M!G_Awd8dUX-fhmF|@=gh2kPWx7};>^Yz21>gr?%_`AYEuvQ}F zeMlWXN1Svc5HyPdE2%ds66giG*m9@w!cjSnp;`^h=Z%Ei^uGtpar4Ka9MMTPvFFWG zo!XACnC4fTz5xyHw+D9?^EbkD^G_sYpe2->T$>VbjMAx$q)fz400i;=x83RS!=#ZS z1}OJQwMR~!2c9%d$?jm{qaC$62BW$J4csJwE>cJQ9=IAxQu%is22lgne`6A^J^`DehwosHZ4 zn`IUj0c95d0P$Y~ADQFy#Z|xcKf6Ckz%=l*?fon4dGB9UMm64`h?nn1Wit16xi@wq z-wShyVOI%^xOU-!Z35)6ByIWdaWk&zV;cVeJDxXXs2P<>-_-b=fs}9(K1P++m1P351N%*_Goq zkr;ct1Ig*;G0l63=;n5Pn^Ugc-1=JtDa>M_;hDsfi48^!WUPiPxE5{6NVSknrmYO+UQzVX7WdWA_ank?_Qq-i= zssh2bZ(YOQUtBrq&G^G=XjUn=_l)upw6PzWIsu0l=aY}R_HSG#%=k}fU;MRhLQ>5W zCA-0K>x62J=!k{EHupN=e&Q2<2;6Xti5k)dRr^9f^uIXvrk$DNQ)=qNDND395iLB8 z-a^567AD*S@xB{muvF4gcW)b{p*#%Vnxt|q=kOSBCViJj4N3~-@6&KVQ)vxi2T{*9 zI4^9iH1NnL_J0k`jbJZtFNyyEhZytST6vRB=d7sJP|DSld~Qs4jL|GcDH1p4Mjrc< z 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 N002ovPDHLkV1f`i!_@!) diff --git a/images/bayesnet.png b/images/bayesnet.png deleted file mode 100644 index 6260ab7e1efd41da85545ebd47c98ba6f5426093..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 81000 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%0D6JcP`nYxQTicw158l<5GzI z6yq8;W12M;nDGA(IK65N`_PMk&?znsLNL~Sc^e-KNwPs1jDu7SIgX(ex8PHV@~gOF gWuKB7_pQCs%CU@{S>b6`A^?B#vMT?9rA@;A2g>(L0RR91 diff --git a/images/broxrevised.png b/images/broxrevised.png deleted file mode 100644 index 87051a383c1edbb776a4c31828fcc8aa23e5251c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 234593 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