高斯消元解线性方程组

思路:

(1)模拟线性代数解方程组办法,在此讨论正方形方程组求解。

(2)考虑几个问题:

  1. 数据存储:采用double数组存储。
  2. 判断是否为零,由于double计算存在误差,采用const double = eps = 1e-6;通过绝对值与eps比较判断是否为0。

(3)算法流程:

  1. 逐列枚举,行也从0开始枚举;
  2. 对于第c列,从第r行开始,找到绝对值最大的行号t;
  3. 如果a[t][c]为0,即该列最大值为0,则该列非固定行值均为0,跳过该列操作(因为不能让该列出现1个1);
  4. 令第c列绝对值最大行与第r行调换位置。
  5. 将r行第c列元素归一。
  6. 用该列的1将r行以下的元素全部消为0;
  7. 此时保证出现一个1了,所以r++;(显然r的数量就是1的数量)
  8. 除b列所有列用完后,判定r是否小于n;
  9. 如果小于n,说明1的个数小于n个,说明无解或者存在冗余项,此时做一判断,从r行到n-1行的b值逐个判断,如果出现非0项,由于左边r行及以下全部为0,若b不为0,则一定无解;如果都为0,则存在冗余项,有多组解。
  10. 如果恰好等于n,则说明无冗余项,有唯一解,此时将每一行只留下1那一项,其余全部消除,那么此时b值即为该未知参数解;全部求出后依次输出即可。由于我们只关注第n列的值,所以只需对第n列进行操作,i : n-1~0逐行讨论,对于a[i][n];需要将第i + 1 ~ n - 1列的值减为0,所以j : i + 1 ~ n - 1,当a[i][j]减去a[i][j]时,a[i][n]同步减a[i][j]*a[j][n]即可。

(4)注意:用绝对值判定。

代码:

#include

using namespace std;

const int N = 110;
const double eps = 1e-6;

double a[N][N];
int n;

void goss()
{
    int r = 0;
    for(int c = 0;c < n;c ++)
    {
        int t = r;
        for(int j = r + 1;j < n;j ++)
            if(fabs(a[j][c]) > fabs(a[t][c]))
                t = j;
        
        if(fabs(a[t][c]) < eps) continue;
        
        for(int j = 0;j < n + 1;j ++)
            swap(a[r][j],a[t][j]);
        
        for(int j = n;j >= c;j --)//从大往小除
            a[r][j] /= a[r][c];
        
        for(int j = r + 1;j < n;j ++)
            if (fabs(a[j][c]) > eps)
                for(int k = n;k >= c;k --)//从大往小除
                    a[j][k] -= a[j][c]*a[r][k];
        
        r ++;
    }
    
    if(r < n)
    {
        int flag = 0;
        for(int i = r;i < n;i ++)
            if(fabs(a[i][n]) > eps)
                flag = 1;
        
        if(flag) puts("No solution");
        else puts("Infinite group solutions");
    }
    else
    {
        for(int i = n - 1;i >= 0;i --)
            for(int j = i + 1;j < n;j ++)
                a[i][n] -= a[j][n]*a[i][j];
        
        for(int i = 0;i < n;i ++)
            printf("%.2lf\n",a[i][n]);
    }
}

int main()
{

    cin >> n;
    
    for(int i = 0;i < n;i ++)
        for(int j = 0;j < n + 1;j ++)
            cin >> a[i][j];
    
    goss();
    
    return 0;
}

你可能感兴趣的:(机器学习,算法,人工智能)