《算法导论》——矩阵

1.矩阵的相关运算(矩阵的乘法):

  根据线性代数里面相关的定义,两个矩阵要能够相乘必须具备的条件是,第一个矩阵的列的维数和第二个矩阵的行维数相等这样才可以相乘,假设有这样两个矩阵 a[m][n] , b[n][m] , 那么得到的结果将是m*n型的矩阵,并且有结果矩阵的每一个元素都等于其对应的行和对应的列的对应每一个元素的积的和

假设有这样的矩阵:
#define MAX 105

struct matrix{
     int volume[MAX][MAX];
     matrix(){
        memset(volume,0,sizeof(volume));
     }
};

那么其乘法定义为:

matrix matrix_multipe(matrix a , matrix b , int n){
    matrix result;
    for(int i=0 ; i<MAX ; ++i)
        for(int j=0 ; j<MAX ; ++j){
                if(a.volume[i][j])                //优化,避免做无用的运算超时
                    for(int k=0 ; k<n ; ++k)
                        result.volume[i][k]+=a.volume[i][j]*b.volume[j][k];

    }
    return result;
}

2.矩阵的快速幂运算:

  何两个数的快速幂运算相同,矩阵也看我一定以相应的快速幂运算,不过却不能做取模运算:

从上面的定义可以定义快速幂运算:

matrix matrix_pow(matrix a , int n , int k){                                    //k次幂,n为这个矩阵维数数(为方便,特将该矩阵定义成了方阵)
    if(k == 1)
        return a;
    matrix result ;
    for(int i=0 ; i<k ; ++i)
        result.volume[i][i]=1;                      //结果矩阵初始化为单位矩阵

    while(k){
        if(k & 1) result = matrix_multipe(result , a , n);        //更新结果
        if(k = k>>1) a = matrix_multipe(a , a , n);
    }
    return result;
}

3.高斯消元法求线性方程的解:

  线性代数中对高斯消元法的描述大致可以总结为以下步骤:

    a.化系数矩阵为上三角矩阵,若增广矩阵的秩大于等于系数矩阵的秩有唯一组解,小于有多组解,大于无解

    b.有唯一组解的情况下从最后一个方程回带求解该方程的解

 假定该方程有解: 

const int max=10;
double matrix[max][max];

void gauss(int n){
    for(int i=0 ; i<n ;++i){              //化为上三角矩阵
        int r=i;
        for(int j=i+1 ; j<n ; ++j){
                if(fabs(matrix[j][r]) > fabs(matrix[r][i]))
                    r = j;
        }
        if(r != i)
            for(int k=0 ; k<=n ; ++k){
                double temp=matrix[r][k];
                matrix[r][k] = matrix[i][k];
                matrix[i][k] = temp;
            }

        for(int j=n ; j>=i ; --j){
            for(int k=i+1 ; k<n ; ++k)
                matrix[k][j] -= matrix[k][i]/matrix[i][i]*matrix[i][j];
        }
    }

    for(int i=n-1 ; i>=0 ; --i){              //会带求解
        for(int j=i+1 ; j<n ; ++j)
            matrix[i][n] -= matrix[j][n]*matrix[i][j];

        matrix[i][n] /= matrix[i][i] ;
    }

}

4.矩阵的逆矩阵

根据线性代数中对逆矩阵的定义:一个矩阵如果有逆矩阵当且仅当该矩阵的行列式的值不为零,那我们可以想办法给系数矩阵不上一个单位矩阵,然后想办法将系数矩阵化为单位矩阵,自然原来的那个单位矩阵就是该系数矩阵的逆矩阵。

void inverse_matrix(double **matrix , double **unit_matrix , int n){
     if(!matrix)
        return ;
     if(!unit_matrix)
        return ;

     memset(unit_matrix,0,sizeof(unit_matrix));

     for(int i=0 ; i<n ; ++i)
        unit_matrix[i][i] = 1;                            //初始化单位矩阵

     for(int i=0 ; i<n ; ++i){
        int r=i;
        for(int j=i+1 ; j<n ; ++j)
            if(fabs(matrix[j][i] > matrix[r][i]))
                r = j;
        if(r != i){
             for(int j=0 ; j<n ; ++j){
                double temp = matrix[i][j];
                matrix[i][j] = matrix[r][j];
                matrix[r][j] = temp;
                temp = unit_matrix[r][j];
                unit_matrix[r][j] = unit_matrix[i][j];
                unit_matrix[i][j] = temp;
             }
        }

        for(int j=0 ; j<n ; ++j){
            if(j != 0 && fabs(matrix[j][i]) > 0){
                double temp=matrix[j][i];

                for(int k=0 ; k<n ; ++k){
                    matrix[k][j] -= temp/matrix[i][i] * matrix[i][j];
                    unit_matrix[k][j] -= temp/unit_matrix[i][i] * unit_matrix[i][j] ;
                }
            }
        }

        for(int k=0 ; k<n ; ++k){
            unit_matrix[i][k] /= matrix[i][i];
        }

        for(int k=n-1 ; k>=i ; --i)
            matrix[i][k] /= matrix[i][i];
    }
}

原文地址:https://www.cnblogs.com/mascotxi/p/4712719.html