只给出一些变量,求解一组简单的方程

时间:2016-10-27 05:56:58

标签: python performance recursion sympy

我有一套几百个简和方程。例如,这里有3:

 w1 - u1 - u2 = 0 
 w1 + w2 - w3 - u3 = 0
 w1 - w2 - w4 = 0

我试图找到一种方法来解决尽可能多的只给出一些值的方法。例如,在上面的等式集中,如果我有u1u2,我可以计算w1,但没有别的。 鉴于u1u2w2,我可以计算w1w4。等等......

目前我正以相当直接的方式接近这个(psudo代码):

while there are new results:
     for each equation:
         try to solve equation:
             if solved update result set

这有效,但感觉笨重而且效率低下。

有更好的方法吗? (如果相关则使用Python)

编辑:我知道这可以通过一系列线性方程来解决,如果我知道足够多的值。我正在寻找一种方法,当我不知道如何解决一个线性方程组时(或者可能有一种奇妙的方法来减少问题)

编辑2 :错误,已删除

编辑3 :对于使用sympy感兴趣我的解决方案的任何人:

from sympy import linsolve, symbols, linear_eq_to_matrix
w1, w2, w3, w4, u1, u2, u3 = symbols("w1, w2, w3, w4, u1, u2, u3", integer=True)
variables = [w1, w2, w3, w4, u1, u2, u3]

def my_solver(known_vals):

    eqns = [w1 - u1 - u2, 
            w1 + w2 - w3 - u3,
            w1 - w2 - w4]

    #add the known variables to equation list
    for x in known_vals.keys():
        eqns.append(x - (known_vals[x]))

    A, b = linear_eq_to_matrix(eqns, variables)
    solution = linsolve((A, b), variables)

    return solution


my_solver({w1:2, u2:-2})

3 个答案:

答案 0 :(得分:3)

只需获取SymPy并将整个线性方程组填充到sympy.solvers.solveset.linsolve中。它将为您提供整个解决方案空间,包括具有确定值的变量值,其形式取决于系统是否具有0,1或无限解。

可能还有一种NumPy / SciPy方法来获得一个未确定系统的解决方案,但无论如何,我都不知道。谷歌建议singular value decomposition会很有用,但我还没弄清楚你是如何得到解决方案的基础的。

如果不清楚,“整个线性方程组”包括将已知变量值公式化为方程式。例如,如果您知道u2 = 5,则u2 = 5将成为线性方程之一。您在u2 - 5列表中将其表示为eqns

答案 1 :(得分:1)

您的原始说明已经足够清晰,并附有示例。

通用解决方案所需的是数据流图和一些图遍历算法。但是,只需要200个方程式,你的蛮力方法就足够了。但是,为了长期使用,我将其设置为我们在编译器构造中的方式:

数据对象

等式有一个变量和系数列表(LHS)和常量(RHS)。此外,还要计算仍未解决的变量数量。这些变量是对......的引用。

变量包括方程式引用(使用)列表和值(如果尚未解决则为None)。

打开方程式列表是未解决的方程式列表。

<强>算法

<强>初始化 按未知数量对方程式列表进行排序 - 至少要识别那些只有1个未知数的那些。

<强>迭代

while there are equations with only 1 unknown:
    for each such equation:
        solve that equation for the remaining variable
        for each equation in the variable's reference list:
            update that equation

请注意&#34;更新该等式&#34;可以涉及几个步骤。最值得注意的是,确保更新未知数;如果现在是1,请将其移入队列中解决。

<强> Afters

如果您很幸运,您已经解决了所有方程式......或者您至少拥有与未知数一样多的方程式,因此您可以使用您喜欢的线性求解设施数学包完成这项工作。

答案 2 :(得分:-1)

您可以使用一些线性代数方法来解决问题。

假设第四个等式是

w1 + w2 + w3 + w4 = 2

然后您可以将矩阵写为:

In [28]: martix = np.array([[ 1,  0,  0,  0],
...:        [ 1,  1, -1,  0],
...:        [ 1, -1,  0, -1],
...:        [ 1,  1,  1,  1]])

假设u1 = 10,u2 = -5,u3 = 6,u4 = 2并将它们移到右边:

In [34]: ans = np.array([u1+u2, u3, 0, u4])

然后使用numpy来解决:

In [35]: np.linalg.solve(martix,ans)
Out[35]: array([  5.,  -7.,  -8.,  12.])

你得到w1 = 5 w2 = -7 w3 = -8和w4 = 12