在Python中使用遗传算法解决逆问题

时间:2019-03-30 07:42:13

标签: python genetic-algorithm

我正在开发一个FEM代码,以解决Python中的反导热问题。我正计划实施遗传算法来预测表面热通量。

给出反问题的简要说明:直接导热问题包括根据表面上给出的数据(即边界条件)求解固体的内部温度分布。但是,在许多实际问题中,特别是在将组件设计为承受某些环境条件时,表面条件可能不是先验的。在这种情况下,必须在模拟或实验室条件下估算表面条件。可以引用这种技术的许多应用领域,例如,铸造和焊接,热处理,聚合物加工等。利用人体内部关键位置的温度历史知识来估计表面状况属于逆问题的范畴。

直接问题中求解和求出温度的矩阵为

[C] {Tn + 1} =([C] -t [K])[Tn] + t {f}

其中[C]和[K]矩阵可以通过元素的形状函数获得 [Tn]矩阵是第n个时间步长的已知温度,t是时间步长,{Tn + 1}是未知温度,{f}是包含已知热通量边界条件的负载矩阵。通过求解类似于[A] {X} = {B}的上述方程的线性方程,我们可以找到{x},即{Tn + 1}

在反问题中,{Tn + 1}是已知的,我们必须找到{f}矩阵中的热通量。为了解决这个问题,我们计划使用遗传算法,该算法为q赋予随机值并解决直接问题,找出{Tn + 1}值并与测量结果进行比较,并计算适应度,然后进一步迭代以达到{tn + 1}的状态将与测得的温度匹配。

import random 

# Number of individuals in each generation 
POPULATION_SIZE = 100

# Valid genes 
GENES = '0123456789'

# Target string to be generated 
TARGET = "150"

class Individual(object): 
    ''' 
    Class representing individual in population 
    '''
    def __init__(self, chromosome): 
        self.chromosome = chromosome  
        self.fitness = self.cal_fitness() 

    @classmethod
    def mutated_genes(self): 
        ''' 
        create random genes for mutation 
        '''
        global GENES 
        gene = random.choice(GENES) 
        return gene 

    @classmethod
    def create_gnome(self): 
        ''' 
        create chromosome or string of genes 
        '''
        global TARGET 
        gnome_len = len(TARGET) 
        return [self.mutated_genes() for _ in range(gnome_len)] 

    def mate(self, par2): 
        ''' 
        Perform mating and produce new offspring 
        '''

        # chromosome for offspring 
        child_chromosome = [] 
        for gp1, gp2 in zip(self.chromosome, par2.chromosome):     

            # random probability   
            prob = random.random() 

            # if prob is less than 0.45, insert gene 
            # from parent 1  
            if prob < 0.45: 
                child_chromosome.append(gp1) 

            # if prob is between 0.45 and 0.90, insert 
            # gene from parent 2 
            elif prob < 0.90: 
                child_chromosome.append(gp2) 

            # otherwise insert random gene(mutate),  
            # for maintaining diversity 
            else: 
                child_chromosome.append(self.mutated_genes()) 

        # create new Individual(offspring) using  
        # generated chromosome for offspring 
        return Individual(child_chromosome) 

    def cal_fitness(self): 
        ''' 
        Calculate fittness score, it is the number of 
        characters in string which differ from target 
        string. 
        '''
        global TARGET 
        fitness = 0
        for gs, gt in zip(Temp, TARGET): 
            if gs != gt: fitness+= 1
        return fitness
# Driver code 
def main(): 
    global POPULATION_SIZE 

    #current generation 
    generation = 1

    found = False
    population = [] 

    # create initial population 
    for _ in range(POPULATION_SIZE): 
                gnome = Individual.create_gnome() 
                population.append(Individual(gnome)) 

    while not found: 

        # sort the population in increasing order of fitness score 
        population = sorted(population, key = lambda x:x.fitness) 

        # if the individual having lowest fitness score ie.  
        # 0 then we know that we have reached to the target 
        # and break the loop 
        if population[0].fitness <= 0: 
            found = True
            break

        # Otherwise generate new offsprings for new generation 
        new_generation = [] 

        # Perform Elitism, that mean 10% of fittest population 
        # goes to the next generation 
        s = int((10*POPULATION_SIZE)/100) 
        new_generation.extend(population[:s]) 

        # From 50% of fittest population, Individuals  
        # will mate to produce offspring 
        s = int((90*POPULATION_SIZE)/100) 
        for _ in range(s): 
            parent1 = random.choice(population[:50]) 
            parent2 = random.choice(population[:50]) 
            child = parent1.mate(parent2) 
            new_generation.append(child) 

        population = new_generation 

        print("Generation: {}\tString: {}\tFitness: {}".\
              format(generation, 
              "".join(population[0].chromosome), 
              population[0].fitness)) 

        generation += 1


    print("Generation: {}\tString: {}\tFitness: {}".\
          format(generation, 
          "".join(population[0].chromosome), 
          population[0].fitness)) 

if __name__ == '__main__': 
    main()

以上是我计划用作基础的基本遗传算法程序。上面示例中的TARGET是测得的温度,我想找到与TARGET或测得的温度相匹配的热通量。因此,请帮助我编程遗传算法以找到热通量。

0 个答案:

没有答案