c++解齐次方程组Cramer Gauss列主元 Gauss全主元 Doolittle算法Word下载.docx
《c++解齐次方程组Cramer Gauss列主元 Gauss全主元 Doolittle算法Word下载.docx》由会员分享,可在线阅读,更多相关《c++解齐次方程组Cramer Gauss列主元 Gauss全主元 Doolittle算法Word下载.docx(11页珍藏版)》请在冰点文库上搜索。
//判断是否行列式>
0,若是,调整为顺序主子式全>
voidxiaoqu_u_l();
//将行列式Doolittle分解
voidcalculate_u_l();
//计算Doolittle结果
double&
calculate_A(intn,intm);
//计算行列式
doublequanpailie_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];
voidexchange(intm,inti);
//交换A_y[m],A_y[i]
voidexchange_lie(intj);
//交换a[][j]与b[];
voidexchange_hang(intm,intn);
//分别交换a[][]和b[]中的m与n两行
voidgauss_row_xiaoqu();
//Gauss列主元消去法
voidgauss_all_xiaoqu();
//Gauss全主元消去法
voidgauss_calculate();
//根据Gauss消去法结果计算未知量的值
voidexchange_a_lie(intm,intn);
//交换a[][]中的m和n列
voidexchange_x(intm,intn);
//交换x[]中的x[m]和x[n]
voidrecovery();
//恢复数据
//主函数
voidmain()
{
intflag=1;
input();
//输入方程
while(flag)
print_menu();
flag=choose();
//选择解答方式
}
//函数定义区
voidprint_menu()
system("
cls"
);
cout<
<
"
------------方程系数和常数矩阵表示如下:
\n"
;
for(intj=0;
j<
lenth;
j++)
cout<
系数"
j+1<
"
\t常数"
endl;
for(inti=0;
i<
i++)
{
for(j=0;
setw(8)<
setiosflags(ios:
:
left)<
a[i][j];
\t"
b[i]<
-----------请选择方程解答的方案----------"
\n
1.克拉默(Cramer)法则"
2.Gauss列主元消去法"
3.Gauss全主元消去法"
4.Doolittle分解法"
5.退出"
输入你的选择:
voidinput()
{inti,j;
方程的个数:
cin>
>
if(lenth>
Number)
Itistoobig.\n"
return;
x=newchar[lenth];
for(i=0;
x[i]='
a'
+i;
//输入方程矩阵
//提示如何输入
====================================================\n"
请在每个方程里输入"
lenth<
系数和一个常数:
例:
\n方程:
a"
for(i=1;
+"
i+1<
x[i];
=10\n"
应输入:
10\n"
==============================\n"
//输入每个方程
输入方程"
cin>
b[i];
//备份数据
copy_a[i][j]=a[i][j];
copy_b[i]=b[i];
copy_lenth=lenth;
//输入选择
intchoose()
intchoice;
charch;
choice;
switch(choice)
case1:
cramer();
break;
case2:
gauss_row();
case3:
guass_all();
case4:
Doolittle();
case5:
return0;
default:
输入错误,请重新输入:
choose();
break;
\n是否换种方法求解(Y/N):
ch;
if(ch=='
n'
||ch=='
N'
)return0;
recovery();
\n\n\n"
return1;
//用克拉默法则求解方程.
voidcramer()
inti,j;
doublesum,sum_x;
//令第i行的列坐标为i
用克拉默(Cramer)法则结果如下:
A_y[i]=i;
sum=calculate_A(lenth,0);
if(sum!
=0)
系数行列式不为零,方程有唯一的解:
for(i=0;
{ch='
a_sum=0;
A_y[j]=j;
exchange_lie(i);
sum_x=calculate_A(lenth,0);
endl<
ch<
="
sum_x/sum;
}
else
系数行列式等于零,方程没有唯一的解."
calculate_A(intn,intm)
{inti;
if(n==1){
a_sum+=quanpailie_A();
}
else{for(i=0;
n;
{exchange(m,m+i);
calculate_A(n-1,m+1);
exchange(m,m+i);
returna_sum;
doublequanpailie_A()
//计算行列式中一种全排列的值
inti,j,l;
doublesum=0,p;
for(i=0,l=0;
A_y[j]!
=i&
&
if(A_y[j]>
i)l++;
for(p=1,i=0;
p*=a[i][A_y[i]];
sum+=p*((l%2==0)?
(1):
(-1));
returnsum;
//高斯列主元排列求解方程
voidgauss_row()
gauss_row_xiaoqu();
//用高斯列主元消区法将系数矩阵变成一个上三角矩阵
setw(10)<
setprecision(5)<
if(a[lenth-1][lenth-1]!
系数行列式不为零,方程有唯一的解:
gauss_calculate();
i++)
//输出结果
{
x[i]<
系数行列式等于零,方程没有唯一的解.\n"
voidgauss_row_xiaoqu()
//高斯列主元消去法
inti,j,k,maxi;
doublelik;
用Gauss列主元消去法结果如下:
for(k=0;
k<
lenth-1;
k++)
j=k;
for(maxi=i=k;
if(fabs(a[i][j])>
fabs(a[maxi][j]))maxi=i;
//添加绝对值运算符
if(maxi!
=k)
exchange_hang(k,maxi);
//
for(i=k+1;
lik=a[i][k]/a[k][k];
for(j=k;
a[i][j]=a[i][j]-a[k][j]*lik;
b[i]=b[i]-b[k]*lik;
//高斯全主元排列求解方程
voidguass_all()
gauss_all_xiaoqu();
x[j]!
='
+i&
j++);
x[j]<
b[j]<
voidgauss_all_xiaoqu()
inti,j,k,maxi,maxj;
用Gauss全主元消去法结果如下:
for(maxi=maxj=i=k;
fabs(a[maxi][maxj]))
{maxi=i;
maxj=j;
if(maxj!
=k)
{
exchange_a_lie(maxj,k);
//交换两列
exchange_x(maxj,k);
voidgauss_calculate()
//高斯消去法以后计算未知量的结果
doublesum_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;
sum_ax+=a[i][j]*b[j];
b[i]=(b[i]-sum_ax)/a[i][i];
voidDoolittle()
//Doolittle消去法计算方程组
doubletemp_a[Number][Number],temp_b[Number];
inti,j,flag;
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();
用Doolittle方法求得结果如下:
voidcalculate_u_l()
//计算Doolittle结果
doublesum_ax=0;
for(j=0,sum_ax=0;
i;
b[i]=b[i]-sum_ax;
for(i=lenth-1;
voidxiaoqu_u_l()
//将行列式按Doolittle分解
{inti,j,n,k;
doubletemp;
for(i=1,j=0;
a[i][j]=a[i][j]/a[0][0];
for(n=1;
n<
n++)
{
//求第n+1层的上三角矩阵部分即U
for(j=n;
{for(k=0,temp=0;
temp+=a[n][k]*a[k][j];
a[n][j]-=temp;
for(i=n+1;
//求第n+1层的下三角矩阵部分即L
temp+=a[i][k]*a[k][n];
a[i][n]=(a[i][n]-temp)/a[n][n];
intDoolittle_check(doubletemp_a[][Number],doubletemp_b[Number])
//若行列式不为零,将系数矩阵调整为顺序主子式大于零
doublelik,temp;
if(temp_a[i][j]>
temp_a[maxi][j])maxi=i;
{exchange_hang(k,maxi);
{temp=temp_a[k][j];
temp_a[k][j]=temp_a[maxi][j];
temp_a[maxi][j]=temp;
lik=temp_a[i][k]/temp_a[k][k];
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)
return0;
voidexchange_hang(intm,intn)
//交换a[][]中和b[]两行
intj;
doubletemp;
for(j=0;
{temp=a[m][j];
a[m][j]=a[n][j];
a[n][j]=temp;
temp=b[m];
b[m]=b[n];
b[n]=temp;
voidexchange(intm,inti)
inttemp;
temp=A_y[m];
A_y[m]=A_y[i];
A_y[i]=temp;
voidexchange_lie(intj)
//交换未知量b[]和第i列
{doubletemp;
inti;
{temp=a[i][j];
a[i][j]=b[i];
b[i]=temp;
voidexchange_a_lie(intm,intn)
//交换a[]中的两列
{temp=a[i][m];
a[i][m]=a[i][n];
a[i][n]=temp;
voidexchange_x(intm,intn)
//交换未知量x[m]与x[n]
{chartemp;
temp=x[m];
x[m]=x[n];
x[n]=temp;
voidrecovery()
//用其中一种方法求解后恢复数据以便用其他方法求解
for(intj=0;
a[i][j]=copy_a[i][j];
b[i]=copy_b[i];
a_sum=0;
lenth=copy_lenth;