私が方程式を持っているとしましょう:
_2x + 6 = 12
_
代数を使用すると、_x = 3
_がわかります。 x
を解くことができるPythonでプログラムを作成するにはどうすればよいですか?プログラミングに不慣れで、eval()
およびexec()
しかし、私がそれらを私が望むことをさせる方法を理解することはできません外部ライブラリ(例えば、SAGE)を使いたくありません、私は単なるPythonでこれをしたいです。
この問題に取り組むには、数値的と記号的の2つの方法があります。
数値的に解決するには、最初に「実行可能な」関数としてエンコードする必要があります-値を保持し、値を取得します。例えば、
def my_function(x):
return 2*x + 6
文字列を解析してそのような関数を自動的に作成することはかなり可能です。 2x + 6
リストへ、[6, 2]
(リストインデックスはxの累乗に対応するため、6 * x ^ 0 + 2 * x ^ 1)。次に:
def makePoly(arr):
def fn(x):
return sum(c*x**p for p,c in enumerate(arr))
return fn
my_func = makePoly([6, 2])
my_func(3) # returns 12
次に、関数にx値を繰り返しプラグインし、結果と検索したいものとの差を調べ、そのx値を微調整して(できれば)差を最小化する別の関数が必要です。
def dx(fn, x, delta=0.001):
return (fn(x+delta) - fn(x))/delta
def solve(fn, value, x=0.5, maxtries=1000, maxerr=0.00001):
for tries in xrange(maxtries):
err = fn(x) - value
if abs(err) < maxerr:
return x
slope = dx(fn, x)
x -= err/slope
raise ValueError('no solution found')
ここには多くの潜在的な問題があります-関数が実際に解を持っていると仮定して(つまり、x ^ 2 + 2 = 0に対する実数値の答えがない)良い開始x値を見つけ、計算精度の限界に達し、しかし、この場合、エラー最小化関数が適切であり、良い結果が得られます。
solve(my_func, 16) # returns (x =) 5.000000000000496
このソリューションは絶対に、正確に正しくないことに注意してください。それを完璧にする必要がある場合、または方程式のファミリーを解析的に解こうとする場合は、より複雑な獣、つまりシンボリックソルバーを使用する必要があります。
MathematicaやMapleなどのシンボリックソルバーは、代数、計算などに関する多くの組み込みルール(「知識」)を備えたエキスパートシステムです。 sinの導関数がcosであること、kx ^ pの導関数がkpx ^(p-1)などであることを「認識」します。方程式を与えると、パス(ルールアプリケーションのセット)から(方程式)になりたい場所(方程式の最も単純な形式、できれば解決策)を見つけようとします。 。
方程式の例は非常に単純です。シンボリックソリューションは次のようになります。
=> LHS([6, 2]) RHS([16])
# rule: pull all coefficients into LHS
LHS, RHS = [lh-rh for lh,rh in izip_longest(LHS, RHS, 0)], [0]
=> LHS([-10,2]) RHS([0])
# rule: solve first-degree poly
if RHS==[0] and len(LHS)==2:
LHS, RHS = [0,1], [-LHS[0]/LHS[1]]
=> LHS([0,1]) RHS([5])
そしてあなたの解決策があります:x = 5。
これがアイデアのフレーバーを与えることを願っています。実装の詳細(ルールの優れた完全なセットを見つけ、各ルールをいつ適用するかを決定する)は、多くの人年の労力を簡単に消費する可能性があります。
Pythonは良いかもしれませんが、それは神ではありません...
方程式を解く方法はいくつかあります。分析ソリューションを探しているなら、SymPyはすでに言及されています。
数値的な解決策があるだけなら、Numpyには役立ついくつかのルーチンがあります。多項式の解だけに興味がある場合は、numpy.rootsが機能します。特にあなたが言及した場合:
>>> import numpy
>>> numpy.roots([2,-6])
array([3.0])
より複雑な式については、scipy.fsolveをご覧ください。
いずれにしても、ライブラリを使用してエスケープすることはできません。
正の整数_mx + c = y
_に対して極度に制限された方程式のセット_m, c, y
_のみを解決したい場合は、次のようにします。
_import re
def solve_linear_equation ( equ ):
"""
Given an input string of the format "3x+2=6", solves for x.
The format must be as shown - no whitespace, no decimal numbers,
no negative numbers.
"""
match = re.match(r"(\d+)x\+(\d+)=(\d+)", equ)
m, c, y = match.groups()
m, c, y = float(m), float(c), float(y) # Convert from strings to numbers
x = (y-c)/m
print ("x = %f" % x)
_
いくつかのテスト:
_>>> solve_linear_equation("2x+4=12")
x = 4.000000
>>> solve_linear_equation("123x+456=789")
x = 2.707317
>>>
_
sin(x) + e^(i*pi*x) = 1
のような任意方程式を認識して解決したい場合は、maxima
、Mathematica
、MATLABのsolve()
またはSymbolic Toolboxなど。初心者としては、これはあなたの考えを超えています。
別のツールを使用してください。 Wolfram Alpha 、 Maple 、 [〜#〜] r [〜#〜] 、 Octave 、-のようなもの Matlab またはその他の代数ソフトウェアパッケージ。
初心者として、おそらくこのような重要な問題を解決しようとすべきではありません。