方程式があるとしましょう:
2x + 6 = 12
代数でそれを見ることができますx = 3
。を解くことができるプログラムをPythonで作成するにはどうすればよいx
ですか? 私はプログラミングが初めてで、andを見ましたeval()
がexec()
、自分がやりたいことをさせる方法がわかりません。私は外部ライブラリ (SAGE など) を使用したくありません。単純な Python でこれを実行したいと考えています。
方程式があるとしましょう:
2x + 6 = 12
代数でそれを見ることができますx = 3
。を解くことができるプログラムをPythonで作成するにはどうすればよいx
ですか? 私はプログラミングが初めてで、andを見ました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
>>>
のような任意の方程式を認識して解きたい場合は、 、、MATLABや Symbolic Toolbox などsin(x) + e^(i*pi*x) = 1
に似た、ある種のシンボリック数学エンジンを実装する必要があります。maxima
Mathematica
solve()
別のツールを使用してください。Wolfram Alpha、Maple、R、Octave、Matlabまたはその他の代数ソフトウェア パッケージのようなもの。
初心者として、このような重要な問題を解決しようとするべきではありません。