Skip to content

Commit 09beeb4

Browse files
Chipe1norvig
authored andcommitted
Added tests (aimacode#620)
* Added tests for search.py * Updated readme * Removed extra newline * Fixed seed * Update README.md * Added docstring for minimal-consistent-det
1 parent 6e12df4 commit 09beeb4

File tree

5 files changed

+103
-9
lines changed

5 files changed

+103
-9
lines changed

README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,11 @@ Here is a table of algorithms, the figure, name of the algorithm in the book and
4646
| 3.14 | Uniform-Cost-Search | `uniform_cost_search` | [`search.py`][search] | Done |
4747
| 3.17 | Depth-Limited-Search | `depth_limited_search` | [`search.py`][search] | Done |
4848
| 3.18 | Iterative-Deepening-Search | `iterative_deepening_search` | [`search.py`][search] | Done |
49-
| 3.22 | Best-First-Search | `best_first_graph_search` | [`search.py`][search] | |
49+
| 3.22 | Best-First-Search | `best_first_graph_search` | [`search.py`][search] | Done |
5050
| 3.24 | A\*-Search | `astar_search` | [`search.py`][search] | Done |
5151
| 3.26 | Recursive-Best-First-Search | `recursive_best_first_search` | [`search.py`][search] | Done |
52-
| 4.2 | Hill-Climbing | `hill_climbing` | [`search.py`][search] | |
53-
| 4.5 | Simulated-Annealing | `simulated_annealing` | [`search.py`][search] | |
52+
| 4.2 | Hill-Climbing | `hill_climbing` | [`search.py`][search] | Done |
53+
| 4.5 | Simulated-Annealing | `simulated_annealing` | [`search.py`][search] | Done |
5454
| 4.8 | Genetic-Algorithm | `genetic_algorithm` | [`search.py`][search] | Done |
5555
| 4.11 | And-Or-Graph-Search | `and_or_graph_search` | [`search.py`][search] | Done |
5656
| 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
6060
| 6 | CSP | `CSP` | [`csp.py`][csp] | Done |
6161
| 6.3 | AC-3 | `AC3` | [`csp.py`][csp] | Done |
6262
| 6.5 | Backtracking-Search | `backtracking_search` | [`csp.py`][csp] | Done |
63-
| 6.8 | Min-Conflicts | `min_conflicts` | [`csp.py`][csp] | |
63+
| 6.8 | Min-Conflicts | `min_conflicts` | [`csp.py`][csp] | Done |
6464
| 6.11 | Tree-CSP-Solver | `tree_csp_solver` | [`csp.py`][csp] | Done |
6565
| 7 | KB | `KB` | [`logic.py`][logic] | Done |
6666
| 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
7171
| 7.15 | PL-FC-Entails? | `pl_fc_resolution` | [`logic.py`][logic] | Done |
7272
| 7.17 | DPLL-Satisfiable? | `dpll_satisfiable` | [`logic.py`][logic] | Done |
7373
| 7.18 | WalkSAT | `WalkSAT` | [`logic.py`][logic] | Done |
74-
| 7.20 | Hybrid-Wumpus-Agent | `HybridWumpusAgent` | [`logic.py`][logic]\* | |
74+
| 7.20 | Hybrid-Wumpus-Agent | `HybridWumpusAgent` | | |
7575
| 7.22 | SATPlan | `SAT_plan` | [`logic.py`][logic] | Done |
7676
| 9 | Subst | `subst` | [`logic.py`][logic] | Done |
7777
| 9.1 | Unify | `unify` | [`logic.py`][logic] | Done |
@@ -102,21 +102,21 @@ Here is a table of algorithms, the figure, name of the algorithm in the book and
102102
| 16.9 | Information-Gathering-Agent | | |
103103
| 17.4 | Value-Iteration | `value_iteration` | [`mdp.py`][mdp] | Done |
104104
| 17.7 | Policy-Iteration | `policy_iteration` | [`mdp.py`][mdp] | Done |
105-
| 17.7 | POMDP-Value-Iteration | | | |
105+
| 17.9 | POMDP-Value-Iteration | | | |
106106
| 18.5 | Decision-Tree-Learning | `DecisionTreeLearner` | [`learning.py`][learning] | Done |
107107
| 18.8 | Cross-Validation | `cross_validation` | [`learning.py`][learning] | |
108108
| 18.11 | Decision-List-Learning | `DecisionListLearner` | [`learning.py`][learning]\* | |
109109
| 18.24 | Back-Prop-Learning | `BackPropagationLearner` | [`learning.py`][learning] | Done |
110110
| 18.34 | AdaBoost | `AdaBoost` | [`learning.py`][learning] | |
111111
| 19.2 | Current-Best-Learning | `current_best_learning` | [`knowledge.py`](knowledge.py) | Done |
112112
| 19.3 | Version-Space-Learning | `version_space_learning` | [`knowledge.py`](knowledge.py) | Done |
113-
| 19.8 | Minimal-Consistent-Det | | |
113+
| 19.8 | Minimal-Consistent-Det | `minimal_consistent_det` | [`knowledge.py`](knowledge.py) | Done |
114114
| 19.12 | FOIL | | |
115115
| 21.2 | Passive-ADP-Agent | `PassiveADPAgent` | [`rl.py`][rl] | Done |
116116
| 21.4 | Passive-TD-Agent | `PassiveTDAgent` | [`rl.py`][rl] | Done |
117117
| 21.8 | Q-Learning-Agent | `QLearningAgent` | [`rl.py`][rl] | Done |
118118
| 22.1 | HITS | `HITS` | [`nlp.py`][nlp] | Done |
119-
| 23 | Chart-Parse | `Chart` | [`nlp.py`][nlp] | |
119+
| 23 | Chart-Parse | `Chart` | [`nlp.py`][nlp] | Done |
120120
| 23.5 | CYK-Parse | `CYK_parse` | [`nlp.py`][nlp] | Done |
121121
| 25.9 | Monte-Carlo-Localization| `monte_carlo_localization` | [`probability.py`][probability] | Done |
122122

knowledge.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ def build_h_combinations(hypotheses):
207207

208208

209209
def minimal_consistent_det(E, A):
210+
"""Returns a minimal set of attributes which give consistent determination"""
210211
n = len(A)
211212

212213
for i in range(n + 1):
@@ -216,6 +217,7 @@ def minimal_consistent_det(E, A):
216217

217218

218219
def consistent_det(A, E):
220+
"""Checks if the attributes(A) is consistent with the examples(E)"""
219221
H = {}
220222

221223
for e in E:

search.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,47 @@ def and_search(states, problem, path):
509509
return or_search(problem.initial, problem, [])
510510

511511

512+
class PeakFindingProblem(Problem):
513+
"""Problem of finding the highest peak in a limited grid"""
514+
515+
def __init__(self, initial, grid):
516+
"""The grid is a 2 dimensional array/list whose state is specified by tuple of indices"""
517+
Problem.__init__(self, initial)
518+
self.grid = grid
519+
self.n = len(grid)
520+
assert self.n > 0
521+
self.m = len(grid[0])
522+
assert self.m > 0
523+
524+
def actions(self, state):
525+
"""Allows movement in only 4 directions"""
526+
# TODO: Add flag to allow diagonal motion
527+
allowed_actions = []
528+
if state[0] > 0:
529+
allowed_actions.append('N')
530+
if state[0] < self.n - 1:
531+
allowed_actions.append('S')
532+
if state[1] > 0:
533+
allowed_actions.append('W')
534+
if state[1] < self.m - 1:
535+
allowed_actions.append('E')
536+
return allowed_actions
537+
538+
def result(self, state, action):
539+
"""Moves in the direction specified by action"""
540+
x, y = state
541+
x = x + (1 if action == 'S' else (-1 if action == 'N' else 0))
542+
y = y + (1 if action == 'E' else (-1 if action == 'W' else 0))
543+
return (x, y)
544+
545+
def value(self, state):
546+
"""Value of a state is the value it is the index to"""
547+
x, y = state
548+
assert 0 <= x < self.n
549+
assert 0 <= y < self.m
550+
return self.grid[x][y]
551+
552+
512553
class OnlineDFSAgent:
513554

514555
"""[Figure 4.21] The abstract class for an OnlineDFSAgent. Override

tests/test_csp.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,15 @@ def test_backtracking_search():
330330
order_domain_values=lcv, inference=mac)
331331

332332

333+
def test_min_conflicts():
334+
random.seed("aima-python")
335+
assert min_conflicts(australia)
336+
assert min_conflicts(usa)
337+
assert min_conflicts(france)
338+
australia_impossible = MapColoringCSP(list('RG'), 'SA: WA NT Q NSW V; NT: WA Q; NSW: Q V; T: ')
339+
assert min_conflicts(australia_impossible, 1000) is None
340+
341+
333342
def test_universal_dict():
334343
d = UniversalDict(42)
335344
assert d['life'] == 42

tests/test_search.py

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
vacumm_world = GraphProblemStochastic('State_1', ['State_7', 'State_8'], vacumm_world)
77
LRTA_problem = OnlineSearchProblem('State_3', 'State_5', one_dim_state_space)
88

9-
109
def test_find_min_edge():
1110
assert romania_problem.find_min_edge() == 70
1211

@@ -20,6 +19,22 @@ def test_breadth_first_search():
2019
assert breadth_first_search(romania_problem).solution() == ['Sibiu', 'Fagaras', 'Bucharest']
2120

2221

22+
def test_best_first_graph_search():
23+
# uniform_cost_search and astar_search test it indirectly
24+
assert best_first_graph_search(
25+
romania_problem,
26+
lambda node: node.state).solution() == ['Sibiu', 'Fagaras', 'Bucharest']
27+
assert best_first_graph_search(
28+
romania_problem,
29+
lambda node: node.state[::-1]).solution() == ['Timisoara',
30+
'Lugoj',
31+
'Mehadia',
32+
'Drobeta',
33+
'Craiova',
34+
'Pitesti',
35+
'Bucharest']
36+
37+
2338
def test_uniform_cost_search():
2439
assert uniform_cost_search(
2540
romania_problem).solution() == ['Sibiu', 'Rimnicu', 'Pitesti', 'Bucharest']
@@ -56,6 +71,33 @@ def test_recursive_best_first_search():
5671
romania_problem).solution() == ['Sibiu', 'Rimnicu', 'Pitesti', 'Bucharest']
5772

5873

74+
def test_hill_climbing():
75+
prob = PeakFindingProblem((0, 0), [[0, 5, 10, 20],
76+
[-3, 7, 11, 5]])
77+
assert hill_climbing(prob) == (0, 3)
78+
prob = PeakFindingProblem((0, 0), [[0, 5, 10, 8],
79+
[-3, 7, 9, 999],
80+
[1, 2, 5, 11]])
81+
assert hill_climbing(prob) == (0, 2)
82+
prob = PeakFindingProblem((2, 0), [[0, 5, 10, 8],
83+
[-3, 7, 9, 999],
84+
[1, 2, 5, 11]])
85+
assert hill_climbing(prob) == (1, 3)
86+
87+
88+
def test_simulated_annealing():
89+
random.seed("aima-python")
90+
prob = PeakFindingProblem((0, 0), [[0, 5, 10, 20],
91+
[-3, 7, 11, 5]])
92+
sols = {prob.value(simulated_annealing(prob)) for i in range(100)}
93+
assert max(sols) == 20
94+
prob = PeakFindingProblem((0, 0), [[0, 5, 10, 8],
95+
[-3, 7, 9, 999],
96+
[1, 2, 5, 11]])
97+
sols = {prob.value(simulated_annealing(prob)) for i in range(100)}
98+
assert max(sols) == 999
99+
100+
59101
def test_BoggleFinder():
60102
board = list('SARTELNID')
61103
"""

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

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:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy