用Python解决数学方程的最简单方法

27

我想解决一组线性或二次方程。虽然我没有特定的问题,但我经常遇到这种情况。

使用与Mathematica类似的网站wolframalpha.com来解决它们非常简单。但这并不能像在iPython shell中那样提供舒适和便利。

有没有一个简单的库可以在python shell中处理线性和二次方程?

就个人而言,我觉得使用卡西欧991 MS科学计算器非常方便。我知道如何设置变量,解决方程等等。我希望能够从ipython shell中使用这样的工具。我很惊讶竟然没有找到这样的库。Sage并没有给我留下足够深刻的印象;也许我错过了什么。


你是否了解Maxima语言和WxMaxima界面?我发现它比IPython更加舒适。 - Foad S. Farimani
16个回答

50

sympy 就是你要找的东西。


点赞了。让我们看一个演示!我刚刚发布了一个带有sympy演示的答案,以帮助人们入门。 - Gabriel Staples

23
您将最佳答案视为不可接受。
您的问题是:“我想要一个免费的计算机代数系统,可以在Python中使用。”
答案是:“SAGE就是这样做的。”
您看过maxima/macsyma吗?SAGE为其提供绑定,这是其中更强大的免费系统之一。 http://maxima.sourceforge.net/

11

这里是使用Python(通过Sage)解决原问题的方法。这基本上澄清了Paul McMillan在上面所做的评论。

sage: a,b,c = var('a,b,c')
sage: solve([a+b+c==1000, a^2+b^2==c^2], a,b,c)
[[a == 1000*(r1 + sqrt(r1^2 + 2000*r1 - 1000000))/(r1 + sqrt(r1^2 + 2000*r1 - 1000000) + 1000), b == -1/2*r1 - 1/2*sqrt(r1^2 + 2000*r1 - 1000000) + 500, c == r1], [a == 1000*(r2 - sqrt(r2^2 + 2000*r2 - 1000000))/(r2 - sqrt(r2^2 + 2000*r2 - 1000000) + 1000), b == -1/2*r2 + 1/2*sqrt(r2^2 + 2000*r2 - 1000000) + 500, c == r2]]

9

对于不精确的解决方案,请阅读线性规划顺序二次优化,然后搜索可以为您执行此类优化的Python库。

如果方程需要整数解,则应搜索Python的丢番图方程求解器。

请注意,仅使用简单的求解器来解决欧拉计划问题是缺乏意义的。有趣且富有教育意义的部分是学习如何使用原始方法自己解决问题!


他们可以提供精确的解决方案 - 这取决于模型、约束和容差...对于连续问题,使用梯度下降算法...对于混合整数问题,请参考分支定界法 - 但它在LP求解器内部使用,您不需要关心算法本身,找到适合解决任务的库(如scipy.optimize、pulp、GEKKO、Networkx等)。 - undefined

6
一个免费的Web服务,用于解决大规模非线性方程组(1百万+)是APMonitor.com。有一个浏览器界面和与Python/MATLAB的API。Python的API是一个单一的脚本(apm.py),可以从apmonitor.com主页下载。一旦将脚本加载到Python代码中,便能解决以下问题:
- 非线性方程 - 微分和代数方程 - 最小二乘模型拟合 - 移动视角估计 - 非线性模型预测控制 - 等等
对于新用户,APM Python软件有一个Google Groups论坛,用户可以在其中发布问题。每两周会有网络研讨会,展示运筹学和工程优化问题的优化案例。
以下是一个优化问题的示例(hs71.apm)。
Model

  Variables

    x[1] = 1, >=1, <=5

    x[2] = 5, >=1, <=5

    x[3] = 5, >=1, <=5

    x[4] = 1, >=1, <=5

  End Variables



  Equations

    x[1] * x[2] * x[3] * x[4] > 25

    x[1]^2 + x[2]^2 + x[3]^2 + x[4]^2 = 40



    minimize  x[1] * x[4] * (x[1]+x[2]+x[3]) + x[3]

  End Equations

End Model

以下Python脚本用于解决优化问题:

# Import

from apm import *

# Select server

server = 'http://xps.apmonitor.com'

# Application name

app = 'eqn'

# Clear previous application

apm(server,app,'clear all')

# Load model file

apm_load(server,app,'hs71.apm')

# Option to select solver (1=APOPT, 2=BPOPT, 3=IPOPT)

apm_option(server,app,'nlc.solver',3)

# Solve on APM server

solver_output = apm(server,app,'solve')


# Display solver output

print solver_output


# Retrieve results

results = apm_sol(server,app)

# Display results

print '--- Results of the Optimization Problem ---'

print results

# Display Results in Web Viewer 

url = apm_var(server,app)

print "Opened Web Viewer: " + url

5

4

参考资料:沃尔夫拉姆阿尔法的解决方案

a-1000!=0,   b = (1000 (a-500))/(a-1000),   c = (-a^2+1000 a-500000)/(a-1000)

在Python中,使用{{link1:sympy的求解器模块}}(请注意,它假设所有方程都设置为零):
>>> import sympy
>>> a, b, c = sympy.symbols('a, b, c')
>>> sympy.solve([a + b + c - 1000, a**2 + b**2 - c**2], b, c)
[(1000*(a - 500)/(a - 1000), (-a**2 + 1000*a - 500000)/(a - 1000))]

当然,a!= 1000,因为a-1000是这两个方程的分母。

2

1

SymPy符号Python库演示:符号求解数学和积分以及漂亮的输出

来自@Autoplectic:

sympy正是你所需要的。

虽然我有时倾向于在Stack Overflow上写一些最长的答案,但这是我在Stack Overflow上看到的最短的答案。

让我们添加一个基本演示。

您需要的参考和教程:

  1. https://www.sympy.org/zh/index.html --> 点击“开始教程”
    1. 教程索引:https://docs.sympy.org/latest/tutorial/index.html 示例页面:
      1. 基本操作
      2. 打印
      3. 简化
      4. 微积分

我想出的微积分演示(参见此处以查看我用来入门的主要教程):

简短版:

#!/usr/bin/env python3

from sympy import *
x, y, z = symbols('x y z')
init_printing(use_unicode=True)

integral = Integral(exp(-x**2 - y**2), (x, -oo, oo), (y, -oo, oo))
print(pretty(integral))
result = integral.doit() # "do it": evaluate the integral
print(pretty(result))

更长的版本:

eRCaGuy_hello_world/math/sympy_integral_and_printing.py:

#!/usr/bin/env python3

from sympy import *
x, y, z = symbols('x y z')
init_printing(use_unicode=True)

# Store an integral
integral = Integral(exp(-x**2 - y**2), (x, -oo, oo), (y, -oo, oo))
# print it in various ways
print("ORIGINAL INTEGRAL:")
print(pretty(integral))
pprint(integral)        # "pretty print": same as above
print(pretty(integral, use_unicode=False))  # pretty print with ASCII instead 
                                            # of unicode
print(integral)         # plain text
print(latex(integral))  # in LaTeX format

# Now solve the integral and output the result by telling it to
# "do it".
result = integral.doit()
# print it in various ways
print("\nRESULT:")
print(pretty(result))
pprint(result)
print(pretty(result, use_unicode=False))
print(result)
print(latex(result))

请注意,使用pprint(integral)print(pretty(integral))相同。
运行上述命令的输出:
ORIGINAL INTEGRAL:
∞  ∞                  
⌠  ⌠                  
⎮  ⎮      2    2      
⎮  ⎮   - x  - y       
⎮  ⎮  ℯ          dx dy
⌡  ⌡                  
-∞ -∞                 
∞  ∞                  
⌠  ⌠                  
⎮  ⎮      2    2      
⎮  ⎮   - x  - y       
⎮  ⎮  ℯ          dx dy
⌡  ⌡                  
-∞ -∞                 
 oo  oo                 
  /   /                 
 |   |                  
 |   |      2    2      
 |   |   - x  - y       
 |   |  e          dx dy
 |   |                  
/   /                   
-oo -oo                 
Integral(exp(-x**2 - y**2), (x, -oo, oo), (y, -oo, oo))
\int\limits_{-\infty}^{\infty}\int\limits_{-\infty}^{\infty} e^{- x^{2} - y^{2}}\, dx\, dy

RESULT:
π
π
pi
pi
\pi

Python中的SymPy符号数学库可以处理几乎任何类型的数学问题,例如解方程、简化、因式分解、替换变量值、漂亮的打印输出、转换为LaTeX格式等等。在我非常有限的使用中,它似乎是一个相当强大的求解器。我建议尝试一下。

对于我来说(在Linux Ubuntu上测试),安装它就像这样简单:

pip3 install sympy

1
我会用 Octave 进行这个,但我同意,Octave 的语法并不令人兴奋(文档总是让我更加困惑)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接