我正在尝试实现差分进化算法来求解 PV 模型的参数。我认为我编写的代码是正确的,但我似乎得到了奇怪的答案。随着算法的每次运行,我都会得到新的参数,这些参数变化很大。此外,我似乎也无法使用 sympy 求解方程,因为我认为指数会产生巨大的值,从而导致溢出。使用 sympy 求解得到以下错误代码:“Python int too large to convert to 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 页显示了伪代码。
任何和所有的帮助都将不胜感激,因为我不确定出了什么问题,也不知道有人可以提供帮助。预先感谢您的任何帮助!