高斯消元模板

来源:互联网 发布:血色残阳知乎 编辑:程序博客网 时间:2024/06/06 03:33

高斯消元:

其实就是用矩阵初等变换解线性方程组,只是他要求每次选取的主元一定要是最大值。

模板

#include <iostream>#include <stdio.h>#include <string.h>#include <stdlib.h>using namespace std;const int MAXN=10000;int a[MAXN][MAXN];//增广矩阵int x[MAXN];//解集bool free_x[MAXN];//标记是否是不确定的变元int gcd(int a,int b){//最大公约数    int t;    while(b!=0)    {        t=b;        b=a%b;        a=t;    }    return a;}int lcm(int a,int b){//求最小公倍数    return a/gcd(a,b)*b;//先除后乘防溢出}int Gauss(int equ,int var){    int i,j,k;    int max_r;// 当前这列绝对值最大的行.    int col;//当前处理的列    int ta,tb;    int LCM,temp,free_x_num,free_index;    for(int i=0; i<=var; i++)    {        //初始化        x[i]=0;        free_x[i]=true;    }//转换为行阶梯阵.    col=0; // 当前处理的列  k为当前处理的行    for(k = 0; k < equ && col < var; k++,col++)    {        //最后一列没有化解//找到该col列元素绝对值最大的那行与第k行交换(为了在除法时减小误差)        max_r=k;        for(i=k+1; i<equ; i++)        {            if(abs(a[i][col])>abs(a[max_r][col]))                max_r=i;        }        if(max_r!=k)        {            //与第k行交换.            for(j=k; j<var+1; j++)                swap(a[k][j],a[max_r][j]);        }        if(a[k][col]==0)        {//说明该col列第k行以下全是0了,则处理当前行的下一列.            k--;            continue;        }        for(i=k+1; i<equ; i++)        {            // 利用主元消元            if(a[i][col]!=0)            {                LCM = lcm(abs(a[i][col]),abs(a[k][col]));                ta = LCM/abs(a[i][col]);                tb = LCM/abs(a[k][col]);                if(a[i][col]*a[k][col]<0)                    tb=-tb;//异号的情况是相加                for(j=col; j<var+1; j++)                    a[i][j] = a[i][j]*ta-a[k][j]*tb;            }        }    }// 1. 无解的情况有:0=d;    for (i = k; i < equ; i++)        if (a[i][col] != 0) return -1;// 2. 无穷解的情况    if (k < var)    {        //var是未知元个数,首先,自由变元有var - k个        for (i = k - 1; i >= 0; i--)        {            free_x_num = 0;            for (j = 0; j < var; j++)                if (a[i][j] != 0 && free_x[j])                    free_x_num++;            free_index = j;            if (free_x_num > 1) continue;// 无法求解出确定的变元.// 说明就只有一个不确定的变元free_index,那么可以求解出该变元,且该变元是确定的.            temp = a[i][var];            for (j = 0; j < var; j++)            {                //找已经求出的未知元                if (a[i][j] != 0 && j != free_index)                    temp -= a[i][j] * x[j];//移项            }// 求出该变元.            x[free_index] = temp / a[i][free_index];            free_x[free_index] = 0; // 该变元是确定的.        }        return var - k; // 自由变元有var - k个.    }// 唯一解的情况:在var*(var + 1)的增广阵中形成严格的上三角阵.// 计算出Xn-1, Xn-2 ... X0.    for (i=var-1; i>=0; i--)    {        temp=a[i][var];        for (j = i + 1; j < var; j++)        {            if (a[i][j] != 0) temp -= a[i][j] * x[j];        }        if (temp % a[i][i] != 0)            return -2; // 说明有浮点数解,但无整数解.        x[i] = temp / a[i][i];    }    return 0;}int main(){    int i, j;    int equ,var;//行,列    while (scanf("%d %d", &equ, &var) != EOF)    {        memset(a, 0, sizeof(a));        for (i = 0; i < equ; i++)        {            for (j = 0; j < var + 1; j++)            {                //增广矩阵                scanf("%d", &a[i][j]);            }        }        int free_num = Gauss(equ,var);    }    return 0;}





0 0