高斯消去法解线性方程组

解线性方程组,只支持有唯一解的情况。如果无解或者有多个解,则退出。

 

 

方程组的系数阵为m*m的方阵A,增广阵为m*n矩阵为B,有n=m+1。增广阵在系数阵加入的那1列就是方程组等号右边那些常数组成的列向量。

 

 

算法步骤:

1>. 先搞第1列。找出第1列中绝对值最大的数,称作主元素(mainElement)。把主元素所在的行与第1行进行行交换,则主元素此时落在对角线上。将第1行(所有元素)除以主元素,则主元素为1。

1>. 第1列的元素为a[u][0],其中u=1...m-1。第2行与第1行进行row addition,即r 2+(-a[u][0])*r1,这样第2行第1个元素会成为0。第3行以致第m行也进行r_u-a[u][0]*r1这样的操作,则在第1列,除了第1 行之外,所有下面的元素都变成0.

1>.对第2列重复上面的步骤,但注意主元素要放到对角线(左上-右下)上,进行row addition时,选择第2行。

1>.对列j重复第2列的操作,有2<=j<=m-2(系数阵最后一列和增广的那1列不用搞)。

1>.完成之后,则系数阵成为上三角阵。此时未知数x[m-1]首先得解。然后将x[m-1]回代到上一行,可以解得x[m-2];再将x[m-1], x[m-2]往上回代解得x[m-3] ... 直到解出x[0]。

1>.打完收工。

 

#! /usr/bin/env python
#coding=utf-8
#[email protected]

import math

class LinEqu:
    def __init__(self, mat_aug):
        self.mat_aug = mat_aug;
   self.index = len(mat_aug[0])-1;
   self.solution = [0 for a in range(self.index)];
   print 'Original matrix: ';
   self.printMatrix();
    def eliminate(self):
   m = self.index;
   n = self.index+1;
   i,j=0,0;
   while True:
        if i>m-2 or j>n-2: break;
        print '\ni=%d, j=%d' % (i , j);
            mainElement = 0.0;
            for k in range(i+1, m):
                if math.fabs(mat_aug[k][i]>mainElement):
                    mainElement=mat_aug[k][i];
                    exchangeRow = k;
        if not mainElement>0.0:
       print 'There is no solution or the solutions are more than 1. Exit.';
       return None;
                  
            for l in range(n):
       #Swap row i and exchangeRow that contains mainElement
                mat_aug[i][l], mat_aug[exchangeRow][l] = mat_aug[exchangeRow][l], mat_aug[i][l];
       mat_aug[i][l] /= mainElement;
        print 'After round %d of row swap and normalization: ' % i;
        self.printMatrix();
          
            for u in range(i+1, m):
       pivot = mat_aug[u][j];
       for v in range(n):
            mat_aug[u][v]=mat_aug[u][v]-mat_aug[i][v]*pivot;
        print 'After round %d of elimination: ' % i;
        self.printMatrix();
        i+=1;
        j+=1;

    def backSub(self):
   mat_aug = self.mat_aug;
   x=self.solution;
   m=self.index;
   n=self.index+1;
   b=[0 for row in range(self.index)];

   x[m-1]=mat_aug[m-1][n-1]/mat_aug[m-1][n-2];
   for i in reversed(range(self.index)):
        b[i] = self.mat_aug[i][n-1];
        sum = 0.0;
        for j in reversed(range(i+1, n-1)):
       sum+=mat_aug[i][j]*x[j];
        x[i] = (b[i]-sum)/mat_aug[i][i];

    def printMatrix(self):
   for row in range(len(self.mat_aug)):
        print mat_aug[row];
   print;
    def printSolu(self):
   print
   print 'The soluiton is: ', self.solution;
    def main(self):
   self.eliminate();
   self.backSub();
   self.printSolu();

if __name__=='__main__':
    #mat_aug = [[9.0,3,4,7],[4,3,4,8],[1,1,1,3]];
    mat_aug = [[0.0,2.0,1.0,4.0],[1.0,1.0,2.0,6.0],[2.0,1.0,1.0,7]];
    equation = LinEqu(mat_aug);
    equation.main();

 

解的过程:

$ ./gaussian_elimination.py
Original matrix:
[0.0, 2.0, 1.0, 4.0]
[1.0, 1.0, 2.0, 6.0]
[2.0, 1.0, 1.0, 7]


i=0, j=0
After round 0 of row swap and normalization:
[1.0, 0.5, 0.5, 3.5]
[1.0, 1.0, 2.0, 6.0]
[0.0, 2.0, 1.0, 4.0]

After round 0 of elimination:
[1.0, 0.5, 0.5, 3.5]
[0.0, 0.5, 1.5, 2.5]
[0.0, 2.0, 1.0, 4.0]


i=1, j=1
After round 1 of row swap and normalization:
[1.0, 0.5, 0.5, 3.5]
[0.0, 1.0, 0.5, 2.0]
[0.0, 0.5, 1.5, 2.5]

After round 1 of elimination:
[1.0, 0.5, 0.5, 3.5]
[0.0, 1.0, 0.5, 2.0]
[0.0, 0.0, 1.25, 1.5]


The soluiton is: [2.2000000000000002, 1.3999999999999999, 1.2]

 

 

参考资料:

1. [web] http://ceee.rice.edu/Books/CS/chapter2/linear43.html

2. [web]. Wikipedia contributors, "Gaussian elimination," Wikipedia, The Free Encyclopedia,http://en.wikipedia.org/w/index.php?title=Gaussian_elimination&oldid=392526152 (accessed November 28, 2010).

3. [web]. http://marekrychlik.com/cgi-bin/gauss.cgi

你可能感兴趣的:(Web,算法,python,J#,Gmail)