您的当前位置:首页正文

c++解答齐次方程组的几种方法

2023-07-30 来源:爱go旅游网
c++解答齐次方程组的几种方法——Cramer,Gauss列主元,Gauss全主元,Doolittle算法 2009-06-20 19:03

//红色部分为后来修改内容,程序的错误在所难免,你们的反馈是程序完善的动力!

//解线性方程组 //By JJ,2008

#include #include #include #include

//----------------------------------------------全局变量定义区 const int Number=15; //方程最大个数 double

a[Number][Number],b[Number],copy_a[Number][Number],copy_b[Number]; //系数行列式

int A_y[Number]; //a[][]中随着横坐标增加列坐标的排列顺序,如a[0][0],a[1][2],a[2][1]...则A_y[]={0,2,1...}; int lenth,copy_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;jcout<<\"系数\"<for(int i=0;ifor(j=0;jcout<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//输入方程矩阵 //提示如何输入

cout<<\"====================================================\\n\"; cout<<\"请在每个方程里输入\"<cout<<\"+\"<cout<<\"=10\\n\"; cout<<\"应输入:\"; for(i=0;icout<<\"==============================\\n\";

//输入每个方程

for(i=0;icout<<\"输入方程\"<>a[i][j]; cin>>b[i]; }

//备份数据

for(i=0;i//输入选择 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;isum=calculate_A(lenth,0); if(sum!=0) {

cout<<\"系数行列式不为零,方程有唯一的解:\"; for(i=0;ifor(j=0;jexchange_lie(i);

sum_x=calculate_A(lenth,0); cout<cout<<\"系数行列式等于零,方程没有唯一的解.\"; }

cout<<\"\\n\"; }

double & calculate_A(int n,int m) //计算行列式 { int i; if(n==1) {

a_sum+= quanpailie_A(); }

else{for(i=0;ireturn a_sum; }

double quanpailie_A() //计算行列式中一种全排列的值 {

int i,j,l;

double sum=0,p;

for(i=0,l=0;ifor(j=0;A_y[j]!=i&&ji) l++; for(p=1,i=0;isum+=p*((l%2==0)?(1):(-1)); return sum; }

//高斯列主元排列求解方程 void gauss_row() {

int i,j;

gauss_row_xiaoqu(); //用高斯列主元消区法将系数矩阵变成一个上三角矩阵

for(i=0;ifor(j=0;jcout<if(a[lenth-1][lenth-1]!=0) {

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

for(i=0;icout<cout<<\"系数行列式等于零,方程没有唯一的解.\\n\"; }

void gauss_row_xiaoqu() //高斯列主元消去法 {

int i,j,k,maxi;double lik;

cout<<\"用Gauss列主元消去法结果如下:\\n\"; for(k=0;k{

j=k;

for(maxi=i=k;iif(fabs(a[i][j])>fabs(a[maxi][j])) maxi=i; //添加绝对值运算符 if(maxi!=k)

exchange_hang(k,maxi);//

for(i=k+1;ilik=a[i][k]/a[k][k]; for(j=k;ja[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;ifor(j=0;jcout<if(a[lenth-1][lenth-1]!=0) {

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

for(i=0;ifor(j=0;x[j]!='a'+i&&jcout<cout<<\"系数行列式等于零,方程没有唯一的解.\\n\"; }

void gauss_all_xiaoqu() //Gauss全主元消去法 {

int i,j,k,maxi,maxj;double lik;

cout<<\"用Gauss全主元消去法结果如下:\\n\";

for(k=0;kfor(maxi=maxj=i=k;ifor(j=k;jif(fabs(a[i][j])>fabs(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;ilik=a[i][k]/a[k][k]; for(j=k;ja[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;jb[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;iflag=Doolittle_check(temp_a,temp_b);

if(flag==0) cout<<\"\\n行列式为零.无法用Doolittle求解.\"; xiaoqu_u_l(); calculate_u_l();

cout<<\"用Doolittle方法求得结果如下:\\n\"; for(i=0;ifor(j=0;x[j]!='a'+i&&jcout<void calculate_u_l() //计算Doolittle结果 { int i,j;double sum_ax=0; for(i=0;ifor(j=0,sum_ax=0;jfor(i=lenth-1;i>=0;i--) {

for(j=i+1,sum_ax=0;jb[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{ //求第n+1层的上三角矩阵部分即U for(j=n;j{ for(k=0,temp=0;kfor(i=n+1;ia[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;kj=k;

for(maxi=i=k;iif(temp_a[i][j]>temp_a[maxi][j]) maxi=i; if(maxi!=k)

{ exchange_hang(k,maxi); for(j=0;jtemp_a[k][j]=temp_a[maxi][j]; temp_a[maxi][j]=temp; } }

for(i=k+1;ilik=temp_a[i][k]/temp_a[k][k]; for(j=k;jtemp_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;jtemp=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;ivoid exchange_a_lie(int m,int n) //交换a[]中的两列 { double temp;int i; for(i=0;ivoid 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;ilenth=copy_lenth; }

因篇幅问题不能全部显示,请点此查看更多更全内容