【问题标题】:Algorithm(s) for rearranging simple symbolic algebraic expressions重新排列简单符号代数表达式的算法
【发布时间】:2011-01-02 03:42:03
【问题描述】:

我想知道是否有一种简单的算法可以重新排列简单的符号代数表达式。理想情况下,我希望能够在左侧仅使用一个变量来重写任何此类表达式。例如,给定输入:

m = (x + y) / 2

...我希望能够以my 的形式询问x,或者以xm 的形式询问y,并得到这些:

x = 2*m - y
y = 2*m - x

当然,多年来我们都在纸上完成了这个算法。但我想知道它是否有名字。这看起来很简单,但如果有人已经对各种“陷阱”进行了分类,那会让生活变得更轻松。

出于我的目的,我不需要它来处理二次方程。

(是的,CAS 系统可以做到这一点,是的,我知道我可以将它们用作库。我想在我的应用程序中避免这种依赖关系。我真的很想知道是否有命名算法解决这个问题。)

【问题讨论】:

  • 那些“命名算法”是在 CAS 中实现的。这是NIH的案例吗? (此处未发明)

标签: algorithm cas algebra


【解决方案1】:

您想要的是方程求解算法。但我敢打赌,这是一个巨大的话题。一般情况下,可能有:

  • 方程组
  • 方程可能是非线性的,因此需要额外的算法,例如方程分解。
  • 需要知道如何反转函数,例如 => sin(x) + 10 = z,求解 x 我们反转 sin(),即 arcsin()。 (并非所有功能都是可逆的!)
  • 最后,即使是 CAS,有些方程也可能难以求解,例如 sin(x)+x=y,求解 x。

硬性答案是——最好的办法是获取一些 CAS 的源代码——例如,你可以查看用 LISP 编写的 MAXIMA CAS 源代码。并找到负责方程求解的代码。

简单的答案 - 如果您只需要求解线性方程并且仅由基本运算符 +-*/ 组成。那你已经知道答案了——使用旧的好纸方法 - 想想我们在纸上使用的规则,然后将这些规则重写为操作方程字符串的符号算法。

祝你好运!

【讨论】:

  • 我做了更多的研究,发现约束求解器都处理这种事情。由于无论如何我的应用程序将严重依赖约束,因此我可以只使用 Choco 或 JaCoP 之类的东西。你说得对,这是一个巨大的话题,我很确定你的直觉(以及下面的另一个答案)是正确的,即方程组就是它所在的位置。
【解决方案2】:

您似乎感兴趣的是维护一个线性方程组,然后随时能够根据所有其他变量求解一个变量。如果您将关系编码为矩阵,那么您似乎可以将矩阵简化为某种不错的形式(例如,简化的行梯形形式)以获得变量之间“最简单”的依赖关系(对于“最简单”的一些很好的定义。 ") 一旦你有了这样的数据,你应该能够通过查看某个行的相关变量的非零条目来读取所有依赖关系,然后对其进行归一化以使变量具有系数 1。

注意 - 通常,您不会总是为每个变量获得唯一的解决方案。例如,给定平凡的方程

x = y
x = z

然后求解 z 可能会产生“z = x”或“z = y”,具体取决于您想要多少简化。或者,在类似的设置中

x = 2y + 3w
x = 9z

返回 x 的值可以返回表达式,或者它们的总和超过 2,或者一大堆其他的东西,这些东西在技术上都是正确的,但不一定有用。我不确定你会如何处理这个问题,但根据你的方程式的形式,你可能会找到一种处理它的方法。

【讨论】:

    【解决方案3】:

    将您的表达式转换为反向波兰表示法的数据结构(树)。你的树由节点组成,每个节点都有一个操作,一个左和一个右。左右各可以是一个符号(例如:“x”)或另一个节点。例如:

    (x + (a + b))
    

    会变成:

    (+ x (+ a b))
    

    或者在 JSON 中:

    ["+", "x", ["+", "a", "b"]]
    

    您的原始表达式m = (x + y) / 2 如下所示:

    m = ["/", ["+", "x", "y"], "2"]
    

    您想要的表达式之一(求解 x)如下所示:

    x = ["-", ["*", "m", "2"], "y"]
    

    你能看到表达式树已经被翻过来并且每个运算符都被颠倒了吗? “-”是“+”的反面,现在包裹着“*”,它是“/”的反面。该:

    ["+", "x", "y"]
    

    变成:

    ["-", (something), "y"]
    

    where (something) 是外部表达式的递归反转。尝试解释该过程:a)递归地降低表达式树,直到找到包含要求解的符号的节点,b)创建一个包含此节点操作反向的新节点,c)替换您想要的符号使用反向的外部表达式求解,在向外进行时递归地执行此操作。

    【讨论】:

      【解决方案4】:

      有多种简单的方法可以修改初始方程,以正确的顺序执行正确的修改将导致正确的解。那么如何将其视为搜索甚至寻路问题呢?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-01-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-04
        • 1970-01-01
        • 1970-01-01
        • 2014-09-16
        相关资源
        最近更新 更多