【计算方法】解线性方程组的四种方法

1.使用高斯列主消元法求解

#include
#include
#include
#include
/* 2018/4/18日在写程序之前没有思考清楚就直接写了。 调试完成发现自己写的耦合度太高,不适于修改。 用指针去访问二维数组,每次加一定的偏移量,增加了程序的复杂性,而且不利于修改。 */ 
/*************************************** *使用四种方法求解线性方程组 * 1. 高斯消元法 * 2.追赶法 * 3.雅克比迭代法 * 4.高斯--赛德尔迭代法 * *****************************************/ 
#define N 5
#define M 4
void dep(double *p);
void display(double array[][N]);



static double A[M][N] = { {8,7,0,0,0}, {6,12,5,0,-2}, {0,4,9,3,8}, {0,0,1,2,6} };
double B[N] = {0,-2,8,6};

//交换 
void swap(double *p, double *t) { 
    double s;
    s = *p;
    *p = *t;
    *t = s; 
}

//通过计算列的max值交换行 
void f(double *p, int row) {

    double max = fabs(*p);

    int r1 = row; 
    int r2 = row;       //保留当前行数 
    int i = 1;

    for(;row < M - 1; row++, i++) { 

        if (max < fabs( *(p + i * N) ) ) {
            max = *(p + i * N);
            r1 = row;     //记录最大的行数 
        }
    }   

    //调用交换函数 
    for(int i = 0; i < N; i++) {     
        swap(&A[r2][i], &A[r1][i]);  
    }

    dep(p);

    return ;
}

void display(double array[][N]) {

    for(int i = 0; i < M; i++) {    
        for(int j = 0; j < N; j++) {
            printf("%10f",array[i][j]);
        }
        printf("\n");
    } 
    return ;
}

//消元 ----消去每一列 
void dep(double* p) {
    double result;
    double *temp; 
    double *tail;
    //消去row+1 ----N行第row列的值 
    for (int i = 1; i < M ; i++) {
        tail = p;
        result =  *(p + i * N) / *p;
        temp = p + i * N;
        for(int j = 0; j < N; j++) {    
            *temp -= *tail * result;    //每一列减去系数,然后得0 
            temp++;
            tail++;
        }
    } 

    return ; 
}
/* //回代过程 double* solve() { double x[M]; int i; memset(x, 0, sizeof(x)); //初始化数组 x[M - 1] = A[M - 1][N -1] / A[M - 1][N - 2]; for(i = M -2; i >= 0; i--){ double s = A[i][N - 1]; for (int j = i + 1; j < N -1; j++) { s -= (A[i][j]*x[i + 1]); } x[i] = s / A[i][i]; } return x; } void merge() { double newArray[N][N]; //定义一个增广矩阵 for(int i = 0; i < N ; i++ ) { for(int j = 0; j < N + 1; j++) { newArray[i][j] = A[i][j]; if(j == N) { newArray[i][j] = B[i]; } } } } */
int main() {     
/********************************************** *方法1.高斯列消元法 * 1)先换行 * 2)消元 * 3)给出答案 ***********************************************/    
    double x[M];
    int i;
    memset(x, 0, sizeof(x));        //初始化数组 

    display(A);
    for(i = 0; i < 4; i++) {
        f(&A[i][i],i);
    }
    printf("处理后的结果\n");
    system("pause");
    system("cls");
    display(A);
    //回代过程 
    x[M - 1] = A[M - 1][N -1] / A[M - 1][N - 2];

    for(i = M -2; i >= 0; i--){

        double s = A[i][N - 1];
        for (int j = i + 1; j < N -1; j++) {
            s -= (A[i][j]*x[i + 1]);
        }
        x[i] = s / A[i][i];
    }
    for (i = 0; i < M; i++) {
        printf("%-10lf",x[i]);
    } 
    return 0; 
}

2.使用追赶法求解

#include
#include
#include
#include
/**
*追赶法求解线性方程组 
*/

#define N 5 

void display(double *temp) {
    int i  = 0;
    for(; i < N; i++, temp++) {
        printf("%-8lf\n",*temp);
    } 
}

int main() {

    double a[N] = {0, 0, 6, 4, 1};
    double b[N] = {0, 8, 12, 9, 2}; 
    double c[N] = {0, 7, 5, 3, 0};

    double f[N] = {0, 0, -2, 8, 6}; //存放常数项 

    double Y[N];
    double U[N];
    double X[N];        //解空间向量

    double L;
    int i,j;
    memset(Y,0,sizeof(Y));
    memset(U,0,sizeof(U));
    memset(X,0,sizeof(X));
    /**
    *1.求解Y空间向量 
    *追的过程(消元) 
    */ 
    Y[1] = f[1] / b[1];
    U[1] = c[1] / b[1];

    for (i = 2; i < N - 1; i++) {
        L = b[i] - a[i] * U[i - 1]; //计算L的值 
        U[i] = c[i] / L;    
        Y[i] = (f[i] - a[i] * Y[i - 1]) / L; 
    }

    /**
    *赶的过程(回代) 
    */ 
    Y[N - 1] = (f[N-1] - Y[N - 2] * a[N - 1]) / (b[N -1] - U[N - 2] * a[N - 1]); 
    X[N-1] = Y[N - 1];
    for (i = N - 2; i > 0; i--) {       
        X[i] = Y[i] - U[i] * X[i + 1]; 
    }
    printf("\n");
    display(X);

}

雅克比与高斯赛德尔迭代法

你可能感兴趣的:(计算方法)