迭代限制

问题描述 投票:0回答:1

如何修复错误:“RuntimeWarning:double_scalars 中遇到无效值”和“AssertionError:达到迭代限制”。我的代码是针对优化问题的。我想也许初始条件导致了这个错误。我更改了它们,但错误仍然存在。我的代码如下:

import numpy as np
import sympy as sp
from sympy import *
from scipy.special import roots_legendre, eval_legendre

from scipy.optimize import minimize, NonlinearConstraint
# create variables
N=8;n1=2;n2=3;n3=2;n4=3;z=1;m=2;a=0;b=1
x = [sp.symbols('x%d' % i) for i in range(2*(n1+n2+n3+n4)-4)]
s=zeros(2*n1-1,1);e=zeros(2*n2-1,1);h=zeros(2*n3-1,1);l=zeros(2*n4-1)
for i in range(2*n1-1):
    s[i]=x[i]
for i in range(2*n2-1):
    e[i]=x[i+2*n1-1]
for i in range(2*n3-1):
    h[i]=x[i+2*(n1+n2)-2]
for i in range(2*n4-1):
    l[i]=x[i+2*(n1+n2+n3)-3]   
#s = [sp.symbols('s%d' % i) for i in range(2*n1-1)]
#e = [sp.symbols('e%d' % i) for i in range(2*n2-1)]#Instead of "i" we choose "e"
#h = [sp.symbols('h%d' % i) for i in range(2*n3-1)]
#l = [sp.symbols('l%d' % i) for i in range(2*n4-1)]
from sympy.abc import t
B=zeros(N,N)
number = range(N)
for i in number:
   for j in number:
       if i<j :
           B[i,j]=0
       else :
           B[i,j]=sp.factorial(i+j)/(2**j*sp.factorial(j)*sp.factorial(i-j))
PS=Matrix(1,n1,s[0:n1]);PI=Matrix(1,n2,e[0:n2]);PH=Matrix(1,n3,h[0:n3]);PL=Matrix(1,n4,l[0:n4])
TS=[[1]];TI=[[1]];TH=[[1]];TL=[[1]]
for i in range(n1-1):
    TS.append([t**(s[n1+i]+i+1)])
for i in range(n2-1):    
    TI.append([t**(e[n2+i]+i+1)])
for i in range(n3-1):        
    TH.append([t**(h[n3+i]+i+1)])
for i in range(n4-1):            
    TL.append([t**(l[n4+i]+i+1)])
MTS=Matrix(TS);MTI=Matrix(TI);MTH=Matrix(TH);MTL=Matrix(TL)
BS=B[0:n1,0:n1];BI=B[0:n2,0:n2];BH=B[0:n3,0:n3];BL=B[0:n4,0:n4]
S=PS*BS*MTS;II=PI*BI*MTI;H=PH*BH*MTH;L=PL*BL*MTL

#CONVERT SYMPY MATRICES TO NUMPY ONE
S0=np.array(S);I0=np.array(II);H0=np.array(H);L0=np.array(L)
GS=zeros(n1,n1);GI=zeros(n2,n2);GH=zeros(n3,n3);GL=zeros(n4,n4)

for i in range(n1):
   if i==0:
      GS[i,i]=0
   else:
       GS[i,i]=simplify(gamma(s[n1+i-1]+1)/gamma(s[n1+i-1]+1-z))
for i in range(n2):
    if i==0:
      GI[i,i]=0
    else:
     GI[i,i]=simplify(gamma(e[n2+i-1]+1)/gamma(e[n2+i-1]+1-z))
for i in range(n3):
    if i==0:
      GH[i,i]=0
    else:
      GH[i,i]=simplify(gamma(h[n3+i-1]+1)/gamma(h[n3+i-1]+1-z))
for i in range(n4):
    if i==0:
      GL[i,i]=0
    else:
      GL[i,i]=simplify(gamma(l[n4+i-1]+1)/gamma(l[n4+i-1]+1-z))     
DS=simplify(t**(-z)*PS*BS*GS*MTS)
DI=simplify(t**(-z)*PI*BI*GI*MTI)
DH=simplify(t**(-z)*PH*BH*GH*MTH)
DL=simplify(t**(-z)*PL*BL*GL*MTL)
RS=DS[0,0]-(.0043217-.5944*S[0,0]*II[0,0]-(.025+3.5)*S[0,0])
RI=DI[0,0]-(.5944*S[0,0]*II[0,0]+.0056*H[0,0]*II[0,0]+.27*L[0,0]-(.025+3.5+.0025+.5)*II[0,0])
RH=DH[0,0]-(.535-.0056*H[0,0]*II[0,0]+.5*II[0,0]-(.025+3.5)*H[0,0])
RL=DL[0,0]-(.0025*II[0,0]-(.025+3.5+.27)*L[0,0])      
#f = lambdify(t, R)
import decimal
decimal.getcontext().prec=4
def R(k):
   return (RS**2+RI**2+RH**2+RL**2).subs(t,k)
r, w = roots_legendre(m)
F=zeros(1,m)
I1=0
for i in range (m):
   F[i]=r[i]*R((b-a)/2*r[i]+(b+a)/2)
   I1=I1+F[i]
OF1=((b-a)/2)*I1 #OF=Objective Function
OF=OF1.evalf(3)
t = next(s for s in S.free_symbols if s.name == 't')
x = [
    next(s for s in OF.free_symbols if s.name == f'x{i}')
    for i in range(2*(n1+n2+n3+n4)-4)
]
args = [t, *x]
OF = sp.lambdify(args, OF)
S = sp.lambdify(args, S.flat()[0])
I = sp.lambdify(args, II.flat()[0])
H = sp.lambdify(args, H.flat()[0])
L = sp.lambdify(args, L.flat()[0])

def objective(params: np.ndarray) -> float:
    return OF(*params)

def Sc(params: np.ndarray) -> float:
    return S(*params)
def Ic(params: np.ndarray) -> float:
    return I(*params)
def Hc(params: np.ndarray) -> float:
    return H(*params)
def Lc(params: np.ndarray) -> float:
    return L(*params)

res = minimize(
    fun=objective,
    x0=np.ones(1 + 2*(n1+n2+n3+n4)-4),
    constraints=(
        NonlinearConstraint(fun=Sc, lb=43994, ub=43994),
        NonlinearConstraint(fun=Ic, lb=1, ub=1),
        NonlinearConstraint(fun=Hc, lb=1, ub=1),
        NonlinearConstraint(fun=Lc, lb=1, ub=1),
    ),
)
assert res.success, res.message
print(res)

      
python optimization iteration
1个回答
0
投票

最大迭代次数可以在

minimize
函数中更改。这可以与设置收敛容差的
tol
参数结合使用。例如,

res = minimize(                                                                                         
    fun=objective,                                                                                      
    x0=np.ones(1 + 2*(n1+n2+n3+n4)-4),                                                                  
    constraints=(                                                                                       
        NonlinearConstraint(fun=Sc, lb=43994, ub=43994),                                                
        NonlinearConstraint(fun=Ic, lb=1, ub=1),                                                        
        NonlinearConstraint(fun=Hc, lb=1, ub=1),                                                        
        NonlinearConstraint(fun=Lc, lb=1, ub=1),                                                        
    ),                                                                                                  
    tol=1.e-3,                                                                                          
    options={"maxiter": 2000}                                                                           
)  

也就是说,您在遇到错误之前收到的警告似乎与您的问题无法收敛的原因有关。

您应该检查您尝试优化的函数是否正确,如果是,那么您应该探索其数学特性,以便选择正确的优化方法。

minimize
提供了几种方法,请参阅文档:https://docs.scipy.org/doc/scipy/reference/ generated/scipy.optimize.minimize.html

© www.soinside.com 2019 - 2024. All rights reserved.