請教編程題:編程實現(xiàn)高斯列主元消去法求解線性方程組,寫出相應(yīng)的程序或程序段,編程語言不限。 采用高斯先列主元消元法求解線性方程組AX=b,編寫一個程序C...
http://hi.baidu.com/ycdoit/blog/item/832586b066955d5d082302ef.html
這里給你源代碼
//解線性方程組
//By JJ,2008
#include<iostream.h>
#include<iomanip.h>
#include<stdlib.h>
//----------------------------------------------全局變量定義區(qū)
const int Number=15; //方程最大個數(shù)
double a[Number][Number],b[Number],copy_a[Number][Number],copy_b[Number]; //系數(shù)行列式
int A_y[Number]; //a[][]中隨著橫坐標(biāo)增加列坐標(biāo)的排列順序,如a[0][0],a[1][2],a[2][1]...則A_y[]={0,2,1...};
int lenth,copy_lenth; //方程的個數(shù)
double a_sum; //計算行列式的值
char * x; //未知量a,b,c的載體
//----------------------------------------------函數(shù)聲明區(qū)
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,若是,調(diào)整為順序主子式全>0
void xiaoqu_u_l(); //將行列式Doolittle分解
void calculate_u_l(); //計算Doolittle結(jié)果
double & calculate_A(int n,int m); //計算行列式
double quanpailie_A(); //根據(jù)列坐標(biāo)的排列計算的值,如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(); //根據(jù)Gauss消去法結(jié)果計算未知量的值
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(); //恢復(fù)數(shù)據(jù)
//主函數(shù)
void main()
{
int flag=1;
input(); //輸入方程
while(flag)
{
print_menu(); //打印主菜單
flag=choose(); //選擇解答方式
}
}
//函數(shù)定義區(qū)
void print_menu()
{
system("cls");
cout<<"------------方程系數(shù)和常數(shù)矩陣表示如下:\n";
for(int j=0;j<lenth;j++)
cout<<"系數(shù)"<<j+1<<" ";
cout<<"\t常數(shù)";
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<<"方程的個數(shù):";
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<<"系數(shù)和一個常數(shù):\n";
cout<<"例:\n方程:a";
for(i=1;i<lenth;i++)
{
cout<<"+"<<i+1<<x[i];
}
cout<<"=10\n";
cout<<"應(yīng)輸入:";
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];
}
//備份數(shù)據(jù)
for(i=0;i<lenth;i++)
for(j=0;j<lenth;j++)
copy_a[i][j]=a[i][j];
for(i=0;i<lenth;i++)
copy_b[i]=b[i];
copy_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行的列坐標(biāo)為i
cout<<"用克拉默(Cramer)法則結(jié)果如下:\n";
for(i=0;i<lenth;i++)
A_y[i]=i;
sum=calculate_A(lenth,0);
if(sum!=0)
{
cout<<"系數(shù)行列式不為零,方程有唯一的解:";
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<<"系數(shù)行列式等于零,方程沒有唯一的解.";
}
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(); //用高斯列主元消區(qū)法將系數(shù)矩陣變成一個上三角矩陣
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<<"系數(shù)行列式不為零,方程有唯一的解:\n";
gauss_calculate();
for(i=0;i<lenth;i++) //輸出結(jié)果
{
cout<<x[i]<<"="<<b[i]<<"\n";
}
}
else
cout<<"系數(shù)行列式等于零,方程沒有唯一的解.\n";
}
void gauss_row_xiaoqu() //高斯列主元消去法
{
int i,j,k,maxi;double lik;
cout<<"用Gauss列主元消去法結(jié)果如下:\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<<"系數(shù)行列式不為零,方程有唯一的解:\n";
gauss_calculate();
for(i=0;i<lenth;i++) //輸出結(jié)果
{
for(j=0;x[j]!='a'+i&&j<lenth;j++);
cout<<x[j]<<"="<<b[j]<<endl;
}
}
else
cout<<"系數(shù)行列式等于零,方程沒有唯一的解.\n";
}
void gauss_all_xiaoqu() //Gauss全主元消去法
{
int i,j,k,maxi,maxj;double lik;
cout<<"用Gauss全主元消去法結(jié)果如下:\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() //高斯消去法以后計算未知量的結(jié)果
{
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方法求得結(jié)果如下:\n";
for(i=0;i<lenth;i++) //輸出結(jié)果
{
for(j=0;x[j]!='a'+i&&j<lenth;j++);
cout<<x[j]<<"="<<b[j]<<endl;
}
}
void calculate_u_l() //計算Doolittle結(jié)果
{ 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]) //若行列式不為零,將系數(shù)矩陣調(diào)整為順序主子式大于零
{
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() //用其中一種方法求解后恢復(fù)數(shù)據(jù)以便用其他方法求解
{
for(int i=0;i<lenth;i++)
for(int j=0;j<lenth;j++)
a[i][j]=copy_a[i][j];
for(i=0;i<lenth;i++)
b[i]=copy_b[i];
for(i=0;i<lenth;i++)
x[i]='a'+i;
a_sum=0;
lenth=copy_lenth;
}
用列主元消去法解線性方程組
5、其中,對角線上的元素是主元,其他元素為0。然后,我們可以直接求解x。通過列主元消去法,我們可以有效地求解線性方程組,同時保證計算的穩(wěn)定性和準(zhǔn)確性。線性方程的相關(guān)知識 1、線性方程是一類基本的數(shù)學(xué)方程,它在代數(shù)學(xué)、物理學(xué)、工程學(xué)等領(lǐng)域都有廣泛的應(yīng)用。線性方程是初等數(shù)學(xué)中的基本方程之一,...
列主元高斯消去法是什么?
列主元消去法雖然和高斯消去法原理一樣,但是列主元消去法可以減小舍入誤差,精度比較高,是解決小型稠密矩陣的一個較好的算法。而高斯消去法雖然編程簡單,但是計算量大,而且對于兩個相近的解時由于舍入誤差的存在,使得結(jié)果誤差很大。引起其他元素 的數(shù)量級及舍人誤差急劇增大,導(dǎo)致最終計算結(jié)果不可靠。
為什么要用列主元消去法
針對你給的二元方程,談?wù)劄槭裁匆昧兄髟シ?通常高斯消去法有兩個過程:消元過程和回代過程. 如果不選主元,消元過程第1步需要進(jìn)行下面運算,a22-(a21\/a11)*a12 這是消元后所得新的第2個方程的x2的系數(shù),如果a11較a21小的多,則a21\/a11就很大,由于在計算機(jī)上編程計算或手算時,舍入誤差難以...
用列主元消去法求解線性方程組!給我具體的步驟
x1=107\/15 x2=49\/75 x3=94\/30 答案是這個嗎?
列主元消去法和高斯消元發(fā)一樣嗎
你這個是科學(xué)計算的吧,列主元消去法雖然和高斯消去法原理一樣,但是列主元消去法可以減小舍入誤差,精度比較高,是解決小型稠密矩陣的一個較好的算法。而高斯消去法雖然編程簡單,但是計算量大,而且對于兩個相近的解時由于舍入誤差的存在,使得結(jié)果誤差很大。
線性方程組如何求解
2、消去法:Gauss(高斯)消去法——是最基本的和最簡單的直接方法,它由消元過程和回代過程構(gòu)成,基本思想是:將方程組逐列逐行消去變量,轉(zhuǎn)化為等價的上三角形方程組(消元過程);然后按照方程組的相反順序求解上三角形方程組,得到原方程組的解(回代過程)。優(yōu)缺點:簡單易行,但是要求主元均不...
高斯列主元消去法與高斯喬丹消去法的區(qū)別
高斯列主消去法比高斯約旦消去法簡單,它保留了化簡的第二步,然后一步步的消去,最后在一個個的回代!!
線性方程組-直接法 1:Gauss消去與LU分解
這種方法適用于非奇異矩陣,并且在數(shù)值穩(wěn)定性好的情況下可靠。LU分解則進(jìn)一步分解矩陣為上、下三角矩陣,便于處理變化的右端項,其時間復(fù)雜度更低,預(yù)處理后只需解兩個三角方程。然而,當(dāng)矩陣出現(xiàn)主元為零或數(shù)值不穩(wěn)定的情況時,常規(guī)的Gauss消去法會遇到問題。為解決這個問題,引入了列主元Gauss消去,通過...
用高斯消去法和高斯列主元消去法解方程組x+2y+z=2,4x+4y-2z=-1,2x+...
利用初等行變換,將方程組增廣矩陣[AB]化為階梯陣再求解:4 2 1 7 4 2 1 7 [A B]= 2 -5 2 -1 -> 0 12 -3 9 1 2 6 9 0 6 23 29 4 2 1 7 8 0 3 11 -> 0 4 -1 3 -> 0 4 -1 3 0 6 23 29 0 0 49 49 8 0 0 8 1 0 0 1 -> 0 4 0 4 -> 0 1...
解線性方程組時候何時有列主元高斯消去法?何時用全主元高斯消去法?
但它的計算量要比列主元法大的多,列主元法在每做一次消元僅與同列的元素做比較,比較的次數(shù)與線性方程組的階n是同階的量,而全主元法每做一次消元要與系數(shù)矩陣所有元素進(jìn)行比較,計算量是與n^2同階的量,計算量較列主元大的多,一般來說不采用全主元法,而采用列主元法即可.
相關(guān)評說:
潼關(guān)縣機(jī)械: ______ 我們以方程組 2x1 + 6x2 - x3 = -12 5x1 - x2 +2x3 = 29 -3x1 - 4x2 + x3 = 5 為例 來說明樓主自己把方程組化為矩陣形式.以下為源代碼 . #include <stdio.h>#include <stdlib.h>#include <malloc.h>#include <math.h> int GS(int,double**,double *,double...
潼關(guān)縣機(jī)械: ______ matalb下標(biāo)從1開始; 代碼我就懶得看了,我直接給你寫個,加注釋后你自己看看,我們剛好最近學(xué)這個,寫著試試. gauss消除法是對線性方程組的增廣矩陣施以行初等變換,化A為上三角矩陣,從而得到三角形方程組,然后回代求解,列主元法就是增加了每次選取每列最大的數(shù),防止除的時候分母太小,導(dǎo)致數(shù)太大. 搞了一下午,終于搞定了,你自己可以試試
潼關(guān)縣機(jī)械: ______ !高斯消去法 subroutine agaus(a,b,n,x,l,js) dimension a(n,n),x(n),b(n),js(n) double precision a,b,x,t l=1 !邏輯變量 do k=1,n-1 d=0.0 do i=k,n do j=k,n if (abs(a(i,j))>d) then d=abs(a(i,j)) js(k)=j is=i end if end do end do !把行絕對值最大的元素?fù)Q...
潼關(guān)縣機(jī)械: ______ 列選主元消元法/**Gauss.cpp*功能:列選主元消元法 */#include#include"Gass.h"//高斯消元法(列選主元)void Gaus...
潼關(guān)縣機(jī)械: ______ function x=gauss_lie(A,b)%采用高斯列主元法求解方程組Ax=bn=length(b);p=1:n;lu=A;y=[];for k=1:n [c,i]=max(abs(lu(k:n,k))); ik=i+k-1; if ik~=k m=p(k);p(k)=p(i...
潼關(guān)縣機(jī)械: ______ 昨天才回答過這個問題..你可以再搜搜的 Gauss消去法的分析. 其包括兩個過程: 消去過程:把方程組系數(shù)矩陣A化為同解的上三角矩陣; 回代過程:按相反的順序,從xn至x1逐個求解上三角方...
潼關(guān)縣機(jī)械: ______ void gauss(double a[n][n+1],double x[n]){ int i,j,k;double temp,s,l; for(i=0;i<n;j++) { if(fabs(a[j][i])...
潼關(guān)縣機(jī)械: ______ int a,b //甲乙的實際年齡 for(a=4;a<67;a++) { for(b=4;b<a;b++) { if (a-b=b-4) if (a-b=64-a) print(d%d%,a,b); } }
潼關(guān)縣機(jī)械: ______ #include "stdlib.h" #include "math.h" #include "stdio.h" int rgauss(n,a,b) int n; double a[],b[]; { int *js,l,k,i,j,is,p,q; double d,t; js=malloc(n*sizeof(int)); l=1; for (k=0;k<=n-2;k++) { d=0.0; for (i=k;i<=n-1;i++) for (j=k;j<=n-1;j++) { t=fabs(a[i*n+j]); if (t>d...