掃き出し法 (row reduction), ガウスの消去法 (Gaussian Elimination)
概要
連立方程式 \(A \boldsymbol{x} = \boldsymbol{b}\) を解くためのアルゴリズム。
拡大係数行列を行基本変形で上三角の形に変形し、唯一解、解なし、いくつも解ありのいずれかかを判別する。
計算量
\(O(N^3)\)
実装
EPS = 1e-9
def gaussian_elimination(N, A, bs):
M = [[0]*(N+1) for i in range(N)]
for i in range(N):
M[i][:N] = A[i]
M[i][N] = bs[i]
cur = 0
for i in range(N):
k = cur; ma = abs(M[cur][i])
for j in range(cur+1, N):
if ma < abs(M[j][i]):
k = j
ma = abs(M[j][i])
if ma < EPS:
continue
if k != cur:
M[cur], M[k] = M[k], M[cur]
Mc = M[cur]
for Mj in M[cur+1:]:
if abs(Mj[i]) > EPS:
e = Mj[i] / Mc[i]
Mj[i] = 0
for k in range(i+1, N+1):
Mj[k] -= e*Mc[k]
cur += 1
if cur == N:
xs = [Mi[N] for Mi in M]
for i in range(N-1, -1, -1):
Mi = M[i]
xs[i] -= sum(Mi[j] * xs[j] for j in range(i+1, N))
xs[i] /= Mi[i]
return 1, xs
if any(Mi[N] > EPS for Mi in M[cur:]):
return 0, None
return 2, None
Verified
-
AOJ: "1232: Super Star": source (Python3, 7.62sec)
実装 (logical matrix)
from operator import xor
# calculate a vector x s.t. Ax = b
# - A is a N×N logical matrix
# - x and b are N-dimensional logical vectors
def gaussian_elimination(N, A, bs):
M = [[0]*(N+1) for i in range(N)]
for i in range(N):
M[i][:N] = A[i]
M[i][N] = bs[i]
cur = 0
for i in range(N):
if M[cur][i] == 0:
k = cur+1
while k < N and M[k][i] == 0:
k += 1
if k == N:
continue
M[cur], M[k] = M[k], M[cur]
Mc = M[cur]
for Mj in (Mj for Mj in M[cur+1:] if Mj[i]):
Mj[i:] = map(xor, Mj[i:], Mc[i:])
cur += 1
if cur == N:
# an unique solution
xs = [Mi[N] for Mi in M]
for i in range(N-1, -1, -1):
Mi = M[i]
xs[i] ^= sum(Mi[j] & xs[j] for j in range(i+1, N)) & 1
return 1, xs
if any(Mi[N] for Mi in M[cur:]):
# no solution
return 0, None
# infinitely many solutions
return 2, None
N = 3
A = [[1, 0, 1], [0, 1, 1], [1, 0, 0]]
bs = [1, 0, 1]
print(gaussian_elimination(N, A, bs))
# => "(1, [1, 0, 0])"
Verified
-
AOJ: "2624: Graph Automata Player": source (Python3, 36.71sec)