Создание очень простого «эволюционного» алгоритма в Python - PullRequest
0 голосов
/ 28 апреля 2018

Я пытаюсь создать очень простой «эволюционный» алгоритм в python.

Сначала я хочу создать популяцию из ~ 100 человек с четырьмя числовыми атрибутами (a1-4), использовать функцию, чтобы получить оценку по этим атрибутам, а затем удалить худший результат из 20 человек.

Это то, что я имею до сих пор

import random
population = 100

class Individual(object):
    def __init__(self, a1, a2, a3, a4):
        self.a1 = a1
        self.a2 = a2
        self.a3 = a3
        self.a4 = a4

starting_population = list()

for i in range (population):
    a1 = random.randint(1,10)
    a2 = random.randint(1,10)
    a3 = random.randint(1,10)
    a4 = random.randint(1,10)
    starting_population.append(Individual(a1,a2,a3,a4))

def fitness(x):
    fitness = a1*a2/a3*a4
    return fitness

Я застрял на том, как применить функцию к членам списка населения?

Кроме того, я очень плохо знаком с Python и уверен, что кое-что сделал плохо, поэтому любые советы очень ценятся!

Спасибо

Ответы [ 2 ]

0 голосов
/ 28 апреля 2018

Во-первых, вы должны сделать fitness метод Individual:

import random
population = 100

class Individual(object):
    def __init__(self, a1, a2, a3, a4):
        self.a1 = a1
        self.a2 = a2
        self.a3 = a3
        self.a4 = a4

    def fitness(self):
        fitness = self.a1*self.a2/self.a3*self.a4
        return fitness

starting_population = list()

for i in range (population):
    a1 = random.randint(1,10)
    a2 = random.randint(1,10)
    a3 = random.randint(1,10)
    a4 = random.randint(1,10)
    starting_population.append(Individual(a1,a2,a3,a4))

Если вы хотите удалить 20 наименее скоринговых, сначала отсортируйте их по пригодности, затем возьмите часть списка:

sorted_people = sorted(starting_population, key=lambda i:i.fitness())
fit_people = sorted_people[20:]

Вы также можете отфильтровать их по значению их пригодности, например, используя понимание списка:

fit_people = [i for i in starting_population if i.fitness() > 0.5]
0 голосов
/ 28 апреля 2018

Что не так с циклом?

for person in starting_population:
    person.fitness = person.a1*person.a2/person.a3*person.a4 #Add fitness to object

Также обратите внимание, порядок операций:

((a1*a2)/a3)*a4)

на случай, если вы имели в виду что-то другое. Вы можете подумать о том, чтобы сделать фитнес методом индивидуума:

class Individual(object):
    def __init__(self, a1, a2, a3, a4):
        self.a1 = a1
        self.a2 = a2
        self.a3 = a3
        self.a4 = a4

    def fitness(self,x):
        fitness = self.a1*self.a2/self.a3*self.a4
        return fitness

starting_population = list()   
for i in range (population):
    a1 = random.randint(1,10)
    a2 = random.randint(1,10)
    a3 = random.randint(1,10)
    a4 = random.randint(1,10)
    starting_population.append(Individual(a1,a2,a3,a4))

, чтобы вы могли немедленно вызвать starting_population[i].fitness() или вычислить значение в __init__ и сделать его полем.

Другое решение, убравшее ясность объекта в коде в пользу массива numpy для скорости:

import numpy.random as rnd
rnd.seed(78943598743)
starting_population=rnd.randint(1,10,size=100*4).reshape(100,4) #100 rows, 4 columns, each row a person
fitness_vector = starting_population[:,0]*starting_population[:,1]/starting_population[:,2]*starting_population[:,3]
...