zoukankan      html  css  js  c++  java
  • 数论--高斯消元法

    高斯消元是一个常用的解n元一次方程组的方法。
    1.处理数据:
    我们设方程Ai>ai1x1+ai2x2+ainxn=bi
    那么对于A1An这n个方程,我们可以将它们放在一个矩阵里,方便操作。
    例如这样:
    2x1+4x2=10
    3x1+2x2=1
    存储为矩阵:
    2 4 10
    -3 2 1
    2.矩阵变换:
    我们可以对于矩阵的某一部分作出一些变换使得在方程组本身没有本质变化的前提下可以求解。
    变换1:交换两行。
    变换2:给一行乘(除)一个数。
    变换3:将某一行加(减)给另一行。
    变换2+3:将某一行乘(除)一个数之后再加(减)给另一行。
    以上的变换一定要好好理解。
    3.矩阵求解:
    首先,我们先来看看上面那个方程是怎么解的:
    1
    2x1+4x2=10—-A
    3x1+2x2=1—-B

    2
    1x1+2x2=5—-A/2—-变换2

    3
    8x2=16—-A*3+B—-变换2+3

    4
    x2=2
    x1=1

    以上过程转换成矩阵就是:

    1
    2 4 10
    -3 2 1

    2
    R1/2
    1 2 5
    -3 2 1

    3
    R2+R1*3
    1 2 5
    0 8 16

    4
    R2/8
    1 2 5
    0 1 2

    5
    R1-R2*2
    1 0 1
    0 1 2

    6
    此时的矩阵转换为方程就是:
    1x1+0x2=1
    0x1+1x2=2
    化简后即为:
    x1=1
    x2=2
    至此,解题完毕。

    看了以上过程之后是不是有点儿明白了呢?
    可以先看看代码,一边看,一边自己用代码来处理一下上面的题,有助于理解。
    代码:洛谷 P3389 【模板】高斯消元法

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const double eps=1e-8;
    int n;
    double a[101][102];
    bool gauss(){
        for(int i=1;i<=n;i++){//依次从x1到xn消去每一个未知数
            int mx=i;//有一个优化我还没说,就是每次找绝对值最大的一行,可以减小精度误差
            for(int j=i+1;j<=n;j++)if(fabs(a[j][i])>fabs(a[mx][i]))mx=j;
            if(fabs(a[mx][i])<eps)return 0;//几乎为零,这种情况下无解或有无穷多解
            for(int j=i;j<=n+1;j++)swap(a[i][j],a[mx][j]);//交换两行(变换1)
            double mul=a[i][i];
            for(int j=i;j<=n+1;j++){
                a[i][j]/=mul;//除一个数(变换2)
            }
            for(int k=1;k<=n;k++){
                if(k==i)continue;//不能给自己减
                mul=a[k][i];
                for(int j=i;j<=n+1;j++){
                    a[k][j]-=a[i][j]*mul;//乘以一个数,再减给另一行(变换2+3)
                }
            }
        }
        return 1;
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n+1;j++){
                scanf("%lf",&a[i][j]);
            }
        }
        if(!gauss()){
            printf("No Solution");
            return 0;
        }
        else{
            for(int i=1;i<=n;i++){
                printf("%.2lf
    ",a[i][n+1]);//依次输出每一个解
            }
        }
        return 0;
    }
  • 相关阅读:
    Android Studio设置字体和主题
    Android 使用shape定义不同控件的的颜色、背景色、边框色
    Linux下mysql的常用操作
    部署腾讯云(CentOS6.6版本,jdk1.7+tomcat8+mysql)
    在linux下如何使用yum查看安装了哪些软件包
    Tomcat下wtpwebapps文件夹 和 webapps文件夹区别
    安卓开源框架SlidingMenu使用
    Android_scaleType属性
    Android_Jar mismatch! Fix your dependencies
    操作系统原理之进程管理(第二章)
  • 原文地址:https://www.cnblogs.com/stone41123/p/7581259.html
Copyright © 2011-2022 走看看