如何使用 Python 求解一对非线性方程?

2025-03-04 08:23:00
admin
原创
95
摘要:问题描述:使用 Python解决一对非线性方程的(最佳)方法是什么。(Numpy、Scipy 或 Sympy)例如:x+y^2 = 4e^x+ xy = 3解决上述问题的代码片段将会很棒解决方案 1:对于数值解,可以使用 fsolve:http://docs.scipy.org/doc/scipy/refer...

问题描述:

使用 Python解决一对非线性方程的(最佳)方法是什么。(Numpy、Scipy 或 Sympy)

例如:

  • x+y^2 = 4

  • e^x+ xy = 3

解决上述问题的代码片段将会很棒


解决方案 1:

对于数值解,可以使用 fsolve:

http://docs.scipy.org/doc/scipy/reference/ generated/scipy.optimize.fsolve.html#scipy.optimize.fsolve

from scipy.optimize import fsolve
import math

def equations(p):
    x, y = p
    return (x+y**2-4, math.exp(x) + x*y - 3)

x, y =  fsolve(equations, (1, 1))

print equations((x, y))

解决方案 2:

简短回答:使用 fsolve

正如其他答案中提到的那样,针对您提出的特定问题的最简单解决方案是使用类似以下方法fsolve

from scipy.optimize import fsolve
from math import exp

def equations(vars):
    x, y = vars
    eq1 = x+y**2-4
    eq2 = exp(x) + x*y - 3
    return [eq1, eq2]

x, y =  fsolve(equations, (1, 1))

print(x, y)

输出:

0.6203445234801195 1.8383839306750887

分析解决方案?

您说的是“解决”方法,但解决方案有很多种。既然您提到了 SymPy,我应该指出这可能意味着的最大区别,即解析解数值解之间的区别。您给出的特定示例没有(简单的)解析解,但其他非线性方程组有。当有现成的解析解时,SymPY 通常可以为您找到它们:

from sympy import *

x, y = symbols('x, y')
eq1 = Eq(x+y**2, 4)
eq2 = Eq(x**2 + y, 4)

sol = solve([eq1, eq2], [x, y])

输出:

⎡⎛ ⎛  5   √17⎞ ⎛3   √17⎞    √17   1⎞  ⎛ ⎛  5   √17⎞ ⎛3   √17⎞    1   √17⎞  ⎛ ⎛  3   √13⎞ ⎛√13   5⎞  1   √13⎞  ⎛ ⎛5   √13⎞ ⎛  √13   3⎞  1   √13⎞⎤
⎢⎜-⎜- ─ - ───⎟⋅⎜─ - ───⎟, - ─── - ─⎟, ⎜-⎜- ─ + ───⎟⋅⎜─ + ───⎟, - ─ + ───⎟, ⎜-⎜- ─ + ───⎟⋅⎜─── + ─⎟, ─ + ───⎟, ⎜-⎜─ - ───⎟⋅⎜- ─── - ─⎟, ─ - ───⎟⎥
⎣⎝ ⎝  2    2 ⎠ ⎝2    2 ⎠     2    2⎠  ⎝ ⎝  2    2 ⎠ ⎝2    2 ⎠    2    2 ⎠  ⎝ ⎝  2    2 ⎠ ⎝ 2    2⎠  2    2 ⎠  ⎝ ⎝2    2 ⎠ ⎝   2    2⎠  2    2 ⎠⎦

请注意,在此示例中,SymPy 找到了所有解决方案,并且不需要给出初始估计。

您可以使用以下方法以数值方式评估这些解决方案evalf

soln = [tuple(v.evalf() for v in s) for s in sol]
[(-2.56155281280883, -2.56155281280883), (1.56155281280883, 1.56155281280883), (-1.30277563773199, 2.30277563773199), (2.30277563773199, -1.30277563773199)]

数值解的精度

然而,大多数非线性方程组都没有合适的解析解,因此使用上述 SymPy 效果很好,但并不普遍适用。这就是为什么我们最终会寻找数值解,尽管有数值解:1) 当有很多解时,我们无法保证我们找到了所有解或“正确”解。2) 我们必须提供一个初始猜测,这并不总是那么容易。

接受我们需要数字解决方案的事实后,类似这样的方法fsolve通常可以满足您的所有需求。对于这种问题,SymPy 可能会慢得多,但它可以提供其他功能,即更精确地找到(数字)解决方案:

from sympy import *

x, y = symbols('x, y')
nsolve([Eq(x+y**2, 4), Eq(exp(x)+x*y, 3)], [x, y], [1, 1])
⎡0.620344523485226⎤
⎢                 ⎥
⎣1.83838393066159 ⎦

更精确地:

nsolve([Eq(x+y**2, 4), Eq(exp(x)+x*y, 3)], [x, y], [1, 1], prec=50)
⎡0.62034452348522585617392716579154399314071550594401⎤
⎢                                                    ⎥
⎣ 1.838383930661594459049793153371142549403114879699 ⎦

解决方案 3:

如果您更喜欢 sympy,那么您可以使用nsolve。

>>> nsolve([x+y**2-4, exp(x)+x*y-3], [x, y], [1, 1])
[0.620344523485226]
[1.83838393066159]

第一个参数是方程列表,第二个参数是变量列表,第三个参数是初始猜测。

解决方案 4:

另一种方法fsolveroot

import numpy as np
from scipy.optimize import root    

def your_funcs(X):

    x, y = X
    # all RHS have to be 0
    f = [x + y**2 - 4,
         np.exp(x) + x * y - 3]

    return f

sol = root(your_funcs, [1.0, 1.0])
print(sol.x)

这将打印

[0.62034452 1.83838393]

如果你检查

print(your_funcs(sol.x))

你获得

[4.4508396968012676e-11, -1.0512035686360832e-11]

确认解决方案是正确的。

解决方案 5:

试试这个,我向你保证它会完美地发挥作用。

    import scipy.optimize as opt
    from numpy import exp
    import timeit

    st1 = timeit.default_timer()

    def f(variables) :
        (x,y) = variables

        first_eq = x + y**2 -4
        second_eq = exp(x) + x*y - 3
        return [first_eq, second_eq]

    solution = opt.fsolve(f, (0.1,1) )
    print(solution)


    st2 = timeit.default_timer()
    print("RUN TIME : {0}".format(st2-st1))

->

[ 0.62034452  1.83838393]
RUN TIME : 0.0009331008900937708

仅供参考。如上所述,您还可以通过将“fsolve”替换为“broyden1”来使用“Broyden 近似”。它有效。我做到了。

我不清楚 Broyden 近似法的具体工作原理,但它花费了 0.02 秒。

而且我建议你不要使用 Sympy 的功能<- 确实很方便,但就速度而言,它相当慢。你会看到。

解决方案 6:

我在 IDL 中使用 Broyden 方法来处理耦合非线性方程(通常涉及多项式和指数),但我还没有在 Python 中尝试过:

http://docs.scipy.org/doc/scipy/reference/ generated/scipy.optimize.broyden1.html#scipy.optimize.broyden1

scipy.optimize.broyden1

scipy.optimize.broyden1(F, xin, iter=None, alpha=None, reduction_method='restart', max_rank=None, verbose=False, maxiter=None, f_tol=None, f_rtol=None, x_tol=None, x_rtol=None, tol_norm=None, line_search='armijo', callback=None, **kw)[source]

使用 Broyden 的第一雅可比近似找到函数的根。

该方法也被称为“Broyden好方法”。

解决方案 7:

您可以使用 openopt 包及其 NLP 方法。它有许多动态规划算法来求解非线性代数方程,包括:

goldenSection、scipy_fminbound、scipy_bfgs、scipy_cg、scipy_ncg、amsg2p、scipy_lbfgsb、scipy_tnc、bobyqa、ralg、ipopt、scipy_slsqp、scipy_cobyla、lincher、algencan,您可以从中选择。 其中一些算法可以解决受约束的非线性规划问题。因此,您可以使用如下函数

将您的方程组引入openopt.NLP() :

lambda x: x[0] + x[1]**2 - 4, np.exp(x[0]) + x[0]*x[1]

解决方案 8:

from scipy.optimize import fsolve

def double_solve(f1,f2,x0,y0):
    func = lambda x: [f1(x[0], x[1]), f2(x[0], x[1])]
    return fsolve(func,[x0,y0])

def n_solve(functions,variables):
    func = lambda x: [ f(*x) for f in functions]
    return fsolve(func, variables)

f1 = lambda x,y : x**2+y**2-1
f2 = lambda x,y : x-y

res = double_solve(f1,f2,1,0)
res = n_solve([f1,f2],[1.0,0.0])

解决方案 9:

您可以使用nsolvesympy意思是numerical solver

下面是一个用 求解方程的示例代码片段sympy

from sympy import *

L = 4.11 * 10 ** 5
nu = 1
rho = 0.8175
mu = 2.88 * 10 ** -6
dP = 20000
eps = 4.6 * 10 ** -5

Re, D, f = symbols('Re, D, f')

nsolve((Eq(Re, rho * nu * D / mu),
       Eq(dP, f * L / D * rho * nu ** 2 / 2),
       Eq(1 / sqrt(f), -1.8 * log ( (eps / D / 3.) ** 1.11 + 6.9 / Re))),
      (Re, D, f), (1123, -1231, -1000))

其中(1123, -1231, -1000)是寻找根的初始向量。它给出:

[    13602.9381926005 - 5.34318284637546 * 10^-27 i 
   0.0479222776693451 - 1.88236901455499 * 10^-32 i
  0.00570516040320484 + 2.76709731583615 * 10^-34 i ]

虚部非常小,均为 10^(-20),因此我们可以认为它们为零,这意味着根均为实数。Re ~ 13602.938,D ~ 0.047922,f~0.0057。

您可以编辑代码以求解所需的方程式,这就是其中Eq(..., ...)的一部分。不要忘记首先声明元素symbols('...')

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   3878  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   2714  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Freshdesk、ClickUp、nTask、Hubstaff、Plutio、Productive、Targa、Bonsai、Wrike。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在项目管理过程中面临着诸多痛点,如任务分配不...
项目管理系统   49  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Monday、TeamGantt、Filestage、Chanty、Visor、Smartsheet、Productive、Quire、Planview。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多项目经理和团队在管理复杂项目时,常...
开源项目管理工具   49  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Smartsheet、GanttPRO、Backlog、Visor、ResourceGuru、Productive、Xebrio、Hive、Quire。在当今快节奏的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在选择项目管理工具时常常面临困惑:...
项目管理系统   49  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用