高斯消元法解线性方程组(C++实现)

      最近在学数值分析,正好学到求解线性方程组。就自己动手简单实现了一下。关于本算法的原理可以在《数值分析》第5版(李庆扬编),对应于该书的P145页,详细讲解了公式。因本人时间有限,暂时不详细编辑公式,等空闲了再来重新补充。
      简要的说明下该算法的应用吧,高斯消元法在线性代数那门课肯定学过了,对于一般简单的3、4阶线性方程组,还可以进行纸上的笔运算,但是当数目过多,算起来就比较吃力了,所以借助于计算机实现。如果很多的数学软件里都有矩阵的求解的函数,如mathematic和matlab,因本人对这些软件不熟悉,所以也没去去尝试使用。
      对于非奇异矩阵并且主对角线上的元素不为0。就可以用高斯消元法来求解。
      我直接用简单的C++编程方式,有点类C风格,并没有运用C++的奇淫技巧,由于本人技术不成熟,时间有限,就暂时用简单的实现。等空闲了,一定把奇淫技巧运用上去。
      先贴代码吧!

#include
using namespace std;

const int n = 3;

void gaussin(double a[n][n], double b[n])
{
    //判断能否用高斯消元法,如果矩阵主对角线上有0元素存在是不能用的
    for (int i = 0; i < n; i++)
        if (a[i][i] == 0)
        {
            cout << "can't use gaussin meathod" << endl;
            return;
        }

    int i, j, k;
    double c[n];    //存储初等行变换的系数,用于行的相减
    //消元的整个过程如下,总共n-1次消元过程。
    for (k = 0; k < n - 1; k++)
    {
        //求出第K次初等行变换的系数
        for (i = k + 1; i < n; i++)
            c[i] = a[i][k] / a[k][k];

        //第K次的消元计算
        for (i = k + 1; i < n; i++)
        {
            for (j = 0; j < n; j++)
            {
                a[i][j] = a[i][j] - c[i] * a[k][j];
            }
            b[i] = b[i] - c[i] * b[k];
        }
    }

//解的存储数组
    double x[n];
    //先计算出最后一个未知数;
    x[n - 1] = b[n - 1] / a[n - 1][n - 1];
    //求出每个未知数的值
    for (i = n - 2; i >= 0; i--)
    {
        double sum = 0;
        for (j = i + 1; j < n; j++)
        {
            sum += a[i][j] * x[j];
        }
        x[i] = (b[i] - sum) / a[i][i];
    }

    cout << " the solution of the equations is:" << endl;
    cout << endl;
    for (i = 0; i < n; i++)     
        cout <<"x"<1<<"="<< x[i] << endl;

}

1.  我们进行判断主对角线元素是否有0值,如果有0值就不能用这个方法了。因为这个简单的高斯消元法并没有进行行列交换,所以主队角线不能为0,否则那个行变换的大小就不能得到(除数为0.undefined).   2.为初等行变换计算变换大小,存储在数组C[N] 3.进行消元过程。 4.外循环继续第二次重复(2)(3)步骤,直到K=N-1次为止。  5.进行解的倒推。                                                                                                               分析一下该算法的不足之处吧,由于我本人能力有限,对于C++的特性还不是很熟悉
1 由于这个数组传参问题就是我的弱项,我的想法是由用户指定任意大小的数组,但这样就要多一个参数。
2 本人只是做了个double类型的矩阵运算。我的思路是可以将这些修改成函数模板,用模板支持各种数据类型的矩阵。如果矩阵是整数类型的,里面的运算可能会产生double型,进行转换赋值会丢失精度。而且一般来说double型的矩阵计算,由于机器运算的原因,会有计算机产生的误差,所以改成模板,似乎没有什么应用。         3.对于空间和性能分析,该算法的局限性很大,首先由于该算法不能对主对角线上为0的元素进行计算,所以局限性很大,关于改进版的算法,接下来我会陆续编写求解方法。其次,对于该算法,我的实现过程用了2个存储n维数组来保存值,对其实可以存储在算矩阵本身,因为消元过程完成后,那个空间基不会再使用了,不加上时间的消耗 ,并不是一个理想的算法,接下里我会改进此算法。 

“`
对后续结果产生影响,按理应该能直接存储在矩阵中。   时间分析:该算法时间复杂度是O(N^3),所以运算很大,int main()
{

double a[3][3] = { 1,1,1,0,4,-1,2,-2,1 };
double b[3] = { 6,5,1}

gaussin(a, b);
return 0;

}

“`           这是测试代码,结果运算结果是1,2,3。我时间有限,没有进行很多测试,希望大家能与我多探讨,相互学习和促进,做更多的分析和讨论!如有错误和不适之处,请各位指出!

你可能感兴趣的:(数值分析)