y=x^2
Javascriptのような単純な関数を区別する calc クラスのサイド プロジェクトに取り組んでいます。そのために、式を抽象構文ツリーに解析し、積規則や連鎖規則などの導関数規則をハードコーディングしました。
これに入れられる唯一の関数は、AP 微積分/1 年目の微積分の問題です。そのため、三角関数、対数、指数はすべて有効です。
私のプログラムは導関数を問題なく取りますが、最終的に得られるのは、途方もなく単純化されていない方法で記述された関数です。
たとえば、微分するとx^2
が得られます(2*(x^(2-1)))
。これは技術的には正しいですが、2*x のように簡単に記述できます。これまでのところ、基本的にツリーを繰り返し分析し、いくつかの基本的なルールを適用する基本的な単純化機能があります。
私が持っている一般的な手順は、再帰降下で分析することです。
現在のツリーに変数がない場合は、それを評価し、現在のノードを結果で置き換えます。
それ以外の場合は、大量の if ステートメントを適用して単純化します。これには次のようなものが含まれます
- ゼロを掛ける場合は、式をゼロに置き換えます
- 1 を掛ける場合は、式を他のオペランドに置き換えます
- 0 乗する場合は、式を 1 に置き換えます。
などなど。似たような用語を組み合わせるなど、本当の単純化を実際に行いたい場合、これはすぐに制御不能になります。また、任意の 2 つの式が等しいかどうかを判断したい場合、私が持っている最善の解決策は、単に関数のドメインで乱数を生成し、それらが等しいかどうかを確認することです。ただし、これはあまり効率的ではないようです。
x+2
2 つの異なる式 (単純な例はand )の等価性をより効率的に判断するに2+x
はどうすればよいですか? また、大量の if ステートメントを使用せずに関数を単純化する方法はありますか?