高斯消元整数版和浮点数版实现
生活随笔
收集整理的這篇文章主要介紹了
高斯消元整数版和浮点数版实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
簡介
實現
整數版
#include <iostream>#include <stdio.h> #include <stdlib.h> #include <vector>using namespace std;#define MAXN 100 //最大變量數量 int arr[MAXN][MAXN]; //保存增廣矩陣 int result[MAXN]; //保存方程的解 int unuse_result[MAXN];//判斷是否是不確定的變元 int unuse_num; void swap(int *a,int *b) //交換兩數 {int t;t=*a;*a=*b;*b=t; } int gcd(int a,int b) //返回最大公約數 {int t;while(b!= 0){t=b;b=a%b;a=t;}return a; } int lcm(int a,int b) //返回最小公倍數 {return a*b/gcd(a,b); } void debug(int equ,int var) {int i,j;for(i=0;i<equ;i++){for(j=0;j<var+1;j++)printf("%d ",arr[i][j]);printf("\n");}printf("\n"); } int Gauss(int equ,int var) {int i,j,k,col;int max_r,ta,tb,lcm1;int temp,unuse_x_num,unuse_index;col=0; //設當前處理列的值為0,表示從第1列開始處理for(k=0;k<equ && col<var;k++,col++) //循環處理矩陣中的行{max_r=k; //絕對值最大行for(i=k+1;i<equ;i++)if(abs(arr[i][col])>abs(arr[max_r][col]))max_r=i; //保存絕對值最大的行號if(max_r!=k) //最大行不是當前行,則與第k行交換for(j=k;j<var+1;j++)swap(&arr[k][j], &arr[max_r][j]); //交換矩陣右上角數據if(arr[k][col]==0) //說明col列第k行以下全是0了,則處理當前行的下一列{k--;continue;}for(i=k+1;i<equ;i++) //查找要刪除的行{if(arr[i][col]!=0) //左列不為0,進行消元運算{lcm1=lcm(abs(arr[i][col]),abs(arr[k][col])); //求最小公倍數ta=lcm1/abs(arr[i][col]);tb=lcm1/abs(arr[k][col]);if(arr[i][col]*arr[k][col]<0) //相乘為負,表示兩數符號不同tb=-tb; //異號的情況是兩個數相加for(j=col;j<var+1;j++)arr[i][j]=arr[i][j]*ta-arr[k][j]*tb;}}}for(i=k;i<equ;i++)//判斷最后一行最后一列,若不為0,表示無解if(arr[i][col]!=0)return -1; //返回無解if(k<var)//自由變元有var-k個,即不確定的變元至少有var-k個.{for(i=k-1;i>=0;i--){unuse_x_num=0; //判斷該行中不確定變量數量,若超過1個,則無法求解for(j=0;j<var;j++){if(arr[i][j]!=0 && unuse_result[j]){unuse_x_num++;unuse_index=j;}}if(unuse_x_num>1)continue; // 無法求解出確定的解temp=arr[i][var];for(j=0;j<var;j++){if(arr[i][j]!=0 && j!=unuse_index)temp-=arr[i][j]*result[j];}result[unuse_index]=temp/arr[i][unuse_index]; // 求出該變元.unuse_result[unuse_index]=0; //該變元是確定的}return var-k; //自由變元有var-k個}for(i=var-1;i>=0;i--) //回代求解{temp=arr[i][var];for(j=i+1;j<var;j++){if(arr[i][j]!=0)temp-=arr[i][j]*result[j];}if(temp % arr[i][i]!=0) //若不能整除return -2; //返回有浮點數解,但無整數解// 如果存在浮點數解,則直取前面固定位數值result[i]=temp/arr[i][i];}return 0; }int main(int argc, const char * argv[]) {// insert code here...int i,j;int equ, var;printf("方程數:");scanf("%d",&equ); //輸入方程數量printf("變量數:");scanf("%d",&var); //輸入變量數量for(i=0;i<equ;i++) //循環輸入各方程的系數{printf("第%d個方程的系數:",i+1);for(j=0;j<var+1;j++) //循環輸入一個方程的系數{scanf("%d", &arr[i][j]);}}unuse_num=Gauss(equ,var); //調用高斯函數if(unuse_num==-1) //無解printf("無解!\n");else if(unuse_num==-2) //只有浮點數解printf("有浮點數解,無整數解!\n");else if(unuse_num>0) //無窮多解{printf("無窮多解! 自由變量數量為%d\n",unuse_num);for(i=0;i<var;i++){if(unuse_result[i])printf("x%d 是不確定的\n",i+1);elseprintf("x%d: %d\n",i+1,result[i]);}}else{for(i=0;i<var;i++) //輸出解{printf("x%d=%d\n",i+1,result[i]);}}printf("\n");return 0; }浮點數版
#include <stdlib.h> #include <stdio.h> #include <cmath> #include <memory.h> #include <iostream> #include <string.h> #include <string> using namespace std;const int maxn=1002; const double eps=1e-12; double a[maxn][maxn]; //增廣矩陣 //int equ,var;//equ個方程,var個變量 double x[maxn];//解集 bool free_x[maxn]; int n;int sgn(double x) {return (x>eps)-(x<-eps); }void swap(double *a,double *b) //交換兩數 {double t;t=*a;*a=*b;*b=t; }// 高斯消元法解方程組(Gauss-Jordan elimination).(0表示無解,1表示唯一解,大于1表示無窮解,并返回自由變元的個數) int gauss(int equ,int var) {int i,j,k;int max_r; // 當前這列絕對值最大的行.int col; // 當前處理的列.double temp;int free_x_num;int free_index = 0;// 轉換為階梯陣.col=0; // 當前處理的列.memset(free_x,true,sizeof(free_x));for(k=0;k<equ&&col<var;k++,col++){max_r=k;for(i=k+1;i<equ;i++){if(sgn(fabs(a[i][col])-fabs(a[max_r][col]))>0)max_r=i;}if(max_r!=k){ // 與第k行交換.for(j=k;j<var+1;j++)swap(a[k][j],a[max_r][j]);}if(sgn(a[k][col])==0){ // 說明該col列第k行以下全是0了,則處理當前行的下一列.k--; continue;}for(i=k+1;i<equ;i++){ // 枚舉要刪去的行.if (sgn(a[i][col])!=0){temp=a[i][col]/a[k][col];for(j=col;j<var+1;j++){a[i][j]=a[i][j]-a[k][j]*temp;}}}}for(i=k;i<equ;i++){if (sgn(a[i][col])!=0)return 0;}if(k<var){for(i=k-1;i>=0;i--){free_x_num=0;for(j=0;j<var;j++){if (sgn(a[i][j])!=0&&free_x[j])free_x_num++,free_index=j;}if(free_x_num>1) continue;temp=a[i][var];for(j=0;j<var;j++){if(sgn(a[i][j])!=0&&j!=free_index)temp-=a[i][j]*x[j];}x[free_index]=temp/a[i][free_index];free_x[free_index]=0;}return var-k;}for (i=var-1;i>=0;i--){temp=a[i][var];for(j=i+1;j<var;j++){if(sgn(a[i][j])!=0)temp-=a[i][j]*x[j];}x[i]=temp/a[i][i];}return 1; }int main(int argc, const char * argv[]) {// insert code here...int i,j;int equ, var;printf("方程數:");scanf("%d",&equ); //輸入方程數量printf("變量數:");scanf("%d",&var); //輸入變量數量for(i=0;i<equ;i++) //循環輸入各方程的系數{printf("第%d個方程的系數:",i+1);for(j=0;j<var+1;j++) //循環輸入一個方程的系數{scanf("%lf", &a[i][j]);}}n=gauss(equ,var); //調用高斯函數if(n==0) //無解printf("無解!\n");else if(n>1) //無窮多解{printf("無窮多解! 自由變量數量為%d\n",n);for(i=0;i<var;i++){if(free_x[i])printf("x%d 是不確定的\n",i+1);elseprintf("x%d: %f\n",i+1,x[i]);}}else if(n==1){for(i=0;i<var;i++) //輸出解{printf("x%d=%f\n",i+1,x[i]);}}printf("\n");return 0; }轉載于:https://www.cnblogs.com/George1994/p/6399890.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的高斯消元整数版和浮点数版实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POJ 1661 Help Jimmy
- 下一篇: 指定想要进入的页面