高斯消元矩阵

文章目录


一、前言


二、算法

模板:

c++ 复制代码
/*
*功能: 列选主元消元法
*@Author: lzyws739307453
*@Language: C++
*@File Name: Gauss.cpp
*@Create Time: 2019年05月05日 星期日
*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 5;
//输出矩阵
void printM(double a[][MAXN], int n) {
   for (int i = 1; i <= n; i++) {
       for (int j = 1; j <= n + 1; j++)
           printf("%10f,", a[i][j]);
       printf("\n");
   }
}
//选择列主元并进行消元
void SelectColE(double a[][MAXN], int n) {
   double temp; //用于记录消元时的因数
   for (int i = 1; i <= n; i++) {
       int r = i;
       for (int j = i + 1; j <= n; j++)
           if (fabs(a[j][i]) > fabs(a[r][i]))
               r = j;
       if (r != i)
           for (int j = i; j <= n + 1; j++)
               swap(a[i][j], a[r][j]);//与最大主元所在行交换
       for (int j = i + 1; j <= n; j++) {//消元
           temp = a[j][i] / a[i][i];
           for (int k = i; k <= n + 1; k++)
               a[j][k] -= a[i][k] * temp;
       }
       printf("第%d列消元后:\n", i);
       printM(a, n);
   }
}
//高斯消元法(列选主元)
void Gauss(double a[][MAXN], int n) {
   SelectColE(a, n);//列选主元并消元成上三角
   printf("上三角的结果:\n");
   printM(a, n);
   for (int i = n; i >= 1; i--) {//回代求解
       for (int j = i + 1; j <= n; j++)
           a[i][n + 1] -= a[i][j] * a[j][n + 1];
       a[i][n + 1] /= a[i][i];
   }
}
//测试函数
int main() {
   double a[5][MAXN] = {
           {0,   0,   0,   0,   0},
           {0,   2,   1,  -1,   8},
           {0,  -3,  -1,   2, -11},
           {0,  -2,   1,   2,  -3}
   };
   Gauss(a, 3);
   //3个方程3个未知数
   for (int i = 1; i <= 3; i++)
       printf("X%d = %9f\n", i, a[i][4]);
   return 0;
}

1.Matrix Equation


题解:

bitset优化版本见收藏夹,感觉那个才算是正解

代码:

c 复制代码
#include<bits/stdc++.h>

using namespace std;
#define int long long
const int mod = 998244353;
const int N = 210;
int a[N][N];//增广矩阵
int x[N];//解集
bool freeX[N];//标记是否为自由变元
int n;
int A[N][N],B[N][N];

int Gauss(int equ,int var){//返回自由变元个数
  /*初始化*/
  for(int i=0;i<=var;i++){
      x[i]=0;
      freeX[i]=0;
  }

  /*转换为阶梯阵*/
  int col=0;//当前处理的列
  int num=0;//自由变元的序号
  int row;//当前处理的行
  for(row=0;row<equ&&col<var;row++,col++){//枚举当前处理的行
      int maxRow=row;//当前列绝对值最大的行
      for(int i=row+1;i<equ;i++){//寻找当前列绝对值最大的行
          if(abs(a[i][col])>abs(a[maxRow][col]))
              maxRow=i;
      }
      if(maxRow!=row){//与第row行交换
          for(int j=row;j<var+1;j++)
              swap(a[row][j],a[maxRow][j]);
      }
      if(a[row][col]==0){//col列第row行以下全是0,处理当前行的下一列
          freeX[num++]=col;//记录自由变元
          row--;
          continue;
      }

      for(int i=row+1;i<equ;i++){
          if(a[i][col]!=0){
              for(int j=col;j<var+1;j++){//对于下面出现该列中有1的行,需要把1消掉
                  a[i][j]^=a[row][j];
              }
          }
      }
  }

  /*求解*/
  //无解:化简的增广阵中存在(0,0,...,a)这样的行,且a!=0
  for(int i=row;i<equ;i++)
      if(a[i][col]!=0)
          return -1;

  //无穷解: 在var*(var+1)的增广阵中出现(0,0,...,0)这样的行
  int temp=var-row;//自由变元有var-row个
  if(row<var)//返回自由变元数
      return temp;

  //唯一解: 在var*(var+1)的增广阵中形成严格的上三角阵
  for(int i=var-1;i>=0;i--){//计算解集
      x[i]=a[i][var];
      for(int j=i+1;j<var;j++)
          x[i]^=(a[i][j]&&x[j]);
  }
  return 0;
}

int qpow(int base,int power) {
  int res = 1;
  while(power) {
      if(power & 1) res = res*base%mod;
      base = base*base%mod;
      power >>= 1;
  }return res;
}

signed main(){
  int equ,var;//equ个方程,var个变元

  cin >> n;
  equ = n; var = n;

  for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) cin >> A[i][j];
  }

  for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) cin >> B[i][j];
  }

  int ans = 1;

  for (int k = 0; k < n; k++) {
      //对于c的第几列
      memset(a,0,sizeof(a));
      for (int i = 0; i < n; i++) {
          for (int j = 0; j < n; j++) {
              a[i][j] = A[i][j];
          }
          a[i][n] = 0;
          if(A[i][i] == B[i][k]) a[i][i] = 0;
          else a[i][i] = 1;
      }
      int freeNum=Gauss(equ,var);//自由元个数
      ans = ans*qpow(2,freeNum);
      ans %= mod;
  }

  cout  << ans << endl;

//        if(freeNum==-1)//无解
//            printf("无解\n");
//        else if(freeNum==-2)//有浮点数解无整数解
//            printf("无整数解\n");
//        else if(freeNum>0){//有无穷多解
//            printf("有无穷多解,自由变元个数为%d\n",freeNum);
//            for(int i=0;i<var;i++){
//                if(freeX[i])
//                    printf("x%d是自由变元\n",i+1);
//                else
//                    printf("x%d=%d\n",i+1,x[i]);
//            }
//        }
//        else{//有唯一解
//            for(int i=0;i<var;i++)
//                printf("x%d=%d\n",i+1,x[i]);
//        }
}

三、总结

相关推荐
小蝙蝠侠3 小时前
安德烈·卡帕西:深入探索像ChatGPT这样的大语言模型内容列表
人工智能·算法·机器学习
闻缺陷则喜何志丹3 小时前
【贪心之临项交换】P8732 [蓝桥杯 2020 国 ABC]|普及
c++·算法·蓝桥杯·贪心·洛谷
charlie1145141913 小时前
理解C++20的革命特性——协程支持1
c++·学习·c++20·协程·语言特性·调度·现代c++
而后笑面对3 小时前
关于力扣2025.10.4每日 11.盛最多雨水的容器
算法·leetcode·职场和发展
郝学胜-神的一滴4 小时前
Effective STL 第1条:慎重选择容器类型
开发语言·c++·程序人生·软件工程
UrbanJazzerati4 小时前
考研数学:数轴根法(穿根法)——高效求解高次不等式的利器
算法
可触的未来,发芽的智生4 小时前
新奇特:负权重橡皮擦,让神经网络学会主动遗忘
人工智能·python·神经网络·算法·架构
阿明64 小时前
list模拟实现(简单版)【C++】
开发语言·c++·学习·list
DoomGT4 小时前
UE5 - C++项目基础
c++·ue5·ue4·虚幻·虚幻引擎·unreal engine