def __init__(self): self.tree_id = None self.score = None self.tree_type = None self.root = None self.depth = 0 self.size = 0 self.program = [] self.func_nodes = [] self.term_nodes = [] self.input_nodes = [] self.parser = TreeParser()
def setUp(self): self.config = { "max_population": 10, "tree_generation": { "tree_type": "SYMBOLIC_REGRESSION", "method": "RAMPED_HALF_AND_HALF_METHOD", "initial_max_depth": 3 }, "function_nodes": [ {"type": "FUNCTION", "arity": 2, "name": "ADD"}, {"type": "FUNCTION", "arity": 2, "name": "SUB"}, {"type": "FUNCTION", "arity": 2, "name": "MUL"}, {"type": "FUNCTION", "arity": 2, "name": "DIV"}, {"type": "FUNCTION", "arity": 1, "name": "COS"}, {"type": "FUNCTION", "arity": 1, "name": "SIN"} ], "terminal_nodes": [ {"type": "CONSTANT", "value": 1.0}, {"type": "INPUT", "name": "x"}, {"type": "INPUT", "name": "y"}, { "type": "RANDOM_CONSTANT", "data_range": { "upper_bound": 10.0, "lower_bound": -10.0, "decimal_places": 1 } } ], "input_variables": [ {"name": "x"}, {"name": "y"} ] } self.functions = GPFunctionRegistry("SYMBOLIC_REGRESSION") self.generator = TreeGenerator(self.config) self.parser = TreeParser()
def setUp(self): self.config = { "max_population": 10, "tree_generation": { "method": "FULL_METHOD", "initial_max_depth": 4 }, "function_nodes": [ {"type": "FUNCTION", "name": "ADD", "arity": 2}, {"type": "FUNCTION", "name": "SUB", "arity": 2}, {"type": "FUNCTION", "name": "MUL", "arity": 2}, {"type": "FUNCTION", "name": "DIV", "arity": 2}, {"type": "FUNCTION", "name": "COS", "arity": 1}, {"type": "FUNCTION", "name": "SIN", "arity": 1} ], "terminal_nodes": [ {"type": "CONSTANT", "value": 1.0}, {"type": "INPUT", "name": "x"}, {"type": "INPUT", "name": "y"}, {"type": "INPUT", "name": "z"} ], "input_variables": [ {"name": "x"}, {"name": "y"}, {"name": "z"} ] } self.t_parser = TreeParser() self.tree = Tree() node_x = Node(NodeType.INPUT, name="x") node_y = Node(NodeType.INPUT, name="y") node_z = Node(NodeType.INPUT, name="z") self.tree.input_nodes.append(node_x) self.tree.input_nodes.append(node_y) self.tree.input_nodes.append(node_z)
def setUp(self): self.config = { "tree_generation": { "method": "GROW_METHOD", "initial_max_depth": 4 }, "mutation": { "methods": [ "POINT_MUTATION", "HOIST_MUTATION", "SUBTREE_MUTATION", "SHRINK_MUTATION", "EXPAND_MUTATION" ], "probability": 1.0 }, "function_nodes": [{ "type": "FUNCTION", "name": "ADD", "arity": 2 }, { "type": "FUNCTION", "name": "SUB", "arity": 2 }, { "type": "FUNCTION", "name": "MUL", "arity": 2 }, { "type": "FUNCTION", "name": "DIV", "arity": 2 }, { "type": "FUNCTION", "name": "COS", "arity": 1 }, { "type": "FUNCTION", "name": "SIN", "arity": 1 }, { "type": "FUNCTION", "name": "RAD", "arity": 1 }], "terminal_nodes": [{ "type": "CONSTANT", "value": 1.0 }, { "type": "CONSTANT", "value": 2.0 }, { "type": "INPUT", "name": "x" }], "input_variables": [{ "type": "INPUT", "name": "x" }] } self.functions = GPFunctionRegistry("SYMBOLIC_REGRESSION") self.generator = TreeGenerator(self.config) self.parser = TreeParser() self.mutation = TreeMutation(self.config) # create nodes left_node = Node(NodeType.CONSTANT, value=1.0) right_node = Node(NodeType.INPUT, name="x") cos_func = Node(NodeType.FUNCTION, name="COS", arity=1, branches=[left_node]) sin_func = Node(NodeType.FUNCTION, name="SIN", arity=1, branches=[right_node]) add_func = Node(NodeType.FUNCTION, name="ADD", arity=2, branches=[cos_func, sin_func]) # create tree self.tree = Tree() self.tree.root = add_func self.tree.update_program() self.tree.update_func_nodes() self.tree.update_term_nodes()
class Tree(object): def __init__(self): self.tree_id = None self.score = None self.tree_type = None self.root = None self.depth = 0 self.size = 0 self.program = [] self.func_nodes = [] self.term_nodes = [] self.input_nodes = [] self.parser = TreeParser() def valid(self, config_input_nodes): # convert config input nodes from dict to list of Nodes check_list = [] for node in config_input_nodes: check_list.append(node["name"]) # convert tree input nodes tree_input_nodes = [] for node in self.input_nodes: tree_input_nodes.append(node.name) result = set(check_list) - set(tree_input_nodes) if len(list(result)) == 0: return True else: return False def get_linked_node(self, target_node): try: index = self.program.index(target_node) + 1 for node in self.program[index:]: if node.has_value_node(target_node) is not False: return node except ValueError: return None def replace_node(self, target_node, replace_with, override_update=False): linked_node = self.get_linked_node(target_node) branch_index = linked_node.has_value_node(target_node) linked_node.branches[branch_index] = replace_with if override_update is False: self.update() def equals(self, tree): if len(self.program) != len(tree.program): return False index = 0 for node in self.program: equals = node.equals(tree.program[index]) if equals is False: return False index += 1 return True def update_program(self): del self.program[:] self.program = self.parser.post_order_traverse(self.root) def update_func_nodes(self): del self.func_nodes[:] for node in self.program: if node.is_function(): if node is not self.root: self.func_nodes.append(node) def update_term_nodes(self): del self.term_nodes[:] for node in self.program: if node.is_terminal(): self.term_nodes.append(node) def update_input_nodes(self): del self.input_nodes[:] for node in self.program: if node.is_input(): self.input_nodes.append(node) def update_tree_info(self): self.size = len(self.program) self.branches = len(self.term_nodes) + len(self.input_nodes) def update(self): self.program = self.parser.parse_tree(self, self.root) def __str__(self): if self.tree_type == "CLASSIFICATION_TREE": return self.parser.parse_classification_tree(self.root) else: return self.parser.parse_equation(self.root) def to_dict(self): self_dict = { "id": id(self), "score": self.score, "size": self.size, "depth": self.depth, "func_nodes_len": len(self.func_nodes), "term_nodes_len": len(self.term_nodes), "input_nodes_len": len(self.input_nodes), "func_nodes": [str(node) for node in self.func_nodes], "term_nodes": [str(node) for node in self.term_nodes], "input_nodes": [str(node) for node in self.input_nodes], "program": str(self) } return self_dict
def setUp(self): self.config = { "tree_generation": { "initial_max_depth": 4 }, "crossover": { "method": "POINT_CROSSOVER", "probability": 1.0 }, "function_nodes": [{ "type": "FUNCTION", "name": "ADD", "arity": 2 }, { "type": "FUNCTION", "name": "SUB", "arity": 2 }, { "type": "FUNCTION", "name": "MUL", "arity": 2 }, { "type": "FUNCTION", "name": "DIV", "arity": 2 }, { "type": "FUNCTION", "name": "COS", "arity": 1 }, { "type": "FUNCTION", "name": "SIN", "arity": 1 }, { "type": "FUNCTION", "name": "RAD", "arity": 1 }], "terminal_nodes": [{ "type": "CONSTANT", "value": 1.0 }, { "type": "CONSTANT", "value": 2.0 }, { "type": "CONSTANT", "value": 2.0 }, { "type": "CONSTANT", "value": 3.0 }, { "type": "CONSTANT", "value": 4.0 }, { "type": "CONSTANT", "value": 5.0 }, { "type": "CONSTANT", "value": 6.0 }, { "type": "CONSTANT", "value": 7.0 }, { "type": "CONSTANT", "value": 8.0 }, { "type": "CONSTANT", "value": 9.0 }, { "type": "CONSTANT", "value": 10.0 }], "input_variables": [{ "type": "INPUT", "name": "x" }] } self.functions = GPFunctionRegistry("SYMBOLIC_REGRESSION") self.generator = TreeGenerator(self.config) self.crossover = TreeCrossover(self.config) self.parser = TreeParser() # create nodes left_node_1 = Node(NodeType.INPUT, name="x") right_node_1 = Node(NodeType.CONSTANT, value=2.0) node = Node(NodeType.CONSTANT, value=2.0) left_node_2 = Node(NodeType.CONSTANT, value=3.0) right_node_2 = Node(NodeType.CONSTANT, value=4.0) cos_func_1 = Node(NodeType.FUNCTION, name="ADD", arity=2, branches=[left_node_1, right_node_1]) sin_func_1 = Node(NodeType.FUNCTION, name="SIN", arity=1, branches=[node]) cos_func_2 = Node(NodeType.FUNCTION, name="COS", arity=1, branches=[left_node_2]) sin_func_2 = Node(NodeType.FUNCTION, name="SIN", arity=1, branches=[right_node_2]) add_func = Node(NodeType.FUNCTION, name="ADD", arity=2, branches=[cos_func_1, sin_func_1]) sub_func = Node(NodeType.FUNCTION, name="SUB", arity=2, branches=[sin_func_2, cos_func_2]) # create tree_1 self.tree_1 = Tree() self.tree_1.root = add_func self.tree_1.update() print self.tree_1 # create tree_2 self.tree_2 = Tree() self.tree_2.root = sub_func self.tree_2.update()
def setUp(self): self.config = { "max_population": 10, "tree_generation": { "tree_type": "SYMBOLIC_REGRESSION", "method": "RAMPED_HALF_AND_HALF_METHOD", "initial_max_depth": 3 }, "function_nodes": [{ "type": "FUNCTION", "arity": 2, "name": "ADD" }, { "type": "FUNCTION", "arity": 2, "name": "SUB" }, { "type": "FUNCTION", "arity": 2, "name": "MUL" }, { "type": "FUNCTION", "arity": 2, "name": "DIV" }, { "type": "FUNCTION", "arity": 1, "name": "COS" }, { "type": "FUNCTION", "arity": 1, "name": "SIN" }], "terminal_nodes": [{ "type": "CONSTANT", "value": 1.0 }, { "type": "INPUT", "name": "x" }, { "type": "INPUT", "name": "y" }, { "type": "RANDOM_CONSTANT", "data_range": { "upper_bound": 10.0, "lower_bound": -10.0, "decimal_places": 1 } }], "input_variables": [{ "name": "x" }, { "name": "y" }] } self.functions = GPFunctionRegistry("SYMBOLIC_REGRESSION") self.generator = TreeGenerator(self.config) self.parser = TreeParser()
class TreeGeneratorTests(unittest.TestCase): def setUp(self): self.config = { "max_population": 10, "tree_generation": { "tree_type": "SYMBOLIC_REGRESSION", "method": "RAMPED_HALF_AND_HALF_METHOD", "initial_max_depth": 3 }, "function_nodes": [{ "type": "FUNCTION", "arity": 2, "name": "ADD" }, { "type": "FUNCTION", "arity": 2, "name": "SUB" }, { "type": "FUNCTION", "arity": 2, "name": "MUL" }, { "type": "FUNCTION", "arity": 2, "name": "DIV" }, { "type": "FUNCTION", "arity": 1, "name": "COS" }, { "type": "FUNCTION", "arity": 1, "name": "SIN" }], "terminal_nodes": [{ "type": "CONSTANT", "value": 1.0 }, { "type": "INPUT", "name": "x" }, { "type": "INPUT", "name": "y" }, { "type": "RANDOM_CONSTANT", "data_range": { "upper_bound": 10.0, "lower_bound": -10.0, "decimal_places": 1 } }], "input_variables": [{ "name": "x" }, { "name": "y" }] } self.functions = GPFunctionRegistry("SYMBOLIC_REGRESSION") self.generator = TreeGenerator(self.config) self.parser = TreeParser() def tearDown(self): del self.config del self.generator del self.parser def test_generate_func_node(self): # SYMBOLIC REGRESSION TREES for i in range(100): node = self.generator.generate_func_node() self.assertEquals(node.node_type, NodeType.FUNCTION) # CLASSIFICATION TREES self.config["tree_generation"]["tree_type"] = "CLASSIFICATION_TREE" self.config["function_nodes"] = [{ "type": "CLASS_FUNCTION", "name": "GREATER_THAN", "arity": 2, "data_range": { "lower_bound": 0.0, "upper_bound": 10.0, "decimal_places": 1 } }] self.config["class_attributes"] = [ "attrubte_1", "attrubte_2", "attrubte_3" ] generator = TreeGenerator(self.config) for i in range(100): node = generator.generate_func_node() class_attribute = node.class_attribute self.assertEquals(node.node_type, NodeType.CLASS_FUNCTION) self.assertTrue(class_attribute in self.config["class_attributes"]) def test_resolve_random_constant(self): upper_bound = 10.0 lower_bound = -10.0 decimal_places = 0 for i in range(100): n_details = { "type": "RANDOM_CONSTANT", "data_range": { "lower_bound": lower_bound, "upper_bound": upper_bound, "decimal_places": decimal_places } } new_n_details = self.generator.resolve_random_constant(n_details) node_type = new_n_details["type"] node_value = new_n_details["value"] self.assertEquals(node_type, "CONSTANT") self.assertTrue(upper_bound >= node_value) self.assertTrue(lower_bound <= node_value) self.assertEquals(node_value, int(node_value)) upper_bound = 100.0 lower_bound = -100.0 decimal_places = 1 for i in range(100): n_details = { "type": "RANDOM_CONSTANT", "data_range": { "lower_bound": lower_bound, "upper_bound": upper_bound, "decimal_places": decimal_places } } new_n_details = self.generator.resolve_random_constant(n_details) node_type = new_n_details["type"] node_value = new_n_details["value"] self.assertEquals(node_type, "CONSTANT") self.assertTrue(upper_bound >= node_value) self.assertTrue(lower_bound <= node_value) node_value = decimal.Decimal(str(node_value)) node_decimal_places = abs(node_value.as_tuple().exponent) self.assertEquals(decimal_places, node_decimal_places) def test_generate_term_node(self): for i in range(100): node = self.generator.generate_term_node() self.assertTrue(node.node_type == NodeType.CONSTANT or NodeType.INPUT) def test_full_method(self): tests = 1 for i in xrange(tests): tree = self.generator.full_method() # asserts init_max = self.config["tree_generation"]["initial_max_depth"] self.assertEquals(tree.depth, init_max) self.assertTrue(tree.size > init_max) def test_grow_method(self): tests = 1000 for i in xrange(tests): tree = self.generator.grow_method() # asserts init_max = self.config["tree_generation"]["initial_max_depth"] self.assertEquals(tree.depth, init_max) self.assertTrue(tree.size > init_max) def test_generate_tree_from_dict(self): population = self.generator.init() tree = population.individuals[0] tree_dict = self.parser.tree_to_dict(tree, tree.root) tree_generated = self.generator.generate_tree_from_dict(tree_dict) program_str = "" for i in tree.program: if i.name is not None: program_str += i.name else: program_str += str(i.value) generated_str = "" for i in tree_generated.program: if i.name is not None: generated_str += i.name else: generated_str += str(i.value) self.assertEquals(program_str, generated_str) def test_init(self): population = self.generator.init() self.assertEquals(len(population.individuals), 10)
class TreeGeneratorTests(unittest.TestCase): def setUp(self): self.config = { "max_population": 10, "tree_generation": { "tree_type": "SYMBOLIC_REGRESSION", "method": "RAMPED_HALF_AND_HALF_METHOD", "initial_max_depth": 3 }, "function_nodes": [ {"type": "FUNCTION", "arity": 2, "name": "ADD"}, {"type": "FUNCTION", "arity": 2, "name": "SUB"}, {"type": "FUNCTION", "arity": 2, "name": "MUL"}, {"type": "FUNCTION", "arity": 2, "name": "DIV"}, {"type": "FUNCTION", "arity": 1, "name": "COS"}, {"type": "FUNCTION", "arity": 1, "name": "SIN"} ], "terminal_nodes": [ {"type": "CONSTANT", "value": 1.0}, {"type": "INPUT", "name": "x"}, {"type": "INPUT", "name": "y"}, { "type": "RANDOM_CONSTANT", "data_range": { "upper_bound": 10.0, "lower_bound": -10.0, "decimal_places": 1 } } ], "input_variables": [ {"name": "x"}, {"name": "y"} ] } self.functions = GPFunctionRegistry("SYMBOLIC_REGRESSION") self.generator = TreeGenerator(self.config) self.parser = TreeParser() def tearDown(self): del self.config del self.generator del self.parser def test_generate_func_node(self): # SYMBOLIC REGRESSION TREES for i in range(100): node = self.generator.generate_func_node() self.assertEquals(node.node_type, NodeType.FUNCTION) # CLASSIFICATION TREES self.config["tree_generation"]["tree_type"] = "CLASSIFICATION_TREE" self.config["function_nodes"] = [ { "type": "CLASS_FUNCTION", "name": "GREATER_THAN", "arity": 2, "data_range": { "lower_bound": 0.0, "upper_bound": 10.0, "decimal_places": 1 } } ] self.config["class_attributes"] = [ "attrubte_1", "attrubte_2", "attrubte_3" ] generator = TreeGenerator(self.config) for i in range(100): node = generator.generate_func_node() class_attribute = node.class_attribute self.assertEquals(node.node_type, NodeType.CLASS_FUNCTION) self.assertTrue(class_attribute in self.config["class_attributes"]) def test_resolve_random_constant(self): upper_bound = 10.0 lower_bound = -10.0 decimal_places = 0 for i in range(100): n_details = { "type": "RANDOM_CONSTANT", "data_range": { "lower_bound": lower_bound, "upper_bound": upper_bound, "decimal_places": decimal_places } } new_n_details = self.generator.resolve_random_constant(n_details) node_type = new_n_details["type"] node_value = new_n_details["value"] self.assertEquals(node_type, "CONSTANT") self.assertTrue(upper_bound >= node_value) self.assertTrue(lower_bound <= node_value) self.assertEquals(node_value, int(node_value)) upper_bound = 100.0 lower_bound = -100.0 decimal_places = 1 for i in range(100): n_details = { "type": "RANDOM_CONSTANT", "data_range": { "lower_bound": lower_bound, "upper_bound": upper_bound, "decimal_places": decimal_places } } new_n_details = self.generator.resolve_random_constant(n_details) node_type = new_n_details["type"] node_value = new_n_details["value"] self.assertEquals(node_type, "CONSTANT") self.assertTrue(upper_bound >= node_value) self.assertTrue(lower_bound <= node_value) node_value = decimal.Decimal(str(node_value)) node_decimal_places = abs(node_value.as_tuple().exponent) self.assertEquals(decimal_places, node_decimal_places) def test_generate_term_node(self): for i in range(100): node = self.generator.generate_term_node() self.assertTrue( node.node_type == NodeType.CONSTANT or NodeType.INPUT ) def test_full_method(self): tests = 1 for i in xrange(tests): tree = self.generator.full_method() # asserts init_max = self.config["tree_generation"]["initial_max_depth"] self.assertEquals(tree.depth, init_max) self.assertTrue(tree.size > init_max) def test_grow_method(self): tests = 1000 for i in xrange(tests): tree = self.generator.grow_method() # asserts init_max = self.config["tree_generation"]["initial_max_depth"] self.assertEquals(tree.depth, init_max) self.assertTrue(tree.size > init_max) def test_generate_tree_from_dict(self): population = self.generator.init() tree = population.individuals[0] tree_dict = self.parser.tree_to_dict(tree, tree.root) tree_generated = self.generator.generate_tree_from_dict(tree_dict) program_str = "" for i in tree.program: if i.name is not None: program_str += i.name else: program_str += str(i.value) generated_str = "" for i in tree_generated.program: if i.name is not None: generated_str += i.name else: generated_str += str(i.value) self.assertEquals(program_str, generated_str) def test_init(self): population = self.generator.init() self.assertEquals(len(population.individuals), 10)
def test_evaluate(self): random.seed(10) # solution = { # "results": # [ # {"score": 15726642.002161335}, # {"score": 359.25843589015597}, # {"score": 92155571.22132382}, # {"score": 26186.46142920347}, # {"score": 15649304.847552022}, # {"score": 188.86069156360125}, # {"score": 23439.33097274221}, # ] # } # setup config = { "max_population" : 10, "max_generation" : 5, "tree_generation" : { "method" : "GROW_METHOD", "initial_max_depth" : 3 }, "evaluator": { "use_cache" : True }, "selection" : { "method" : "TOURNAMENT_SELECTION", "tournament_size": 5 }, "crossover" : { "method" : "POINT_CROSSOVER", "probability" : 0.8 }, "mutation" : { "methods": [ "POINT_MUTATION", "HOIST_MUTATION", "SUBTREE_MUTATION", "SHRINK_MUTATION", "EXPAND_MUTATION" ], "probability" : 0.9 }, "function_nodes" : [ {"type": "FUNCTION", "name": "ADD", "arity": 2}, {"type": "FUNCTION", "name": "SUB", "arity": 2}, {"type": "FUNCTION", "name": "MUL", "arity": 2}, {"type": "FUNCTION", "name": "DIV", "arity": 2}, {"type": "FUNCTION", "name": "COS", "arity": 1}, {"type": "FUNCTION", "name": "SIN", "arity": 1} ], "terminal_nodes" : [ {"type": "CONSTANT", "value": 1.0}, {"type": "CONSTANT", "value": 2.0}, {"type": "CONSTANT", "value": 2.0}, {"type": "CONSTANT", "value": 3.0}, {"type": "CONSTANT", "value": 4.0}, {"type": "CONSTANT", "value": 5.0}, {"type": "CONSTANT", "value": 6.0}, {"type": "CONSTANT", "value": 7.0}, {"type": "CONSTANT", "value": 8.0}, {"type": "CONSTANT", "value": 9.0}, {"type": "CONSTANT", "value": 10.0} ], "data_file" : "tests/data/sine.dat", "input_variables" : [{"type": "INPUT", "name": "x"}], "response_variables" : [{"name": "y"}] } parser = TreeParser() population = TreeGenerator(config).init() # create a dictionary of trees data = {"config": config, "individuals": []} for individual in population.individuals: tree_json = parser.tree_to_dict(individual, individual.root) data["individuals"].append(tree_json) # make sure population size is equals to number of trees population_size = len(population.individuals) individuals = len(data["individuals"]) self.assertEquals(population_size, individuals) # evaluating individuals data = json.dumps(data) host = "localhost" port = 8080 req_type = "POST" path = "evaluate" response = self.transmit(host, port, req_type, path, data) response = json.loads(response) print response
def __init__(self, config): self.config = config self.gen_config = config["tree_generation"] self.max_depth = self.gen_config.get("initial_max_depth", 0) self.parser = TreeParser()
class TreeTests(unittest.TestCase): def setUp(self): self.config = { "max_population": 10, "tree_generation": { "method": "FULL_METHOD", "initial_max_depth": 4 }, "function_nodes": [ {"type": "FUNCTION", "name": "ADD", "arity": 2}, {"type": "FUNCTION", "name": "SUB", "arity": 2}, {"type": "FUNCTION", "name": "MUL", "arity": 2}, {"type": "FUNCTION", "name": "DIV", "arity": 2}, {"type": "FUNCTION", "name": "COS", "arity": 1}, {"type": "FUNCTION", "name": "SIN", "arity": 1} ], "terminal_nodes": [ {"type": "CONSTANT", "value": 1.0}, {"type": "INPUT", "name": "x"}, {"type": "INPUT", "name": "y"}, {"type": "INPUT", "name": "z"} ], "input_variables": [ {"name": "x"}, {"name": "y"}, {"name": "z"} ] } self.t_parser = TreeParser() self.tree = Tree() node_x = Node(NodeType.INPUT, name="x") node_y = Node(NodeType.INPUT, name="y") node_z = Node(NodeType.INPUT, name="z") self.tree.input_nodes.append(node_x) self.tree.input_nodes.append(node_y) self.tree.input_nodes.append(node_z) def test_valid(self): # assert valid res = self.tree.valid(self.config["input_variables"]) self.assertTrue(res) # assert fail valid self.tree.input_nodes.pop() res = self.tree.valid(self.config["input_variables"]) self.assertFalse(res) def test_get_linked_node(self): # setup del self.tree.input_nodes[:] left_node = Node(NodeType.INPUT, name="x") right_node = Node(NodeType.INPUT, name="y") add_func = Node( NodeType.FUNCTION, name="ADD", arity=2, branches=[left_node, right_node] ) self.tree.root = add_func self.tree.program = self.t_parser.post_order_traverse(self.tree.root) # pass test linked_node = self.tree.get_linked_node(left_node) self.assertTrue(linked_node is add_func) linked_node = self.tree.get_linked_node(right_node) self.assertTrue(linked_node is add_func) # fail test random_node = Node(NodeType.INPUT, name="z") linked_node = self.tree.get_linked_node(random_node) self.assertFalse(linked_node is add_func) def test_replace_node(self): # setup node_x = Node(NodeType.INPUT, name="x") node_y = Node(NodeType.INPUT, name="y") add_func = Node( NodeType.FUNCTION, name="ADD", arity=2, branches=[node_x, node_y] ) # build tree tree = Tree() tree.root = add_func tree.update_program() # replace input node new_node = Node(NodeType.INPUT, name="z") before_replace = list(tree.program) tree.replace_node(node_x, new_node) after_replace = list(tree.program) # assert self.assertTrue(before_replace == before_replace) self.assertTrue(after_replace == after_replace) self.assertFalse(before_replace == after_replace) self.assertTrue(add_func.branches[0] is new_node) def test_equal(self): # create nodes left_node_1 = Node(NodeType.CONSTANT, value=1.0) right_node_1 = Node(NodeType.CONSTANT, value=2.0) left_node_2 = Node(NodeType.CONSTANT, value=3.0) right_node_2 = Node(NodeType.CONSTANT, value=4.0) cos_func_1 = Node( NodeType.FUNCTION, name="COS", arity=1, branches=[left_node_1] ) sin_func_1 = Node( NodeType.FUNCTION, name="SIN", arity=1, branches=[right_node_1] ) cos_func_2 = Node( NodeType.FUNCTION, name="COS", arity=1, branches=[left_node_2] ) sin_func_2 = Node( NodeType.FUNCTION, name="SIN", arity=1, branches=[right_node_2] ) add_func = Node( NodeType.FUNCTION, name="ADD", arity=2, branches=[cos_func_1, sin_func_1] ) sub_func = Node( NodeType.FUNCTION, name="SUB", arity=2, branches=[sin_func_2, cos_func_2] ) # create tree_1 tree_1 = Tree() tree_1.root = add_func tree_1.update() # create tree_2 tree_2 = Tree() tree_2.root = sub_func tree_2.update() self.assertTrue(tree_1.equals(tree_1)) self.assertFalse(tree_1.equals(tree_2)) self.assertTrue(tree_2.equals(tree_2)) self.assertFalse(tree_2.equals(tree_1)) def test_str(self): # setup del self.tree.input_nodes[:] left_node = Node(NodeType.INPUT, name="x") right_node = Node(NodeType.INPUT, name="y") add_func = Node( NodeType.FUNCTION, name="ADD", arity=2, branches=[left_node, right_node] ) self.tree.root = add_func self.tree.program = self.t_parser.post_order_traverse(self.tree.root) # assert self.assertEquals(str(self.tree), "(x ADD y)")
def setUp(self): random.seed(10) self.config = { "max_population": 10, "tree_generation": { "method": "FULL_METHOD", "initial_max_depth": 4 }, "function_nodes": [ {"type": "FUNCTION", "name": "ADD", "arity": 2}, {"type": "FUNCTION", "name": "SUB", "arity": 2}, {"type": "FUNCTION", "name": "MUL", "arity": 2}, {"type": "FUNCTION", "name": "DIV", "arity": 2}, {"type": "FUNCTION", "name": "COS", "arity": 1}, {"type": "FUNCTION", "name": "SIN", "arity": 1} ], "terminal_nodes": [ {"type": "CONSTANT", "value": 1.0}, {"type": "INPUT", "name": "x"}, {"type": "INPUT", "name": "y"}, {"type": "INPUT", "name": "z"} ], "input_variables": [ {"name": "x"}, {"name": "y"}, {"name": "z"} ] } self.functions = GPFunctionRegistry("SYMBOLIC_REGRESSION") self.generator = TreeGenerator(self.config) self.parser = TreeParser() # create nodes left_node = Node(NodeType.CONSTANT, value=1.0) right_node = Node(NodeType.CONSTANT, value=2.0) cos_func = Node( NodeType.FUNCTION, name="COS", arity=1, branches=[left_node] ) sin_func = Node( NodeType.FUNCTION, name="SIN", arity=1, branches=[right_node] ) add_func = Node( NodeType.FUNCTION, name="ADD", arity=2, branches=[cos_func, sin_func] ) # create tree self.tree = Tree() self.tree.root = add_func self.tree.update_program() self.tree.update_func_nodes() self.tree.update_term_nodes()
class TreeParserTests(unittest.TestCase): def setUp(self): random.seed(10) self.config = { "max_population": 10, "tree_generation": { "method": "FULL_METHOD", "initial_max_depth": 4 }, "function_nodes": [ {"type": "FUNCTION", "name": "ADD", "arity": 2}, {"type": "FUNCTION", "name": "SUB", "arity": 2}, {"type": "FUNCTION", "name": "MUL", "arity": 2}, {"type": "FUNCTION", "name": "DIV", "arity": 2}, {"type": "FUNCTION", "name": "COS", "arity": 1}, {"type": "FUNCTION", "name": "SIN", "arity": 1} ], "terminal_nodes": [ {"type": "CONSTANT", "value": 1.0}, {"type": "INPUT", "name": "x"}, {"type": "INPUT", "name": "y"}, {"type": "INPUT", "name": "z"} ], "input_variables": [ {"name": "x"}, {"name": "y"}, {"name": "z"} ] } self.functions = GPFunctionRegistry("SYMBOLIC_REGRESSION") self.generator = TreeGenerator(self.config) self.parser = TreeParser() # create nodes left_node = Node(NodeType.CONSTANT, value=1.0) right_node = Node(NodeType.CONSTANT, value=2.0) cos_func = Node( NodeType.FUNCTION, name="COS", arity=1, branches=[left_node] ) sin_func = Node( NodeType.FUNCTION, name="SIN", arity=1, branches=[right_node] ) add_func = Node( NodeType.FUNCTION, name="ADD", arity=2, branches=[cos_func, sin_func] ) # create tree self.tree = Tree() self.tree.root = add_func self.tree.update_program() self.tree.update_func_nodes() self.tree.update_term_nodes() def tearDown(self): del self.config del self.generator del self.parser def test_parse_tree(self): # self.parser.print_tree(tree.root) program = self.parser.parse_tree(self.tree, self.tree.root) for i in program: if i.name is not None: print i.name else: print i.value self.assertEquals(self.tree.size, 5) self.assertEquals(self.tree.depth, 2) self.assertEquals(len(self.tree.func_nodes), 2) self.assertEquals(len(self.tree.term_nodes), 2) self.assertEquals(len(self.tree.input_nodes), 0) def test_parse_equation(self): # self.parser.print_tree(tree.root) equation = self.parser.parse_equation(self.tree.root) self.assertEquals(equation, "((COS(1.0)) ADD (SIN(2.0)))") def test_tree_to_dict(self): solution = { 'program': [ {'type': 'CONSTANT', 'value': 1.0}, {'arity': 1, 'type': 'FUNCTION', 'name': 'COS'}, {'type': 'CONSTANT', 'value': 2.0}, {'arity': 1, 'type': 'FUNCTION', 'name': 'SIN'}, {'arity': 2, 'type': 'FUNCTION', 'root': True, 'name': 'ADD'} ] } results = self.parser.tree_to_dict(self.tree, self.tree.root) self.assertEquals(results["program"], solution["program"])
def setUp(self): self.config = { "max_population": 10, "tree_generation": { "method": "FULL_METHOD", "initial_max_depth": 4 }, "function_nodes": [{ "type": "FUNCTION", "name": "ADD", "arity": 2 }, { "type": "FUNCTION", "name": "SUB", "arity": 2 }, { "type": "FUNCTION", "name": "MUL", "arity": 2 }, { "type": "FUNCTION", "name": "DIV", "arity": 2 }, { "type": "FUNCTION", "name": "COS", "arity": 1 }, { "type": "FUNCTION", "name": "SIN", "arity": 1 }], "terminal_nodes": [{ "type": "CONSTANT", "value": 1.0 }, { "type": "INPUT", "name": "x" }, { "type": "INPUT", "name": "y" }, { "type": "INPUT", "name": "z" }], "input_variables": [{ "name": "x" }, { "name": "y" }, { "name": "z" }] } self.t_parser = TreeParser() self.tree = Tree() node_x = Node(NodeType.INPUT, name="x") node_y = Node(NodeType.INPUT, name="y") node_z = Node(NodeType.INPUT, name="z") self.tree.input_nodes.append(node_x) self.tree.input_nodes.append(node_y) self.tree.input_nodes.append(node_z)
class TreeTests(unittest.TestCase): def setUp(self): self.config = { "max_population": 10, "tree_generation": { "method": "FULL_METHOD", "initial_max_depth": 4 }, "function_nodes": [{ "type": "FUNCTION", "name": "ADD", "arity": 2 }, { "type": "FUNCTION", "name": "SUB", "arity": 2 }, { "type": "FUNCTION", "name": "MUL", "arity": 2 }, { "type": "FUNCTION", "name": "DIV", "arity": 2 }, { "type": "FUNCTION", "name": "COS", "arity": 1 }, { "type": "FUNCTION", "name": "SIN", "arity": 1 }], "terminal_nodes": [{ "type": "CONSTANT", "value": 1.0 }, { "type": "INPUT", "name": "x" }, { "type": "INPUT", "name": "y" }, { "type": "INPUT", "name": "z" }], "input_variables": [{ "name": "x" }, { "name": "y" }, { "name": "z" }] } self.t_parser = TreeParser() self.tree = Tree() node_x = Node(NodeType.INPUT, name="x") node_y = Node(NodeType.INPUT, name="y") node_z = Node(NodeType.INPUT, name="z") self.tree.input_nodes.append(node_x) self.tree.input_nodes.append(node_y) self.tree.input_nodes.append(node_z) def test_valid(self): # assert valid res = self.tree.valid(self.config["input_variables"]) self.assertTrue(res) # assert fail valid self.tree.input_nodes.pop() res = self.tree.valid(self.config["input_variables"]) self.assertFalse(res) def test_get_linked_node(self): # setup del self.tree.input_nodes[:] left_node = Node(NodeType.INPUT, name="x") right_node = Node(NodeType.INPUT, name="y") add_func = Node(NodeType.FUNCTION, name="ADD", arity=2, branches=[left_node, right_node]) self.tree.root = add_func self.tree.program = self.t_parser.post_order_traverse(self.tree.root) # pass test linked_node = self.tree.get_linked_node(left_node) self.assertTrue(linked_node is add_func) linked_node = self.tree.get_linked_node(right_node) self.assertTrue(linked_node is add_func) # fail test random_node = Node(NodeType.INPUT, name="z") linked_node = self.tree.get_linked_node(random_node) self.assertFalse(linked_node is add_func) def test_replace_node(self): # setup node_x = Node(NodeType.INPUT, name="x") node_y = Node(NodeType.INPUT, name="y") add_func = Node(NodeType.FUNCTION, name="ADD", arity=2, branches=[node_x, node_y]) # build tree tree = Tree() tree.root = add_func tree.update_program() # replace input node new_node = Node(NodeType.INPUT, name="z") before_replace = list(tree.program) tree.replace_node(node_x, new_node) after_replace = list(tree.program) # assert self.assertTrue(before_replace == before_replace) self.assertTrue(after_replace == after_replace) self.assertFalse(before_replace == after_replace) self.assertTrue(add_func.branches[0] is new_node) def test_equal(self): # create nodes left_node_1 = Node(NodeType.CONSTANT, value=1.0) right_node_1 = Node(NodeType.CONSTANT, value=2.0) left_node_2 = Node(NodeType.CONSTANT, value=3.0) right_node_2 = Node(NodeType.CONSTANT, value=4.0) cos_func_1 = Node(NodeType.FUNCTION, name="COS", arity=1, branches=[left_node_1]) sin_func_1 = Node(NodeType.FUNCTION, name="SIN", arity=1, branches=[right_node_1]) cos_func_2 = Node(NodeType.FUNCTION, name="COS", arity=1, branches=[left_node_2]) sin_func_2 = Node(NodeType.FUNCTION, name="SIN", arity=1, branches=[right_node_2]) add_func = Node(NodeType.FUNCTION, name="ADD", arity=2, branches=[cos_func_1, sin_func_1]) sub_func = Node(NodeType.FUNCTION, name="SUB", arity=2, branches=[sin_func_2, cos_func_2]) # create tree_1 tree_1 = Tree() tree_1.root = add_func tree_1.update() # create tree_2 tree_2 = Tree() tree_2.root = sub_func tree_2.update() self.assertTrue(tree_1.equals(tree_1)) self.assertFalse(tree_1.equals(tree_2)) self.assertTrue(tree_2.equals(tree_2)) self.assertFalse(tree_2.equals(tree_1)) def test_str(self): # setup del self.tree.input_nodes[:] left_node = Node(NodeType.INPUT, name="x") right_node = Node(NodeType.INPUT, name="y") add_func = Node(NodeType.FUNCTION, name="ADD", arity=2, branches=[left_node, right_node]) self.tree.root = add_func self.tree.program = self.t_parser.post_order_traverse(self.tree.root) # assert self.assertEquals(str(self.tree), "(x ADD y)")