Python 中截断方程的最佳求解方法
Best approach for solving equation with truncations in Python
我正在尝试使用数值方法求解一个可以在 Python 中截断的方程。我想知道最好的图书馆和方法是什么?以下是有关该问题的更多详细信息:
等式每次都在变化。从人类的角度来看,方程式应该非常简单;它们包括常见的运算符,如 +、-、*、/,它们有时也有截断函数(截断为整数)或限制函数(限制两个提供的边界之间括号中的值)或(很少)多个变量。几个例子(这些是单独的例子而不是方程组)是:
- 截断(VAR_1 + 300) - 50.4 = 200
- (VAR_2 + VAR_3)*3 = 35
- 限制(3,5)(VAR_4) = 8
- VAR_5 = 34
(这并不完全是等式的样子,因为我是用后缀表示法写的,但我有一个计算器可以根据提供的输入值确定它们的值。)
对于这些方程,我所需要的只是为每个变量求解每个方程的一些值;我不需要知道每个解决方案。
关于此的一些额外注意事项是 a) 这些变量都有最大值和最小值,b) 虽然完美会很好,偶尔的错误是可以接受的,并且 c) 一些变量是整数,我希望这是真的使事情复杂化。现在,我通过将整数值四舍五入到最接近的 int 来非常草率地处理这个问题,但对于我的情况来说也是可以接受的。
为了解决这个问题,我尝试使用 Sympy 进行分析解决(如您所料,它对截断不起作用并且难以实现),并且我还尝试使用 Scipy 最小化作为如下:
minimize(minimization, x0, method = 'SLSQP', constraints = cons, tol = 1e-3, options={'ftol': 1e-3, 'disp':True, 'maxiter': 100, "eps":.1}, args = (x_vals, postfix, const_values, value))
这个被截断卡住了,大概是因为它不知道移动的方向,除非我将步长设置为 1,这会降低准确性。出于某种原因,它似乎也没有遵循 ftol,因为它会在公差范围内给出可接受的答案,但只会继续迭代限制。
我正在考虑使用像“马尔可夫链 Monte Carlo”方法这样的随机游走的方法,但我真的对此了解不多,很想听听其他想法。
我最终以两种略有不同的方式解决了这个问题。他们都使用了 joni 在对原始问题的评论中建议的 Powell 求解器,对于他们两个,我必须将传递给“fun”参数的函数的输出相乘(我命名为 minimize 的函数) 100,因为我永远无法在求解器函数调用中调整公差。
当方程只有一个变量时,我从最小化函数中删除了截断。这对我的目的有用,因为我使用的方程式被截断的原因是它们将等于一个整数值(通常)。所以,当方程输出是一个整数并且只有一个变量时,我相信只要假装求解器中不存在截断函数就可以获得正确的解(尽管记得要警惕浮点数学)。 (如果截断之外的任何数字都是整数,则方程可能无解。)
在有多个变量的情况下,我的解决方案是 a) 在最小化函数中包含截断函数和 b) 按照我计划在最后舍入它们的方式舍入求解器建议的 x 值(例如,如果它们是整数值,则将它们舍入为整数)。
无论如何,此解决方案适用于上述定义的问题,但在其他方面有一些局限性。不能保证总能找到正确的输出,尤其是第二部分。遇到这个问题的人可能希望考虑的另一种方法是某种整数规划,如果他们有线性方程的话。
我正在尝试使用数值方法求解一个可以在 Python 中截断的方程。我想知道最好的图书馆和方法是什么?以下是有关该问题的更多详细信息:
等式每次都在变化。从人类的角度来看,方程式应该非常简单;它们包括常见的运算符,如 +、-、*、/,它们有时也有截断函数(截断为整数)或限制函数(限制两个提供的边界之间括号中的值)或(很少)多个变量。几个例子(这些是单独的例子而不是方程组)是:
- 截断(VAR_1 + 300) - 50.4 = 200
- (VAR_2 + VAR_3)*3 = 35
- 限制(3,5)(VAR_4) = 8
- VAR_5 = 34
(这并不完全是等式的样子,因为我是用后缀表示法写的,但我有一个计算器可以根据提供的输入值确定它们的值。)
对于这些方程,我所需要的只是为每个变量求解每个方程的一些值;我不需要知道每个解决方案。
关于此的一些额外注意事项是 a) 这些变量都有最大值和最小值,b) 虽然完美会很好,偶尔的错误是可以接受的,并且 c) 一些变量是整数,我希望这是真的使事情复杂化。现在,我通过将整数值四舍五入到最接近的 int 来非常草率地处理这个问题,但对于我的情况来说也是可以接受的。
为了解决这个问题,我尝试使用 Sympy 进行分析解决(如您所料,它对截断不起作用并且难以实现),并且我还尝试使用 Scipy 最小化作为如下:
minimize(minimization, x0, method = 'SLSQP', constraints = cons, tol = 1e-3, options={'ftol': 1e-3, 'disp':True, 'maxiter': 100, "eps":.1}, args = (x_vals, postfix, const_values, value))
这个被截断卡住了,大概是因为它不知道移动的方向,除非我将步长设置为 1,这会降低准确性。出于某种原因,它似乎也没有遵循 ftol,因为它会在公差范围内给出可接受的答案,但只会继续迭代限制。
我正在考虑使用像“马尔可夫链 Monte Carlo”方法这样的随机游走的方法,但我真的对此了解不多,很想听听其他想法。
我最终以两种略有不同的方式解决了这个问题。他们都使用了 joni 在对原始问题的评论中建议的 Powell 求解器,对于他们两个,我必须将传递给“fun”参数的函数的输出相乘(我命名为 minimize 的函数) 100,因为我永远无法在求解器函数调用中调整公差。
当方程只有一个变量时,我从最小化函数中删除了截断。这对我的目的有用,因为我使用的方程式被截断的原因是它们将等于一个整数值(通常)。所以,当方程输出是一个整数并且只有一个变量时,我相信只要假装求解器中不存在截断函数就可以获得正确的解(尽管记得要警惕浮点数学)。 (如果截断之外的任何数字都是整数,则方程可能无解。)
在有多个变量的情况下,我的解决方案是 a) 在最小化函数中包含截断函数和 b) 按照我计划在最后舍入它们的方式舍入求解器建议的 x 值(例如,如果它们是整数值,则将它们舍入为整数)。
无论如何,此解决方案适用于上述定义的问题,但在其他方面有一些局限性。不能保证总能找到正确的输出,尤其是第二部分。遇到这个问题的人可能希望考虑的另一种方法是某种整数规划,如果他们有线性方程的话。