【问题标题】:Solve set of simple equations given only a few variables求解仅给定几个变量的简单方程组
【发布时间】:2016-10-27 05:56:57
【问题描述】:

我有一组几百个简单的求和方程。例如这里有 3 个:

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

我正试图找到一种方法来解决尽可能多的问题,只要给出几个值。例如,在上面的方程组中,如果我有u1u2,我可以计算w1,但没有别的。 给定u1u2w2,我可以计算出w1w4。等等……

目前我正在以一种相当直接的方式处理这个问题(伪代码):

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

这可行,但感觉笨重且效率低下。

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

编辑:我知道这可以通过一系列线性方程来解决,如果我对这些值足够了解的话。我正在寻找一种方法,当我对作为线性方程组的求解不够了解时使用(或者可能有一种奇特的方法来以某种方式减少问题)

EDIT 2:错误,已删除

EDIT 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})

【问题讨论】:

  • 你能用你的数据结构发布一些代码吗?有很多方法可以表示这些东西,我希望能够使用您自己的设置来回答。
  • @Prune - 当然,我今天不在办公室,但今晚会举个例子
  • @Prune - 根据我的示例添加了一些代码。
  • 听起来你应该把它扔到sympy.solvers.solveset.linsolve 并收工。这将为您提供解决方案集的完整基础,包括可以确定其值的任何变量的值。你的蛮力解决方案不会找到所有东西。
  • (Reduced Row Echelon Form) 谷歌搜索“RREF”应该可以帮到你……如果你没有线性代数的背景,那么你可能需要做一点背景阅读,但应该是光,我见过的大多数文本都是第 1 章或第 2 章。

标签: python performance recursion sympy


【解决方案1】:

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

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


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

【讨论】:

    【解决方案2】:

    您的原始描述很清楚,示例完整。

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


    数据对象

    方程有一个变量和系数 (LHS) 和常数 (RHS) 的列表。此外,请计算仍有多少变量尚未解决。这些变量是对...的引用

    变量包括方程引用(用途)列表和一个值(如果尚未求解,则为无)。

    Open equation list是未解方程的列表。


    算法

    初始化 按未知数对方程式列表进行排序——至少可以识别出只剩下 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
    

    请注意,“更新该方程式”可能涉及多个步骤。最值得注意的是,确保更新未知数;如果现在是 1,则将其移入队列以解决。


    之后

    如果你幸运的话,你会解出所有的方程......或者你至少会有和未知数一样多的方程,所以你可以使用你最喜欢的数学包的线性求解工具来完成这项工作.

    【讨论】:

    • “您的蛮力方法将足够有效” - 嗯,这取决于您的“足够有效”标准。不能保证找到具有确定值的所有变量的值;它甚至可能不会接近。
    • 嗯,那条评论在我写的时候是有效的——大约是在用代码编辑之前 6 小时。
    【解决方案3】:

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

    假设第 4 个方程是

    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

    【讨论】:

    • 如果我知道所有的 u1、u2、u3 和 u4,这很好。但如果我只知道其中 2 个呢?
    • @jprockbelly u 你的意义不大,你必须确保你有相同数量的方程和未知数。或者你无法得到未知号码。
    • 抱歉,如果我的问题不清楚,我正在寻找一个解决方案,因为我没有相同数量的未知数和方程。在我的真实案例中,我有大约 200 个方程和大约 75 个变量,但我一次只能知道一小部分变量。见上面的编辑
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多