使用 fsolve 和不等式方程求解方程

问题描述

我无法理解如何将不等式方程添加到 fsolve 函数中。

例如:

这是包:

import numpy as np
from scipy.optimize import fsolve

这些是我想要使用的方程:

x1 >= 0.4 and x1 <= 0.7
x2 >= 0.2 and x2 <= 0.4
5x2**2 + 2x1**3 = 2 

这是我试图创建的函数

myFunc(z):
    x1 = z[0]
    x2 = z[1]
    
    F = np.empty((3))
    F[0] = x1 >= 0.4 and x1 <= 0.7 # <-- This is the first equation
    F[1] = x2 >= 0.2 and x2 <= 0.4 # <-- this is the second equation
    F[2] = 5x2**2 + 2x1**3 = 2 # <-- this is the third equation
    return F

然后我们调用 fsolve:

zGuess = np.array([0.3,0.3])
z = fsolve(myFunction,zGuess)
print(z)

关于如何设置不等式方程有什么想法吗?

解决方法

fsolve 方法既不能处理不等式约束,也不能处理变量的界限。您的前两个约束是简单的框约束,即变量的边界,因此您只想求解受变量边界约束的非线性方程组 2x1**3 + 5x**2 == 2。这可以表述为约束最小化问题,类似于 this answer:

For F(x) = 2x1**3 + 5x**2 - 2 you want to solve

min ||F(x)|| 

s.t. 0.4 <= x1 <= 0.7,0.2 <= x2 <= 0.4

这个约束优化问题可以用 scipy.optimize.minimize 轻松解决,如下所示:

from scipy.optimize import minimize
import numpy as np

def obj(x): return 5*x[1]**2 + 2*x[0]**3 - 2

# Set the variable bounds
bounds = [(0.4,0.7),(0.2,0.4)]

# Set initial guess
x0 = np.array([0.3,0.3])

# Solve the problem (res.x contains your solution)
res = minimize(lambda x: np.linalg.norm(obj(x)),x0=x0,bounds=bounds)

请注意,在您的范围内没有满足非线性方程的点。无论如何,当我们最小化残差的欧几里德范数时,我们得到了最好的点。