You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

变量规模可变的Sympy方程组I2最小化方案求助

问题描述

需要对以下Python代码中的I2进行最小化处理。尝试过scipy、sympy、gekko等库,但这些库要求显式定义变量,而变量数量会随代码中n的取值变化(如20、28、36个变量),显式定义大量变量并不合理。当前通过x = [sp.symbols('x%d' % i) for i in range(8*n-4)]生成变量,询问是否需要改用其他方法,或是对现有方法进行修改。

原始代码
import numpy as np
import sympy as sp
from sympy import *
from scipy.special import roots_legendre, eval_legendre

# create variables
n=2;z=1;m=2;a=0;b=100
x = [sp.symbols('x%d' % i) for i in range(8*n-4)]
#x=sp.symbols('x:20')
#t=sp.symbols('t ')
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]=factorial(i+j)/(2**j*factorial(j)*factorial(i-j))
PS=Matrix(1,n,x[0:n]);PI=Matrix(1,n,x[n:2*n]);PH=Matrix(1,n,x[2*n:3*n]);PL=Matrix(1,n,x[3*n:4*n])
TS=[[1]];TI=[[1]];TH=[[1]];TL=[[1]]
for i in range(n-1):
    TS.append([t**(x[4*n+i]+i+1)])
    TI.append([t**(x[5*n+i-1]+i+1)])
    TH.append([t**(x[6*n+i-2]+i+1)])
    TL.append([t**(x[7*n+i-3]+i+1)])
MTS=Matrix(TS);MTI=Matrix(TI);MTH=Matrix(TH);MTL=Matrix(TL)
S=PS*B*MTS;I=PI*B*MTI;H=PH*B*MTH;L=PL*B*MTL
#CONVERT SYMPY MATRICES TO NUMPY ONE
S0=np.array(S);I0=np.array(I);H0=np.array(H);L0=np.array(L)
GS=zeros(n,n);GI=zeros(n,n);GH=zeros(n,n);GL=zeros(n,n)
for i in range(n):
   if i==0:
      GS[i,i]=0
      GI[i,i]=0
      GH[i,i]=0
      GL[i,i]=0
   else:
      GS[i,i]=simplify(gamma(x[4*n+i-1]+i+1)/gamma(x[4*n+i-1]+i+1-z))
      GI[i,i]=simplify(gamma(x[5*n+i-2]+i+1)/gamma(x[5*n+i-2]+i+1-z))
      GH[i,i]=simplify(gamma(x[6*n+i-3]+i+1)/gamma(x[6*n+i-3]+i+1-z))
      GL[i,i]=simplify(gamma(x[7*n+i-4]+i+1)/gamma(x[7*n+i-4]+i+1-z))
DS=simplify(t**(-z)*PS*B*GS*MTS)
DI=simplify(t**(-z)*PI*B*GI*MTI)
DH=simplify(t**(-z)*PH*B*GH*MTH)
DL=simplify(t**(-z)*PL*B*GL*MTL)
RS=DS[0,0]-(.0043217-.125*S[0,0]*I[0,0]-(.002+.0008)*S[0,0])
RI=DI[0,0]-(.125*S[0,0]*I[0,0]+.0056*H[0,0]*I[0,0]+.029*L[0,0]-(.002+.0008+.025+.35)*I[0,0])
RH=DH[0,0]-(.535-.0056*H[0,0]*I[0,0]+.35*I[0,0]-(.002+.0008)*H[0,0])
RL=DL[0,0]-(.025*I[0,0]-(.002+.0008+.029)*L[0,0])
#f = lambdify(t, R)
def R(s):
   return (RS**2+RI**2+RH**2+RL**2).subs(t,s)
r, w = roots_legendre(m)
w=zeros(1,m)
I1=0
for i in range (m):
   w[i]=R((b-a)/2*r[i]+(b+a)/2)
   I1=I1+w[i]
I2=((b-a)/2)*I1
解决方案

不需要放弃当前的变量生成方式,可通过以下两种适配方案实现最小化:

1. 适配Scipy优化器:符号转数值函数

利用Sympy的lambdify工具,将符号表达式I2转换为接受numpy数组输入的数值函数,直接适配Scipy的优化接口,无需显式定义单个变量:

# 先确保I2是仅依赖x的符号表达式(t已被积分消除)
# 将I2转为支持数组输入的数值函数
I2_func = sp.lambdify(x, I2, 'numpy')

# 定义优化目标函数,接受一维numpy数组
def objective(x_arr):
    return I2_func(*x_arr)

# 生成初始值数组,长度与变量列表一致
x0 = np.ones(len(x))

# 调用Scipy优化器求解
from scipy.optimize import minimize
result = minimize(objective, x0, method='L-BFGS-B')

print("最优变量值:", result.x)
print("最小I2值:", result.fun)

2. 适配Gekko:动态生成变量

Gekko支持动态批量创建变量,无需逐个显式定义,只需将原Sympy逻辑转换为Gekko支持的运算语法即可:

from gekko import GEKKO

# 初始化本地Gekko模型
m = GEKKO(remote=False)
# 动态生成变量列表,数量随n自动变化
x = [m.Var(value=1) for _ in range(8*n-4)]

# 以下为原Sympy逻辑的Gekko转换示例(需替换对应运算)
# 1. 构建B矩阵
B = m.Array(m.Const, (n,n))
for i in range(n):
    for j in range(n):
        if i < j:
            B[i,j] = 0
        else:
            # Gekko中阶乘可用m.factorial
            B[i,j] = m.factorial(i+j)/(2**j * m.factorial(j) * m.factorial(i-j))

# 2. 构建PS、PI等矩阵(Gekko矩阵操作)
PS = m.Array(m.Var, (1,n))
for i in range(n):
    PS[0,i] = x[i]
# 其余PI、PH、PL同理...

# 3. 处理gamma函数(Gekko直接支持m.gamma)
# 其余逻辑按Gekko语法转换后,定义目标函数
m.Obj(I2)

# 求解
m.solve(disp=True)

3. 可选优化:减少变量规模

观察代码中变量的使用模式,例如TS、TI中的指数变量是否存在可合并的约束关系,可尝试归类变量,减少总变量数,降低优化问题的复杂度。

内容的提问来源于stack exchange,提问作者hojat saeidi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 15:54:51