Example #1
0
def test_simulation():
    w = World(4)

    w.populate(
        Individual(is_zombie = True),
        2, 1
    )

    w.populate(
        Individual(),
        1, 2
    )

    w.simulate(moves = "DLUURR")

    score, positions = w.get_stats()

    # One victim
    assert 1 == score

    # Two zombies
    assert 2 == len(positions)

    # First at (3, 0)
    assert 3 == positions[0]['x']
    assert 0 == positions[0]['y']

    # Second at (2, 1)
    assert 2 == positions[1]['x']
    assert 1 == positions[1]['y']
Example #2
0
    def populate(self,
                 individual: Individual,
                 x_coord: int = 0,
                 y_coord: int = 0) -> None:
        """ Populate the world with an individual.

        Args:
            individual (Individual) : Individual of the world. Either a zombie or victim.
            x_coord    (int)        : The position, x coordinate, of the individual
            y_coord    (int)        : The position, y coordinate, of the individual
        """

        # Save coordinates
        individual.x_coord = x_coord
        individual.y_coord = y_coord

        # Add to population
        self.population.append(individual)

        # Get the population index of this individual
        population_index = len(self.population) - 1

        # Place the individual on the map
        self.map[x_coord][y_coord] = population_index

        # Add zombie to the queue to action
        if (individual.is_zombie):
            self.__enqueue(individual)
def test_moves():
    individual = Individual(is_zombie=is_zombie,
                            x_coord=x,
                            y_coord=y,
                            moves=moves)
    for m in moves:
        assert m.lower() == individual.get_move()
def test_add_score():
    individual = Individual(is_zombie=is_zombie,
                            x_coord=x,
                            y_coord=y,
                            moves=moves)
    individual.add_score(10)

    assert individual.score == 10
Example #5
0
 def ConstructPopulation(self):
     for _ in range(self.m_PopulationCount):
         individual = Individual(self.m_StopsCount, self.m_RoadLength,
                                 self.m_MutationProbability,
                                 self.m_MinStopsDistance,
                                 self.m_MaxStopsDistance,
                                 self.m_bannedAreas)
         individual.CreateIndividual()
         self.m_Population.append(individual)
    def cabbage_growing(parent_1, parent_2):
        """
        скрещивание 2х особей
        :param parent_1: родитель1
        :param parent_2: родитель2
        :return: 2 потомка особей
        """

        # создание экземляров потомков
        son = Individual(GENE_LEN, gene_number)
        daughter = Individual(GENE_LEN, gene_number)
        if rnd.randint(0, 1):  # псевдоравномерное скрещивание

            daughter.ind_gene = "".join(parent_2)
            son.ind_gene = "".join([
                rnd.choices([parent_1, parent_2], [1, 1])[0][i]
                for i in range(GENE_LEN)
            ])

        else:  # создание 1 - точечного кроссовера

            border1 = rnd.randint(0, int(GENE_LEN // 2))
            #
            son.ind_gene = "".join(parent_1[:border1] + parent_2[border1:])
            daughter.ind_gene = "".join(parent_2[:(GENE_LEN - border1)] +
                                        parent_1[(GENE_LEN - border1):])

        return son, daughter
Example #7
0
    def TournamentSelection(self):
        usedStops = []
        newPopulation = []
        while len(usedStops) < self.m_PopulationCount:
            firstChallanger = random.randint(0, self.m_PopulationCount - 1)
            secondChallanger = random.randint(0, self.m_PopulationCount - 1)
            if (firstChallanger not in usedStops
                    and secondChallanger not in usedStops):
                usedStops.append(firstChallanger)
                usedStops.append(secondChallanger)
                if self.m_Population[
                        firstChallanger].m_Quality >= self.m_Population[
                            secondChallanger].m_Quality:
                    newPopulation.append(self.m_Population[firstChallanger])
                else:
                    newPopulation.append(self.m_Population[secondChallanger])

        self.m_Population = newPopulation

        for i in range(int(self.m_PopulationCount / 2),
                       self.m_PopulationCount):
            self.m_Population.append(
                Individual(self.m_StopsCount, self.m_RoadLength,
                           self.m_MutationProbability, self.m_MinStopsDistance,
                           self.m_MaxStopsDistance, self.m_bannedAreas))
            self.m_Population[i].CreateIndividual()
            self.m_Population[i].m_Quality = self.GoalFunction(
                self.m_Population[i])

        x = lambda a: a.m_Quality
        self.m_Population.sort(key=x)

        if self.m_Population[0].m_Quality < self.m_AlfaMale.m_Quality:
            self.m_AlfaMale.m_Chromosome = self.m_Population[0].m_Chromosome[:]
            self.m_AlfaMale.m_Quality = self.m_Population[0].m_Quality
Example #8
0
 def __init__(self,
              halfPopulationCount,
              roadLength,
              stopsCount,
              popularPlaces,
              mutationProbability=0.05,
              mutationMethod='mr',
              iterationCount=10000,
              minStopsDistance=2,
              maxStopsDistance=8,
              bannedAreas=[]):
     self.m_PopulationCount = 2 * halfPopulationCount
     self.m_RoadLength = roadLength
     self.m_StopsCount = stopsCount
     self.m_PopularPlaces = popularPlaces
     self.m_Population = []
     self.m_IterationCount = iterationCount
     self.m_MutationProbability = mutationProbability
     self.m_MutationMethod = mutationMethod
     self.m_MinStopsDistance = minStopsDistance
     self.m_MaxStopsDistance = maxStopsDistance
     self.m_bannedAreas = bannedAreas
     self.m_AlfaMale = Individual(self.m_StopsCount, self.m_RoadLength,
                                  self.m_MutationProbability,
                                  self.m_MinStopsDistance,
                                  self.m_MaxStopsDistance,
                                  self.m_bannedAreas)
     self.m_AlfaMale.m_Quality = math.inf
Example #9
0
class Population:
    pop_size = 100

    idv = Individual()

    def __init__(self):
        pass

    def creat_pop(self):
        P = []
        for i in range(self.pop_size):
            P.append(self.idv.creat_one())
        return P

    def next_Pop(self, Pop):
        n_P = []
        idv = self.idv
        P = Pop
        p_size = len(P)
        for p in P:
            p = idv.reset_one(p)
            cp = idv.creat_one()
            cp.X[:] = p.X[:]
            cp.F_value[:] = p.F_value[:]
            n_P.append(cp)
        # 产生下一代
        select(n_P)
        for i in range(p_size):
            j = np.random.randint(0, p_size, size=1)[0]
            cross(n_P[i], n_P[j])
            n_P[j] = mutate(n_P[j])
        return n_P
Example #10
0
    def __move(self, individual: Individual, direction: str) -> None:
        """ Move the individual around the map.

        This moves the individual according to the direction given.
        Zombie can move from one edge through the edge.

        Args:
            individual (Individual) : Individual of the world
            direction  (str)        : Direction for individual to move
        """

        # Make sure to lowercase
        direction = direction.lower()

        # Going Up
        if (direction == 'u'):
            if (individual.y_coord == 0):
                if (individual.is_zombie):
                    individual.y_coord = self.N - 1
            else:
                individual.y_coord -= 1

        # Going Down
        if (direction == 'd'):
            if (individual.y_coord == self.N - 1):
                if (individual.is_zombie):
                    individual.y_coord = 0
            else:
                individual.y_coord += 1

        # Going Left
        if (direction == 'l'):
            if (individual.x_coord == 0):
                if (individual.is_zombie):
                    individual.x_coord = self.N - 1
            else:
                individual.x_coord -= 1

        # Going Right
        if (direction == 'r'):
            if (individual.x_coord == self.N - 1):
                if (individual.is_zombie):
                    individual.x_coord = 0
            else:
                individual.x_coord += 1
Example #11
0
def test_populate():
    w = World(4)

    w.populate(
        Individual(),
        1, 3
    )

    assert 1 == len(w.get_population())
Example #12
0
def test_queeu_when_zombie_is_populated():
    w = World(4)

    w.populate(
        Individual(is_zombie = True),
        1, 3
    )

    assert 1 == len(w.get_queue())
Example #13
0
    def play(self) -> None:
        """ Run the world simulation
        """

        i = 0

        for inp in self.inputs:

            i += 1

            print("Simulation: ", i)
            print("World: " + str(inp['n']) + " x " + str(inp['n']))
            print()

            # Create world
            world = World(inp['n'])

            # Place zombie
            world.populate(Individual(is_zombie=True), inp['zombie']['x'],
                           inp['zombie']['y'])

            # Place creatures
            for creature in inp['creatures']:
                world.populate(Individual(), creature['x'], creature['y'])

            # Simulate
            world.simulate(inp['moves'])

            # Get stats
            score, positions = world.get_stats()

            print("zombies' score: ", score)
            print("zombies' positions:")

            for position in positions:
                print("(" + str(position['x']) + ", " + str(position['y']) +
                      ")",
                      end=" ")

            print()
            print("---")
            print()
def test_has_no_move():
    individual = Individual(is_zombie=is_zombie,
                            x_coord=x,
                            y_coord=y,
                            moves=moves)
    while individual.has_move():
        individual.get_move()

    assert individual.has_move() == False
Example #15
0
    def RankSelection(self):
        x = lambda a: a.m_Quality
        self.m_Population.sort(key=x)

        for i in range(int(self.m_PopulationCount / 2),
                       self.m_PopulationCount):
            self.m_Population[i] = Individual(self.m_StopsCount,
                                              self.m_RoadLength,
                                              self.m_MutationProbability,
                                              self.m_MinStopsDistance,
                                              self.m_MaxStopsDistance,
                                              self.m_bannedAreas)
            self.m_Population[i].CreateIndividual()
            self.m_Population[i].m_Quality = self.GoalFunction(
                self.m_Population[i])

        self.m_Population.sort(key=x)

        if self.m_Population[0].m_Quality < self.m_AlfaMale.m_Quality:
            self.m_AlfaMale.m_Chromosome = self.m_Population[0].m_Chromosome[:]
            self.m_AlfaMale.m_Quality = self.m_Population[0].m_Quality
    def make_evaluation(population):
        """
        проводит оценку особей популяции.
        :param population: оцениваемая популяция
        :return: лучшая особь
        """

        master_individ = Individual(
            GENE_LEN, gene_number)  # создание экземпляра доминантного индивида
        for i in range(POP_LEN):
            ind_list = list(population[i].ind_gene)
            degree = 1

            for j in range(GENE_LEN):  # оценка схожести с идеалом
                degree += 1 if GENE_LIST[j] == ind_list[j] else 0

            population[i].ind_degree = degree  # присвоение оценки

            # перезапись доминанта при совпадении условий
            master_individ = population[
                i] if degree > master_individ.ind_degree else master_individ

        return master_individ
Example #17
0
    def RouletteSelection(self):
        goalFunctionSum = 0
        for i in range(0, self.m_PopulationCount):
            goalFunctionSum += self.m_Population[i].m_Quality

        for i in range(0, self.m_PopulationCount):
            if random.random(
            ) < self.m_Population[i].m_Quality / goalFunctionSum:
                self.m_Population[i] = Individual(self.m_StopsCount,
                                                  self.m_RoadLength,
                                                  self.m_MutationProbability,
                                                  self.m_MinStopsDistance,
                                                  self.m_MaxStopsDistance,
                                                  self.m_bannedAreas)
                self.m_Population[i].CreateIndividual()
                self.m_Population[i].m_Quality = self.GoalFunction(
                    self.m_Population[i])

        x = lambda a: a.m_Quality
        self.m_Population.sort(key=x)

        if self.m_Population[0].m_Quality < self.m_AlfaMale.m_Quality:
            self.m_AlfaMale.m_Chromosome = self.m_Population[0].m_Chromosome[:]
            self.m_AlfaMale.m_Quality = self.m_Population[0].m_Quality
    def cabbage_growing(parent_1, parent_2):
        """
        скрещивание 2х особей
        :param parent_1: родитель1
        :param parent_2: родитель2
        :return: 2 потомка особей
        """

        # создание экземляров потомков
        son = Individual(GENE_LEN, gene_number)
        daughter = Individual(GENE_LEN, gene_number)

        parents = [parent_1, parent_2]

        # псевдоравномерное скрещивание
        son.ind_gene = "".join([
            rnd.choices(parents, [1, rnd.uniform(1.1, 2.5)])[0][i]
            for i in range(GENE_LEN)
        ])
        daughter.ind_gene = "".join([
            rnd.choices(parents, [1, rnd.uniform(1.1, 2.5)])[0][i]
            for i in range(GENE_LEN)
        ])

        # создание 1 - точечного кроссовера
        # recessive_gene = parents[0]
        # dominant_gene = parents[1]

        # border1 = rnd.randint(0, int(GENE_LEN//2))
        #
        # son.ind_gene = "".join(recessive_gene[:border1] +
        #        dominant_gene[border1:])
        # daughter.ind_gene =  "".join(dominant_gene[:(GENE_LEN-border1)] +
        #        recessive_gene[(GENE_LEN-border1):])

        return son, daughter
Example #19
0
 def __init__(self):
     self.populations = Population()
     ga.idv = Individual()
def test_coord():
    individual = Individual(is_zombie=is_zombie,
                            x_coord=x,
                            y_coord=y,
                            moves=moves)
    assert x == individual.x_coord and y == individual.y_coord
def make_genetic_algorithm(gene, gene_number):
    """
    генетический алгоритм оптимизации
    :param gene: идеальный геном
    :param gene_number: возможная выборка генов
    :return:
    """
    def make_evaluation(population):
        """
        проводит оценку особей популяции.
        :param population: оцениваемая популяция
        :return: лучшая особь
        """

        master_individ = Individual(
            GENE_LEN, gene_number)  # создание экземпляра доминантного индивида

        for i in range(POP_LEN):
            ind_list = list(population[i].ind_gene)
            degree = 1

            for j in range(GENE_LEN):  # оценка схожести с идеалом
                degree += 1 if GENE_LIST[j] == ind_list[j] else 0

            population[i].ind_degree = degree  # присвоение оценки

            # перезапись доминанта при совпадении условий
            master_individ = population[
                i] if degree > master_individ.ind_degree else master_individ

        return master_individ

    def get_selection(population):
        """
        проведение селекции лучших особей методом рулетки
        :return:
        """

        # делим популяцию поровну на готовых к селекции и нет
        best_individs = []
        if rnd.randint(0, 1):  # селекция рулеткой
            while len(best_individs) < 0.3 * POP_LEN:
                act_pop_len = len(population)

                # псевдослучайный выбор особи на скрещивание
                # winner = rnd.choices([i for i in range(act_pop_len)],
                #                    [population[i].ind_degree/act_pop_len for i in
                #                     range(act_pop_len)])[0]
                # winner = rnd.choices([i for i in range(act_pop_len)],
                #                    [population[i].ind_degree/math.log(math.e + (population[i].ind_degree)) for i in range(act_pop_len)])[0]
                #
                # турнир
                pretendents = [
                    rnd.randint(0, act_pop_len - 1) for i in range(1, 5)
                ]
                winner = rnd.choices(
                    pretendents,
                    [population[i].ind_degree for i in pretendents])[0]

                best_individs.append(
                    population.pop(winner))  # добавление в список селекции

        else:  # селекция усечением

            # сортировка популяции по оценкам и срез
            population = sorted(population, key=(lambda ind: ind.ind_degree))
            best_individs = population[int(len(population) * 0.7):]
            population = population[:int(len(population) * 0.7)]

        return best_individs, population

    def cabbage_growing(parent_1, parent_2):
        """
        скрещивание 2х особей
        :param parent_1: родитель1
        :param parent_2: родитель2
        :return: 2 потомка особей
        """

        # создание экземляров потомков
        son = Individual(GENE_LEN, gene_number)
        daughter = Individual(GENE_LEN, gene_number)
        if rnd.randint(0, 1):  # псевдоравномерное скрещивание

            daughter.ind_gene = "".join(parent_2)
            son.ind_gene = "".join([
                rnd.choices([parent_1, parent_2], [1, 1])[0][i]
                for i in range(GENE_LEN)
            ])

        else:  # создание 1 - точечного кроссовера

            border1 = rnd.randint(0, int(GENE_LEN // 2))
            #
            son.ind_gene = "".join(parent_1[:border1] + parent_2[border1:])
            daughter.ind_gene = "".join(parent_2[:(GENE_LEN - border1)] +
                                        parent_1[(GENE_LEN - border1):])

        return son, daughter

    def crossbreed_individs(best_individs):
        """
        скрещивание особей
        :param best_individs: выборка особей на скрещивание
        :return: скрещенная популяция
        """
        new_individs = []
        ind_len = len(best_individs)

        while len(new_individs) < ind_len:

            # случайный выбор партнеров на скрешивание
            par_ind = [
                rnd.randint(0,
                            len(best_individs) - 1),
                rnd.randint(0,
                            len(best_individs) - 1)
            ]

            # составление рабочих списков из выбранных особей
            degrees_list = sorted(
                [best_individs[par_ind[0]], best_individs[par_ind[1]]],
                key=lambda ind: ind.ind_degree)
            parents_list = [
                list(degrees_list[0].ind_gene),
                list(degrees_list[1].ind_gene)
            ]

            coincidence = 0  # совпадение по генам
            for i in range(GENE_LEN):
                coincidence += 1 if parents_list[0][i] == parents_list[1][
                    i] == gene[i] else 0

            " если худшая особь имеет некоторое количество оригинальных хороших" \
            "генов, то пара скрещивается"
            if math.fabs(degrees_list[0].ind_degree - coincidence) >= 1:
                # скрещивание и добавление потомков в новую популяцию
                new_individs.extend(
                    cabbage_growing(parents_list[0], parents_list[1]))
                # сокращение списка потенциальных партнеров
                best_individs = [
                    best_individs[i] for i in range(len(best_individs))
                    if i not in par_ind
                ]

        return new_individs

    def mutate_individs(feeble_individs):
        """
        процесс мутации
        :param feeble_individs:
        :return:
        """

        mutation_prob = 1 / GENE_LEN

        for i in range(len(feeble_individs)):
            individ_gene = list(feeble_individs[i].ind_gene)

            for j in range(GENE_LEN):
                if rnd.choices([0, 1],
                               [1 - mutation_prob,
                                math.fabs(mutation_prob)])[0]:
                    individ_gene[j] = rnd.choice(gene_number)

            feeble_individs[i].ind_gene = "".join(individ_gene)

        return

    def output_inform(master):

        master_list = list(master.ind_gene)
        print(
            "".join([
                "\033[34m{}".format(master_list[i]) if master_list[i]
                == GENE_LIST[i] else "\033[31m{}".format(master_list[i])
                for i in range(GENE_LEN)
            ]), Style.RESET_ALL, master.ind_degree)

    def handle_genotype(pop):
        """
        обработка популяции
        :param pop: популяция
        :return: новая популяция
        """
        best_individs, feeble_individs = get_selection(pop)  # селекция
        # print([best_individs[i].ind_degree for i in range(len(best_individs))], len(best_individs))
        new_individs = crossbreed_individs(best_individs)  # скрещивание
        mutate_individs(feeble_individs)  # мутация

        return feeble_individs + new_individs  # новая популяция

    GENE_LIST = list(gene)  # разбивка строки на символьный список
    GENE_LEN = len(GENE_LIST)  # длина генома
    POP_LEN = 20
    # размер популяции
    STEP = 100  # шаг смены эры
    assert POP_LEN % 4 == 0, "Размер популяции приведет к зацикливанию"

    pop1 = [Individual(GENE_LEN, gene_number)
            for i in range(POP_LEN)]  # создание новой популяции
    # pop2 = [Individual(GENE_LEN, gene_number) for j in range(POP_LEN)]  # создание новой популяции
    # pop3 = [Individual(GENE_LEN, gene_number) for i in range(POP_LEN)]  # создание новой популяции
    generation = 1

    while True:

        print("\nERA:", generation // STEP, "GENERATION: ", generation % STEP)

        # оценка популяций
        master1 = make_evaluation(pop1)
        # master2 = make_evaluation(pop2)

        # master3 = make_evaluation(pop3)

        # вывод схожестей генов
        output_inform(master1)
        # output_inform(master2)
        # output_inform(master3)

        # условие выхода из алгоритма
        # if (master1.ind_degree > GENE_LEN) or (master2.ind_degree > GENE_LEN)\
        #         or (master3.ind_degree > GENE_LEN): break
        # if (master1.ind_degree > GENE_LEN) or (master2.ind_degree > GENE_LEN): break
        if (master1.ind_degree > GENE_LEN): break

        # проведение селекции, скрещивания и мутации
        pop1 = handle_genotype(pop1)
        # pop2 = handle_genotype(pop2)

        # pop3 = handle_genotype(pop3, master3.ind_degree)

        generation += 1
def test_is_zombie():
    individual = Individual(is_zombie=is_zombie,
                            x_coord=x,
                            y_coord=y,
                            moves=moves)
    assert is_zombie == individual.is_zombie
def test_has_move():
    individual = Individual(is_zombie=is_zombie,
                            x_coord=x,
                            y_coord=y,
                            moves=moves)
    assert individual.has_move() == True