C++でガウス・ジョルダン消去法を実装する方法|連立一次方程式を解くサンプルコード
この記事では、ガウス・ジョルダン消去法(Gauss-Jordan Elimination)をC++で実装するプログラムを紹介します。この手法は連立一次方程式を解析するために用いられるもので、行基本変形(掃き出し操作)によって方程式系を対角行列の形へと変形し、解を直接導出できる点が大きな特徴です。
ガウス・ジョルダン消去法とは
ガウス・ジョルダン消去法は、連立一次方程式を解くための代表的な数値計算手法のひとつです。方程式系を拡大係数行列として表現し、「ある行を定数倍する」「別の行との和を取る」といった行基本変形を繰り返すことで、係数部分を対角成分だけが残る形(対角行列)に近づけていきます。最終的に対角化できれば、行列の右端の列がそのまま解となります。
アルゴリズム
開始
n = 入力行列のサイズ
対角行列の各要素を求める手順:
二重のforループ(j = 0〜n、i = 0〜n)を用意する
まず第1行・第1列の要素を1にし、
第1列の残りの要素をすべて0にする。
次に第2行・第2列の要素を1にし、
第2列のその他の要素を0にする。以降も同様に繰り返す。
求まったすべての解の値を出力する。
終了
C++による実装例
#include<iostream>
using namespace std;
int main() {
int i, j, k, n; // 変数の宣言
float a[10][10], b, x[10]; // a: 拡大係数行列 / x: 解
cout << "行列のサイズを入力してください: ";
cin >> n;
cout << "拡大係数行列の要素を行ごとに入力してください:\n";
for(i = 1; i <= n; i++) {
for(j = 1; j <= n + 1; j++) {
cout << "A[" << i << ", " << j << "] = ";
cin >> a[i][j];
}
}
// 対角行列の要素を求める(掃き出し操作)
for(j = 1; j <= n; j++) {
for(i = 1; i <= n; i++) {
if(i != j) {
b = a[i][j] / a[j][j];
for(k = 1; k <= n + 1; k++) {
a[i][k] = a[i][k] - b * a[j][k];
}
}
}
}
cout << "\n解は次の通りです:\n";
for(i = 1; i <= n; i++) {
x[i] = a[i][n + 1] / a[i][i];
cout << "x" << i << " = " << x[i] << " ";
}
return 0;
}
コードのポイント
- 拡大係数行列の入力: 係数行列と定数項をまとめて2次元配列 a に格納します。n 元の連立方程式なら、各行に n+1 個の値を入力します。
- 掃き出し操作: 対角成分以外の要素を0にするため、b = a[i][j] / a[j][j] を計算し、i 行目から「b 倍した j 行目」を引いています。
- 解の算出: 変形後の行列では対角成分 a[i][i] が係数、最終列 a[i][n+1] が定数項に対応するため、x[i] = a[i][n+1] / a[i][i] で解が直接求まります。
なお、実務的な数値計算では、対角成分が0に近い場合のゼロ除算や誤差の増大を避けるため、ピボット選択(絶対値の大きい要素との行交換)を組み合わせるのが一般的です。
実行結果
行列のサイズを入力してください: 3 拡大係数行列の要素を行ごとに入力してください: A[1, 1] = 1 A[1, 2] = 2 A[1, 3] = -4 A[1, 4] = 2 A[2, 1] = 7 A[2, 2] = 6 A[2, 3] = -2 A[2, 4] = -5 A[3, 1] = 0 A[3, 2] = -3 A[3, 3] = -5 A[3, 4] = -8 解は次の通りです: x1 = -2.89831 x2 = 2.5678 x3 = 0.059322
-
シーザー暗号を実装するC++プログラム
シーザー暗号とは シーザー暗号は、平文の各文字を別の文字に置き換えることで暗号文を作り出す「単一換字式暗号(モノアルファベット暗号)」の一種です。換字式暗号の中でも最も基本的でシンプルな方式とされています。 この暗号方式は、一般的に「シフト暗号」とも呼ばれます。その考え方は、各アルファベットを0〜25の範囲内の固定した数だけ「ずらした」別のアルファベットに置き換えるというものです。 この方式では、送信者と受信者があらかじめ「秘密のシフト数」を共有しておきます。この0〜25の間の数値が、暗号化の鍵(キー)として機能します。 特に「3文字ずらす」場合には、このシフト暗号を指して「シーザー暗号」と
-
C++でグラフの隣接行列を実装する方法【サンプルコード付き解説】
隣接行列とは グラフの隣接行列(Adjacency Matrix)とは、V×Vのサイズを持つ正方行列のことです。ここでVはグラフGの頂点数を表します。行列の行と列にはそれぞれ頂点が対応付けられ、頂点iから頂点jへの辺が存在する場合は、i行目・j列目の要素に1が格納されます(重み付きグラフの場合は、辺の重みなどの非ゼロの値が入ります)。辺が存在しない場合は0が格納されます。 なお、無向グラフの場合、辺は双方向につながりを持つため、隣接行列は必ず対称行列になります。つまり、adj[i][j]とadj[j][i]は常に同じ値となります。 隣接行列表現の計算量 空間計算量: 隣接行列にはO(V²)