高斯消元法(模板)

高斯消元法(列选主元法)

唯一解:判定存在性并求值

  1. a a a数组存增广矩阵(第 n + 1 n+1 n+1列为常数列)
  2. m r mr mr为每次所选取的最大系数的行标号,然后交换第 i i i行和 m r mr mr
  3. 若存在唯一解,则系数矩阵会被化简为 n × n n×n n×n的单位矩阵,相应的常数列就是 x i x_i xi的解啦!
  4. 调用:Gauss();
  5. 返回值: 0 0 0表示无唯一解, 1 1 1表示有唯一解
#include "bits/stdc++.h"
#define hhh printf("hhh\n")
#define see(x) (cerr<<(#x)<<'='<<(x)< pr;
inline int read() {int x=0;char c=getchar();while(c<'0'||c>'9')c=getchar();while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();return x;}

const int maxn = 1e5+10;
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
const double eps = 1e-7;

int n;
double a[101][102];

bool Gauss() {
    for(int i=1; i<=n; ++i) {
        int mr=i;
        for(int j=i+1; j<=n; ++j) if(fabs(a[j][i])>fabs(a[mr][i])) mr=j;
        swap(a[i],a[mr]);
        if(fabs(a[i][i])

无穷解:判定解的情况

  1. 要先判定无解,再判定无穷解(但是要在化简过程中先记录)
  2. 判定无解要在化简结束后,并且要检查所有行
#include "bits/stdc++.h"
#define hhh printf("hhh\n")
#define see(x) (cerr<<(#x)<<'='<<(x)< pr;
inline int read() {int x=0;char c=getchar();while(c<'0'||c>'9')c=getchar();while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();return x;}

const int maxn = 1e5+10;
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
const double eps = 1e-7;

int n;
double a[101][102];

int Gauss() {
    bool Inf=0;
    for(int i=1; i<=n; ++i) {
        int mr=i;
        for(int j=i+1; j<=n; ++j) if(fabs(a[j][i])>fabs(a[mr][i])) mr=j;
        swap(a[i],a[mr]);
        if(fabs(a[i][i])=eps) { f=0; break; }
        if(f&&fabs(a[i][n+1])) return 0;
    }
    if(Inf) return 2;
    return 1;
}

int main() {
    //ios::sync_with_stdio(false); cin.tie(0);
    n=read();
    for(int i=1; i<=n; ++i)
        for(int j=1; j<=n+1; ++j) scanf("%lf", &a[i][j]);
    int ans=Gauss();
    if(ans==1) for(int i=1; i<=n; ++i) printf("x%d=%.2f\n", i, a[i][n+1]);
    else printf("%d\n", ans?0:-1);
}

高级版(可求出自由变量数目)(还没用过这个板子,但感觉可以用上面的写法稍微改改就好了)

a数组中常系数保存在a[i][var]中;
唯一解保存在x数组中;
自由变量保存在free_x数组中;

const double eps = 1e-9;

double a[maxn][maxn];//每个方程中每个未知数的系数
double x[maxn];//解集
bool free_x[maxn];

int sgn(double x) {
    return (x>eps)-(x<-eps);
}

int gauss(int equ, int var) {
    int i,j,k;
    int max_r; // 当前这列绝对值最大的行.
    int col; // 当前处理的列.
    double temp;
    int free_x_num;
    int free_index;
    // 转换为阶梯阵.
    col=0; // 当前处理的列.
    memset(free_x,1,sizeof(free_x));
    for(k=0; k0) max_r=i;
        }
        if(max_r!=k){ // 与第k行交换.
            for(j=k; j<=var; j++) swap(a[k][j],a[max_r][j]);
        }
        if(sgn(a[k][col])==0) { k--; continue; }// 说明该col列第k行以下全是0了,则处理当前行的下一列.
        for(i=k+1; i=0; i--) {
            free_x_num=0;
            for(j=0; j1) continue;
            temp=a[i][var];
            for(j=0; j=0; i--) {
        temp=a[i][var];
        for(j=i+1; j

再附带一份同余版本的高斯消元

你可能感兴趣的:(数学)