高斯消元法的C++簡單實現


高斯消元法

  首先,我們導入幾個概念。

定義1: 一個矩陣稱為階梯形(行階梯形),若它有以下三個性質:

  1.每一非零行在每一零行之上;

  2.某一行的先導元素所在的列位於前一行先導元素的后面;

  3.某一行先導元素所在列下方元素都是零。

  比如,

定義2:若一個階梯形矩陣還滿足以下性質,稱它為簡化階梯形(簡化行階梯形):

  1.每一非零行的先導元素是1;

  2.每一先導元素1是該元素所在列的惟一非零元素。

  比如,

定理1:每個矩陣行等價於惟一的簡化階梯形矩陣。即簡化階梯形矩陣是惟一的。


   下面,我們用一個具體例子來說明高斯消元法的主要步驟。

  原矩陣:

  第一步,由最左的非零列開始,這是一個主元列。主元位置在該列頂端。

  第二步,在主元列中選取一個非零元作為主元。若有必要的話,對換兩行使這個元素移到主元位置上。

  第三步,用倍加行變換將主元下面的元素變成0.

  第四步,暫時不管包含主元位置的行以及它上面的各行,對剩下的子矩陣使用上述的三個步驟直到沒有非零行需要處理為止。

  對每一行重復上述步驟。

  第五步,由最右面的主元開始,把每個主元上方的各元素變成0.若某個主元不是1,用倍乘變換將它變成1.

  最后,我們就得到了原矩陣的簡化階梯形。

  其中,第1~4步稱為行化簡算法的向前步驟,產生唯一的簡化階梯形的第5步,稱為向后步驟。

 


 

C++實現

  我們嘗試用C++來實現以上步驟。這里只是簡單的實現,也就是用代碼描述了上述步驟,沒有考慮過多的問題。歡迎大家在評論里指出問題,提出更好的建議,以便於日后改進。

  大概的實現思路就是先實現向前步驟:

  首先,我們對於每一行找到第一個不為零的元素,並且將這一行置為1 * * * *的形式,用這一行乘上倍數加到之后的每一行。

  再實現向后步驟:

  然后,我們從最后一行開始,選擇主元,加到之前的每一行上,使得該列的元素都為零。

  最后,我們就完成了化簡,得到了簡化階梯形。

  以上算法只是一個粗略實現,主要體現在:

  1.對於主元的選定不夠最優;

  2.會出現精度問題;

  3.對於某些情況無法處理。

  先暫時貼上代碼,之后有時間再進行優化。

 1 #include <iostream>
 2 #include <cstdio>
 3 
 4 using namespace std;
 5 
 6 int main()
 7 {
 8     double martix[100][100];
 9     int n, m; // n行m列
10 
11     scanf("%d %d", &n, &m);
12 
13     // 輸入
14     for(int i = 0; i < n; i++)
15         for(int j = 0; j < m; j++)
16             scanf("%lf", &martix[i][j]);
17 
18     // 向前步驟
19     for(int i = 0; i < n - 1; i++)
20     {
21         // 找主元
22         int pos = 0;
23         for(int j = 0; j < m; j++)
24             if(martix[i][j])
25             {
26                 pos = j;
27                 break;
28             }
29 
30         if(martix[i][pos] != 1 && martix[i][pos] != 0)
31         {
32             double tmp = martix[i][pos];
33             for(int j = pos; j < m; j++)
34             {
35                 martix[i][j] = martix[i][j] / tmp;
36             }
37         }
38         for(int j = i + 1; j < n; j++)
39         {
40             if(!martix[j][pos])
41                 continue;
42             double tmp = martix[j][pos];
43             for(int k = pos; k < m; k++)
44             {
45                 martix[j][k] = martix[j][k] - martix[i][k] * tmp;
46             }
47         }
48     }
49 
50     // 向后步驟
51     for(int i = n - 1; i > 0; i--)
52     {
53         int pos = 0;
54         for(int j = 0; j < m; j++)
55             if(martix[i][j])
56             {
57                 pos = j;
58                 break;
59             }
60 
61         if(martix[i][pos] != 1 && martix[i][pos] != 0)
62         {
63             double tmp = martix[i][pos];
64             for(int j = pos; j < m; j++)
65             {
66                 martix[i][j] = martix[i][j] / tmp;
67             }
68         }
69 
70         for(int j = 0; j < i; j++)
71         {
72             if(!martix[j][pos])
73                 continue;
74             double tmp = martix[j][pos];
75             for(int k = pos; k < m; k++)
76             {
77                 martix[j][k] = martix[j][k] - martix[i][k] * tmp;
78             }
79         }
80     }
81 
82     // 輸出
83     for(int i = 0; i < n; i++)
84     {
85         for(int j = 0; j < m; j++)
86             printf("%-10.2f", martix[i][j]);
87         printf("\n");
88     }
89     return 0;
90 }

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM