Exemple #1
0
    def mutation(self, old_pop, gen):
        new_pop = []
        # three different mutation method
        for p in old_pop:
            mut_option = np.random.randint(1, 2)
            if mut_option == 1:
                # first mutation method: regular binary mutation
                bit_string, mutated = self.mutation_bin(p)
            elif mut_option == 2:
                # second mutation method: shuffle the indv phases order
                bit_string, mutated = self.mutation_shuffle(p)

            new_pop.append(
                nsga2_individual.IndividualEDNN(bit_string, self.n_phases,
                                                self.n_nodes))
            new_pop[-1].id = "{}_{}".format(gen, len(new_pop) - 1)

            if mutated:
                new_pop[-1].mut_option = mut_option
                new_pop[-1].parents.append(p)
            else:
                for parent in p.parents:
                    new_pop[-1].parents.append(parent)

        return new_pop
Exemple #2
0
    def crossover(self, parent1, parent2):
        p1_bit_string = np.concatenate(
            [np.array(i) for i in parent1.bit_string])
        p2_bit_string = np.concatenate(
            [np.array(i) for i in parent2.bit_string])
        common_bits = (p1_bit_string - p2_bit_string) == 0
        child_base = np.zeros((len(p1_bit_string), ), dtype=np.int)
        child_base[common_bits] = p1_bit_string[common_bits]
        compl = np.array([np.sum(p1_bit_string),
                          np.sum(p2_bit_string)]) - np.sum(child_base)
        compl_lb, compl_ub = np.amin(compl), np.amax(compl)
        # assuming create two offspring from two parents
        offspring = []
        for i in range(2):
            # 1 blend of two parents
            if np.random.rand() < 1.5:
                child_bit_string = np.copy(child_base)
                idx, = np.where(common_bits == False)
                idx = np.random.permutation(idx)
                if compl_ub > compl_lb:
                    idx = idx[:np.random.randint(compl_lb, compl_ub)]
                else:
                    idx = idx[:compl_lb]
                child_bit_string[idx] = 1
                child_bit_string = self.convert_to_bit_string(child_bit_string)
            # 2 swap phases
            else:
                child_bit_string = []
                for j in range(self.n_phases):
                    if np.random.rand() < 0.5:
                        child_bit_string.append(parent1.bit_string[j])
                    else:
                        child_bit_string.append(parent2.bit_string[j])

            offspring.append(
                nsga2_individual.IndividualEDNN(child_bit_string,
                                                self.n_phases, self.n_nodes))
            # fill in details
            offspring[-1].cr = 1
            offspring[-1].parents.append(parent1)
            offspring[-1].parents.append(parent2)

        return offspring
Exemple #3
0
    def initialization(self):
        # two stages initialization
        config_archive = []  # initialize a empty unique config list
        # 1st stage: extract different unique phase configurations
        phase_length = int((self.n_nodes - 1) * self.n_nodes / 2 + 1)
        possible_phase_string = list(
            map(list, itertools.product([0, 1], repeat=phase_length)))
        # randomly shuffle the list
        np.random.shuffle(possible_phase_string)

        for phase_string in possible_phase_string:
            config_archive = self.update_config_archive(
                phase_string, config_archive, self.n_nodes)
            # terminate the loop if the desired number of unique phase configuration is reached
            if len(config_archive) >= self.pop_size * self.n_phases:
                break

        # 2nd stage: assemble these phase config together
        pop = []
        idx = np.random.permutation(len(config_archive))
        # check if found phase config is enough for creating initial population
        while len(idx) < self.pop_size * self.n_phases:
            idx = np.append(idx, np.random.permutation(len(config_archive)))

        idx = idx[:self.pop_size * self.n_phases]
        idx = idx.tolist()

        for i in range(0, len(idx), self.n_phases):
            bit_string, conn = [], []
            for j in range(self.n_phases):
                conn.append(idx[i + j])
                bit_string.append(config_archive[idx[i + j]].bit_string)
            pop.append(
                nsga2_individual.IndividualEDNN(bit_string, self.n_phases,
                                                self.n_nodes))
            pop[-1].phase_connection = conn
            pop[-1].pt = 1
            pop[-1].id = "{}_{}".format(0, len(pop) - 1)

        return pop, config_archive
Exemple #4
0
    def heuristic_recombination(self, pop, config_archive, pop_archive):
        if len(pop) < self.pop_size:
            max_trail = 20  # set the maximum trails to avoid infinite loop
            pop_bayesian = self.fill_nondominated_sort(
                pop_archive, int(len(pop_archive) / 2))

            for i in range(len(pop), self.pop_size):
                trial = 1
                while True:
                    conn = self.sample_conn_from_bayesian(pop_bayesian)
                    duplicate = False  # assumes this conn is not duplicate
                    # 1st check if conn exists in current population
                    for p in pop:
                        if p.phase_connection == conn:
                            duplicate = True
                            break
                    # 2nd check if conn exists in population archive
                    for member in pop_archive:
                        if member.phase_connection == conn:
                            duplicate = True
                            break
                    if (not duplicate) or (trial > max_trail):
                        break
                    # print(trial)
                    trial += 1

                if not duplicate:
                    bit_string = []
                    for phase in range(len(conn)):
                        # for c in conn:
                        bit_string.append(
                            config_archive[conn[phase]].bit_string)
                    pop.append(
                        nsga2_individual.IndividualEDNN(
                            bit_string, self.n_phases, self.n_nodes))
                    pop[-1].phase_connection = conn
                    trial = 0
                    pop[-1].cr = 0

        return pop