当前位置:首页 » 编程语言 » 列主元高斯消去法c语言

列主元高斯消去法c语言

发布时间: 2022-10-28 13:26:40

Ⅰ 如何用C++用列主元高斯消去法求解线性方程组的解

大二的时候自己写得,包你满意!
四种方法:
Cramer算法解方程组
Gauss列主元解方程组
Gauss全主元解方程组
用Doolittle算法解方程组

//解线性方程组
#include<iostream.h>
#include<iomanip.h>
#include<stdlib.h>

//----------------------------------------------全局变量定义区
const int Number=15; //方程最大个数
double a[Number][Number],b[Number],_a[Number][Number],_b[Number]; //系数行列式
int A_y[Number]; //a[][]中随着横坐标增加列坐标的排列顺序,如a[0][0],a[1][2],a[2][1]...则A_y[]={0,2,1...};
int lenth,_lenth; //方程的个数
double a_sum; //计算行列式的值
char * x; //未知量a,b,c的载体

//----------------------------------------------函数声明区
void input(); //输入方程组
void print_menu(); //打印主菜单
int choose (); //输入选择
void cramer(); //Cramer算法解方程组
void gauss_row(); //Gauss列主元解方程组
void guass_all(); //Gauss全主元解方程组
void Doolittle(); //用Doolittle算法解方程组
int Doolittle_check(double a[][Number],double b[Number]); //判断是否行列式>0,若是,调整为顺序主子式全>0
void xiaoqu_u_l(); //将行列式Doolittle分解
void calculate_u_l(); //计算Doolittle结果
double & calculate_A(int n,int m); //计算行列式
double quanpailie_A(); //根据列坐标的排列计算的值,如A_y[]={0,2,1},得sum=a[0][ A_y[0] ] * a[1][ A_y[1] ] * a[2][ A_y[2] ]=a[0][0]*a[1][2]*a[2][1];
void exchange(int m,int i); //交换A_y[m],A_y[i]
void exchange_lie(int j); //交换a[][j]与b[];
void exchange_hang(int m,int n); //分别交换a[][]和b[]中的m与n两行
void gauss_row_xiaoqu(); //Gauss列主元消去法
void gauss_all_xiaoqu(); //Gauss全主元消去法
void gauss_calculate(); //根据Gauss消去法结果计算未知量的值
void exchange_a_lie(int m,int n); //交换a[][]中的m和n列
void exchange_x(int m,int n); //交换x[]中的x[m]和x[n]
void recovery(); //恢复数据

//主函数
void main()
{
int flag=1;
input(); //输入方程
while(flag)
{
print_menu(); //打印主菜单

flag=choose(); //选择解答方式
}

}

//函数定义区
void print_menu()
{
system("cls");
cout<<"------------方程系数和常数矩阵表示如下:\n";
for(int j=0;j<lenth;j++)
cout<<"系数"<<j+1<<" ";
cout<<"\t常数";
cout<<endl;
for(int i=0;i<lenth;i++)
{
for(j=0;j<lenth;j++)
cout<<setw(8)<<setiosflags(ios::left)<<a[i][j];
cout<<"\t"<<b[i]<<endl;
}
cout<<"-----------请选择方程解答的方案----------";
cout<<"\n 1. 克拉默(Cramer)法则";
cout<<"\n 2. Gauss列主元消去法";
cout<<"\n 3. Gauss全主元消去法";
cout<<"\n 4. Doolittle分解法";
cout<<"\n 5. 退出";
cout<<"\n 输入你的选择:";

}

void input()
{ int i,j;
cout<<"方程的个数:";
cin>>lenth;
if(lenth>Number)
{
cout<<"It is too big.\n";
return;
}
x=new char[lenth];
for(i=0;i<lenth;i++)
x[i]='a'+i;

//输入方程矩阵
//提示如何输入
cout<<"====================================================\n";
cout<<"请在每个方程里输入"<<lenth<<"系数和一个常数:\n";
cout<<"例:\n方程:a";
for(i=1;i<lenth;i++)
{
cout<<"+"<<i+1<<x[i];
}
cout<<"=10\n";
cout<<"应输入:";
for(i=0;i<lenth;i++)
cout<<i+1<<" ";
cout<<"10\n";
cout<<"==============================\n";

//输入每个方程
for(i=0;i<lenth;i++)
{
cout<<"输入方程"<<i+1<<":";
for(j=0;j<lenth;j++)
cin>>a[i][j];
cin>>b[i];
}

//备份数据
for(i=0;i<lenth;i++)
for(j=0;j<lenth;j++)
_a[i][j]=a[i][j];
for(i=0;i<lenth;i++)
_b[i]=b[i];
_lenth=lenth;
}

//输入选择
int choose()
{
int choice;char ch;
cin>>choice;
switch(choice)
{
case 1:cramer();break;
case 2:gauss_row();break;
case 3:guass_all();break;
case 4:Doolittle();break;
case 5:return 0;
default:cout<<"输入错误,请重新输入:";
choose();
break;
}
cout<<"\n是否换种方法求解(Y/N):";
cin>>ch;
if(ch=='n'||ch=='N') return 0;
recovery();
cout<<"\n\n\n";
return 1;

}

//用克拉默法则求解方程.
void cramer()
{
int i,j;double sum,sum_x;char ch;
//令第i行的列坐标为i
cout<<"用克拉默(Cramer)法则结果如下:\n";

for(i=0;i<lenth;i++)
A_y[i]=i;
sum=calculate_A(lenth,0);
if(sum!=0)
{
cout<<"系数行列式不为零,方程有唯一的解:";
for(i=0;i<lenth;i++)
{ ch='a'+i;
a_sum=0;
for(j=0;j<lenth;j++)
A_y[j]=j;
exchange_lie(i);
sum_x=calculate_A(lenth,0);
cout<<endl<<ch<<"="<<sum_x/sum;
exchange_lie(i);
}
}
else
{
cout<<"系数行列式等于零,方程没有唯一的解.";
}
cout<<"\n";
}

double & calculate_A(int n,int m) //计算行列式
{ int i;
if(n==1) {
a_sum+= quanpailie_A();
}
else{for(i=0;i<n;i++)
{ exchange(m,m+i);
calculate_A(n-1,m+1);
exchange(m,m+i);
}
}
return a_sum;
}

double quanpailie_A() //计算行列式中一种全排列的值
{
int i,j,l;
double sum=0,p;
for(i=0,l=0;i<lenth;i++)
for(j=0;A_y[j]!=i&&j<lenth;j++)
if(A_y[j]>i) l++;
for(p=1,i=0;i<lenth;i++)
p*=a[i][A_y[i]];
sum+=p*((l%2==0)?(1):(-1));
return sum;
}

//高斯列主元排列求解方程
void gauss_row()
{
int i,j;
gauss_row_xiaoqu(); //用高斯列主元消区法将系数矩阵变成一个上三角矩阵

for(i=0;i<lenth;i++)
{
for(j=0;j<lenth;j++)
cout<<setw(10)<<setprecision(5)<<a[i][j];
cout<<setw(10)<<b[i]<<endl;
}

if(a[lenth-1][lenth-1]!=0)
{

cout<<"系数行列式不为零,方程有唯一的解:\n";
gauss_calculate();
for(i=0;i<lenth;i++) //输出结果
{
cout<<x[i]<<"="<<b[i]<<"\n";
}
}
else
cout<<"系数行列式等于零,方程没有唯一的解.\n";
}

void gauss_row_xiaoqu() //高斯列主元消去法
{
int i,j,k,maxi;double lik;
cout<<"用Gauss列主元消去法结果如下:\n";
for(k=0;k<lenth-1;k++)
{
j=k;
for(maxi=i=k;i<lenth;i++)
if(a[i][j]>a[maxi][j]) maxi=i;
if(maxi!=k)
exchange_hang(k,maxi);//

for(i=k+1;i<lenth;i++)
{
lik=a[i][k]/a[k][k];
for(j=k;j<lenth;j++)
a[i][j]=a[i][j]-a[k][j]*lik;
b[i]=b[i]-b[k]*lik;
}
}
}

//高斯全主元排列求解方程
void guass_all()
{
int i,j;
gauss_all_xiaoqu();
for(i=0;i<lenth;i++)
{
for(j=0;j<lenth;j++)
cout<<setw(10)<<setprecision(5)<<a[i][j];
cout<<setw(10)<<b[i]<<endl;
}
if(a[lenth-1][lenth-1]!=0)
{

cout<<"系数行列式不为零,方程有唯一的解:\n";
gauss_calculate();

for(i=0;i<lenth;i++) //输出结果
{
for(j=0;x[j]!='a'+i&&j<lenth;j++);

cout<<x[j]<<"="<<b[j]<<endl;
}
}
else
cout<<"系数行列式等于零,方程没有唯一的解.\n";
}

void gauss_all_xiaoqu() //Gauss全主元消去法
{
int i,j,k,maxi,maxj;double lik;
cout<<"用Gauss全主元消去法结果如下:\n";

for(k=0;k<lenth-1;k++)
{

for(maxi=maxj=i=k;i<lenth;i++)
{
for(j=k;j<lenth;j++)
if(a[i][j]>a[maxi][ maxj])
{ maxi=i;
maxj=j;
}

}
if(maxi!=k)
exchange_hang(k,maxi);
if(maxj!=k)
{
exchange_a_lie(maxj,k); //交换两列
exchange_x(maxj,k);

}

for(i=k+1;i<lenth;i++)
{
lik=a[i][k]/a[k][k];
for(j=k;j<lenth;j++)
a[i][j]=a[i][j]-a[k][j]*lik;
b[i]=b[i]-b[k]*lik;
}
}
}

void gauss_calculate() //高斯消去法以后计算未知量的结果
{
int i,j;double sum_ax;
b[lenth-1]=b[lenth-1]/a[lenth-1][lenth-1];
for(i=lenth-2;i>=0;i--)
{
for(j=i+1,sum_ax=0;j<lenth;j++)
sum_ax+=a[i][j]*b[j];
b[i]=(b[i]-sum_ax)/a[i][i];
}
}

void Doolittle() //Doolittle消去法计算方程组
{
double temp_a[Number][Number],temp_b[Number];int i,j,flag;
for(i=0;i<lenth;i++)
for(j=0;j<lenth;j++)
temp_a[i][j]=a[i][j];
flag=Doolittle_check(temp_a,temp_b);
if(flag==0) cout<<"\n行列式为零.无法用Doolittle求解.";
xiaoqu_u_l();
calculate_u_l();
cout<<"用Doolittle方法求得结果如下:\n";
for(i=0;i<lenth;i++) //输出结果
{
for(j=0;x[j]!='a'+i&&j<lenth;j++);

cout<<x[j]<<"="<<b[j]<<endl;
}

}

void calculate_u_l() //计算Doolittle结果
{ int i,j;double sum_ax=0;
for(i=0;i<lenth;i++)
{
for(j=0,sum_ax=0;j<i;j++)
sum_ax+=a[i][j]*b[j];
b[i]=b[i]-sum_ax;
}

for(i=lenth-1;i>=0;i--)
{
for(j=i+1,sum_ax=0;j<lenth;j++)
sum_ax+=a[i][j]*b[j];
b[i]=(b[i]-sum_ax)/a[i][i];
}

}

void xiaoqu_u_l() //将行列式按Doolittle分解
{ int i,j,n,k;double temp;
for(i=1,j=0;i<lenth;i++)
a[i][j]=a[i][j]/a[0][0];
for(n=1;n<lenth;n++)
{ //求第n+1层的上三角矩阵部分即U
for(j=n;j<lenth;j++)
{ for(k=0,temp=0;k<n;k++)
temp+=a[n][k]*a[k][j];
a[n][j]-=temp;
}
for(i=n+1;i<lenth;i++) //求第n+1层的下三角矩阵部分即L
{ for(k=0,temp=0;k<n;k++)
temp+=a[i][k]*a[k][n];
a[i][n]=(a[i][n]-temp)/a[n][n];
}
}
}

int Doolittle_check(double temp_a[][Number],double temp_b[Number]) //若行列式不为零,将系数矩阵调整为顺序主子式大于零
{
int i,j,k,maxi;double lik,temp;

for(k=0;k<lenth-1;k++)
{
j=k;
for(maxi=i=k;i<lenth;i++)
if(temp_a[i][j]>temp_a[maxi][j]) maxi=i;
if(maxi!=k)
{ exchange_hang(k,maxi);
for(j=0;j<lenth;j++)
{ temp=temp_a[k][j];
temp_a[k][j]=temp_a[maxi][j];
temp_a[maxi][j]=temp;
}
}
for(i=k+1;i<lenth;i++)
{
lik=temp_a[i][k]/temp_a[k][k];
for(j=k;j<lenth;j++)
temp_a[i][j]=temp_a[i][j]-temp_a[k][j]*lik;
temp_b[i]=temp_b[i]-temp_b[k]*lik;
}
}

if(temp_a[lenth-1][lenth-1]==0) return 0;
return 1;
}

void exchange_hang(int m,int n) //交换a[][]中和b[]两行
{
int j; double temp;
for(j=0;j<lenth;j++)
{ temp=a[m][j];
a[m][j]=a[n][j];
a[n][j]=temp;

}
temp=b[m];
b[m]=b[n];
b[n]=temp;
}

void exchange(int m,int i) //交换A_y[m],A_y[i]
{ int temp;
temp=A_y[m];
A_y[m]=A_y[i];
A_y[i]=temp;
}

void exchange_lie(int j) //交换未知量b[]和第i列
{ double temp;int i;
for(i=0;i<lenth;i++)
{ temp=a[i][j];
a[i][j]=b[i];
b[i]=temp;
}
}

void exchange_a_lie(int m,int n) //交换a[]中的两列
{ double temp;int i;
for(i=0;i<lenth;i++)
{ temp=a[i][m];
a[i][m]=a[i][n];
a[i][n]=temp;
}
}

void exchange_x(int m,int n) //交换未知量x[m]与x[n]
{ char temp;
temp=x[m];
x[m]=x[n];
x[n]=temp;
}

void recovery() //用其中一种方法求解后恢复数据以便用其他方法求解
{
for(int i=0;i<lenth;i++)
for(int j=0;j<lenth;j++)
a[i][j]=_a[i][j];
for(i=0;i<lenth;i++)
b[i]=_b[i];
for(i=0;i<lenth;i++)
x[i]='a'+i;
a_sum=0;
lenth=_lenth;
}

Ⅱ 用c语言编程高斯全主元消去法(请用图中的过程)

#include <iostream>
#include <iomanip.h>
using namespace std;
#define N 20
double a[N][N];
double x[N+1];
double b[N+1];
int n;//n方程个数,n未知数个数
int set( )
{
cout<<"请输入方程的个数和未知数个数: "<<endl;
cin>>n;
int i,j;
cout<<"请输入方程组(逐个输入方程 i)"<<endl;
for(i = 1;i <= n;i++)
{
for(j = 1;j<=n;j++)
{
cin>>a[i][j];//系数
}
cin>>b[i];//结果
}
return 0;
}
int find(int k)//寻找第k列主元
{
int i,tag = k;
double maxv=0;
for(i = k;i <= n;i++)
{
if(a[i][k] > maxv)
{
maxv = a[i][k];
tag = i;
}
}
return tag;
}
void exchange(int i1,int i2)//将第 i1 i2行互换
{
int j;
for(j = 1;j <= n;j++)
{
swap(a[i1][j],a[i2][j]);
}
swap(b[i1],b[i2]);
}
void div(int k)//让第k个方程的首项系数为1
{
double temp = a[k][k];
for(int j = k; j <= n;j++)
{
a[k][j]/=temp;
}
b[k]/=temp;
}
void disME(int k)
{
int i,j;
for(i =1 ;i<=n;i++)
{
for(j = i;j<= n;j++)
{
if(a[i][j])
{
if(a[i][j]==1)
{ if(j==n)
cout<<"x"<<j;
else
cout<<"x"<<j<<" + ";
}
else
{
if(j==n)
cout<<a[i][j]<<"x"<<j;
else
cout<<a[i][j]<<"x"<<j<<" + ";
}
}
}
cout<<" = "<<b[i]<<endl;
}
system("pause");
}
void eliminate(int k)//消元
{
int i,j;
double t;
for(i = k+1;i<= n;i++)
{
t = a[i][k]/a[k][k];
for(j = k;j <= n;j++)
{
a[i][j]-=a[k][j] * t;
}
b[i] -= b[k] * t;
}
}
void Gauss()//高斯消元法
{
int i,j,k;
for(k = 1;k < n;k++)//共进行n - 1次消元
{
int l = find(k);//寻找第k次消元法的主元方程
if(l!=k)
{
exchange(l,k);
}
//消元
div(k);
eliminate(k);
cout<<"第"<<k<<"次消元结果:"<<endl;
disME(k);
}
div(k);
x[k] = b[k];
//disM();
for(i = n - 1;i>=1;i--)
{
for(j = i+1;j <=n ;j++)
{
b[i] -= a[i][j] * b [j];
}
x[i] = b[i];
}
}
void dis()
{
int i;
cout<<"解方程得:"<<endl;
for(i = 1;i<=n;i++)
{
cout<<"x"<<i<<" = ";
printf("%.5f\n",x[i]);
}
}
int main()
{
set();
Gauss();
dis();
system("pause");
return 0;
}

Ⅲ 高斯列主元消去法,求解齐次线性方程组的C语言实现

C/C++ code #include<stdio.h> #include <math.h> #define N 20 int main() { int n,i,j,k; int mi,tmp,mx; float a[N][N],b[N],x[N]; printf("\nInput n:"); scanf("%d",&n); if(n>N) { printf("The input n should in(0,N)!\n");     getch();     return 1; } if(n<=0) { printf("The input n should in(0,N)!\n");     getch();     return 1; } printf("Now input a(i,j),i,j=0...%d:\n",n-1); for(i=0;i<n;i++) { for(j=0;j<n;j++)     scanf("%f",&a[i][j]);} printf("Now input b(i),i,j=0...%d:\n",n-1); for(i=0;i<n;i++) scanf("%f",&b[i]); for(i=0;i<n-2;i++) { for(j=i+1,mi=i,mx=fabs(a[i][j]);j<n-1;j++)     if(fabs(a[j][i])>mx)     { mi=j;       mx=fabs(a[j][i]);     }     if(i<mi)     { tmp=b[i];b[i]=b[mi];b[mi]=tmp;       for(j=i;j<n;j++)       { tmp=a[i][j];         a[i][j]=a[mi][j];         a[mi][j]=tmp;       }     }     for(j=i+1;j<n;j++)     { tmp=-a[j][i]/a[i][i];       b[j]+=b[i]*tmp;       for(k=i;k<n;k++)       a[j][k]+=a[i][k]*tmp;     } } x[n-1]=b[n-1]/a[n-1][n-1]; for(i=n-2;i>=0;i--) { x[i]=b[i];     for(j=i+1;j<n;j++)     x[i]-=a[i][j]*x[j];     x[i]/=a[i][i]; } for(i=0;i<n;i++) printf("Answer:\n x[%d]=%f\n",i,x[i]); getch(); return 0; } #include<math.h> #include<stdio.h> #define NUMBER 20 #define Esc   0x1b #define Enter 0x0d float A[NUMBER][NUMBER+1] ,ark; int flag,n; exchange(int r,int k); float max(int k); message(); main() {    float x[NUMBER];        int r,k,i,j;    char celect;    clrscr();      printf("\n\nUse Gauss.");    printf("\n\n1.Jie please press Enter.");    printf("\n\n2.Exit press Esc.");    celect=getch();    if(celect==Esc)      exit(0);    printf("\n\n input n=");    scanf("%d",&n);      printf(" \n\nInput matrix A and B:");    for(i=1;i<=n;i++)    {     printf("\n\nInput a%d1--a%d%d and b%d:",i,i,n,i);            for(j=1;j<=n+1;j++)        scanf("%f",&A[i][j]);    }    for(k=1;k<=n-1;k++)                         {    ark=max(k);     if(ark==0)                      {       printf("\n\nIt's wrong!");message();     }     else if(flag!=k)      exchange(flag,k);      for(i=k+1;i<=n;i++)      for(j=k+1;j<=n+1;j++)      A[i][j]=A[i][j]-A[k][j]*A[i][k]/A[k][k];    }    x[n]=A[n][n+1]/A[n][n];    for( k=n-1;k>=1;k--)    {      float me=0;      for(j=k+1;j<=n;j++)      {        me=me+A[k][j]*x[j];      }        x[k]=(A[k][n+1]-me)/A[k][k];    }    for(i=1;i<=n;i++)    {      printf(" \n\nx%d=%f",i,x[i]);    }    message(); } exchange(int r,int k)      { int i; for(i=1;i<=n+1;i++)     A[0][i]=A[r][i]; for(i=1;i<=n+1;i++)     A[r][i]=A[k][i]; for(i=1;i<=n+1;i++)     A[k][i]=A[0][i]; } float max(int k)         { int i; float temp=0; for(i=k;i<=n;i++)     if(fabs(A[i][k])>temp)     {       temp=fabs(A[i][k]);       flag=i;     } return temp; } message()                                    { printf("\n\n Go on Enter ,Exit press Esc!"); switch(getch()) {    case Enter: main();    case Esc: exit(0);    default:{printf("\n\nInput error!");message();} } }

Ⅳ 如何用编程实现高斯列主元消去法

用C语言编制以下程序:
#include <stdio.h>
#include <math.h>
void main()
{
int i,j,k,ik,n;
float max,t,a[10][10],x[10],sum;
printf("请输入方程组的阶数:");
scanf("%d",&n);
printf("请输入增广矩阵\n");
for (i=1;i<=n;i++)
for (j=1;j<=n+1;j++)
scanf("%f",&a[i][j]);
for (k=1;k<=n-1;k++)
{
max=0.0;
for (i=k;i<=n;i++)
if (max<fabs(a[i][k]))
{
max=fabs(a[i][k]);
ik=i;
}
if (max==0)
{
printf("A is singular");
break;
}
if (ik!=k)
for (j=k;j<=n+1;j++)
{
t=a[k][j];
a[k][j]=a[ik][j];
a[ik][j]=t;
}
for(i=k+1;i<=n;i++)
{
a[i][k]=a[i][k]/a[k][k];
for (j=k+1;j<=n+1;j++)
a[i][j]=a[i][j]-a[i][k]*a[k][j];
}
}
if (a[n][n]==0)
printf("A is singular");
else
x[n]=a[n][n+1]/a[n][n];
for (k=n-1;k>=1;k--)
{
sum=0.0;
for (j=k+1;j<=n;j++)
sum=sum+a[k][j]*x[j];
x[k]=(a[k][n+1]-sum)/a[k][k];
}
for (i=1;i<=n;i++)
printf("x[%d]=%f\n",i,x[i]);
}

Ⅳ 用C语言编程高斯全主元消元法

//TurboC 2.0太落后了,建议使用VC++6.0。
#include"stdio.h"
#include"math.h"
//最大49阶
#define N 50
void Gauss(float U[N][N],int n);
void main()
{
int n,i,j;
float U[N][N];
printf("------------特殊说明---------------\n");
printf("当输出的数据含有<-1.#IND>时,表示在计算过程中数据已经出现溢出!\n");
printf("-----------------------------------\n");
printf("输入对应方程的阶数:");
scanf("%d",&n);
for(i=0;i<N;i++)
for(j=0;j<N;j++)
U[i][j]=0;
printf("输入方程组的增广矩阵:\n");
for(i=0;i<n;i++)
for(j=0;j<=n;j++)
scanf("%f",&U[i][j]);
Gauss(U,n);
}

//高斯选列主元消去法
void Gauss(float U[N][N],int n)
{
int i,j,m,row;
float max,t,sum;
float result[50];
for(m=0;m<n-1;m++)
{
//选取主元
max=U[m][m];
for(i=m;i<n;i++)
{
if(fabs(max)<fabs(U[i][m]))
{
max=U[i][m];
row=i;
}
}

if(fabs(max)<0.01)
{
printf("主元接近于零,方法失效!\n");
return;
}
else
{
if(max!=U[m][m])
{
for(j=m;j<=n;j++)
{
t=U[m][j];
U[m][j]=U[row][j];
U[row][j]=t;
}
}
}
//消元
for(i=m+1;i<n;i++)
{
float t1,t2;
t1=U[i][m];
t2=U[m][m];
U[i][m]=0;
for(j=m+1;j<=n;j++)
U[i][j]=U[i][j]*t2-U[m][j]*t1;
}
}
//回代求解
for(i=n-1;i>=0;i--)
{
if(i==n-1) result[i]=U[i][i+1]/U[i][i];
else
{
sum=0;
for(j=i+1;j<n;j++)
sum=U[i][j]*result[j]+sum;
result[i]=(U[i][n]-sum)/U[i][i];
}
}
//输出根
printf("高斯选列主元消去法求得的解为:\n");
for(i=0;i<n;i++)
printf("%3.3f ",result[i]);
printf("\n");

}

Ⅵ 用c语言编译 采用高斯先列主元消元法求解线性方程组AX=b

545

Ⅶ 求C语言课程设计:用高斯列主元消元法解线性方程组

这里向你推荐一下克鲁特算法(其实就是对高斯列主元消元法进行优化,使之更适合于计算机编程),首先将矩阵A进行LU分解(将系数矩阵分解成一个上三角矩阵和一个下三角矩阵),分解的过程中用到了隐式的主元寻找法,同时利用克鲁特算法可以将两个n*n矩阵压缩到一个n*n矩阵中,大大节省了存储空间提高了计算速度。
方程可化为L*U*x=B,令U*x=y --->L*y=B
然后利用回代先求y,再利用y求x
因为该方法在求解过程中不涉及增广矩阵所以矩阵B几乎不参与什么运算,所以它的计算速度应该能够达到高斯列主元消元法的三倍,但原理与其基本一致。
而且我在程序中使用了动态数组方便你今后进行扩展。

以下程序按照《矩阵论第二版》和《C语言数值计算法方法大全》编写,LU分解部分程序主要参考了《C语言数值计算法方法大全》第二章的程序
如果你需要详细的理论讲解我可以将这两本书和源程序发给你,上面的论述相当详细足够你答辩用的了,我的邮箱[email protected]

计算结果:
A矩阵:
2 2 5
3 4 7
1 3 3
B矩阵:
5
6
5
解矩阵:
x 1=-7
x 2=0.333333
x 3=3.66667

Press any key to continue

#include <cmath>
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <functional>
#include <vector>
#include <algorithm>
using namespace std;
#define TINY 1.0e-20 //A small number.
#define N 3
void ludcmp(vector<vector<float> > &a, int n, vector<int> &indx, float &d);//对矩阵进行LU分解
void lubksb(vector<vector<float> > &a, int n, vector<int> &indx, vector<float> &b);//对矩阵进行前向和后向回代
void root(vector<vector<float> > &x,vector<float> &col);//解方程结果保存在y中
void iniv(vector<vector<float> > &x,vector<float> line,int n);//对二维动态数组进行初始化
void main()
{
int i,j,n=N;//输入矩阵的维数
float A[N][N]={{2,2,5},{3,4,7},{1,3,3}};//左边A矩阵
float B[N]={5,6,5};//右边B矩阵
vector<vector<float> > x;//建立动态二维数组存放A,保证你的程序进行扩展时只改A,B,N
vector<float> line;
vector<float> y(n);//建立动态数组存放B
iniv(x,line,n);
y.clear();
for(i=0;i<n;i++)//将A赋给x,B赋给y
{
y.push_back(B[i]);
for(j=0;j<n;j++)
{
x[i].push_back(A[i][j]);
}
}
cout<<"A矩阵:"<<endl;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
cout<<setw(2)<<setiosflags(ios::left)<<setw(2)<<x[i][j]<<" ";
}
cout<<endl;
}
cout<<"B矩阵:"<<endl;
for(i=0;i<n;i++)
{
cout<<setw(2)<<setiosflags(ios::left)<<setw(2)<<y[i]<<endl;
}
root(x,y);//求根
cout<<"解矩阵:"<<endl;
for(i=0;i<n;i++)
{
cout<<setw(2)<<setiosflags(ios::left)<<"x"<<i+1<<"="<<y[i]<<endl;
}
cout<<endl;
}
void root(vector<vector<float> > &x,vector<float> &col)
{
int n=x.size(),i=0,j=0;
vector<int> index(n);//用于记录寻找主元素过程中对矩阵的初等变换
index.clear();
float m=1.0;//记录变换方式,此程序中无用
ludcmp(x,n,index,m);//进行LU分解
lubksb(x,n,index,col);//根据分解结果进行回带
}
//以下程序按照《矩阵论第二版》和《C语言数值计算法方法大全》编写,LU分解部分程序主要参考了《C语言数值计算法方法大全》第二章的程序
//如果你需要详细的理论讲解我可以将这两本书和源程序发给你,我的邮箱[email protected]
void ludcmp(vector<vector<float> > &a, int n, vector<int> &indx, float &d)
{

int i,imax,j,k;
float big=0,m=0,sum=0,temp=0;
vector<float> vv(n);
vv.clear();
d=1.0;
for (i=0;i<n;i++)
{
big=0.0;
for (j=0;j<n;j++)
if ((temp=fabs(a[i][j])) > big)
big=temp;
vv[i]=1.0/big;
}
for (j=0;j<n;j++)
{
for (i=0;i<j;i++)
{
sum=a[i][j];
for (k=0;k<i;k++)
sum -= a[i][k]*a[k][j];
a[i][j]=sum;
}
big=0.0;
for (i=j;i<n;i++)
{
sum=a[i][j];
for (k=0;k<j;k++)
sum -= a[i][k]*a[k][j];
a[i][j]=sum;
if ( (m=vv[i]*fabs(sum)) >= big)
{
big=m;
imax=i;
}
}
if (j != imax)
{
for (k=0;k<n;k++)
{
m=a[imax][k];
a[imax][k]=a[j][k];
a[j][k]=m;
}
d = -(d);
vv[imax]=vv[j];
}
indx[j]=imax;
if (a[j][j] == 0.0)
a[j][j]=TINY;
if (j != n)
{
m=1.0/(a[j][j]);
for (i=j+1;i<n;i++)
a[i][j] *= m;
}
}
}
void lubksb(vector<vector<float> > &a, int n, vector<int> &indx, vector<float> &b)
{
int i,ii=0,ip,j;
float sum;
for(i=0;i<n;i++)//按LU分解时寻找主元所进行的初等变换进行反边变换。
{
ip=indx[i];
sum=b[ip];
b[ip]=b[i];
b[i]=sum;
}
sum=0;
for (i=1;i<n;i++)
{
sum=0;
for(j=0;j<i;j++)
{
sum+=a[i][j]*b[j];
}
b[i]=b[i]-sum;
}
b[n-1]=b[n-1]/a[n-1][n-1];
for (i=n-2;i>=0;i--)
{
sum=0;
for(j=i+1;j<n;j++)
{
sum+=a[i][j]*b[j];
}
b[i]=(b[i]-sum)/a[i][i];
}
}
void iniv(vector<vector<float> > &x,vector<float> line,int n)
{
int i,j;
for(i=0;i<n;i++)
{
x.push_back(line);
for(j=0;j<n;j++)
{
x[i].clear();
}
}
}

Ⅷ 用c语言编写高斯-约当全主元消去法

#include <iostream>
#include <iomanip.h>
using namespace std;
#define N 20
double a[N][N];
double x[N+1];
double b[N+1];
int n;//n方程个数,n未知数个数
int set( )
{
cout<<"请输入方程的个数和未知数个数: "<<endl;
cin>>n;
int i,j;
cout<<"请输入方程组(逐个输入方程 i)"<<endl;
for(i = 1;i <= n;i++)
{
for(j = 1;j<=n;j++)
{
cin>>a[i][j];//系数
}
cin>>b[i];//结果
}
return 0;
}
int find(int k)//寻找第k列主元
{
int i,tag = k;
double maxv=0;
for(i = k;i <= n;i++)
{
if(a[i][k] > maxv)
{
maxv = a[i][k];
tag = i;
}
}
return tag;
}
void exchange(int i1,int i2)//将第 i1 i2行互换
{
int j;
for(j = 1;j <= n;j++)
{
swap(a[i1][j],a[i2][j]);
}
swap(b[i1],b[i2]);
}
void div(int k)//让第k个方程的首项系数为1
{
double temp = a[k][k];
for(int j = k; j <= n;j++)
{
a[k][j]/=temp;
}
b[k]/=temp;
}
void disME(int k)
{
int i,j;
for(i =1 ;i<=n;i++)
{
for(j = i;j<= n;j++)
{
if(a[i][j])
{
if(a[i][j]==1)
{ if(j==n)
cout<<"x"<<j;
else
cout<<"x"<<j<<" + ";
}
else
{
if(j==n)
cout<<a[i][j]<<"x"<<j;
else
cout<<a[i][j]<<"x"<<j<<" + ";
}
}
}
cout<<" = "<<b[i]<<endl;
}
system("pause");
}
void eliminate(int k)//消元
{
int i,j;
double t;
for(i = k+1;i<= n;i++)
{
t = a[i][k]/a[k][k];
for(j = k;j <= n;j++)
{
a[i][j]-=a[k][j] * t;
}
b[i] -= b[k] * t;
}
}
void Gauss()//高斯消元法
{
int i,j,k;
for(k = 1;k < n;k++)//共进行n - 1次消元
{
int l = find(k);//寻找第k次消元法的主元方程
if(l!=k)
{
exchange(l,k);
}
//消元
div(k);
eliminate(k);
cout<<"第"<<k<<"次消元结果:"<<endl;
disME(k);
}
div(k);
x[k] = b[k];
//disM();
for(i = n - 1;i>=1;i--)
{
for(j = i+1;j <=n ;j++)
{
b[i] -= a[i][j] * b [j];
}
x[i] = b[i];
}
}
void dis()
{
int i;
cout<<"解方程得:"<<endl;
for(i = 1;i<=n;i++)
{
cout<<"x"<<i<<" = ";
printf("%.5f\n",x[i]);
}
}
int main()
{
set();
Gauss();
dis();
system("pause");
return 0;
}
———————————————————————————————
希望答案能帮到你,要是你有疑问可以追问
当然,采纳也是您的美德,谢谢

Ⅸ 用C语言进行列主元素高斯消元法,遇到问题

for(i=k+1;i<N;i++)
{
m[i-1][k]=a[i][k]/a[k][k];
//这里m的坐标应该是[i-1][k],如果是[i][k]会造成越界
for(j=0;j<N;j++)
{
temp=a[i][j];
a[i][j]=temp-m[i-1][k]*a[k][j];
//这里也一样
}
}
m是
2X2
的数组,而a是
3X3
的数据,即a[1][0]与a[0][0]的比值应存在m[0][0]中!
希望可以帮到你!

热点内容
比亚迪唐dmi哪个配置值得买 发布:2025-01-04 05:50:17 浏览:169
内存储器的功能 发布:2025-01-04 05:50:11 浏览:679
sqlcountsum 发布:2025-01-04 05:49:24 浏览:233
linux怎么改ip 发布:2025-01-04 05:39:32 浏览:477
c语言mallocfree 发布:2025-01-04 05:38:49 浏览:267
台式电脑在哪里设置密码锁 发布:2025-01-04 05:36:27 浏览:631
msg编译路径 发布:2025-01-04 05:36:26 浏览:666
雷霆战机电脑脚本 发布:2025-01-04 05:26:43 浏览:995
原神在哪里下载安卓手机 发布:2025-01-04 05:21:50 浏览:378
csr2安卓正式服在哪里 发布:2025-01-04 05:17:33 浏览:222