QGXZ [線形代数xOI / ACM]係数行列の分解

重要でないQ&A

Q:どのようにあなたは、この空想のアルゴリズムああだと思いますか?
そして、線形代数を学ぶために数日前名誉:Magolorギャングスターアルゴリズムが$ LUの$分解を検討したときに、問題の時間計算のための複数のソリューション、この奇妙なのうちそうYY(?)。

Q:なぜそれが$ QGXZ $それを分解すると呼ばれていますか?あなたは、ああ強制的にロードされていませんか?
:名前がされてMagolor兄がプレイし、私は少しだけ無条件に従うことができます~~任意の類似性は決して学術的な違法行為であります

Q:Magolorギャング強すぎるの友達〜
A:私たちのコンセンサスにおめでとうございます-

アウトライン

$ QGXZ $分解は、線形方程式や問題について、より一般的な解決策を解決するためのアルゴリズムです。具体的に:

$アックス= B_1、斧= B_2求めそれぞれ、係数の時間M $ $ A $行列\ $ Nを与え 、...、斧= b_qの$ 一般解 $ B_i $ $のn \回1 $カラムベクトル。以下の仮定$ N、M、Q $と同じ順序。

$ b_i $必須オンラインならば、アルゴリズムの時間の複雑さは、単純なの$ O(N ^ 4)$です。$ QGXZ $マトリックス分解した場合、複雑さは$ O(N ^ 3)$に減少しています。

事前スキル

$ QGXZ $ $ $ LU分解分解は、本質的に拡張したものですので、$のLUの$分解を導入する最初の。

$ n個の\倍に分解されるの$ n \回M $行列、N $三角行列L $下$とn \時間は$上台形行列は、のU- $を$ M $は$ LU $分解製品の結果は、すなわち、= Lの\回U $を$。

探している:マトリックスが上から下マトリクス行変換処理に$を$ため(単に第ライン変換を検討する:ゼロに追加される行数に行を掛けます)。我々は、ラインの変化が$ A $ $ B $プロセスは$ K $は変換行列で説明$ A = K \倍B $フォームを使用することができるとなると、その知っています。前提消費支出の$ K $は下三角行列である下、下三角行列の積は下三角行列であるので、各変換行列の積は、我々は三角行列L $ $を求めているもので、$と最終結果は、$ $ U $の上台形行列です。

例えば:

$$
\開始{pmatrixの}
1・1・0 0 \\\
1&0&1&1 \\\
2&1&0&0 \端{pmatrixの} =
\ {pmatrixの}開始
1&0&0 \\\
1&1&0 \\\
2&0&1
\端{pmatrixのを}
\ {pmatrixの}開始
1&1&0&0 \\\を
0 -1・1・1 \\\
0 -1&0&0
\端{pmatrixの} =
\ {pmatrixのを}開始
1&0&0 \\\
1&1&0 \\\
2&-1&1つの
\端{pmatrixの}
\開始{pmatrixの}
1・1・0 0 \\\
0 -1・1・1 \\ \
0 0 -1 -1&
\端{pmatrixの}
$$

$ LU $分解の使用は何ですか?

方程式$ Ax = bの$がある場合、それは$ルクス=のb $と等価です。私たちは、全体の$ yを$として$ UXの$を置くことができ、式$ Lyとの最初のソリューションは$ UXの=のy $デその後、B $を=。明らかに、これらの二つの方程式を解く比較的「簡単」です。

制限

$のLUの$分解の2つの制限があります。

  1. 変換プロセスラインがあるので必要があり、いくつかのマトリックスは、したがって、直接$ $ LU分解ではないかもしれないため、行の消費下の行の上に使用すること。

  2. Y $ $ UXは=ときLU $ $行列要素を表すために必要な主な要素からなる、方程式の複数のソリューション場合、方程式の解で、分解することができる場合であっても。解決、(N)$ O $方程式は$ O(N)$主元素に置換され、各式は、存在を置換する過程で、各主素子用の$ O(N)$は、自由な要素を表します一つのLU係数行列$ $はフォームを分解知っている場合でもこのように、複雑さが$ O(N ^ 3)$、と差がないと暴力に置換されています。

ここでは、これら2つの制限を解決するために$ GXZ $ $ $ QGXZ分解と分解をご紹介します。

$ GXZ $分解

$ n個の\回N $下三角行列の$ Gの$、$ n個の\回N $上三角行列の$ X- $とに分解されるの$ N \回数Mの$行列、は$ GXZ $分解減少行階段(各列は$ 0 $行行列を階段状である他のピボット位置)での$ n \回M $行列、すなわち、$ A = G \倍X \回Z、Zする$ $製品を結果$。

この評価方法は非常に簡単である:変換行列の$ L $と行階段行列が$ 0 $に行消去上記一次エレメント列の対応する位置とU-の$、我々はその後、抗消滅波を$後に得られたスパーキャンセルを翻訳行を使用して、LU分解、そしてLU $ $分解して変換行列の記録方法を使用して。以下、上記各円弧として上部三角結合行列($および$同様のLU分解)で使用されるので、変換行列れます。

$ A = GXZ $は、変数名の波の後に置換してあります。

例えば:

$$
\開始{pmatrixの}
1・1・0 0 \\\
1&0&1&1 \\\
2&1&0&0
\端{pmatrixの} =
\ {pmatrixのを}開始
1&0&0 \\\
1&1&0 \\\
2&-1&1
\端{pmatrixの}
\開始{pmatrixの}
1&0&0 \ \\
0&1&-1 \\\
0 0 1
\端{pmatrixの}
\ {pmatrixの}開始
1&1&0&0 \\\
0 -1・0 0 \\\
0 0 -1&-1
\端{pmatrixのを}
$$

この場合、式$のGd =のb $、$キセノン= D $と$ Zxを=電子の$缶の唯一の解決策。最初の二つの方程式明確$ O(N ^ 2)$、および第三の方程式のみ前部要素と置換しない処理が$ O(N ^ 2)$です。

だから我々は、$ Oを取得(N ^ 3)$の前処理、$ O(N ^ 2)$単一尋問アルゴリズム。

$ QGXZ $分解

$ GXZ $制限の第二の点を分解し、$ QGXZ $分解による最初のポイントの制限は解決します。

$ QGXZ $が回\ M $の順列行列は製品マトリックスの中にフォームを展開し、$ Q $ $ $ GXZ分解すぐに$ Nを爆発させました。

特定の方法:最初のステップ(LU分解)$ $ GXZ分解は、消費電流は、$ A = L_0U_0 $形式変換をさらに二列$ $ U_0ときに除去、即ちに交換されることが見出されたとなっていることを前提と$ U_0 = T_0U_1 $、$ T_0 $は順列行列です。私たちが今、必要なのA $ L_0T_0U_1 $ $ $ T_1L_1U_1になることです、それは$ L_0T_0 $は$ T_1L_1 $となっています。

我々は2つのラインの$ L_0T_0の$ 2回の交換の同等$ L_0 $、および$ T_1L_1 $等価交換$ L_1 $、知っています。私たちの除去処理は、上から下に行われるので、$ $ L_0は2つだけの主対角線である$ 1 $、$ 0 $静止位置でなければなりません交換するので。

したがって、我々は手動でのみ$ L_1 $の一環として、主要L_0 $ $上記2本の対応の対角線を交換する必要がある、とT_0は$ $ $ $ T_Lにそのままとして、フロントで直接取得します。

例えば:私たちは$ L_0 $ $ 2 $番目及び$ 3 $行、手動交換$ L_0 $フロント$ $ 2 $行と$ 3 $ライン\テキスト{分}(2,3)-1 $番目を交換しますすることができますように前に$ L_1 $の数、$ T_0 $ GET $ L_0 $ $ L_1 $として。それは次のとおりです。

$$
\開始{pmatrixの}
1&0&0 \\\
X&1&0 \\\
Y&0&1
\端{pmatrixの}
\開始{pmatrixの}
1&0&0 \\\
0 0 1 \\\
0&1&0
\端{pmatrixの} =
\ {pmatrixのを}開始
1&0&0 \\\
0 0 1 \\\
0&1&0
\端{pmatrixの}
\ {} pmatrixの開始
1&0&0 \\\
Y&1&0 \\\
X&0&1
\端{pmatrixのを}
$$

各交換は、このような処理を行っているので、私たちは一緒に入れ順列行列と転置行列、下三角行列と一緒に入れ下三角行列を置きます。製品の彼らの特別な性質の行列は変更されませんので、最終的な$ Q $の避けられないにも行列を順列ので、$ G $はまた、下三角行列でなければなりません。

これは、$ Ax = bのは$溶液になる:分解$ A = Q \回G \倍X \倍Zの$、次いで溶液は$、$のGd = C $、$のXe = Dの$ B = $ Qcとしました、 $ Zxを=のE $へ。

単一の時間計算量は$ O(N ^ 2)$変更されません尋ねました。

コード

#include <bits/stdc++.h>
#define N 510
#define eps 1e-6
using namespace std;
int pos[N];
double Q[N][N] , G[N][N] , X[N][N] , Z[N][N] , b[N] , c[N] , d[N] , e[N];
int main()
{
    int n , m , q , i , j , k , p = 0 , t;
    double mx;
    scanf("%d%d%d" , &n , &m , &q);
    for(i = 1 ; i <= n ; i ++ )
        for(j = 1 ; j <= m ; j ++ )
            scanf("%lf" , &Z[i][j]);
    for(i = 1 ; i <= n ; i ++ ) Q[i][i] = G[i][i] = X[i][i] = 1;
    for(i = 1 ; i <= m ; i ++ )
    {
        t = 0 , mx = eps;
        for(j = p + 1 ; j <= n ; j ++ )
            if(abs(Z[j][i]) > mx)
                t = j , mx = abs(Z[j][i]);
        if(!t) continue;
        pos[ ++ p] = i;
        for(k = i ; k <= m ; k ++ ) swap(Z[p][k] , Z[t][k]);
        for(k = 1 ; k <= n ; k ++ ) swap(Q[p][k] , Q[t][k]);
        for(k = 1 ; k < p ; k ++ ) swap(G[p][k] , G[t][k]);
        for(j = p + 1 ; j <= n ; j ++ )
        {
            G[j][p] = Z[j][i] / Z[p][i];
            for(k = i ; k <= m ; k ++ )
                Z[j][k] -= Z[p][k] * G[j][p];
        }
    }
    for(i = p ; i ; i -- )
    {
        for(j = i - 1 ; j ; j -- )
        {
            X[j][i] = Z[j][pos[i]] / Z[i][pos[i]];
            for(k = pos[i] ; k <= m ; k ++ )
                Z[j][k] -= Z[i][k] * X[j][i];
        }
    }
    while(q -- )
    {
        for(i = 1 ; i <= n ; i ++ ) scanf("%lf" , &b[i]);
        for(i = 1 ; i <= n ; i ++ )
            for(j = 1 ; j <= n ; j ++ )
                if(Q[i][j] == 1)
                    c[j] = b[i];
        for(i = 1 ; i <= n ; i ++ )
        {
            d[i] = c[i];
            for(j = 1 ; j < i ; j ++ )
                d[i] -= G[i][j] * d[j];
        }
        for(i = n ; i ; i -- )
        {
            e[i] = d[i];
            for(j = n ; j > i ; j -- )
                e[i] -= X[i][j] * e[j];
        }
        for(i = p + 1 ; i <= n ; i ++ )
            if(abs(e[i]) > eps)
                break;
        if(i <= n) puts("No solution!");
        else
        {
            for(i = 1 ; i <= p ; i ++ )
            {
                printf("x[%d]=%lf" , pos[i] , e[i] / Z[i][pos[i]]);
                for(j = pos[i] + 1 ; j <= m ; j ++ )
                    if(abs(Z[i][j]) > eps)
                        printf("%+lfx[%d]" , -Z[i][j] / Z[i][pos[i]] , j);
                puts("");
            }
        }
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/GXZlegend/p/11735752.html