求用编程化简一个数学表达式 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
crella
V2EX    问与答

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

  •  
  •   crella 2020 年 5 月 1 日 2570 次点击
    这是一个创建于 2167 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    表达式为 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 年 5 月 1 日 via Android
    假设有一个函数 f(e),输入表达式,输出表达式的最简化表达式。

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

    这个问题太大了,我可以给一个关键字 HoTT
    aguesuka
        2
    aguesuka  
       2020 年 5 月 1 日 via Android
    murmur
        3
    murmur  
       2020 年 5 月 1 日
    符号计算啊,我建议不要想了,matlab 的符号计算都是买来的
    当然,如果没这么远大的志向,可以试试比如这个
    https://www.cnblogs.com/sunshine-blog/p/8477523.html
    ppyybb
        4
    ppyybb  
       2020 年 5 月 1 日 via iPhone   1
    可以看下这个,符号计算的 simplify 。https://www.zhihu.com/question/27156917/answer/125226736
    另外你只是想化简而不是一定要最简吧
    crella
        5
    crella  
    OP
       2020 年 5 月 1 日
    @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 年 5 月 2 日
    感觉楼主的心态像是在做算法题 …
    aguesuka
        7
    aguesuka  
       2020 年 5 月 2 日 via Android   1
    @crella 现在的问题是解析表达式吗?可以读一下编译原理,把表达式解析成语法树。学会了以后写一个互递归的解析器应该不用半个小时。
    secondwtq
        8
    secondwtq  
       2020 年 5 月 2 日   1
    @aguesuka 其实我在楼主的另一个主题里说过类似的话
    奈何楼主就是喜欢无视 state of the art 自己折腾…
    BiteTheDust
        10
    BiteTheDust  
       2020 年 5 月 2 日
    印象里比较常规的做法是中缀表达式转换成后缀表达式再算
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1201 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 17:30 PVG 01:30 LAX 10:30 JFK 13:30
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86