當前位置:首頁 » 編程語言 » c語言消元法

c語言消元法

發布時間: 2025-05-01 15:29:06

Ⅰ 求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語言或者c++編程,實現用高斯消元法求解線性方程組Ax=b。

void gaussj(double a[], int n, double b[])
{
int i,j,k,l,ll,irow,icol;
double big,pivinv,m;
int ipiv[50], indxr[50], indxc[50];
for (j=0;j<=n-1;j++)
{
ipiv[j]=0;
}
for (i=0;i<=n-1;i++)
{
big=0.0;
for (j=0;j<=n-1;j++)
{
if(ipiv[j]!=1)
{
for(k=0;k<=n-1;k++)
{
if(ipiv[k]==0)
{
if(fabs(a[j*n+k])>=big)
{
big=fabs(a[j*n+k]);
irow=j;
icol=k;
}
else if(ipiv[k]>1)
{
cout<<"singular matrix";
}
}
}
}
}
ipiv[icol]=ipiv[icol]+1;
if(irow!=icol)
{
for(l=0;l<=n-1;l++)
{
m=(a[irow*n+l]);
a[irow*n+l]=a[icol*n+l];
a[icol*n+l]=m;
}
m=b[irow];
b[irow]=b[icol];
b[icol]=m;
}
indxr[i]=irow;
indxc[i]=icol;
if(a[icol*n+icol]==0.0)
{
cout<< "singular matrix.";
}
pivinv=1.0/(a[icol*n+icol]);
a[icol*n+icol]=1.0;
for(l=0;l<=n-1;l++)
{
a[icol*n+l]=a[icol*n+l]*pivinv;
}
b[icol]=b[icol]*pivinv;
for(ll=0;ll<=n-1;ll++)
{
if(ll!=icol)
{
m=a[ll*n+icol];
a[ll*n+icol]=0.0;
for(l=0;l<=n-1;l++)
{
a[ll*n+l]=a[ll*n+l]-a[icol*n+l]*m;
}
b[ll]=b[ll]-b[icol]*m;
}
}
}
for(l=n-1;l<=0;l--)
{
if(indxr[l]!=indxc[l])
{
for(k=0;k<=n-1;k++)
{
m=a[k*n+indxr[l]];
a[k*n+indxr[l]]=a[k*n+indxc[l]];
a[k*n+indxr[l]]=m;
}
}
}
}

Ⅲ 高斯先列主消元法求解線性方程組AX=b C語言

其中用到了高斯先列主消元法 #include <iostream.h>
#include <stdlib.h>
#include <math.h>

/*樓競網站www.LouJing.com
擁有該程序的版權,轉載請保留該版權.
謝謝合作!*/
double* allocMem(int ); //分配內存空間函數
void GaussLineMain(double*,double*,double*,int );//採用高斯列主元素消去法求解x的初始向量值
void Jacobi(double*,double*,double*,double*,int,int);//利用雅可比迭代公式求解x的值

void main()
{
short matrixNum; //矩陣的行數(列數)
double *matrixA; //矩陣A,初始系數矩陣
double *matrixD; //矩陣D為A中的主對角陣
double *matrixL; //矩陣L為A中的下三角陣
double *matrixU; //矩陣U為A中的上三角陣
double *B; //矩陣B為雅可比方法迭代矩陣
double *f; //矩陣f為中間的過渡的矩陣
double *x; //x為一維數組,存放結果
double *xk; //xk為一維數組,用來在迭代中使用
double *b; //b為一維數組,存放方程組右邊系數

int i,j,k;

cout<<"<<請輸入矩陣的行數(列數與行數一致)>>:";
cin>>matrixNum;

//分別為A、D、L、U、B、f、x、b分配內存空間
matrixA=allocMem(matrixNum*matrixNum);
matrixD=allocMem(matrixNum*matrixNum);
matrixL=allocMem(matrixNum*matrixNum);
matrixU=allocMem(matrixNum*matrixNum);
B=allocMem(matrixNum*matrixNum);
f=allocMem(matrixNum);
x=allocMem(matrixNum);
xk=allocMem(matrixNum);
b=allocMem(matrixNum);

//輸入系數矩陣各元素值
cout<<endl<<endl<<endl<<"<<請輸入矩陣中各元素值(為 "<<matrixNum<<"*"<<matrixNum<<",共計 "<<matrixNum*matrixNum<<" 個元素)"<<">>:"<<endl<<endl;
for(i=0;i<matrixNum;i++)
{
cout<<"請輸入矩陣中第 "<<i+1<<" 行的 "<<matrixNum<<" 個元素:";
for(j=0;j<matrixNum;j++)
cin>>*(matrixA+i*matrixNum+j);
}

//輸入方程組右邊系數b的各元素值
cout<<endl<<endl<<endl<<"<<請輸入方程組右邊系數各元素值,共計 "<<matrixNum<<" 個"<<">>:"<<endl<<endl;
for(i=0;i<matrixNum;i++)
cin>>*(b+i);

/* 下面將A分裂為A=D-L-U */
//首先將D、L、U做初始化工作
for(i=0;i<matrixNum;i++)
for(j=0;j<matrixNum;j++)
*(matrixD+i*matrixNum+j)=*(matrixL+i*matrixNum+j)=*(matrixU+i*matrixNum+j)=0;
//D、L、U分別得到A的主對角線、下三角和上三角;其中D取逆矩陣、L和U各元素取相反數
for(i=0;i<matrixNum;i++)
for(j=0;j<matrixNum;j++)
if(i==j&&*(matrixA+i*matrixNum+j)) *(matrixD+i*matrixNum+j)=1/(*(matrixA+i*matrixNum+j));
else if(i>j) *(matrixL+i*matrixNum+j)=-*(matrixA+i*matrixNum+j);
else *(matrixU+i*matrixNum+j)=-*(matrixA+i*matrixNum+j);
//求B矩陣中的元素
for(i=0;i<matrixNum;i++)
for(j=0;j<matrixNum;j++)
{
double temp=0;
for(k=0;k<matrixNum;k++)
temp+=*(matrixD+i*matrixNum+k)*(*(matrixL+k*matrixNum+j)+*(matrixU+k*matrixNum+j));
*(B+i*matrixNum+j)=temp;
}
//求f中的元素
for(i=0;i<matrixNum;i++)
{
double temp=0;
for(j=0;j<matrixNum;j++)
temp+=*(matrixD+i*matrixNum+j)*(*(b+j));
*(f+i)=temp;
}

/* 計算x的初始向量值 */
GaussLineMain(matrixA,x,b,matrixNum);

/* 利用雅可比迭代公式求解xk的值 */
int JacobiTime;
cout<<endl<<endl<<endl<<"<<雅可比迭代開始,請輸入希望迭代的次數>>:";
cin>>JacobiTime;
while(JacobiTime<=0)
{
cout<<"迭代次數必須大於0,請重新輸入:";
cin>>JacobiTime;
}
Jacobi(x,xk,B,f,matrixNum,JacobiTime);

//輸出線性方程組的解 */
cout<<endl<<endl<<endl<<"<<方程組運算結果如下>>"<<endl;
cout.precision(20); //設置輸出精度,以此比較不同迭代次數的結果
for(i=0;i<matrixNum;i++)
cout<<"x"<<i+1<<" = "<<*(xk+i)<<endl;

cout<<endl<<endl<<"求解過程結束..."<<endl<<endl;

//釋放掉所有動態分配的內存
delete [] matrixA;
delete [] matrixD;
delete [] matrixL;
delete [] matrixU;
delete [] B;
delete [] f;
delete [] x;
delete [] xk;
delete [] b;
}

/*--------------------
分配內存空間函數
www.LouJing.com
--------------------*/
double* allocMem(int num)
{
double *head;
if((head=new double[num])==NULL)
{
cout<<"內存空間分配失敗,程序終止運行!"<<endl;
exit(0);
}
return head;
}

/*---------------------------------------------
計算Ax=b中x的初始向量值,採用高斯列主元素消去法
www.LouJing.com
---------------------------------------------*/
void GaussLineMain(double* A,double* x,double* b,int num)
{
int i,j,k;

//共處理num-1行
for(i=0;i<num-1;i++)
{
//首先每列選主元,即最大的一個
double lineMax=fabs(*(A+i*num+i));
int lineI=i;
for(j=i;j<num;j++)
if(fabs(*(A+j*num+i))>fabs(lineMax)) lineI=j;

//主元所在行和當前處理行做行交換,右系數b也隨之交換
for(j=i;j<num;j++)
{
//A做交換
lineMax=*(A+i*num+j);
*(A+i*num+j)=*(A+lineI*num+j);
*(A+lineI*num+j)=lineMax;
//b中對應元素做交換
lineMax=*(b+i);
*(b+i)=*(b+lineI);
*(b+lineI)=lineMax;
}

if(*(A+i*num+i)==0) continue; //如果當前主元為0,本次循環結束

//將A變為上三角矩陣,同樣b也隨之變換
for(j=i+1;j<num;j++)
{
double temp=-*(A+j*num+i)/(*(A+i*num+i));
for(k=i;k<num;k++)
{
*(A+j*num+k)+=temp*(*(A+i*num+k));
}
*(b+j)+=temp*(*(b+i));
}
}

/* 驗證Ax=b是否有唯一解,就是驗證A的行列式是否為0;
如果|A|!=0,說明有唯一解*/
double determinantA=1;
for(i=0;i<num;i++)
determinantA*=*(A+i*num+i);
if(determinantA==0)
{
cout<<endl<<endl<<"通過計算,矩陣A的行列式為|A|=0,即A沒有唯一解。\n程序退出..."<<endl<<endl;
exit(0);
}

/* 從最後一行開始,回代求解x的初始向量值 */
for(i=num-1;i>=0;i--)
{
for(j=num-1;j>i;j--)
*(b+i)-=*(A+i*num+j)*(*(x+j));
*(x+i)=*(b+i)/(*(A+i*num+i));
}
}

/*------------------------------------
利用雅可比迭代公式求解x的精確值
www.LouJing.com
迭代公式為:xk=Bx+f
------------------------------------*/
void Jacobi(double* x,double* xk,double* B,double* f,int num,int time)
{
int t=1,i,j;
while(t<=time)
{
for(i=0;i<num;i++)
{
double temp=0;
for(j=0;j<num;j++)
temp+=*(B+i*num+j)*(*(x+j));
*(xk+i)=temp+*(f+i);
}

//將xk賦值給x,准備下一次迭代
for(i=0;i<num;i++)
*(x+i)=*(xk+i);
t++;
}
}

Ⅳ 用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]中!
希望可以幫到你!

熱點內容
流行加密演算法 發布:2025-05-01 18:38:46 瀏覽:117
安卓應用市場下載的app在哪裡 發布:2025-05-01 18:27:34 瀏覽:925
寶來自舒有哪些配置 發布:2025-05-01 18:05:12 瀏覽:803
sqloracle計算天數 發布:2025-05-01 17:59:23 瀏覽:460
快考題源碼 發布:2025-05-01 17:45:48 瀏覽:367
python生成文檔 發布:2025-05-01 17:32:31 瀏覽:318
上傳文件不存在 發布:2025-05-01 17:30:02 瀏覽:536
android開機 發布:2025-05-01 17:13:29 瀏覽:259
配置文件怎麼下載 發布:2025-05-01 16:50:13 瀏覽:889
c語言買百雞 發布:2025-05-01 16:49:23 瀏覽:18