在python3中用DEAP实现差分进化算法

2024-04-27 11:17:28 发布

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

我正在尝试实现一个差分进化算法来求解PV模型的参数。我认为我写的代码是正确的,但我似乎得到了奇怪的答案。每次运行算法,我都会得到新的参数,这些参数变化很大。此外,我似乎也不能用sympy来解这个方程,因为我认为指数会产生一个巨大的值,从而导致溢出。使用sympy solve获得以下错误代码:“Python int太大,无法转换为C ssize\t”

import random
from random import randint
import array
import math
import numpy
from deap import base
from deap import tools
from deap import benchmarks
from deap import creator
from decimal import Decimal
import sympy
from sympy.solvers import solve
from sympy import Symbol
from sympy import Eq

# STEP 1 -> Defined constants
## number of individuals in the population
NP = 300
##coefficients from the datasheet of the PV panel
IscTempcoeff = 0.059
VocTempcoeff = -0.32
PeakPowTempcoeff = - 0.43
Voc = 45.79
Vmp = 36.38
Isc = 8.99
Imp = 8.52
Vt = 0.026
##amount of generations
max = 300
##lower and upper bounds of the variables to solve
Xih = [2, 1, 3000, 0.1, Isc]
Xil = [1, 0.1, 100, 0.000009, 0.1]


#crossover based on binomial
def cxBinomial(x, mutant, cr):
   size = len(x)
   index = random.randrange(size)
    for i in range(size):
        if i == index or random.random() < cr:
            x[i] = mutant[i]
    return x

#mutation function
def mutateDE(mutant, a, b, c, f):
    size = len(mutant)
    for i in range(len(mutant)):
        mutant[i] = a[i] + f * (b[i] - c[i])
    return mutant

#Penalty function to ensure the parameters remain in acceptable range
def cxPenalty(x):
    z = random.uniform(0, 1)
    if (x[0] > 2 or x[1] > 1 or x[2] > 3000 or x[3] > 0.1 or x[4] > Isc):
        x[0] = x[0] - (z * (Xih[0] - Xil[0]))
        x[1] = x[1] - (z * (Xih[1] - Xil[1]))
        x[2] = x[2] - (z * (Xih[2] - Xil[2]))
        x[3] = x[3] - (z * (Xih[3] - Xil[3]))
        x[4] = x[4] - (z * (Xih[4] - Xil[4]))
     elif (x[0] < Xil[0] or x[1] < Xil[1] or x[2] < Xil[2] or x[3] < Xil[3] or x[4] < Xil[4]):
        x[0] = x[0] + (z * (Xih[0] - Xil[0]))
        x[1] = x[1] + (z * (Xih[1] - Xil[1]))
        x[2] = x[2] + (z * (Xih[2] - Xil[2]))
        x[3] = x[3] + (z * (Xih[3] - Xil[3]))
        x[4] = x[4] + (z * (Xih[4] - Xil[4]))

     return x

 #evaluation and selection function
def eval(a, Rs, Rp, Io):
    r = (1 / (a * Vt))
    Gp = (1 / Rp)
    preex = Decimal(r*(Vmp + (Imp * Rs)))
    expo = numpy.exp(preex)
    Jnum = Decimal(Io) * Decimal(r) * expo - Decimal(Gp)
    Jden = 1 + (Decimal(Io) * Decimal(r) * Decimal(Rs) * expo) + Decimal(Gp * Rs)
    J = Jnum / Jden
    return J


def main():
    generation = 0
    state = []
    creator.create("Fitnessmin", base.Fitness, weights=(-1.0,))
    creator.create("Individual", array.array, typecode='d', fitness=creator.Fitnessmin)
    toolbox = base.Toolbox()
    toolbox.register("attr_a", random.uniform, 1, 2)
    toolbox.register("attr_rs", random.uniform, 0.1, 1)
    toolbox.register("attr_rp", random.uniform, 100, 3000)
    toolbox.register("attr_io", random.uniform, 0.000009, 0.1)
    toolbox.register("attr_ipv", random.uniform, 0.1, Isc)
    toolbox.register("individual", tools.initCycle, creator.Individual,
                 (toolbox.attr_a, toolbox.attr_rs, toolbox.attr_rp,     toolbox.attr_io, toolbox.attr_ipv), 1)
    toolbox.register("population", tools.initRepeat, list, toolbox.individual)
    toolbox.register("mutate", mutateDE, f=0.4)
    toolbox.register("select", tools.selRandom, k=3)
    toolbox.register("mate", cxBinomial, cr=0.4)
    toolbox.register("evaluate", eval)
    # STEP 2 - > generate population
    pop1 = toolbox.population(n=NP)
    # STEP 3 -> start the algorithm
    ## Hall of fame to save the best individual
    hof = tools.HallOfFame(1)
    while (generation <= max):
        for agent in pop1:
            # Mutation
            a, b, c = [toolbox.clone(ind) for ind in     toolbox.select(pop1)]
            mutant1 = toolbox.clone(agent)
            mutant = toolbox.clone(agent)
            mutant = toolbox.mutate(mutant, a, b, c)
            # crossover
            trialvec = toolbox.mate(mutant1, mutant)
            trialvec = cxPenalty(trialvec)
            trialeval = toolbox.evaluate(trialvec[0], trialvec[1], trialvec[2], trialvec[3])
            curreval = toolbox.evaluate(agent[0], agent[1], agent[2], agent[3])

            if (trialeval < curreval):
                #selection -> trialvector is better than original vector
                agent = trialvec
                state.append(trialeval)
            else:
                 #selection -> trialvector IS NOT better than original vector
                state.append(curreval)

        hof.update(pop1)
        print(generation)
        generation = generation + 1

    ##extract best individual from the hall of fame
    bestid = hof[0]
    ##extract parameters from individual
    a = round((bestid[0]), 2)
    Rs = round((bestid[1]), 2)
    Rp = round((bestid[2]), 2)
    print("Io")
    io = round((bestid[3]), 2)
    print(io)
    print("RS")
    print(Rs)
    print("Rp")
    print(Rp)
    print("a")
    print(a)
    I = Symbol('I')
    r = (1 / (a * Vt))
    #Solve to ensure that Imp is retrieved when Vmp is provided
    print("solving start")
    ## solving equation 3
    eqn = Eq(Isc-io*(((sympy.exp(r*(Vmp + (I * Rs))))) - 1)-((Vmp+(I*Rs))/Rp ) - I)
    t = solve(eqn,I,rational=False,real=True)
    print("solving done")
    print(t)


main()

我希望每次运行算法时都能收到一些类似的参数,所以我假设我在某个地方犯了一个错误,我真的找不到它,因此我需要一些帮助,因为我仍然掌握着python和进化算法。你知道吗

This是论文。你知道吗

它们在第3页提供了每个步骤的解释,并在第5页显示了伪代码。你知道吗

任何和所有的帮助将真的很感激,因为我不知道什么是错的,也不知道有人可以帮助我。提前感谢您的帮助!你知道吗


Tags: orthefromimportregistertoolboxrandomagent