V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
crella
V2EX  ›  问与答

求用编程化简一个数学表达式

  •  
  •   crella · 2020-05-01 18:47:31 +08:00 · 2164 次点击
    这是一个创建于 1696 天前的主题,其中的信息可能已经有所发展或是发生改变。

    求用编程化简一个数学表达式,尽量用自己的算法而不是借用各种科学计算的库。

    表达式为 1+3*4/(x+1)^2/2-3

    公式扫描后得到的符号数组为:[1,'+',3,'*',4,'/','(','x','+',1,')','^',2,'/',2,'-',3]

    要求化简结果为-2+6/(x+1)^2,-2 在分式前或后都没关系

    各位大佬有什么好的现成的算法吗?我感觉这里最重要的是要建立合适的模型,但是不知道自己做得靠不靠谱。

    10 条回复    2020-05-02 11:56:39 +08:00
    aguesuka
        1
    aguesuka  
       2020-05-01 23:21:17 +08:00 via Android
    假设有一个函数 f(e),输入表达式,输出表达式的最简化表达式。

    那么可以构建一个函数 (e1,e2)-> f(e1)==f(e2)。即输入两个表达式,输出这两个表达式是否外延全等。这个函数是不存在的,所以函数 f 也是不存在的。

    这个问题太大了,我可以给一个关键字 HoTT
    aguesuka
        2
    aguesuka  
       2020-05-01 23:25:31 +08:00 via Android
    murmur
        3
    murmur  
       2020-05-01 23:32:32 +08:00
    符号计算啊,我建议不要想了,matlab 的符号计算都是买来的
    当然,如果没这么远大的志向,可以试试比如这个
    https://www.cnblogs.com/sunshine-blog/p/8477523.html
    ppyybb
        4
    ppyybb  
       2020-05-01 23:36:17 +08:00 via iPhone   ❤️ 1
    可以看下这个,符号计算的 simplify 。https://www.zhihu.com/question/27156917/answer/125226736
    另外你只是想化简而不是一定要最简吧
    crella
        5
    crella  
    OP
       2020-05-01 23:50:48 +08:00
    @aguesuka 我没有想得那么深。假如限定这个函数就是初等数学函数。之前坛里有人指导过我可以模仿 SymPy 的 expand 方法,见 https://docs.sympy.org/latest/tutorial/simplification.html#expand

    我现在就是在不看 SymPy 的情况下尝试做这个事。

    我今天想的办法是,对于主符号数组,先扫描^号,把所有幂运算的部分替换成 PowerModel 实例,然后按顺序扫描*号和 /号,把所有乘法除法运算的部分替换成 DivideModel 实例(它包含分子数组和分母数组),然后扫描+号和-号,跳过所有对于 PowerModel 或 DivideModel 或者含 x 的元素的计算,化简主符号数组。最后把在主符号数组里的各个 PowerModel 实例和 DivideModel 实例展开出来。

    示意图 ![sd4.6-demo1.jpg]( https://i.loli.net/2020/05/01/vm3kwJ9jO8PHzW1.jpg)

    目前我的脚本对括号内的表达式的化简程度还很低……遇到很多没想到的问题
    secondwtq
        6
    secondwtq  
       2020-05-02 00:06:47 +08:00
    感觉楼主的心态像是在做算法题 …
    aguesuka
        7
    aguesuka  
       2020-05-02 00:09:04 +08:00 via Android   ❤️ 1
    @crella 现在的问题是解析表达式吗?可以读一下编译原理,把表达式解析成语法树。学会了以后写一个互递归的解析器应该不用半个小时。
    secondwtq
        8
    secondwtq  
       2020-05-02 00:14:49 +08:00   ❤️ 1
    @aguesuka 其实我在楼主的另一个主题里说过类似的话
    奈何楼主就是喜欢无视 state of the art 自己折腾…
    BiteTheDust
        10
    BiteTheDust  
       2020-05-02 11:56:39 +08:00
    印象里比较常规的做法是中缀表达式转换成后缀表达式再算
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3631 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 04:40 · PVG 12:40 · LAX 20:40 · JFK 23:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.