Exemplo n.º 1
0
    def _mut_shift(self, genotype, ling_var_genotype_range):
        logging.debug("Mut shift")
        (start_idx, num_alleles) = ling_var_genotype_range
        end_idx_exclusive = (start_idx + num_alleles)
        # shift flips a randomly chosen one to a zero then
        # sets either the allele before or after to a one depending on what
        # is possible
        one_allele_idxs = [
            idx for idx in range(start_idx, end_idx_exclusive)
            if genotype[idx] == 1
        ]
        assert len(one_allele_idxs) >= 1
        idx_to_flip = get_rng().choice(one_allele_idxs)
        genotype[idx_to_flip] = 0

        # get info about adjacent alleles of the ling var
        prev_idx = max(start_idx, (idx_to_flip - 1))
        end_idx_inclusive = (end_idx_exclusive - 1)
        next_idx = min(end_idx_inclusive, (idx_to_flip + 1))

        # pick an adjacent allele to set to 1
        if prev_idx == start_idx:
            # edge case, allele flipped to zero originally is first one in seq.
            # for ling var, so set the allele to the right of it to one
            idx_for_one = next_idx
        elif next_idx == end_idx_inclusive:
            # edge case, allele flipped to zero originally is last one in seq.
            # for ling var, so set the allele to the left of it to one
            idx_for_one = prev_idx
        else:
            # nominal case, allele flipped to zero originally not at
            # boundaries, pick either prev or next allele at random to set to
            # one
            idx_for_one = get_rng().choice([prev_idx, next_idx])
        genotype[idx_for_one] = 1
Exemplo n.º 2
0
 def mutate_condition(self, condition, situation=None):
     genotype = condition.genotype
     for allele_idx in range(len(genotype)):
         should_mutate = get_rng().rand() < get_hyperparam("mu")
         if should_mutate:
             mutation_magnitude = get_rng().uniform(0, get_hyperparam("m"))
             mutation_sign = get_rng().choice([1, -1])
             mutation_amount = mutation_magnitude * mutation_sign
             genotype[allele_idx] += mutation_amount
     self._enforce_genotype_maps_to_valid_phenotype(genotype)
Exemplo n.º 3
0
 def mutate_condition(self, condition, situation=None):
     genotype = condition.genotype
     for allele_idx in range(len(genotype)):
         should_mutate = get_rng().rand() < get_hyperparam("mu")
         if should_mutate:
             # mutation draws from +-[0, m_nought)
             m_nought = get_hyperparam("m_nought")
             assert m_nought > 0
             mut_choices = range(0, m_nought)
             mutation_magnitude = get_rng().choice(mut_choices)
             mutation_sign = get_rng().choice([1, -1])
             mutation_amount = mutation_magnitude * mutation_sign
             genotype[allele_idx] += mutation_amount
     self._enforce_genotype_maps_to_valid_phenotype(genotype)
Exemplo n.º 4
0
def make_fuzzy_linear_prediction_classifier(rule, time_step):
    return FuzzyLinearPredictionClassifier(rule, get_hyperparam("epsilon_I"),
                                           get_hyperparam("fitness_I"),
                                           time_step,
                                           get_hyperparam("x_nought"),
                                           get_hyperparam("delta_rls"),
                                           get_rng())
Exemplo n.º 5
0
def _select_random_action_with_valid_prediction(prediction_array):
    if len(prediction_array) != 0:
        possible_actions = prediction_array.keys()
        return get_rng().choice(list(possible_actions))
    else:
        return _fallback_to_random_selection_from_action_set(
            prediction_array.env_action_set)
Exemplo n.º 6
0
def _epsilon_greedy(prediction_array, epsilon):
    logging.debug(f"Epsilon = {epsilon}")
    assert 0.0 <= epsilon <= 1.0
    should_explore = get_rng().rand() <= epsilon
    if should_explore:
        action = \
            _select_random_action_with_valid_prediction(prediction_array)
    else:
        action = select_greedy_action(prediction_array)
    return ActionSelectResponse(action=action, did_explore=should_explore)
Exemplo n.º 7
0
    def __call__(self, operating_set):
        """SELECT OFFSPRING function from 'An Algorithmic Description of XCS'
        (Butz and Wilson, 2002)."""
        fitness_sum = sum([classifier.fitness for classifier in operating_set])
        choice_point = get_rng().rand() * fitness_sum

        fitness_sum = 0
        for classifier in operating_set:
            fitness_sum += classifier.fitness
            if fitness_sum > choice_point:
                return classifier
Exemplo n.º 8
0
 def gen_covering_condition(self, situation):
     alleles = []
     for (idx, situation_elem) in enumerate(situation):
         lower = situation_elem - get_rng().uniform(
             0, get_hyperparam("s_nought"))
         upper = situation_elem + get_rng().uniform(
             0, get_hyperparam("s_nought"))
         dimension = self._situation_space[idx]
         lower = truncate_val(lower,
                              lower_bound=dimension.lower,
                              upper_bound=dimension.upper)
         upper = truncate_val(upper,
                              lower_bound=dimension.lower,
                              upper_bound=dimension.upper)
         assert lower <= upper
         frac_to_upper = self._calc_frac_to_upper(lower, upper,
                                                  dimension.upper)
         alleles.append(lower)
         alleles.append(frac_to_upper)
     genotype = Genotype(alleles)
     return Condition(genotype)
Exemplo n.º 9
0
 def _mut_contract(self, genotype, ling_var_genotype_range):
     logging.debug("Mut contract")
     (start_idx, num_alleles) = ling_var_genotype_range
     end_idx_exclusive = (start_idx + num_alleles)
     # contraction flips a randomly chosen one to a zero
     one_allele_idxs = [
         idx for idx in range(start_idx, end_idx_exclusive)
         if genotype[idx] == 1
     ]
     assert len(one_allele_idxs) >= 2
     idx_to_flip = get_rng().choice(one_allele_idxs)
     genotype[idx_to_flip] = 0
Exemplo n.º 10
0
 def _mut_expand(self, genotype, ling_var_genotype_range):
     logging.debug("Mut expand")
     (start_idx, num_alleles) = ling_var_genotype_range
     end_idx_exclusive = (start_idx + num_alleles)
     # expansion flips a randomly chosen zero to a one
     zero_allele_idxs = [
         idx for idx in range(start_idx, end_idx_exclusive)
         if genotype[idx] == 0
     ]
     assert len(zero_allele_idxs) >= 1
     idx_to_flip = get_rng().choice(zero_allele_idxs)
     genotype[idx_to_flip] = 1
Exemplo n.º 11
0
 def _perform_crossover(self, children, parents, situation):
     should_do_crossover = get_rng().rand() < get_hyperparam("chi")
     if should_do_crossover:
         (child_one, child_two) = children
         logging.debug(f"Before crossover {child_one.condition}, "
                       f"{child_two.condition}")
         self._rule_repr.crossover_conditions(child_one.condition,
                                              child_two.condition,
                                              self._crossover_strat)
         logging.debug(f"After crossover {child_one.condition}, "
                       f"{child_two.condition}")
         self._update_children_params(children, parents, situation)
Exemplo n.º 12
0
 def mutate_condition(self, condition, situation):
     """First part (condition mutation) of APPLY MUTATION function from 'An
     Algorithmic Description of XCS' (Butz and Wilson, 2002)."""
     genotype = condition.genotype
     for idx, (allele,
               situation_elem) in enumerate(zip(genotype, situation)):
         should_mutate_allele = get_rng().rand() < get_hyperparam("mu")
         if should_mutate_allele:
             if self._is_wildcard(allele):
                 genotype[idx] = situation_elem
             else:
                 genotype[idx] = self._WILDCARD_ALLELE
Exemplo n.º 13
0
 def gen_covering_condition(self, situation):
     alleles = []
     for (idx, situation_elem) in enumerate(situation):
         # covering draws from (0, r_nought)
         r_nought = get_hyperparam("r_nought")
         assert r_nought > 1
         cover_choices = range(1, r_nought)
         lower = situation_elem - get_rng().choice(cover_choices)
         upper = situation_elem + get_rng().choice(cover_choices)
         dimension = self._situation_space[idx]
         lower = truncate_val(lower,
                              lower_bound=dimension.lower,
                              upper_bound=dimension.upper)
         upper = truncate_val(upper,
                              lower_bound=dimension.lower,
                              upper_bound=dimension.upper)
         assert lower <= upper
         span_to_upper = self._calc_span_to_upper(lower, upper, dimension)
         alleles.append(lower)
         alleles.append(span_to_upper)
     genotype = Genotype(alleles)
     return Condition(genotype)
Exemplo n.º 14
0
    def _mutate_condition(self, condition):
        ling_var_genotype_ranges = self._get_ling_var_genotype_ranges()
        ling_var_idx_to_mut = get_rng().choice(range(len(self._ling_vars)))
        ling_var_genotype_range = ling_var_genotype_ranges[ling_var_idx_to_mut]

        mut_strat = self._choose_mut_strat_for_ling_var(
            condition.genotype, ling_var_genotype_range)
        if mut_strat == "expand":
            self._mut_expand(condition.genotype, ling_var_genotype_range)
        elif mut_strat == "contract":
            self._mut_contract(condition.genotype, ling_var_genotype_range)
        elif mut_strat == "shift":
            self._mut_shift(condition.genotype, ling_var_genotype_range)
        else:
            raise InternalError("Should not get here")
Exemplo n.º 15
0
 def gen_covering_condition(self, situation):
     """First part (condition generation) of
     GENERATE COVERING CLASSIFIER function from
     'An Algorithmic Description of XCS' (Butz and Wilson, 2002).
     """
     alleles = []
     for situation_elem in situation:
         should_make_wildcard = get_rng().rand() < get_hyperparam(
             "p_wildcard")
         if should_make_wildcard:
             alleles.append(self._WILDCARD_ALLELE)
         else:
             # copy situation
             alleles.append(situation_elem)
     genotype = Genotype(alleles)
     return Condition(genotype)
Exemplo n.º 16
0
 def _correct_crossover_res_if_necessary(self, genotype_before,
                                         genotype_after):
     ling_var_genotype_ranges = self._get_ling_var_genotype_ranges()
     for (start_idx, num_alleles) in ling_var_genotype_ranges:
         end_idx_exclusive = (start_idx + num_alleles)
         after_ling_var_alleles = genotype_after[
             start_idx:end_idx_exclusive]
         has_no_ones_after = after_ling_var_alleles.count(1) == 0
         if has_no_ones_after:
             one_allele_idxs_before = [
                 idx for idx in range(start_idx, end_idx_exclusive)
                 if genotype_before[idx] == 1
             ]
             assert len(one_allele_idxs_before) >= 1
             idx_for_one = get_rng().choice(one_allele_idxs_before)
             genotype_after[idx_for_one] = 1
Exemplo n.º 17
0
    def _select_for_deletion(self, population):
        """First loop (selecting classifier to delete) of
        DELETE FROM POPULATION function from 'An Algorithmic Description of
        XCS' (Butz and Wilson, 2002). 
        This method should only ever be called if the population
        is past its microclassifier capacity."""
        mean_fitness_in_pop = calc_summary_stat(population, "mean", "fitness")
        votes = [
            self._calc_deletion_vote(classifier, mean_fitness_in_pop)
            for classifier in population
        ]
        vote_sum = sum(votes)
        choice_point = get_rng().rand() * vote_sum

        vote_sum = 0
        for (classifier, vote) in zip(population, votes):
            vote_sum += vote
            if vote_sum > choice_point:
                return classifier
Exemplo n.º 18
0
    def _choose_mut_strat_for_ling_var(self, genotype,
                                       ling_var_genotype_range):
        ling_var_alleles = self._get_ling_var_alleles(genotype,
                                                      ling_var_genotype_range)

        # can always shift because it ensures needs at least a single one
        # allele present to operate and guarantees that at least a single one
        # allele remains afterwards
        possible_strats = ["shift"]
        # need at least a single zero allele to expand
        could_expand = ling_var_alleles.count(0) >= 1
        if could_expand:
            possible_strats.append("expand")
        # need at least two one alleles to contract so at least a single one
        # allele remains
        could_contract = ling_var_alleles.count(1) >= 2
        if could_contract:
            possible_strats.append("contract")

        mut_strat = get_rng().choice(possible_strats)
        return mut_strat
Exemplo n.º 19
0
 def __call__(self, first_vec, second_vec):
     assert len(first_vec) == len(second_vec)
     for swap_idx in range(0, len(first_vec)):
         should_swap = get_rng().rand() < get_hyperparam("upsilon")
         if should_swap:
             _swap_vec_elems(first_vec, second_vec, swap_idx)
Exemplo n.º 20
0
 def _choose_random_crossover_idxs(self, vec_len):
     num_idxs = 2
     return tuple([get_rng().randint(0, vec_len) for _ in range(num_idxs)])
Exemplo n.º 21
0
def _fallback_to_random_selection_from_action_set(env_action_set):
    logging.warning("Falling back to random action selection due to empty "
                    "prediction array.")
    return get_rng().choice(list(env_action_set))
Exemplo n.º 22
0
 def mutate_condition(self, condition, situation=None):
     should_do_mutation = get_rng().rand() < get_hyperparam("mu")
     if should_do_mutation:
         self._mutate_condition(condition)
         self._assert_genotype_is_valid(condition.genotype)
Exemplo n.º 23
0
 def _gen_covering_action(self, match_set):
     possible_covering_actions = \
         tuple(self._env_action_set - get_unique_actions_set(match_set))
     assert len(possible_covering_actions) > 0
     return get_rng().choice(possible_covering_actions)
Exemplo n.º 24
0
 def _select_random_classifier_from_set(self, operating_set):
     return get_rng().choice(list(operating_set))