diff --git a/README.md b/README.md index 5791f59e7..ca68ad5ee 100644 --- a/README.md +++ b/README.md @@ -46,11 +46,11 @@ Here is a table of algorithms, the figure, name of the algorithm in the book and | 3.14 | Uniform-Cost-Search | `uniform_cost_search` | [`search.py`][search] | Done | | 3.17 | Depth-Limited-Search | `depth_limited_search` | [`search.py`][search] | Done | | 3.18 | Iterative-Deepening-Search | `iterative_deepening_search` | [`search.py`][search] | Done | -| 3.22 | Best-First-Search | `best_first_graph_search` | [`search.py`][search] | | +| 3.22 | Best-First-Search | `best_first_graph_search` | [`search.py`][search] | Done | | 3.24 | A\*-Search | `astar_search` | [`search.py`][search] | Done | | 3.26 | Recursive-Best-First-Search | `recursive_best_first_search` | [`search.py`][search] | Done | -| 4.2 | Hill-Climbing | `hill_climbing` | [`search.py`][search] | | -| 4.5 | Simulated-Annealing | `simulated_annealing` | [`search.py`][search] | | +| 4.2 | Hill-Climbing | `hill_climbing` | [`search.py`][search] | Done | +| 4.5 | Simulated-Annealing | `simulated_annealing` | [`search.py`][search] | Done | | 4.8 | Genetic-Algorithm | `genetic_algorithm` | [`search.py`][search] | Done | | 4.11 | And-Or-Graph-Search | `and_or_graph_search` | [`search.py`][search] | Done | | 4.21 | Online-DFS-Agent | `online_dfs_agent` | [`search.py`][search] | | @@ -60,7 +60,7 @@ Here is a table of algorithms, the figure, name of the algorithm in the book and | 6 | CSP | `CSP` | [`csp.py`][csp] | Done | | 6.3 | AC-3 | `AC3` | [`csp.py`][csp] | Done | | 6.5 | Backtracking-Search | `backtracking_search` | [`csp.py`][csp] | Done | -| 6.8 | Min-Conflicts | `min_conflicts` | [`csp.py`][csp] | | +| 6.8 | Min-Conflicts | `min_conflicts` | [`csp.py`][csp] | Done | | 6.11 | Tree-CSP-Solver | `tree_csp_solver` | [`csp.py`][csp] | Done | | 7 | KB | `KB` | [`logic.py`][logic] | Done | | 7.1 | KB-Agent | `KB_Agent` | [`logic.py`][logic] | Done | @@ -71,7 +71,7 @@ Here is a table of algorithms, the figure, name of the algorithm in the book and | 7.15 | PL-FC-Entails? | `pl_fc_resolution` | [`logic.py`][logic] | Done | | 7.17 | DPLL-Satisfiable? | `dpll_satisfiable` | [`logic.py`][logic] | Done | | 7.18 | WalkSAT | `WalkSAT` | [`logic.py`][logic] | Done | -| 7.20 | Hybrid-Wumpus-Agent | `HybridWumpusAgent` | [`logic.py`][logic]\* | | +| 7.20 | Hybrid-Wumpus-Agent | `HybridWumpusAgent` | | | | 7.22 | SATPlan | `SAT_plan` | [`logic.py`][logic] | Done | | 9 | Subst | `subst` | [`logic.py`][logic] | Done | | 9.1 | Unify | `unify` | [`logic.py`][logic] | Done | @@ -102,7 +102,7 @@ Here is a table of algorithms, the figure, name of the algorithm in the book and | 16.9 | Information-Gathering-Agent | | | | 17.4 | Value-Iteration | `value_iteration` | [`mdp.py`][mdp] | Done | | 17.7 | Policy-Iteration | `policy_iteration` | [`mdp.py`][mdp] | Done | -| 17.7 | POMDP-Value-Iteration | | | | +| 17.9 | POMDP-Value-Iteration | | | | | 18.5 | Decision-Tree-Learning | `DecisionTreeLearner` | [`learning.py`][learning] | Done | | 18.8 | Cross-Validation | `cross_validation` | [`learning.py`][learning] | | | 18.11 | Decision-List-Learning | `DecisionListLearner` | [`learning.py`][learning]\* | | @@ -110,13 +110,13 @@ Here is a table of algorithms, the figure, name of the algorithm in the book and | 18.34 | AdaBoost | `AdaBoost` | [`learning.py`][learning] | | | 19.2 | Current-Best-Learning | `current_best_learning` | [`knowledge.py`](knowledge.py) | Done | | 19.3 | Version-Space-Learning | `version_space_learning` | [`knowledge.py`](knowledge.py) | Done | -| 19.8 | Minimal-Consistent-Det | | | +| 19.8 | Minimal-Consistent-Det | `minimal_consistent_det` | [`knowledge.py`](knowledge.py) | Done | | 19.12 | FOIL | | | | 21.2 | Passive-ADP-Agent | `PassiveADPAgent` | [`rl.py`][rl] | Done | | 21.4 | Passive-TD-Agent | `PassiveTDAgent` | [`rl.py`][rl] | Done | | 21.8 | Q-Learning-Agent | `QLearningAgent` | [`rl.py`][rl] | Done | | 22.1 | HITS | `HITS` | [`nlp.py`][nlp] | Done | -| 23 | Chart-Parse | `Chart` | [`nlp.py`][nlp] | | +| 23 | Chart-Parse | `Chart` | [`nlp.py`][nlp] | Done | | 23.5 | CYK-Parse | `CYK_parse` | [`nlp.py`][nlp] | Done | | 25.9 | Monte-Carlo-Localization| `monte_carlo_localization` | [`probability.py`][probability] | Done | diff --git a/knowledge.py b/knowledge.py index a5d165e3e..6330923bd 100644 --- a/knowledge.py +++ b/knowledge.py @@ -207,6 +207,7 @@ def build_h_combinations(hypotheses): def minimal_consistent_det(E, A): + """Returns a minimal set of attributes which give consistent determination""" n = len(A) for i in range(n + 1): @@ -216,6 +217,7 @@ def minimal_consistent_det(E, A): def consistent_det(A, E): + """Checks if the attributes(A) is consistent with the examples(E)""" H = {} for e in E: diff --git a/search.py b/search.py index 31d3f0940..68b77a5a8 100644 --- a/search.py +++ b/search.py @@ -509,6 +509,47 @@ def and_search(states, problem, path): return or_search(problem.initial, problem, []) +class PeakFindingProblem(Problem): + """Problem of finding the highest peak in a limited grid""" + + def __init__(self, initial, grid): + """The grid is a 2 dimensional array/list whose state is specified by tuple of indices""" + Problem.__init__(self, initial) + self.grid = grid + self.n = len(grid) + assert self.n > 0 + self.m = len(grid[0]) + assert self.m > 0 + + def actions(self, state): + """Allows movement in only 4 directions""" + # TODO: Add flag to allow diagonal motion + allowed_actions = [] + if state[0] > 0: + allowed_actions.append('N') + if state[0] < self.n - 1: + allowed_actions.append('S') + if state[1] > 0: + allowed_actions.append('W') + if state[1] < self.m - 1: + allowed_actions.append('E') + return allowed_actions + + def result(self, state, action): + """Moves in the direction specified by action""" + x, y = state + x = x + (1 if action == 'S' else (-1 if action == 'N' else 0)) + y = y + (1 if action == 'E' else (-1 if action == 'W' else 0)) + return (x, y) + + def value(self, state): + """Value of a state is the value it is the index to""" + x, y = state + assert 0 <= x < self.n + assert 0 <= y < self.m + return self.grid[x][y] + + class OnlineDFSAgent: """[Figure 4.21] The abstract class for an OnlineDFSAgent. Override diff --git a/tests/test_csp.py b/tests/test_csp.py index 78afac673..5a10f5ce5 100644 --- a/tests/test_csp.py +++ b/tests/test_csp.py @@ -330,6 +330,15 @@ def test_backtracking_search(): order_domain_values=lcv, inference=mac) +def test_min_conflicts(): + random.seed("aima-python") + assert min_conflicts(australia) + assert min_conflicts(usa) + assert min_conflicts(france) + australia_impossible = MapColoringCSP(list('RG'), 'SA: WA NT Q NSW V; NT: WA Q; NSW: Q V; T: ') + assert min_conflicts(australia_impossible, 1000) is None + + def test_universal_dict(): d = UniversalDict(42) assert d['life'] == 42 diff --git a/tests/test_search.py b/tests/test_search.py index af892f6f1..f22ca6f89 100644 --- a/tests/test_search.py +++ b/tests/test_search.py @@ -6,7 +6,6 @@ vacumm_world = GraphProblemStochastic('State_1', ['State_7', 'State_8'], vacumm_world) LRTA_problem = OnlineSearchProblem('State_3', 'State_5', one_dim_state_space) - def test_find_min_edge(): assert romania_problem.find_min_edge() == 70 @@ -20,6 +19,22 @@ def test_breadth_first_search(): assert breadth_first_search(romania_problem).solution() == ['Sibiu', 'Fagaras', 'Bucharest'] +def test_best_first_graph_search(): + # uniform_cost_search and astar_search test it indirectly + assert best_first_graph_search( + romania_problem, + lambda node: node.state).solution() == ['Sibiu', 'Fagaras', 'Bucharest'] + assert best_first_graph_search( + romania_problem, + lambda node: node.state[::-1]).solution() == ['Timisoara', + 'Lugoj', + 'Mehadia', + 'Drobeta', + 'Craiova', + 'Pitesti', + 'Bucharest'] + + def test_uniform_cost_search(): assert uniform_cost_search( romania_problem).solution() == ['Sibiu', 'Rimnicu', 'Pitesti', 'Bucharest'] @@ -56,6 +71,33 @@ def test_recursive_best_first_search(): romania_problem).solution() == ['Sibiu', 'Rimnicu', 'Pitesti', 'Bucharest'] +def test_hill_climbing(): + prob = PeakFindingProblem((0, 0), [[0, 5, 10, 20], + [-3, 7, 11, 5]]) + assert hill_climbing(prob) == (0, 3) + prob = PeakFindingProblem((0, 0), [[0, 5, 10, 8], + [-3, 7, 9, 999], + [1, 2, 5, 11]]) + assert hill_climbing(prob) == (0, 2) + prob = PeakFindingProblem((2, 0), [[0, 5, 10, 8], + [-3, 7, 9, 999], + [1, 2, 5, 11]]) + assert hill_climbing(prob) == (1, 3) + + +def test_simulated_annealing(): + random.seed("aima-python") + prob = PeakFindingProblem((0, 0), [[0, 5, 10, 20], + [-3, 7, 11, 5]]) + sols = {prob.value(simulated_annealing(prob)) for i in range(100)} + assert max(sols) == 20 + prob = PeakFindingProblem((0, 0), [[0, 5, 10, 8], + [-3, 7, 9, 999], + [1, 2, 5, 11]]) + sols = {prob.value(simulated_annealing(prob)) for i in range(100)} + assert max(sols) == 999 + + def test_BoggleFinder(): board = list('SARTELNID') """
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: