1.一般高斯消元法:可能会出现较大的舍入误差
#include<cstdio>
#include<cmath>
using namespace std;
const int N=20;
void Guess(int n,double a[N][N]){
for(int i=0;i<n;i++) //判断
if(a[i][i]==0){
printf("can't use Guess!\n");
return ;
}
//消元
double l[N][N]; //存储系数,行相减
for(int k=0;k<n-1;k++){
for(int i=k+1;i<n;i++){
l[i][k]=a[i][k]/a[k][k];
for(int j=k;j<=n;j++)
a[i][j]=a[i][j]-l[i][k]*a[k][j];
}
}
//回代
double x[N]; //解空间
x[n-1]=a[n-1][n]/a[n-1][n-1];
for(int i=n-1;i>=0;i--){
double sum=0;
for(int j=i+1;j<n;j++)
sum+=a[i][j]*x[j];
x[i]=(a[i][n]-sum)/a[i][i];
}
printf("\n");
for(int i=0;i<n;i++)
printf("X%d:%lf%c",i+1,x[i],i==n-1?'\n':' ');
}
int main(){
int n=1;
while(true){
printf("n=");
scanf("%d",&n);
if(n==0) break;
double a[N][N];
for(int i=0;i<n;i++)
for(int j=0;j<=n;j++)
scanf("%lf",&a[i][j]);
Guess(n,a);
printf("\n");
}
return 0;
}
2.列主元素消元法:行之间进行交换
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=20;
double a[N][N];
void Select(int i,int n){ //列主元素
int p=i+1,q=i;
while(p<n){
if(fabs(a[i][i])<fabs(a[p][i])){
while(q<n+1){
double tmp=a[p][q];
a[p][q]=a[i][q];
a[i][q]=tmp;
q++;
}
q=0;
}
p++;
}
}
void Guess(int n,double a[N][N]){
for(int i=0;i<n;i++) //判断
if(a[i][i]==0){
printf("can't use Guess!\n");
return ;
}
//消元
double l[N][N]; //存储系数,行相减
for(int k=0;k<n;k++){
Select(k,n);
for(int i=k+1;i<n;i++){
l[i][k]=a[i][k]/a[k][k];
for(int j=k;j<=n;j++)
a[i][j]=a[i][j]-l[i][k]*a[k][j];
}
}
//回代
double x[N]; //解空间
x[n-1]=a[n-1][n]/a[n-1][n-1];
for(int i=n-1;i>=0;i--){
double sum=0;
for(int j=i+1;j<n;j++)
sum+=a[i][j]*x[j];
x[i]=(a[i][n]-sum)/a[i][i];
}
printf("\n");
for(int i=0;i<n;i++)
printf("X%d:%lf%c",i+1,x[i],i==n-1?'\n':' ');
}
int main(){
int n=1;
while(true){
printf("n=");
scanf("%d",&n);
if(n==0) break;
for(int i=0;i<n;i++)
for(int j=0;j<=n;j++)
scanf("%lf",&a[i][j]);
Guess(n,a);
printf("\n");
}
return 0;
}
3.完全主元素消元法:行列都进行交换,行多增加一行标记要求的系数下标
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=100;
double a[N][N];
void Select(int x,int n){ //完全主元素
int p=x,q=x;
for(int i=x;i<n;i++){ //记录绝对值最大的位置
for(int j=x;j<n;j++){
if(fabs(a[x][x])<fabs(a[i][j])){
p=i;
q=j;
}
}
}
int tmp=x;
while(tmp<n+1){
swap(a[p][tmp],a[x][tmp]);
tmp++;
}
tmp=0;
while(tmp<n+1){
swap(a[tmp][q],a[tmp][x]);
tmp++;
}
}
void Guess(int n,double a[N][N]){
for(int i=0;i<n;i++) //判断
if(a[i][i]==0){
printf("can't use Guess!\n");
return ;
}
//消元
double l[N][N]; //存储系数,行相减
for(int k=0;k<n;k++){
Select(k,n);
for(int i=k+1;i<n;i++){
l[i][k]=a[i][k]/a[k][k];
for(int j=k;j<=n;j++)
a[i][j]=a[i][j]-l[i][k]*a[k][j];
}
}
//回代
double x[N]; //解空间
x[n-1]=a[n-1][n]/a[n-1][n-1];
for(int i=n-1;i>=0;i--){
double sum=0;
for(int j=i+1;j<n;j++)
sum+=a[i][j]*x[j];
x[i]=(a[i][n]-sum)/a[i][i];
}
printf("\n");
for(int i=0;i<n;i++)
printf("Y%d:%lf%c",i+1,x[i],i==n-1?'\n':' ');
printf("\n");
for(int i=0;i<n;i++)
printf("X%d:%lf%c",(int)a[n][i],x[i],i==n-1?'\n':' ');
}
int main(){
int n=1;
while(true){
printf("n=");
scanf("%d",&n);
if(n==0) break;
for(int i=0;i<n;i++)
for(int j=0;j<=n;j++)
scanf("%lf",&a[i][j]);
for(int j=0;j<n;j++)
a[n][j]=(j+1);
a[n][n]=0;
Guess(n,a);
printf("\n");
}
return 0;
}