如何找到最小值X2+是的2x2+y2用遗传算法?

数据挖掘 遗传算法
2022-03-05 17:06:05

我想找到(x,y)最小化x2+y2与 GA 一起将其应用于另一个功能。

有谁知道这样的带有deap(Python)的GA示例?

1个回答

遗传算法

这包括 4 个关键步骤:初始化、评估、选择和组合。

初始化

种群中的每个个体都由一些基因编码。在我们的例子中,基因代表我们的[x,y]价值观。然后,我们将针对这个特定问题将搜索范围设置为 [0, 1000]。通常你会根据你的问题知道什么是自然可能的。例如,您应该知道自然界中可能的土壤密度范围。我们将在我们的人口中创造 100 个人。

体能评估

此步骤只是要求您将[x,y]值到你的函数中并得到它的结果。很标准的东西。

选择

您可以通过多种方式选择父母。我将永远保留阿尔法男性。种群中最好的个体,他将被克隆到下一个。然后我将使用锦标赛选择。我们将重复以下内容,直到下一代人口满为止。随机选择四个父母,从前两个中选出最好的,从后两个中选出最好的。这将是我们的下一个后代的两个父母。

组合

从这两个父母,我们将使用二元值为孩子构建新的基因组[x,y]父母的价值观。通过均匀随机从两个亲本基因中选择子基因组中每个密码子的所得二进制值。

编码

class Genetic(object):

    def __init__(self, f, pop_size = 100, n_variables = 2):
        self.f = f
        self.minim = -100
        self.maxim = 100
        self.pop_size = pop_size
        self.n_variables = n_variables
        self.population = self.initializePopulation()
        self.evaluatePopulation()

    def initializePopulation(self):
        return [np.random.randint(self.minim, self.maxim, size=(self.n_variables)) 
                           for i in range(self.pop_size)]

    def evaluatePopulation(self):
        return [self.f(i[0], i[1]) for i in self.population]
        #return [(i[0]-4)**2 + i[1]**2 for i in self.population]

    def nextGen(self):
        results = self.evaluatePopulation()
        children = [self.population[np.argmin(results)]]

        while len(children) < self.pop_size:
            # Tournament selection
            randA, randB = np.random.randint(0, self.pop_size), \
                           np.random.randint(0, self.pop_size)
            if results[randA] < results[randB]: p1 = self.population[randA]
            else: p1 = self.population[randB]

            randA, randB = np.random.randint(0, self.pop_size), \
                           np.random.randint(0, self.pop_size)  
            if results[randA] < results[randB]: p2 = self.population[randA]
            else: p2 = self.population[randB]   

            signs = []
            for i in zip(p1, p2):
                if i[0] < 0 and i[1] < 0: signs.append(-1)
                elif i[0] >= 0 and i[1] >= 0: signs.append(1)
                else: signs.append(np.random.choice([-1,1]))

            # Convert values to binary
            p1 = [format(abs(i), '010b') for i in p1]
            p2 = [format(abs(i), '010b') for i in p2]

            # Recombination
            child = []
            for i, j in zip(p1, p2):
                for k, l in zip(i, j):
                    if k == l: child.append(k)
                    else: child.append(str(np.random.randint(min(k, l), 
                                                             max(k,l))))

            child = ''.join(child)
            g1 = child[0:len(child)//2] 
            g2 = child[len(child)//2:len(child)]
            children.append(np.asarray([signs[0]*int(g1, 2), 
                                        signs[1]*int(g2, 2)]))
        self.population = children

    def run(self):
        ix = 0
        while ix < 1000:
            ix += 1
            self.nextGen()
        return self.population[0]

然后你可以使用代码

f = lambda x, y: (x)**2 + y**2
gen = Genetic(f)
minim = gen.run()
print('Minimum found      X =', minim[0], ', Y =', minim[1])

找到的最小值 X = 0 , Y = 0

f = lambda x, y: (x-6)**2 + y**2
gen = Genetic(f)
minim = gen.run()
print('Minimum found      X =', minim[0], ', Y =', minim[1])

找到的最小值 X = 6 , Y = 0