码迷,mamicode.com
首页 > 其他好文 > 详细

行列式计算的两种方法

时间:2015-08-30 20:47:32      阅读:285      评论:0      收藏:0      [点我收藏+]

标签:

#include<iostream> 
#include<cstring>
#include<cstdio>
#include<algorithm>
#define N 100 
using namespace std;
int a[N][N];
double aa[N][N];
int n;

/**********************************************************/
//求行列式的值:是所有取自不同行不同列的n个元素的乘积 
int d[N];
int tmpd[N]; 
int dd[N];
int vis_column[N];//是否在同一列 
int inverse;//逆序数的个数 
int ans = 0;
void merger(int ld, int rd){
    if(ld >= rd) return;
    int mid=(ld+rd)>>1;
    merger(ld,mid);
    merger(mid+1, rd);
    int i=ld, j=mid+1, k=0;
    while(i<=mid && j<=rd){
        int col1 = (tmpd[i]-1)%n+1;
        int col2 = (tmpd[j]-1)%n+1;
        if(col1 < col2){
            dd[++k] = tmpd[i++];
        } else {
            dd[++k] = tmpd[j++];
            inverse += mid-i+1; 
        }
    }
    while(i<=mid) dd[++k] = tmpd[i++];
    while(j<=rd) dd[++k] = tmpd[j++];
    memcpy(tmpd+ld, dd+1, sizeof(int)*(k));
}

void determinantValue(int row){
    if(row>n){
        inverse=0; 
        int tmp = 1;
        for(int k=1; k<=n; ++k){
            int i = (d[k]-1)/n+1;
            int j = (d[k]-1)%n+1;
            tmp *= a[i][j];
        }
        memcpy(tmpd, d, sizeof(int)*(n+1));
        merger(1, n);
        if(inverse&1) ans-=tmp;
        else ans+=tmp;
        return;
    }
    for(int col=1; col<=n; ++col)
        if(!vis_column[col]){
            vis_column[col]=1;
            d[row] = (row-1)*n + col;
            determinantValue(row+1);
            vis_column[col]=0;
        }
}
/**********************************************************/

/**********************************************************/
//以列主元方法,将行列式转变成上三角矩阵

double determinantValueA(){
    int sign = 1;
    double ret = 0.0;
    for(int i=1; i<=n; ++i){
        double maxVal = aa[i][i];
        int j = i;
        for(int k=i+1; k<=n; ++k)//寻找这一列中的元素值的最大值 
            if(maxVal < aa[k][i]){
                maxVal = aa[k][i];
                j = k;
            }
        if(j!=i){
            sign = -sign;
            for(int k=1; k<=n; ++k){//交换两行 
                double tmp = aa[i][k];
                aa[i][k] = aa[j][k];                 
                aa[j][k] = tmp;
            }
        }
        if(maxVal < 1e-10)//最大值为0,也就是意味这对角线上的元素有0出现 
            return ret;
            
        for(int k=i+1; k<=n; ++k){
            double b = aa[k][i]/aa[i][i];
            for(int c=1; c<=n; ++c) 
                aa[k][c] -= b*aa[i][c];
        }
    }
    ret = 1.0;
    for(int i=1; i<=n; ++i)
        ret*=aa[i][i];
    return ret;
}
 
/**********************************************************/
int main() {
//    cin>>n;
//    for(int i=1; i<=n; ++i)
//        for(int j=1; j<=n; ++j)
//            cin>>a[i][j];
//    determinantValue(1);
//    cout<<ans<<endl;
    
    cin>>n;
    for(int i=1; i<=n; ++i)
        for(int j=1; j<=n; ++j)
            cin>>aa[i][j];
    cout<<determinantValueA()<<endl;
    return 0;
}
/*
4
3 4 5 11
2 5 4 9
5 3 2 12
14 -11 21 29

4
2 0 0 0
0 2 0 0
0 0 2 0
0 0 0 2 

2
1 2 3 4
*/

 

行列式计算的两种方法

标签:

原文地址:http://www.cnblogs.com/hujunzheng/p/4771380.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!