C++
 Computer >> コンピューター >  >> プログラミング >> C++

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
  1. シーザー暗号を実装するC++プログラム

    シーザー暗号とは シーザー暗号は、平文の各文字を別の文字に置き換えることで暗号文を作り出す「単一換字式暗号(モノアルファベット暗号)」の一種です。換字式暗号の中でも最も基本的でシンプルな方式とされています。 この暗号方式は、一般的に「シフト暗号」とも呼ばれます。その考え方は、各アルファベットを0〜25の範囲内の固定した数だけ「ずらした」別のアルファベットに置き換えるというものです。 この方式では、送信者と受信者があらかじめ「秘密のシフト数」を共有しておきます。この0〜25の間の数値が、暗号化の鍵(キー)として機能します。 特に「3文字ずらす」場合には、このシフト暗号を指して「シーザー暗号」と

  2. C++でグラフの隣接行列を実装する方法【サンプルコード付き解説】

    隣接行列とは グラフの隣接行列(Adjacency Matrix)とは、V×Vのサイズを持つ正方行列のことです。ここでVはグラフGの頂点数を表します。行列の行と列にはそれぞれ頂点が対応付けられ、頂点iから頂点jへの辺が存在する場合は、i行目・j列目の要素に1が格納されます(重み付きグラフの場合は、辺の重みなどの非ゼロの値が入ります)。辺が存在しない場合は0が格納されます。 なお、無向グラフの場合、辺は双方向につながりを持つため、隣接行列は必ず対称行列になります。つまり、adj[i][j]とadj[j][i]は常に同じ値となります。 隣接行列表現の計算量 空間計算量: 隣接行列にはO(V²)