浮点数表的简单遗传算法

2024-10-01 11:22:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前正在尝试做一个遗传算法来匹配一个浮点数列表和另一个浮点数列表(我知道这有点“毫无意义”,因为我已经有了数据,但我只想在尝试解决更复杂的遗传算法问题之前有能力做到这一点)。我用Python编写了以下代码。在

from random import random
ofInterest = [
                5.76260089714,
                7.87666520017,
                9.53163269149,
                9.72801578613,
                5.20002737716,
                0.50133290228,
                8.58820041647,
                9.65056792475,
                3.07043110493,
                1.13232332178
              ]

print(ofInterest)

fits = []

for i in range(100):
    fits.append([])
    for j in range(10):
        fits[i].append(random()*10)

fitness = []
for i in range(100):
    fitness.append(100000000)


def makeFitnessList():
    for i in range(100):
        fitValue = 0
        for j in range(10):
            fitValue += (fits[i][j] - ofInterest[j])**2
        fitness[i] = fitValue

topTenFitness = []

for i in range(10):
    topTenFitness.append(10000000000000)
print(topTenFitness)

def sortByFitness():
    makeFitnessList()
    temp = []
    count = 0
    while len(temp) < 10:
        k = 100000000000000000000000000
        index = -1
        for i in range(len(fitness)):
            if k > fitness[i]:
                k = fitness[i]
                index = i  
        temp += [index]
        topTenFitness[count] = fitness[index]
        print(fitness[index])
        fitness[index] = 1000000000000
        count += 1
    temp2 = fits
    for i in range(10):
        fits[i] = temp2[temp[i]]

#sortByFitness()
#print(fitness[0])
#print(fits[0])

def cross(rate):
    for i in range(10,100):
        parent1Place = int(random()*10.01)
        if (i*random()) > rate:
            parent2Place = int(random()*10.01)
            crossPoint = int(random()*10.01)
            for i in range(crossPoint):
                tempOne = fits[parent1Place][i]
                tempTwo = fits[parent2Place][i]
                fits[parent1Place][i] = tempOne
                fits[parent2Place][i] = tempTwo
        else:
            fits[i] = fits[parent1Place]



def mutate(rate):
    for i in range(10,100):
        for gene in range(10):
            if random() < rate:
                fits[i][gene] = random()*10

for i in range(10):
    makeFitnessList()
    sortByFitness()
    print("")
    cross(.6)
    mutate(.4)

sortByFitness()
print(fits[0])

该计划运行,但对健康没有好处:

^{pr2}$

Tags: inforindexratedefrangerandomtemp
3条回答

如果你能更容易地使用你的电脑,那就试试看吧:

import numpy as np

ofInterest = np.array([
                5.76260089714,
                7.87666520017,
                9.53163269149,
                9.72801578613,
                5.20002737716,
                0.50133290228,
                8.58820041647,
                9.65056792475,
                3.07043110493,
                1.13232332178
              ])
print(ofInterest)

fits = np.random.random((100,10)) * 10

def sortByFitness():
    global fits
    fitness = np.sum((fits - ofInterest)**2,axis=1)
    fits = fits[fitness.argsort()]

def cross(rate):
    for i in range(10,100):
        parents = fits[np.random.random_integers(0,9,2)]
        if (i*np.random.random()) > rate:
            crossPoint = np.random.random_integers(0,10)
            fits[i] = np.hstack((parents[0,:crossPoint],parents[1,crossPoint:]))
        else:
            fits[i] = parents[0]

def mutate(rate):
    for i in range(10,100):
        for gene in range(10):
            if np.random.random() < rate:
                fits[i][gene] = np.random.random()*10

for i in range(100):
    sortByFitness()
    cross(.6)
    mutate(.4)

print(fits[0])

以下是一些可能导致不良结果的因素:

  1. 你的突变率太高了。每个基因40%意味着每10个基因每个个体平均会有4个变化。实际上,你应该选择突变率,使每一代在整个群体中只引入很少的突变。

  2. 你的cross功能在选择的父母之间交换基因,而不是让父母保持不变,将父母双方的部分基因复制给新创造的孩子。

  3. 如果你使一个基因突变,你就用一个新的独立随机变量来代替它。这是无效的,因为它使得算法运行的环境非常粗糙。如果只向原始值添加小的随机变量,例如在范围[-0.1,0.1]范围内,则可以获得更平滑的景观和更好的拟合效果。

  4. 与其为基因组选择一个交叉点,不如在双亲之间完全随机地选择基因,因为基因的顺序在你的模型中没有意义。

  5. 你等待的时间不够长,10代人不会带你走远。

  6. 据我所见,你没有正确地测量健身增益。你应该打印出人口的平均健康状况(可能是最好的健康状况或前10名的平均值)。

因为遗传算法很有趣。。。:)

import random
target_list = [1,2,3,4,5,6,7,8,9,10]
size_of_individual = len(target_list)
size_of_population = 100
n_generations = 10000

def score_fitness(individual):
    return sum((val-target)**2 for val,target in zip(individual,target_list))

def create_individual():
    return [random.random()*10 for _ in range(size_of_individual)]

def crossover(individual1,individual2):
    return [val1 if random.random() < 0.5 else val2 for val1,val2 in zip(individual1,individual2)]

def mutate(individual,mutation_chance=0.1,mutation_size = 0.1):
    def get_mutation(val):
         return val if random.random()>mutation_chance else val + [-mutation_size,mutation_size][random.random()<0.5]
    return [get_mutation(val) for val in individual]

def selection_step(sorted_old_population):
    def select_one():
        while True:
            candidate_idx = random.randint(0,len(sorted_old_population)-1)
            if random.randint(0,len(sorted_old_population))>= candidate_idx:
                return sorted_old_population[candidate_idx]
    selections = [select_one(),select_one()]
    while selections[1] == selections[0]:
        selections[1] = select_one()
    return selections

def create_new_population(old_population,elitism=0):
    sorted_population = sorted(old_population,key= score_fitness)
    print "BEST OLD:",sorted_population[0],score_fitness(sorted_population[0])
    print "AVG OLD:", sum(score_fitness(i) for i in sorted_population)
    new_population = sorted_population[:elitism]
    while len(new_population) < size_of_population:
          new_population.append(mutate(crossover(*selection_step(sorted_population))))
    return new_population[:size_of_population]


population = [create_individual() for _ in range(size_of_population)]
for i in range(n_generations):
    population = create_new_population(population,5)

请记住,这对遗传算法来说是一个很糟糕的问题,而且还有很多改进的余地(即一起摆脱精英主义)

相关问题 更多 >