Борьба за реализацию дифференциального эволюционного алгоритма из статьи в python3 с DEAP - PullRequest
0 голосов
/ 07 мая 2019

Я пытаюсь реализовать алгоритм дифференциальной эволюции для определения параметров модели 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 и эволюционные алгоритмы.

Это - статья.

Они предоставляют объяснение каждого шага на странице 3 и показывают псевдокод на странице 5.

Любая помощь будет оценена по достоинству, так как я не уверен, что не так, и не делаюЯ знаю кого-то, кто мог бы помочь.Заранее благодарю за любую помощь!

...