• 高斯消元(浮点数主列法消元,有剪枝细节..


     1 #include <iostream>
     2 #include <cstdio>
     3 #include <vector>
     4 #include <cmath>
     5 using namespace std;
     6 const double EPS=1e-8;
     7 
     8 typedef  vector<double> vec;
     9 typedef vector<vec> mat;
    10 
    11 vec Gauss(const mat& A,const vec& b){
    12     int n=A.size();
    13     mat B(n,vec(n+1));
    14     for(int i=0;i<n;++i)
    15         for(int j=0;j<n;++j) B[i][j]=A[i][j];
    16     for(int i=0;i<n;++i) B[i][n]=b[i];
    17     for(int i=0;i<n;++i){
    18         int pivot=i;
    19         for(int j=i+1;j<n;++j)if(abs(B[j][i]>abs(B[pivot][i]))) pivot=j;
    20         swap(B[i],B[pivot]);
    21         if(abs(B[i][i])<EPS) return vec();
    22         for(int j=i+1;j<=n;++j) B[i][j]/=B[i][i];
    23         for(int j=i+1;j<n;++j)
    24             if(j!=i) for(int k=i+1;k<=n;++k) B[j][k]-=B[j][i]*B[i][k];
    25     }
    26     vec x(n);
    27     for(int i=0;i<n;++i) x[i]=B[i][n];  double ans;
    28     for(int i=n-1;i>=0;--i){
    29         ans=x[i];
    30         for(int j=i+1;j<n;++j) ans-=B[i][j]*x[j];x[i]=ans;
    31     }
    32     return x;
    33 }
    34 double ai[3][3]={{1,-2,3},{4,-5,6},{7,-8,10}};
    35 double bi[]={6,12,21};
    36 int main(){
    37     mat A(3,vec(3));
    38     vec b(3);
    39     for(int i=0;i<3;++i){
    40         for(int j=0;j<3;++j){
    41             A[i][j]=ai[i][j];
    42         }
    43     }
    44     for(int i=0;i<3;++i) b[i]=bi[i];
    45     vec x(3);
    46     x=Gauss(A,b);
    47     for(int i=0;i<x.size();++i){
    48         printf("%f,",x[i]);
    49     }
    50     printf("
    ");
    51     return 0;
    52 }

    可能有一个令你疑惑的地方是为什么22行,j从i+1开始除,30行,j从i+1开始除

    因为这些地方其实是被搞成系数为1的,我们在计算的时候不会用到这些值,所以我们不用去管当前消去的这一变量

    最后一个步骤容易忽略,那就是回带的步骤,因为这个方法算完得到的B矩阵(不含增广,是一个上三角行列式,所以我们不断迭代就好了

    这个方法的复杂度是n^3的

    对于1000规模的,我们就需要剪枝了....

    下面附上剪枝后的模板...sdut2878这个题需要剪枝

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <vector>
     4 #include <cmath>
     5 using namespace std;
     6 const double EPS=1e-8;
     7 
     8 typedef  vector<double> vec;
     9 typedef vector<vec> mat;
    10 
    11 vec Gauss(const mat& A,const vec& b){
    12     int n=A.size();
    13     mat B(n,vec(n+1));
    14     for(int i=0;i<n;++i)
    15         for(int j=0;j<n;++j) B[i][j]=A[i][j];
    16     for(int i=0;i<n;++i) B[i][n]=b[i];
    17     for(int i=0;i<n;++i){
    18         int pivot=i;
    19         for(int j=i+1;j<n;++j)if(abs(B[j][i]>abs(B[pivot][i]))) pivot=j;
    20         if(pivot!=i) swap(B[i],B[pivot]);
    21         if(abs(B[i][i])<EPS) return vec();
    22         for(int j=i+1;j<=n;++j) B[i][j]/=B[i][i];
    23         for(int j=i+1;j<n;++j)
    24             if(j!=i) {
    25                 if(abs(B[j][i])<EPS) continue;
    26                 for(int k=i+1;k<=n;++k) B[j][k]-=B[j][i]*B[i][k];
    27             }
    28     }
    29     vec x(n);
    30     for(int i=0;i<n;++i) x[i]=B[i][n];  double ans;
    31     for(int i=n-1;i>=0;--i){
    32         ans=x[i];
    33         for(int j=i+1;j<n;++j) ans-=B[i][j]*x[j];x[i]=ans;
    34     }
    35     return x;
    36 }
    37 double ai[3][3]={{1,-2,3},{4,-5,6},{7,-8,10}};
    38 double bi[]={6,12,21};
    39 int main(){
    40     mat A(3,vec(3));
    41     vec b(3);
    42     for(int i=0;i<3;++i){
    43         for(int j=0;j<3;++j){
    44             A[i][j]=ai[i][j];
    45         }
    46     }
    47     for(int i=0;i<3;++i) b[i]=bi[i];
    48     vec x(3);
    49     x=Gauss(A,b);
    50     for(int i=0;i<x.size();++i){
    51         printf("%f,",x[i]);
    52     }
    53     printf("
    ");
    54     return 0;
    55 }

    20,25行是剪枝的地方

  • 相关阅读:
    post 跨域
    鼠标滚轮 控制作用滚动
    es5的特性 有多少你没用过
    javascript 定义修改属性值
    javascript 原型继承
    C# windows 服务 操作实例
    linq to xml 操作实例
    伪随机数 避免操作
    linq 分组包含时间操作
    时间转换操作
  • 原文地址:https://www.cnblogs.com/linkzijun/p/6695089.html
Copyright © 2020-2023  润新知