Pythonで連立方程式を解く方法を現役エンジニアが解説【初心者向け】

初心者向けにPythonで連立方程式を解く方法について現役エンジニアが解説しています。連立方程式とは二つ以上の方程式を組にしたもので、未知数を解と呼びます。代入法や行列、numpyやsympyを使ってPythonで連立方程式を解く方法を解説します。

TechAcademyマガジンは受講者数No.1のオンラインプログラミングスクールTechAcademy [テックアカデミー]が運営。初心者向けに解説した記事を公開中。現役エンジニアの方はこちらをご覧ください。

Pythonで連立方程式を解く方法について、TechAcademyのメンター(現役エンジニア)が実際のコードを使用して、初心者向けに解説します。

Pythonについてそもそもよく分からないという方は、Pythonとは何なのか解説した記事を読むとさらに理解が深まるでしょう。

 

なお本記事は、TechAcademyのオンラインブートキャンプPython講座の内容をもとに紹介しています。

 

田島悠介

今回は、Pythonに関する内容だね!

大石ゆかり

どういう内容でしょうか?

田島悠介

Pythonで連立方程式を解く方法について詳しく説明していくね!

大石ゆかり

お願いします!

 

 

目次

 

連立方程式とは

二つ以上の方程式を組にしたものを連立方程式、その方程式を同時に満たす未知数の数値の組み合わせを連立方程式の解といいます。

未知数の数がm個、未知数に関する最高次数がn次の場合をm元n次の連立方程式といいます。

一般にm元の連立方程式は独立の方程式がm個あれば解けるが,m−1個以下では解が無数に存在し,m+1個以上なら解が存在しません。

 

[PR] Pythonで挫折しない学習方法を動画で公開中

連立方程式を解く方法

連立方程式を下記の方法で解いてみましょう。

  • 代入法による解法
  • 行列による解法
  • 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)や機械学習の基礎を習得できる、オンラインブートキャンプを開催しています。

また、現役エンジニアから学べる無料体験も実施しているので、ぜひ参加してみてください。