Beispiel #1
0
def test_depth_first_graph_search():
    """
    depth-first graph and tree search are the same on this problem.
    """
    for goal in range(1, 10):
        p = AnnotatedProblem(EasyProblem(0, goal))
        sol = next(depth_first_search(p, graph=True))
        assert sol.state_node.state == goal
        assert p.nodes_expanded == goal * 2
        assert p.goal_tests == goal + 1

        p = AnnotatedProblem(EasyProblem(0, goal))
        sol = next(
            depth_first_search(p, graph=True, forward=False, backward=True))
        assert sol.state_node == sol.goal_node
        assert p.nodes_expanded == goal * 2
        assert p.goal_tests == goal + 1

        p2 = AnnotatedProblem(EasyProblem2(0, goal))
        try:
            next(depth_first_search(p2, graph=True))
            assert False
        except StopIteration:
            assert p2.nodes_expanded == 2
            assert p2.goal_tests == 1
Beispiel #2
0
def test_branch_and_bound():
    initial = 0
    goal = 10
    limits = (-goal, goal)
    p = AnnotatedProblem(
        EasyProblem(initial, initial_cost=initial, extra=limits))
    sol = next(branch_and_bound(p))
    assert abs(sol.state_node.state - limits[0]) <= 0.1

    sol = next(branch_and_bound(p, graph=False))
    assert abs(sol.state_node.state - limits[0]) <= 0.1

    p2 = HillProblem(initial, goal=goal, initial_cost=initial, extra=limits)

    sol = next(branch_and_bound(p2, graph=False))
    assert abs(sol.state_node.state - goal) <= 0.1

    p3 = AnnotatedProblem(
        HillProblem(initial, goal=initial, initial_cost=initial, extra=limits))
    sol = next(branch_and_bound(p3))
    assert p3.nodes_expanded == 0
    assert p3.goal_tests == 1
    assert abs(sol.state_node.state - initial) <= 0.1

    p4 = PlateauProblem(0)
    sol = list(branch_and_bound(p4))
    assert len(sol) == 1
    assert p4.node_value(sol[0].state_node) == -6

    p5 = PlateauProblem(0)
    sol = list(branch_and_bound(p5, depth_limit=1))
    assert len(sol) == 1
    assert p5.node_value(sol[0].state_node) == -5
Beispiel #3
0
def test_local_beam_search():
    initial = 0
    goal = 10
    limits = (-goal, goal)
    p = AnnotatedProblem(
        EasyProblem(initial, initial_cost=initial, extra=limits))
    sol = next(local_beam_search(p, graph=False))
    assert abs(sol.state_node.state - limits[0]) <= 0.1

    p2 = HillProblem(initial, goal=goal, initial_cost=initial, extra=limits)
    sol = next(local_beam_search(p2))
    assert abs(sol.state_node.state - goal) <= 0.1

    p3 = HillProblemNoGoalTest(initial,
                               goal=goal,
                               initial_cost=initial,
                               extra=limits)
    sol = next(local_beam_search(p3))
    assert abs(sol.state_node.state - goal) <= 0.1

    p4 = AnnotatedProblem(
        HillProblem(initial, goal=initial, initial_cost=initial, extra=limits))
    sol = next(local_beam_search(p4))
    assert p4.nodes_expanded == 0
    assert p4.goal_tests == 1
    assert abs(sol.state_node.state - initial) <= 0.1

    p5 = AnnotatedProblem(PlateauProblem(initial))
    sol = next(local_beam_search(p5, beam_width=2))
Beispiel #4
0
def test_hill_climbing():
    initial = 0
    goal = 10
    limits = (-goal, goal)
    p = AnnotatedProblem(
        EasyProblem(initial, initial_cost=initial, extra=limits))
    sol = next(hill_climbing(p, graph=False))
    assert abs(sol.state_node.state - limits[0]) <= 0.1

    p2 = HillProblem(initial, goal=goal, initial_cost=initial, extra=limits)
    sol = next(hill_climbing(p2))
    assert abs(sol.state_node.state - goal) <= 0.1

    p3 = AnnotatedProblem(
        HillProblem(initial, goal=initial, initial_cost=initial, extra=limits))
    sol = next(hill_climbing(p3))
    assert p3.nodes_expanded == 0
    assert p3.goal_tests == 1
    assert abs(sol.state_node.state - initial) <= 0.1

    p4 = AnnotatedProblem(PlateauProblem(initial))
    sol = next(hill_climbing(p4, random_restarts=3))

    p5 = AnnotatedProblem(PlateauProblemWithGoal(initial))
    sols = list(hill_climbing(p5, random_restarts=3))
Beispiel #5
0
def test_simulated_annealing():
    initial = 0
    goal = 10
    limits = (-goal, goal)
    p = AnnotatedProblem(
        EasyProblem(initial, initial_cost=initial, extra=limits))
    sol = next(simulated_annealing(p, temp_length=10, initial_temp=5))
    assert abs(sol.state_node.state - limits[0]) <= 0.1

    p2 = HillProblem(initial, goal=goal, initial_cost=initial, extra=limits)
    sol = next(simulated_annealing(p2))
    assert abs(sol.state_node.state - goal) <= 0.1

    p3 = AnnotatedProblem(
        HillProblem(initial, goal=initial, initial_cost=initial, extra=limits))
    sol = next(simulated_annealing(p3))
    assert p3.nodes_expanded == 0
    assert p3.goal_tests == 1
    assert abs(sol.state_node.state - initial) <= 0.1

    p4 = AnnotatedProblem(
        HillProblem(initial, goal=goal, initial_cost=initial, extra=limits))
    # sol = next(simulated_annealing(p4, limit=2))
    sol = next(simulated_annealing(p4, temp_length=1, limit=2))
    assert p4.nodes_expanded == 2

    p5 = AnnotatedProblem(
        HillProblem(initial, goal=1000, initial_cost=initial, extra=limits))
    # sol = next(simulated_annealing(p4, limit=2))
    sol = next(simulated_annealing(p5, temp_length=100, limit=900))
    assert p5.nodes_expanded == 900
Beispiel #6
0
def test_widening_beam_tree_search():
    """
    like test_beam2_tree_search, but eliminates duplicate nodes
    """
    for goal in range(1, 10):
        p = AnnotatedProblem(EasyProblem(0, goal))
        sol = next(widening_beam_search(p, graph=True))
        assert sol.state_node.state == goal
        assert p.nodes_expanded == goal * 2
        assert p.goal_tests == goal + 1
        assert p.goal_tests == goal + 1

    for goal in range(1, 10):
        p = AnnotatedProblem(HeuristicHardProblem(0, goal))
        sol = next(widening_beam_search(p, graph=True))
        assert sol.state_node.state == goal
Beispiel #7
0
def test_breadth_first_tree_search():
    """
    Test breadth first tree search (i.e., with duplicates).
    """
    for goal in range(1, 10):
        p = AnnotatedProblem(EasyProblem(0, goal))
        sol = next(breadth_first_search(p, graph=False))
        assert sol.state_node.state == goal
        assert p.nodes_expanded == pow(2, goal + 1) - 2
        assert p.goal_tests == pow(2, goal)

        p = AnnotatedProblem(EasyProblem(0, goal))
        sol = next(
            breadth_first_search(p, graph=False, forward=False, backward=True))
        assert sol.state_node == sol.goal_node
        assert p.nodes_expanded == pow(2, goal + 1) - 2
        assert p.goal_tests == pow(2, goal)
Beispiel #8
0
def test_breadth_first_graph_search():
    """
    Test breadth first graph search (i.e., no duplicates). For this test
    problem it performs similar to breadth first.
    """
    for goal in range(1, 10):
        p = AnnotatedProblem(EasyProblem(0, goal))
        sol = next(breadth_first_search(p, graph=True))
        assert sol.state_node.state == goal
        assert p.nodes_expanded == goal * 2
        assert p.goal_tests == goal + 1

        p = AnnotatedProblem(EasyProblem(0, goal))
        sol = next(
            breadth_first_search(p, graph=True, forward=False, backward=True))
        assert sol.state_node == sol.goal_node
        assert p.nodes_expanded == goal * 2
        assert p.goal_tests == goal + 1
Beispiel #9
0
def test_beam2_graph_search():
    """
    like test_beam2_tree_search, but eliminates duplicate nodes
    """
    for goal in range(1, 10):
        p = AnnotatedProblem(EasyProblem(0, goal))
        sol = next(beam_search(p, beam_width=2, graph=True))
        assert sol.state_node.state == goal
        assert p.nodes_expanded == goal * 2
Beispiel #10
0
def test_iterative_deepening_graph_search():
    """
    Test iterative deepening graph search.
    """
    for goal in range(1, 10):
        p = AnnotatedProblem(EasyProblem(0, goal))
        sol = next(iterative_deepening_search(p, graph=True))
        assert sol.state_node.state == goal
        assert p.nodes_expanded == sum([i * 2 for i in range(1, goal + 1)])
        assert p.goal_tests == sum([i + 1 for i in range(1, goal + 1)]) + 1
Beispiel #11
0
def test_best_first_search_with_heuristic():
    """
    Best heuristic is essentially depth first.
    """
    for goal in range(1, 10):
        p = AnnotatedProblem(HeuristicEasyProblem(0, goal))
        sol = next(best_first_search(p, graph=False))
        assert sol.state_node.state == goal
        assert p.nodes_expanded == goal * 2
        assert p.goal_tests == goal + 1
Beispiel #12
0
def test_best_first_search_without_heuristic():
    """
    Best first search without a heuristic is essentially breadth first.
    """
    for goal in range(1, 10):
        p = AnnotatedProblem(EasyProblem(0, goal))
        sol = next(best_first_search(p, graph=False))
        assert sol.state_node.state == goal
        assert p.nodes_expanded == pow(2, goal + 1) - 2
        assert p.goal_tests == pow(2, goal)
Beispiel #13
0
def test_beam1_tree_search():
    """
    Beam search with a width of 1 is like a depth first search, but with no
    backtracking.
    """
    for goal in range(1, 10):
        p = AnnotatedProblem(EasyProblem(0, goal))
        sol = next(beam_search(p, beam_width=1, graph=False))
        assert sol.state_node.state == goal
        assert p.nodes_expanded == goal * 2
        assert p.goal_tests == goal + 1
Beispiel #14
0
def test_bidirectional_tree_search():
    for goal in range(1, 14):
        p = AnnotatedProblem(EasyProblem(0, goal))
        sol = next(
            breadth_first_search(p, graph=False, forward=True, backward=True))
        assert sol.state_node == sol.goal_node
        if goal % 2 == 0:
            assert p.nodes_expanded == 2 * (pow(2, goal / 2 + 1) - 2)
            assert p.goal_tests == pow(2, goal)
        else:
            assert p.nodes_expanded == pow(2, goal // 2 + 2) - 2
Beispiel #15
0
def test_iterative_deepening_best_first_search():
    """
    Without heuristic it is basically the same as iterative_deepening_search.
    (here is the case where we use graph search).
    """
    for goal in range(1, 10):
        p = AnnotatedProblem(EasyProblem(0, goal))
        sol = next(iterative_deepening_best_first_search(p, graph=True))
        assert sol.state_node.state == goal
        assert p.nodes_expanded == sum([i * 2 for i in range(1, goal + 2)]) - 2
        assert p.goal_tests == sum([i + 1 for i in range(1, goal + 1)]) + 1
Beispiel #16
0
def test_beam2_tree_search():
    """
    Beam search with a width of 2 is slightly different. It is like a fusion of
    breadth and depth first searches.
    """
    for goal in range(1, 10):
        p = AnnotatedProblem(EasyProblem(0, goal))
        sol = next(beam_search(p, beam_width=2, graph=False))
        assert sol.state_node.state == goal
        assert p.nodes_expanded == 2 + (goal - 1) * 4
        assert p.goal_tests == 2 + (goal - 1) * 2
Beispiel #17
0
def test_iterative_best_first_tree_search():
    """
    Test iterative deepening tree search. When there is a perfect heuristic the
    cost is increased until the heuristic is included, then search proceeds
    directly to the solution.
    """
    for goal in range(1, 10):
        p = AnnotatedProblem(HeuristicEasyProblem(0, goal))
        sol = next(iterative_deepening_best_first_search(p, graph=False))
        assert sol.state_node.state == goal
        assert p.nodes_expanded == goal * 2
        assert p.goal_tests == goal + 1
Beispiel #18
0
def test_simulated_annealing():
    initial = 0
    goal = 10
    limits = (-goal, goal)
    p = AnnotatedProblem(
        EasyProblem(initial, initial_cost=initial, extra=limits))
    sol = next(simulated_annealing(p))
    assert abs(sol.state_node.state - limits[0]) <= 0.1

    p2 = HillProblem(initial, goal=goal, initial_cost=initial, extra=limits)
    sol = next(simulated_annealing(p2))
    assert abs(sol.state_node.state - goal) <= 0.1

    p3 = AnnotatedProblem(
        HillProblem(initial, goal=initial, initial_cost=initial, extra=limits))
    sol = next(simulated_annealing(p3))
    assert p3.nodes_expanded == 0
    assert p3.goal_tests == 1
    assert abs(sol.state_node.state - initial) <= 0.1

    p4 = HillProblem(initial, goal=goal, initial_cost=initial, extra=limits)
    sol = next(simulated_annealing(p4, limit=2))
Beispiel #19
0
def test_iterative_deepening_tree_search():
    """
    Test iterative deepening tree search.
    """
    for goal in range(1, 10):
        p = AnnotatedProblem(EasyProblem(0, goal))
        sol = next(iterative_deepening_search(p, graph=False))
        assert sol.state_node.state == goal
        assert (p.nodes_expanded == sum(
            [pow(2, i + 1) - 2 for i in range(1, goal)]) + (goal * 2))
        assert (
            p.goal_tests == sum([pow(2, i + 1) - 2
                                 for i in range(1, goal)]) + (goal * 2) + 1)
Beispiel #20
0
def test_branch_and_bound():
    initial = 0
    goal = 10
    limits = (-goal, goal)
    p = AnnotatedProblem(
        EasyProblem(initial, initial_cost=initial, extra=limits))
    sol = next(branch_and_bound(p))
    assert abs(sol.state_node.state - limits[0]) <= 0.1

    sol = next(branch_and_bound(p, graph=False))
    assert abs(sol.state_node.state - limits[0]) <= 0.1

    p2 = HillProblem(initial, goal=goal, initial_cost=initial, extra=limits)

    sol = next(branch_and_bound(p2, graph=False))
    assert abs(sol.state_node.state - goal) <= 0.1

    p3 = AnnotatedProblem(
        HillProblem(initial, goal=initial, initial_cost=initial, extra=limits))
    sol = next(branch_and_bound(p3))
    assert p3.nodes_expanded == 0
    assert p3.goal_tests == 1
    assert abs(sol.state_node.state - initial) <= 0.1
Beispiel #21
0
def test_problem():
    """
    Tests to make sure exceptions are raised.
    """
    p = Problem(None)

    try:
        p.predecessors(p.initial)
        assert False
    except NotImplementedError:
        pass

    try:
        p.successors(p.initial)
        assert False
    except NotImplementedError:
        pass

    try:
        p.random_node()
        assert False
    except NotImplementedError:
        pass

    # test to make sure the goal test falls back on the goal specified during
    # problem construction. In this case None == None - CM
    assert p.goal_test(p.initial)

    ap = AnnotatedProblem(p)

    # Should fall back on problem, which will raise an exception.
    try:
        ap.random_node()
        assert False
    except NotImplementedError:
        pass
Beispiel #22
0
def test_depth_first_tree_search():
    """
    Test depth first tree search (i.e., with duplicates).
    """
    for goal in range(1, 10):
        p = AnnotatedProblem(EasyProblem(0, goal))
        sol = next(depth_first_search(p, graph=False))
        assert sol.state_node.state == goal
        assert p.nodes_expanded == goal * 2
        assert p.goal_tests == goal + 1

        p = AnnotatedProblem(EasyProblem(0, goal))
        sol = next(
            depth_first_search(p, graph=False, forward=False, backward=True))
        assert sol.state_node == sol.goal_node
        assert p.nodes_expanded == goal * 2
        assert p.goal_tests == goal + 1

    try:
        p = EasyProblem(0, 10)
        next(depth_first_search(p, graph=False, depth_limit=5))
        assert False
    except StopIteration:
        pass

    try:
        p = EasyProblem(0, 10)
        next(
            depth_first_search(p,
                               graph=False,
                               forward=False,
                               backward=True,
                               depth_limit=5))
        assert False
    except StopIteration:
        pass
Beispiel #23
0
def test_iterative_deepening_graph_search():
    """
    Test iterative deepening graph search.
    """
    for goal in range(1, 10):
        p = AnnotatedProblem(EasyProblem(0, goal))
        sol = next(iterative_deepening_search(p, graph=True))
        assert sol.state_node.state == goal
        assert p.nodes_expanded == sum([i * 2 for i in range(1, goal + 1)])
        assert p.goal_tests == sum([i + 1 for i in range(1, goal + 1)]) + 1

    p = EasyProblem(0, 10)
    try:
        next(iterative_deepening_search(p, graph=True, max_depth_limit=5))
        assert False
    except StopIteration:
        pass
Beispiel #24
0
def compare_searches(problems, searches):
    """
    A function for comparing different search algorithms on different problems.

    :param problems: problems to solve.
    :type problems: an iterator of problems (usually a list)
    :param searches: search algorithms to use.
    :type searches: an iterator of search functions (usually a list)
    """
    table = []

    for problem in problems:
        for search in searches:
            annotated_problem = AnnotatedProblem(problem)
            start_time = timeit.default_timer()

            try:
                sol = next(search(annotated_problem))
                elapsed = timeit.default_timer() - start_time
                cost = sol.cost()
            except StopIteration:
                elapsed = timeit.default_timer() - start_time
                cost = 'Failed'

            table.append([
                problem.__class__.__name__, search.__name__,
                annotated_problem.goal_tests, annotated_problem.nodes_expanded,
                annotated_problem.nodes_evaluated,
                "%0.3f" % cost if isinstance(cost, float) else cost,
                "%0.4f" % elapsed if isinstance(elapsed, float) else elapsed
            ])

    print(
        tabulate(table,
                 headers=[
                     'Problem', 'Search Alg', 'Goal Tests', 'Nodes Expanded',
                     'Nodes Evaluated', 'Solution Cost', 'Runtime'
                 ],
                 tablefmt="simple"))