Ejemplo n.º 1
0
    def test_compare_random_individuals(self):
        individual_1 = Individual.generate(individual_type=3,
                                           config=Config.get_instance())

        RandomManager.clear_random_values()
        RandomManager.load_random_values(self._random_file)
        individual_2 = Individual.generate(individual_type=3,
                                           config=Config.get_instance())

        self.assertTrue(individual_1.compare(individual_2))
Ejemplo n.º 2
0
    def setUpClass(cls):
        config_file = os.path.join(MLCIntegrationTest.TEST_DIRECTORY,
                                   './configuration.ini')
        ev_script = os.path.join(MLCIntegrationTest.TEST_DIRECTORY,
                                 './default_evaluation_script.py')
        preev_script = os.path.join(MLCIntegrationTest.TEST_DIRECTORY,
                                    './default_preevaluation_script.py')

        # Load the config
        config = Config.get_instance()
        config.read(config_file)

        # Load randoms from file
        random_file = 'matlab_randoms.txt'
        RandomManager.clear_random_values()
        RandomManager.load_random_values(random_file)

        # Create the workspace directory
        try:
            os.makedirs(MLCIntegrationTest.WORKSPACE_DIR)
        except OSError:
            shutil.rmtree(MLCIntegrationTest.WORKSPACE_DIR)
            os.makedirs(MLCIntegrationTest.WORKSPACE_DIR)

        # Create a new experiment, which will be used to
        cls._mlc = MLCLocal(working_dir=MLCIntegrationTest.WORKSPACE_DIR)
        cls._mlc.new_experiment(
            experiment_name=MLCIntegrationTest.EXPERIMENT_NAME,
            experiment_configuration=config_file,
            evaluation_script=ev_script,
            preevaluation_script=preev_script)
        cls._mlc.open_experiment(
            experiment_name=MLCIntegrationTest.EXPERIMENT_NAME)

        for generation_params in MLCIntegrationTest.GENERATIONS:
            if isinstance(generation_params, int):
                cls._mlc.go(experiment_name=MLCIntegrationTest.EXPERIMENT_NAME,
                            to_generation=generation_params)

            elif isinstance(generation_params, list):
                cls._mlc.go(experiment_name=MLCIntegrationTest.EXPERIMENT_NAME,
                            from_generation=generation_params[0],
                            to_generation=generation_params[1])

            else:
                raise Exception(
                    "Integration test, bad value for generations param")

        # List with individuals data
        cls._indivs = []
        cls._populate_indiv_dict()

        cls._pops = []
        cls._populate_pop_dict()
Ejemplo n.º 3
0
def main():
    # MATLAB random numbers, used in integration tests
    RandomManager.load_random_values(
        "./tests/integration_tests/matlab_randoms.txt")

    # load configuration
    config = initialize_config()

    # set logger
    log_mode = config.get('LOGGING', 'logmode')
    set_logger(log_mode)

    simulation = Simulation()
    mlc = Application(simulation)
    mlc.go(to_generation=3, display_best=False)
    raw_input("Press enter to continue...")
Ejemplo n.º 4
0
    def choose_genetic_operation(amount_indivs_left, prob_rep, prob_mut,
                                 prob_cro):
        if (prob_rep + prob_cro + prob_mut) != 1:
            # FIXME: This validation should be done at the beggining of the program
            lg.logger_.error(
                "[POPULATION] Probabilities of genetic operations are not "
                "equal to one. Please adjust and relaunch")
            sys.exit(-1)

        op = None
        rand_prob = RandomManager.rand()
        if amount_indivs_left < 2:
            # Crossover is not possible
            rand_prob *= (prob_rep + prob_mut)
            if rand_prob <= prob_rep:
                op = Population.GeneticOperation.REPLICATION
            else:
                op = Population.GeneticOperation.MUTATION
        else:
            if rand_prob <= prob_rep:
                op = Population.GeneticOperation.REPLICATION
            elif rand_prob > prob_rep and (rand_prob <= (prob_mut + prob_rep)):
                op = Population.GeneticOperation.MUTATION
            else:
                op = Population.GeneticOperation.CROSSOVER

        return op
Ejemplo n.º 5
0
    def setUp(self):
        set_logger("testing")

        # Load randoms from file
        random_file = './mlc/unit_matlab_randoms.txt'
        RandomManager.clear_random_values()
        RandomManager.load_random_values(random_file)

        config = Config.get_instance()
        config.read(
            os.path.join(mlc_config_path.get_test_path(),
                         'mlc/individual/configuration.ini'))

        self._individual_l0 = Individual("(root (cos 5.046))")
        self._individual_l1 = Individual(
            "(root (log (sin (exp (tanh 3.6284)))))")
        self._individual_l2 = Individual(
            "(root (cos (* (+ (* -1.912 -9.178) (cos S0)) 3.113)))")
        self._individual_l3 = Individual(
            "(root (log (/ (* (sin 4.37) (- -8.815 -3.902)) (log (+ 2.025 -8.685)))))"
        )
        self._individual_l4 = Individual("(root S0)")
Ejemplo n.º 6
0
    def _choose_individual(self, subgen_range):
        selection_method = self._config.get("OPTIMIZATION", "selectionmethod")

        if selection_method == "tournament":
            tournament_size = self._config.getint("OPTIMIZATION",
                                                  "tournamentsize")
            # Get randomly as many individuals as tournament_size property is set
            indivs_chosen = []
            subgen_len = subgen_range[1] - subgen_range[0] + 1

            # FIXME: What happen if the size of the tournament is greater
            # than the amount of individuals in the subgeneration?. Ask Thomas

            for i in range(tournament_size):
                # FIXME: This is soooo wrong. The individuals obtained will be always the ones
                # in the first subgeneration. That's because we are working with the length of the
                # subgeneration instead of the indexes
                random_indiv = -1
                while random_indiv == -1 or random_indiv in indivs_chosen:
                    random_indiv = math.ceil(
                        RandomManager.rand() * subgen_len) - 1
                indivs_chosen.append(int(random_indiv))

            # Got the random indivs. Grab the one with the minor cost
            cost = float('inf')
            indiv_chosen = None
            for index in indivs_chosen:
                if self._costs[index] < cost:
                    cost = self._costs[index]
                    indiv_chosen = index

            return indiv_chosen
        else:
            # FIXME: This validation must be done at the beginning of the program
            lg.logger_.error(
                "[POPULATION] choose_individual: Invalid selection method."
                "Correct it and relaunch the program.")
            sys.exit(-1)
Ejemplo n.º 7
0
    def __extract_subtree(self, expression_tree, mindepth, subtreedepthmax,
                          maxdepth):
        candidates = []
        for node in expression_tree.internal_nodes():
            if mindepth <= node.get_depth() <= maxdepth:
                if node.get_subtreedepth() <= subtreedepthmax:
                    candidates.append(node)

        if not candidates:
            raise TreeException(
                "No subtrees to extract from '%s' "
                "with mindepth=%s, maxdepth=%s, subtreedepthmax=%s" %
                (expression_tree, mindepth, maxdepth, subtreedepthmax))

        candidates.sort(key=lambda x: x.get_expr_index(), reverse=False)
        n = int(np.ceil(RandomManager.rand() * len(candidates))) - 1
        extracted_node = candidates[n]
        index = extracted_node.get_expr_index()
        old_value = expression_tree.get_expanded_tree_as_string()
        new_value = old_value[:index] + old_value[index:].replace(
            extracted_node.to_string(), '@', 1)
        return new_value, extracted_node.to_string(
        ), extracted_node.get_subtreedepth()
Ejemplo n.º 8
0
 def _load_random_values(self):
     RandomManager.clear_random_values()
     RandomManager.load_random_values(MLCWorkspaceTest.FILE_WITH_RANDOMS)
Ejemplo n.º 9
0
    def __generate_indiv_regressive_tree(value, config, indiv_type):
        min_depth = 0
        max_depth = 0
        new_value = ""

        # Maxdepthfirst change while we are creating the first population
        if indiv_type:
            if indiv_type == 1:
                min_depth = Individual._maxdepthfirst
                max_depth = Individual._maxdepthfirst
            elif indiv_type == 2 or indiv_type == 3:
                min_depth = int(config.get('GP', 'mindepth'))
                max_depth = Individual._maxdepthfirst
            elif indiv_type == 4:
                min_depth = int(config.get('GP', 'mindepth'))
                max_depth = 1
            else:
                min_depth = int(config.get('GP', 'mindepth'))
                max_depth = int(config.get('GP', 'maxdepth'))

        else:
            min_depth = int(config.get('GP', 'mindepth'))
            max_depth = int(config.get('GP', 'maxdepth'))

        # Check if the seed character is in the string
        index = value.find('@')
        if index == -1:
            return None

        # Split the value in two strings, not containing the first seed character
        begin_str = value[:index]
        end_str = value[index + 1:]

        # Count the amounts of '(' until the first seed character (This is the depth of the seed)
        counter = Counter(begin_str)
        begin_depth = counter['('] - counter[')']

        leaf_node = False
        if begin_depth >= max_depth:
            leaf_node = True
        elif (begin_depth < min_depth
              and end_str.find('@') == -1) or indiv_type == 3:
            leaf_node = False
        else:
            leaf_node = RandomManager.rand() < config.getfloat(
                'POPULATION', 'leaf_prob')

        if leaf_node:
            use_sensor = RandomManager.rand() < config.getfloat(
                'POPULATION', 'sensor_prob')
            if use_sensor:
                sensor_number = math.ceil(RandomManager.rand() * config.getint(
                    'POPULATION', 'sensors')) - 1
                new_value = begin_str + 'z' + str(sensor_number).rstrip(
                    '0').rstrip('.') + end_str
            else:
                range = config.getfloat('POPULATION', 'range')
                precision = config.get('POPULATION', 'precision')
                # Generate a float number between -range and +range with a precision of 'precision'
                new_exp = (("%." + precision + "f") %
                           ((RandomManager.rand() - 0.5) * 2 * range))
                new_value = begin_str + new_exp + end_str
        else:
            # Create a node
            op_num = math.ceil(RandomManager.rand() *
                               Operations.get_instance().length())
            op = Operations.get_instance().get_operation_from_op_num(op_num)
            if (op["nbarg"] == 1):
                new_value = begin_str + '(' + op["op"] + ' @)' + end_str
                new_value = Individual.__generate_indiv_regressive_tree(
                    new_value, config, indiv_type)
            else:
                # nbrag == 2
                new_value = begin_str + '(' + op["op"] + ' @ @)' + end_str
                new_value = Individual.__generate_indiv_regressive_tree(
                    new_value, config, indiv_type)
                new_value = Individual.__generate_indiv_regressive_tree(
                    new_value, config, indiv_type)
        return new_value
Ejemplo n.º 10
0
 def leaf_value_generator():
     leaf_value = (RandomManager.rand() - 0.5) * 2 * self._range
     return "%0.*f" % (self._precision, leaf_value)
Ejemplo n.º 11
0
    def __mutate_tree(self, mutation_type):
        mutmindepth = self._config.getint("GP", "mutmindepth")
        maxdepth = self._config.getint("GP", "maxdepth")
        sensor_spec = self._config.getboolean("POPULATION", "sensor_spec")
        sensors = self._config.getint("POPULATION", 'sensors')
        mutation_types = self._config.get_list("GP", 'mutation_types')

        # equi probability for each mutation type selected.
        if mutation_type == Individual.MutationType.ANY:
            rand_number = RandomManager.rand()
            mutation_type = mutation_types[int(
                np.floor(rand_number * len(mutation_types)))]

        if mutation_type in [
                Individual.MutationType.REMOVE_SUBTREE_AND_REPLACE,
                Individual.MutationType.SHRINK
        ]:
            new_individual_value = None
            preevok = False
            while not preevok:
                # remove subtree and grow new subtree
                try:
                    subtree, _, _ = self.__extract_subtree(
                        self._tree, mutmindepth, maxdepth, maxdepth)
                    if mutation_type == Individual.MutationType.REMOVE_SUBTREE_AND_REPLACE:
                        next_individual_type = 0
                    else:
                        next_individual_type = 4

                    new_individual_value = Individual.__generate_indiv_regressive_tree(
                        subtree, self._config, next_individual_type)

                    if new_individual_value:
                        if sensor_spec:
                            config_sensor_list = sorted(
                                self._config.get_list('POPULATION',
                                                      'sensor_list'))
                        else:
                            config_sensor_list = range(sensors - 1, -1, -1)

                        for i in range(len(config_sensor_list)):
                            new_individual_value = new_individual_value.replace(
                                "z%d" % i, "S%d" % config_sensor_list[i])

                        # Preevaluate the Individual
                        preevok = self._preevaluate_individual(
                            new_individual_value)
                    else:
                        raise TreeException()

                except TreeException:
                    raise TreeException(
                        "[MUTATE_TREE] A non subtractable Individual was generated. "
                        "Individual: {0}".format(
                            self._tree.get_expanded_tree_as_string()))

            return new_individual_value

        elif mutation_type == Individual.MutationType.REPARAMETRIZATION:
            new_individual_value = None
            preevok = False
            while not preevok:
                new_individual_value = self.__reparam_tree(
                    LispTreeExpr(self.get_value()))
                preevok = self._preevaluate_individual(new_individual_value)

            return new_individual_value

        elif mutation_type == Individual.MutationType.HOIST:
            preevok = False
            counter = 0
            maxtries = self._config.getint("GP", "maxtries")

            while not preevok and counter < maxtries:
                counter += 1
                controls = self._config.getint("POPULATION", "controls")
                prob_threshold = 1 / float(controls)

                cl = [
                    stree.to_string()
                    for stree in self.get_tree().get_root_node()._nodes
                ]

                changed = False
                k = 0

                for nc in RandomManager.randperm(controls):
                    k += 1
                    # control law is cropped if it is the last one and no change happend before
                    if (RandomManager.rand() <
                            prob_threshold) or (k == controls and not changed):

                        try:
                            _, sm, _ = self.__extract_subtree(
                                LispTreeExpr('(root ' + cl[nc - 1] + ')'),
                                mutmindepth + 1, maxdepth, maxdepth + 1)
                            cl[nc - 1] = sm
                            changed = True

                        except TreeException:
                            changed = False

                new_individual_value = "(root %s)" % " ".join(cl[:controls])
                preevok = self._preevaluate_individual(new_individual_value)

            if counter == maxtries:
                raise TreeException(
                    "[MUTATE HOIST] Candidate could not found a "
                    "substitution {0} tests".format(maxtries))

            return new_individual_value
        else:
            raise NotImplementedError("Mutation type %s not implemented" %
                                      mutation_type)