Pythonで連立方程式を解く方法を現役エンジニアが解説【初心者向け】
初心者向けにPythonで連立方程式を解く方法について現役エンジニアが解説しています。連立方程式とは二つ以上の方程式を組にしたもので、未知数を解と呼びます。代入法や行列、numpyやsympyを使ってPythonで連立方程式を解く方法を解説します。
テックアカデミーマガジンは受講者数No.1のプログラミングスクール「テックアカデミー」が運営。初心者向けにプロが解説した記事を公開中。現役エンジニアの方はこちらをご覧ください。 ※ アンケートモニター提供元:GMOリサーチ株式会社 調査期間:2021年8月12日~8月16日 調査対象:2020年8月以降にプログラミングスクールを受講した18~80歳の男女1,000名 調査手法:インターネット調査
Pythonで連立方程式を解く方法について、TechAcademyのメンター(現役エンジニア)が実際のコードを使用して、初心者向けに解説します。
Pythonについてそもそもよく分からないという方は、Pythonとは何なのか解説した記事を読むとさらに理解が深まるでしょう。
なお本記事は、TechAcademyのオンラインブートキャンプPython講座の内容をもとに紹介しています。
今回は、Pythonに関する内容だね!
どういう内容でしょうか?
Pythonで連立方程式を解く方法について詳しく説明していくね!
お願いします!
目次
連立方程式とは
二つ以上の方程式を組にしたものを連立方程式、その方程式を同時に満たす未知数の数値の組み合わせを連立方程式の解といいます。
未知数の数がm個、未知数に関する最高次数がn次の場合をm元n次の連立方程式といいます。
一般にm元の連立方程式は独立の方程式がm個あれば解けるが,m−1個以下では解が無数に存在し,m+1個以上なら解が存在しません。
連立方程式を解く方法
連立方程式を下記の方法で解いてみましょう。
- 代入法による解法
- 行列による解法
- numpyによる解法
- sympyによる解法
一般的な2元1次方程式を求める場合
1.代入法による解法
ここで両辺をそれぞれa, cで割ると
二つの式の差は
よって
同様に両辺をb, dで割ると
二つの式の差は
よって
ゆえに求める解は
となります。
さてここで、いくつか注意点を上げておきます。
・a, b, c, dの型は整数型ではなく小数型にしておく必要があります。
・x, yの分母を通分しいただくとad-bcという形が出てくるかと思います。こちらが0となってしまうとErrorとなります。そのため、解の存在の有無をチェックするためにad-bcの値が0とならない様チェックすることをお勧めします。
2.行列による解法
今回の連立方程式を行列を用いて表すと
となります。行列の特徴の一つとして、掛け算の順番が決まっています。そのため逆行列を左側からかけてあげると
となります。ここで逆行列が存在する条件は
となります。
3.numpyによる解法
numpyのnumpy.linag.solveというmethodを使って解を求めることができます。
使い方は以下のとおりです。
a = np.array([[a, b], [c, d]]) b = np.array([A1, A2]) np.linalg.solve(a, b)
入力する形式は行列による解法と同様です。
4.sympyによる解法
sympyのsympy.Symbolで変数を指定し、とsympy.solveを使って解を求めることができます。
使い方は以下のとおりです。
x = Symbol('x') y = Symbol('y') equation1 = a * x + b * y - A1 equation2 = c * x + d * y - A2 X = solve([equation1, equation2])
入力する形式は行列による解法と同様です。
実際に解いてみよう
今回は二つの例を用いて解いてみましょう。まずはそれぞれの解法に対応した関数を用意します。
1.代入法
代入法の関数は以下のとおり設定します。Errorが出る場合には解の存在条件のチェックも合わせて行っています。
def dainyu(a, b, c, d, A1, A2): determinant = a * d - b * c if determinant != 0: x = (A1 / b - A2 / d) / (a / b - c / d) y = (A1 / a - A2 / c) / (b / a - d / c) print(x, y) else: if c/a == A1 / A2: print('解が複数存在します') else: print('解が存在しません')
2.行列を使った解法
行列を使った解法ではnumpyのmatrixを用いて定義します。
import numpy as np def matrix(a, b, c, d, A1, A2): A = np.matrix([[a, b], [c, d]]) determinant = np.linalg.det(A) if determinant != 0: inv_A = np.matrix(np.linalg.inv(A)) B = np.matrix([[A1],[A2]]) X = inv_A * B print(X) else: if c/a == A1 / A2: print('解が複数存在します') else: print('解が存在しません')
3. numpyを用いた解法
import numpy as np def numpy_function(a, b, c, d, A1, A2): A = np.matrix([[a, b], [c, d]]) determinant = np.linalg.det(A) if determinant != 0: B = np.matrix([[A1],[A2]]) X = np.linalg.solve(A, B) print(X) else: if c/a == A1 / A2: print('解が複数存在します') else: print('解が存在しません')
4.sympyによる解法
from sympy import solve, Symbol def sympy_function(a, b, c, d, A1, A2): x = Symbol('x') y = Symbol('y') determinant = a * d - b * c if determinant != 0: equation1 = a * x + b * y - A1 equation2 = c * x + d * y - A2 print(X) else: if c/a == A1 / A2: print('解が複数存在します') else: print('解が存在しません')
以上の関数を用いて下記の例を用いてテストしてみましょう。
例1.
main関数
a = float(2) b = float(-6) c = float(8) d = float(-24) A1 = float(5) A2 = float(2) dainyu(a, b, c, d, A1, A2) matrix(a, b, c, d, A1, A2) numpy_function(a, b, c, d, A1, A2) sympy_function(a, b, c, d, A1, A2)
結果
解が存在しません 解が存在しません 解が存在しません 解が存在しません
解説
この二つの関数は並行無関係にあるため、解が存在しません。
そのため、Errorが起きない様に回避した結果を返しています。また、入力する数値を全てfloatにしているところも注意が必要です。単純に2と入力すると整数として扱いますので、Errorの元となります。
例2.
main関数
a = float(2) b = float(-3) c = float(5) d = float(-2) A1 = float(1) A2 = float(8) dainyu(a, b, c, d, A1, A2) matrix(a, b, c, d, A1, A2) numpy_function(a, b, c, d, A1, A2) sympy_function(a, b, c, d, A1, A2)
結果
1.9999999999999998 1.0 1.0 [[2.] [1.]] [[2.] [1.]] {x: 2.00000000000000, y: 1.00000000000000}
解説
numpyとsympyを使った場合は解がx=2, y=1を求めることができました。一方で代入法を使った場合には誤差が出てきてしまいました。
これがコンピュータを使って計算した場合に起きる桁落ちによる誤差です。
まとめ
今回は4種類の解法をみていきました。最後に計算結果にばらつきが出てきてしまいました。
この桁落ちによる計算精度の低下はコンピュータを用いた計算ではよくみられることです。この様な計算を扱う場合には充分注意してプログラムを作成する必要があります。回避する方法としては割り算を減らしてみることが考えられます。
def dainyu_kai(a, b, c, d, A1, A2): determinant = a * d - b * c if determinant != 0: x = (A1 * d - A2 * b) / (a * d - c *b) y = (A1 * c - A2 * a) / (b * c - d * a) print(x, y) else: if c/a == A1 / A2: print('解が複数存在します') else: print('解が存在しません')
として計算してみると、望み通りの結果が得られます。工夫一つでエラーを起きにくくすることができますので、是非試してみてください。
監修してくれたメンター
メンターkatoさん
学生時代に数値解析のためにプログラミングを始める。現在は企業にて専門職として働くかたわら、プログラムを書き業務効率化を図っている。 現在のメイン言語はPython, JavaScript。また、企業内の希望者にPythonのメンターとして基礎から教えている。テックアカデミーではJavaScriptを教える。 |
大石ゆかり
内容分かりやすくて良かったです!
田島悠介
ゆかりちゃんも分からないことがあったら質問してね!
分かりました。ありがとうございます!
TechAcademyでは、初心者でも、Pythonを使った人工知能(AI)や機械学習の基礎を習得できる、オンラインブートキャンプを開催しています。
また、現役エンジニアから学べる無料体験も実施しているので、ぜひ参加してみてください。