예제 #1
0
def generate_random_expression_tree() -> Tuple[ExprTree, Dict[str, int]]:
    """
    Generate a random expression tree and its lookup dictionary.
    """

    # randomly pick how many variables to have
    var = {'a': randint(0, 2), 'b': randint(0, 2), 'c': randint(0, 2)}

    # ensure at least one variable
    if all([var[v] == 0 for v in var]):
        var['a'] = 1

    # start with a set of leaves
    subtrees = []
    for k in var:
        for _ in range(var[k]):
            subtrees.append(ExprTree(k, []))
    for _ in range(randint(1, 5)):
        subtrees.append(ExprTree(randint(1, 9), []))
    shuffle(subtrees)

    # iteratively form subtrees - starting form our initial set of leaves
    while len(subtrees) > 1:
        op = choice(OPERATORS)
        num_children = randint(2, min(3, len(subtrees)))
        nu_node = ExprTree(op, subtrees[-num_children:])
        for _ in range(num_children):
            subtrees.pop()
        subtrees.insert(randint(0, len(subtrees)), nu_node)

    # there is one tree left in subtrees - this is the root we will return,
    # but first, we will setup its lookup
    lookup = {}
    subtrees[0].populate_lookup(lookup)  # set_lookup recursively sets lookup
    return subtrees[0], lookup
def test_expression_tree_puzzle_fail_fast_false() -> None:
    """Test ExpressionTreePuzzle.fail_fast on a solvable puzzle."""
    exp_t = ExprTree('+', [ExprTree('a', []), ExprTree('b', [])])
    puz = ExpressionTreePuzzle(exp_t, 7)
    puz.variables['a'] = 2

    assert puz.fail_fast() is False
def test_expression_tree_populate_lookup_doctest() -> None:
    """Test ExprTree.populate_lookup on the provided doctest"""
    expr_t = ExprTree('a', [])
    look_up = {}
    expr_t.populate_lookup(look_up)
    assert look_up['a'] == 0
    assert len(look_up) == 1
def test_expression_tree_puzzle_is_solved_doctest() -> None:
    """Test ExpressionTreePuzzle.is_solved on the provided doctest"""
    exp_t = ExprTree('+', [ExprTree('a', []), ExprTree('b', [])])
    puz = ExpressionTreePuzzle(exp_t, 7)
    assert puz.is_solved() is False
    puz.variables['a'] = 7
    assert puz.is_solved() is False
    puz.variables['a'] = 5
    puz.variables['b'] = 2
    assert puz.is_solved() is True
def test_expression_tree_puzzle_extensions_doctest() -> None:
    """Test ExpressionTreePuzzle.extensions on the provided doctest"""
    exp_t = ExprTree('a', [])
    puz = ExpressionTreePuzzle(exp_t, 7)
    exts_of_puz = puz.extensions()
    assert len(exts_of_puz) == 9

    exts_of_an_ext = exts_of_puz[0].extensions()
    assert len(exts_of_an_ext) == 0

    exp_t = ExprTree('+', [ExprTree('a', []), ExprTree('b', [])])
    puz = ExpressionTreePuzzle(exp_t, 8)
    exts_of_puz = puz.extensions()
    assert len(exts_of_puz) == 18
예제 #6
0
def main():

    pop_size = 1000
    max_runs = 50

    mutate_ratio = 0.2

    # Which data set to use.
    mode = 1

    random.seed()

    pop = []

    # Create a random population of trees.
    for i in range(pop_size):
        pop.append(ExprTree(mode))

    print "Population created."

    for tree in pop:
        print tree

    for i in range(max_runs):

        print "Beginning crossover " + str(i) + ":"

        # Crossover and mutate population.
        genetic.mutate(pop, mutate_ratio, mode)
        pop = genetic.crossover(pop, mode)

        print "Crossover " + str(i) + " complete."
예제 #7
0
    def __init__(self, tree: ExprTree, target: int) -> None:
        """
        Create a new expression tree puzzle given the provided
        expression tree and the target value. The variables are initialized
        using the tree's populate_lookup method.

        >>> puz = ExpressionTreePuzzle(ExprTree('a', []), 4)
        >>> puz.variables == {'a': 0}
        True
        >>> puz.target
        4
        """

        self.variables = {}
        tree.populate_lookup(self.variables)
        self._tree = tree
        self.target = target
예제 #8
0
def test_expression_tree_puzzle_str_doctest() -> None:
    """Test ExpressionTreePuzzle.__str__ on the provided doctest"""
    exp_t = ExprTree('+', [ExprTree('*',
                                    [ExprTree('a', []),
                                     ExprTree('+', [ExprTree('b', []),
                                                    ExprTree(6, []),
                                                    ExprTree(6, []),
                                                    ])]),
                           ExprTree(5, [])])
    puz = ExpressionTreePuzzle(exp_t, 61)
    assert str(puz) == "{'a': 0, 'b': 0}\n((a * (b + 6 + 6)) + 5) = 61"
예제 #9
0
def combine(first, second):
    """
	Combine 2 trees to create a child tree.

	Static method.

	Parameters:
		first - ExprTree - tree to combine
		second - ExprTree - tree to combine

	Returns:
		tuple - (ExprTree, ExprTree) - children of given trees
	"""

    first = ExprTree(0, first)
    second = ExprTree(0, second)

    parent1, left1 = first.random_parent()
    parent2, left2 = second.random_parent()

    if left1:
        temp = parent1.left

        if left2:
            parent1.left = parent2.left
            parent2.left = temp

        else:
            parent1.left = parent2.right
            parent2.right = temp
    else:
        temp = parent1.right

        if left2:
            parent1.right = parent2.left
            parent2.left = temp

        else:
            parent1.right = parent2.right
            parent2.right = temp

    return first, second
예제 #10
0
def test_expression_tree_eq_doctest() -> None:
    """Test ExprTree.__eq__ on the provided doctest"""
    t1 = ExprTree(5, [])
    assert t1.__eq__(ExprTree(5, []))

    t2 = ExprTree('*', [ExprTree(5, []), ExprTree(2, [])])
    assert t2.__eq__(ExprTree('*', [ExprTree(5, []), ExprTree(2, [])]))
    assert t2.__eq__(ExprTree('*', [])) is False
예제 #11
0
def test_expression_tree_str_doctest() -> None:
    """Test ExprTree.__str__ on the provided doctest"""

    exp_t = ExprTree('+',
                     [ExprTree('a', []),
                      ExprTree('b', []),
                      ExprTree(3, [])])
    assert str(exp_t) == '(a + b + 3)'

    exp_t = ExprTree(None, [])
    assert str(exp_t) == '()'

    exp_t = ExprTree(5, [])
    assert str(exp_t) == '5'

    exp_t = ExprTree('+', [
        ExprTree('*', [
            ExprTree(7, []),
            ExprTree('+', [ExprTree(6, []), ExprTree(6, [])])
        ]),
        ExprTree(5, [])
    ])
    assert str(exp_t) == '((7 * (6 + 6)) + 5)'

    exp_t = ExprTree('+', [
        ExprTree(3, []),
        ExprTree('*', [ExprTree('x', []), ExprTree('y', [])]),
        ExprTree('x', [])
    ])
    assert str(exp_t) == '(3 + (x * y) + x)'
예제 #12
0
def test_expression_tree_substitute_doctest() -> None:
    """Test ExprTree.substitute on the provided doctest"""
    # This test relies on ExprTree.__str__ working correctly.
    exp_t = ExprTree('a', [])
    exp_t.substitute({'a': 1})
    assert str(exp_t) == '1'

    exp_t = ExprTree('*', [
        ExprTree('a', []),
        ExprTree('*', [ExprTree('a', []), ExprTree(1, [])])
    ])
    exp_t.substitute({'a': 2, '*': '+'})
    assert str(exp_t) == '(2 + (2 + 1))'
예제 #13
0
def test_expression_tree_eval_doctest() -> None:
    """Test ExprTree.eval on the provided doctest"""
    exp_t = ExprTree('+', [
        ExprTree(3, []),
        ExprTree('*', [ExprTree('x', []), ExprTree('y', [])]),
        ExprTree('x', [])
    ])
    look_up = {}
    exp_t.populate_lookup(look_up)
    assert exp_t.eval(look_up) == 3

    look_up['x'] = 7
    look_up['y'] = 3
    assert exp_t.eval(look_up) == 31