来讨论一下线性方程组的计算机解法吧?

时间:2021-12-24 15:04:40
我有几个问题想请教大家:
1。线性方程组的直接解法如高斯-约当消元法是否不适合程序求解?
2。迭代解法是否通常的线性方程组的计算机解法?
3。迭代后的结果不收敛是否说明方程组无解?
4。线性方程组有解的充要条件是什么,如何从程序中判断?

请高手不吝赐教,谢谢。

14 个解决方案

#1


问题提的好,我正愁解不开我的方程组了呢,郁闷啊,已经闷了好几天了还没出来,请高手出来吧

#2


http://expert.csdn.net/Expert/topic/2570/2570158.xml?temp=.1914179

#3


随便找本线性代数的数都有讲的问题。

#4


高斯消元法:计算AX=B,A放在二维数组a[]中,B放在数组b[]中,结果X也放在数组b[]中

   #include  "stdlib.h"  
   #include  "math.h"  
   #include  "stdio.h"  
   int  agaus(a,b,n)  
   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)  {  d=t;  js[k]=j;  is=i;}  
                       }  
               if  (d+1.0==1.0)  l=0;  
               else  
                   {  if  (js[k]!=k)  
                           for  (i=0;i<=n-1;i++)  
                               {  p=i*n+k;  q=i*n+js[k];  
                                   t=a[p];  a[p]=a[q];  a[q]=t;  
                               }  
                       if  (is!=k)  
                           {  for  (j=k;j<=n-1;j++)  
                                   {  p=k*n+j;  q=is*n+j;  
                                       t=a[p];  a[p]=a[q];  a[q]=t;  
                                   }  
                               t=b[k];  b[k]=b[is];  b[is]=t;  
                           }  
                   }  
               if  (l==0)  
                   {  free(js);  printf("fail\n");  
                       return(0);  
                   }  
               d=a[k*n+k];  
               for  (j=k+1;j<=n-1;j++)  
                   {  p=k*n+j;  a[p]=a[p]/d;}  
               b[k]=b[k]/d;  
               for  (i=k+1;i<=n-1;i++)  
                   {  for  (j=k+1;j<=n-1;j++)  
                           {  p=i*n+j;  
                               a[p]=a[p]-a[i*n+k]*a[k*n+j];  
                           }  
                       b[i]=b[i]-a[i*n+k]*b[k];  
                   }  
           }  
       d=a[(n-1)*n+n-1];  
       if  (fabs(d)+1.0==1.0)  
           {  free(js);  printf("fail\n");  
               return(0);  
           }  
       b[n-1]=b[n-1]/d;  
       for  (i=n-2;i>=0;i--)  
           {  t=0.0;  
               for  (j=i+1;j<=n-1;j++)  
                   t=t+a[i*n+j]*b[j];  
               b[i]=b[i]-t;  
           }  
       js[n-1]=n-1;  
       for  (k=n-1;k>=0;k--)  
           if  (js[k]!=k)  
               {  t=b[k];  b[k]=b[js[k]];  b[js[k]]=t;}  
       free(js);  
       return(1);  
   }

#5


关键是用怎么用代码来实现。

#6


http://www.cstvu.com/teacher/kejian/xxds/sousu/select.htm
有详细的关于线性方程组的定义与解法,各位可以浏览一下!!!

#7


有个现性代数的网页就好了。

#8


有个线性代数的网页就好了。

#9


这都是计算方法的内容,线性代数很少专门讲数值计算的内容,虽然也有消元法

#10


几个常用的算法,包括消元,迭代,三角分解等,都是解普通线性方程组的
void gauss(double **a,double *b,double *x,int n)
//高斯列主元消去法求解线性方程组
{
int i,j,k,ik;
double mik,temp;
for(k=0;k<n;k++)
{
mik=-1;
for(i=k;i<n;i++)
if(ABS(a[i][k])>mik)
{
mik=ABS(a[i][k]);
ik=i;
}
for(j=k;j<n;j++)
SWAP(a[ik][j],a[k][j]);
SWAP(b[k],b[ik]);
b[k]/=a[k][k];
for(i=n-1;i>=k;i--)
a[k][i]/=a[k][k];
for(i=k+1;i<n;i++)
{
b[i]-=a[i][k]*b[k];
for(j=n-1;j>=k;j--)
a[i][j]-=a[i][k]*a[k][j];
}
}
for(i=n-1;i>=0;i--)
{
x[i]=b[i];
for(j=i+1;j<n;j++)
x[i]-=a[i][j]*x[j];
}
}

void jacobi(double **a,double *b,double *x,int n,int Times)
//雅可比迭代求线性方程组
{
int i,j,t;
double *xx=new double[n];
for(t=0;t<Times;t++)
{
for(i=0;i<n;i++)
{
xx[i]=b[i];
for(j=0;j<n;j++)
if(j!=i)
xx[i]-=a[i][j]*x[j];
xx[i]/=a[i][i];
}
for(i=0;i<n;i++)
x[i]=xx[i];
}
delete xx;
}

void gs(double **a,double *b,double *x,int n,int Times)
//高斯-赛德尔迭代法求解线性方程组
{
int i,j,t;
for(t=0;t<Times;t++)
{
for(i=0;i<n;i++)
{
x[i]=b[i];
for(j=0;j<n;j++)
if(j!=i)
x[i]-=a[i][j]*x[j];
x[i]/=a[i][i];
}
}
}

void doolittle_deco(double **a,int n)
//Doolittle三角分解,分解后的矩阵保存在a中
{
int i,j,k,m;
for(k=0;k<n;k++)
{
for(j=k;j<n;j++)
for(m=0;m<k;m++)
a[k][j]-=a[k][m]*a[m][j];
for(i=k+1;i<n;i++)
{
for(m=0;m<k;m++)
a[i][k]-=a[i][m]*a[m][k];
a[i][k]/=a[k][k];
}
}
}

void doolittle_back(double **a,double *b,double *x,int n)
//Doolittle三角分解法求解线性方程组的回代过程
{
int i,j;
double *y;
y=new double[n];
for(i=0;i<n;i++)
{
y[i]=b[i];
for(j=0;j<i;j++)
y[i]-=a[i][j]*y[j];
}
for(i=n-1;i>=0;i--)
{
x[i]=y[i];
for(j=i+1;j<n;j++)
x[i]-=a[i][j]*x[j];
x[i]/=a[i][i];
}
delete y;
}

void doolittle(double **a,double *b,double *x,int n)
//Doolittle三角分解法求解线性方程组
{
doolittle_deco(a,n);
doolittle_back(a,b,x,n);
}

#11


前面加上
#include "stdio.h"
#include "math.h"
#define ABS(x) (x)>0?(x):-(x)
#define SWAP(a,b) {temp=(a);(a)=(b);(b)=temp;}

对它们的调用
int main(int argc, char* argv[])
{
int i,j,n;
double **a,*b,*x;
FILE *fp=fopen("d:\\data.txt","r");
fscanf(fp,"%d",&n);
a=new double*[n];
b=new double[n];
x=new double[n];
for(i=0;i<n;i++)
{
a[i]=new double[n];
for(j=0;j<n;j++)
fscanf(fp,"%lf",a[i]+j);
fscanf(fp,"%lf",b+i);
}
fclose(fp);

gauss(a,b,x,n);//Gauss主元消去法
for(i=0;i<n;i++)
printf("%f\t",x[i]);
printf("\n");

for(i=0;i<n;i++)
x[i]=1;
jacobi(a,b,x,3,10);//Jacobi迭代法
for(i=0;i<n;i++)
printf("%f\t",x[i]);
printf("\n");

for(i=0;i<n;i++)
x[i]=1;
gs(a,b,x,n,10);//GS迭代法
for(i=0;i<n;i++)
printf("%f\t",x[i]);
printf("\n");

doolittle(a,b,x,n);//Doolittle三角分解
for(i=0;i<n;i++)
printf("%f\t",x[i]);
printf("\n");

for(i=0;i<n;i++)
delete a[i];
delete a,b,x;
return 0;
}

数值计算可以参考
http://www.library.cornell.edu/nr/bookcpdf.html

#12


楼上的,谢谢,真好,

#13


漏了把数据格式写下来了
d:/data.txt   方程的规模n=3, 左边的1,1,1;2,2,3;3,2,1为系数矩阵,最右端为右端项
3
1 1 1  2.2
2 2 3  1.1
3 2 1  3.3

#14


我自己都已经琢磨出来了,老兄,

#1


问题提的好,我正愁解不开我的方程组了呢,郁闷啊,已经闷了好几天了还没出来,请高手出来吧

#2


http://expert.csdn.net/Expert/topic/2570/2570158.xml?temp=.1914179

#3


随便找本线性代数的数都有讲的问题。

#4


高斯消元法:计算AX=B,A放在二维数组a[]中,B放在数组b[]中,结果X也放在数组b[]中

   #include  "stdlib.h"  
   #include  "math.h"  
   #include  "stdio.h"  
   int  agaus(a,b,n)  
   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)  {  d=t;  js[k]=j;  is=i;}  
                       }  
               if  (d+1.0==1.0)  l=0;  
               else  
                   {  if  (js[k]!=k)  
                           for  (i=0;i<=n-1;i++)  
                               {  p=i*n+k;  q=i*n+js[k];  
                                   t=a[p];  a[p]=a[q];  a[q]=t;  
                               }  
                       if  (is!=k)  
                           {  for  (j=k;j<=n-1;j++)  
                                   {  p=k*n+j;  q=is*n+j;  
                                       t=a[p];  a[p]=a[q];  a[q]=t;  
                                   }  
                               t=b[k];  b[k]=b[is];  b[is]=t;  
                           }  
                   }  
               if  (l==0)  
                   {  free(js);  printf("fail\n");  
                       return(0);  
                   }  
               d=a[k*n+k];  
               for  (j=k+1;j<=n-1;j++)  
                   {  p=k*n+j;  a[p]=a[p]/d;}  
               b[k]=b[k]/d;  
               for  (i=k+1;i<=n-1;i++)  
                   {  for  (j=k+1;j<=n-1;j++)  
                           {  p=i*n+j;  
                               a[p]=a[p]-a[i*n+k]*a[k*n+j];  
                           }  
                       b[i]=b[i]-a[i*n+k]*b[k];  
                   }  
           }  
       d=a[(n-1)*n+n-1];  
       if  (fabs(d)+1.0==1.0)  
           {  free(js);  printf("fail\n");  
               return(0);  
           }  
       b[n-1]=b[n-1]/d;  
       for  (i=n-2;i>=0;i--)  
           {  t=0.0;  
               for  (j=i+1;j<=n-1;j++)  
                   t=t+a[i*n+j]*b[j];  
               b[i]=b[i]-t;  
           }  
       js[n-1]=n-1;  
       for  (k=n-1;k>=0;k--)  
           if  (js[k]!=k)  
               {  t=b[k];  b[k]=b[js[k]];  b[js[k]]=t;}  
       free(js);  
       return(1);  
   }

#5


关键是用怎么用代码来实现。

#6


http://www.cstvu.com/teacher/kejian/xxds/sousu/select.htm
有详细的关于线性方程组的定义与解法,各位可以浏览一下!!!

#7


有个现性代数的网页就好了。

#8


有个线性代数的网页就好了。

#9


这都是计算方法的内容,线性代数很少专门讲数值计算的内容,虽然也有消元法

#10


几个常用的算法,包括消元,迭代,三角分解等,都是解普通线性方程组的
void gauss(double **a,double *b,double *x,int n)
//高斯列主元消去法求解线性方程组
{
int i,j,k,ik;
double mik,temp;
for(k=0;k<n;k++)
{
mik=-1;
for(i=k;i<n;i++)
if(ABS(a[i][k])>mik)
{
mik=ABS(a[i][k]);
ik=i;
}
for(j=k;j<n;j++)
SWAP(a[ik][j],a[k][j]);
SWAP(b[k],b[ik]);
b[k]/=a[k][k];
for(i=n-1;i>=k;i--)
a[k][i]/=a[k][k];
for(i=k+1;i<n;i++)
{
b[i]-=a[i][k]*b[k];
for(j=n-1;j>=k;j--)
a[i][j]-=a[i][k]*a[k][j];
}
}
for(i=n-1;i>=0;i--)
{
x[i]=b[i];
for(j=i+1;j<n;j++)
x[i]-=a[i][j]*x[j];
}
}

void jacobi(double **a,double *b,double *x,int n,int Times)
//雅可比迭代求线性方程组
{
int i,j,t;
double *xx=new double[n];
for(t=0;t<Times;t++)
{
for(i=0;i<n;i++)
{
xx[i]=b[i];
for(j=0;j<n;j++)
if(j!=i)
xx[i]-=a[i][j]*x[j];
xx[i]/=a[i][i];
}
for(i=0;i<n;i++)
x[i]=xx[i];
}
delete xx;
}

void gs(double **a,double *b,double *x,int n,int Times)
//高斯-赛德尔迭代法求解线性方程组
{
int i,j,t;
for(t=0;t<Times;t++)
{
for(i=0;i<n;i++)
{
x[i]=b[i];
for(j=0;j<n;j++)
if(j!=i)
x[i]-=a[i][j]*x[j];
x[i]/=a[i][i];
}
}
}

void doolittle_deco(double **a,int n)
//Doolittle三角分解,分解后的矩阵保存在a中
{
int i,j,k,m;
for(k=0;k<n;k++)
{
for(j=k;j<n;j++)
for(m=0;m<k;m++)
a[k][j]-=a[k][m]*a[m][j];
for(i=k+1;i<n;i++)
{
for(m=0;m<k;m++)
a[i][k]-=a[i][m]*a[m][k];
a[i][k]/=a[k][k];
}
}
}

void doolittle_back(double **a,double *b,double *x,int n)
//Doolittle三角分解法求解线性方程组的回代过程
{
int i,j;
double *y;
y=new double[n];
for(i=0;i<n;i++)
{
y[i]=b[i];
for(j=0;j<i;j++)
y[i]-=a[i][j]*y[j];
}
for(i=n-1;i>=0;i--)
{
x[i]=y[i];
for(j=i+1;j<n;j++)
x[i]-=a[i][j]*x[j];
x[i]/=a[i][i];
}
delete y;
}

void doolittle(double **a,double *b,double *x,int n)
//Doolittle三角分解法求解线性方程组
{
doolittle_deco(a,n);
doolittle_back(a,b,x,n);
}

#11


前面加上
#include "stdio.h"
#include "math.h"
#define ABS(x) (x)>0?(x):-(x)
#define SWAP(a,b) {temp=(a);(a)=(b);(b)=temp;}

对它们的调用
int main(int argc, char* argv[])
{
int i,j,n;
double **a,*b,*x;
FILE *fp=fopen("d:\\data.txt","r");
fscanf(fp,"%d",&n);
a=new double*[n];
b=new double[n];
x=new double[n];
for(i=0;i<n;i++)
{
a[i]=new double[n];
for(j=0;j<n;j++)
fscanf(fp,"%lf",a[i]+j);
fscanf(fp,"%lf",b+i);
}
fclose(fp);

gauss(a,b,x,n);//Gauss主元消去法
for(i=0;i<n;i++)
printf("%f\t",x[i]);
printf("\n");

for(i=0;i<n;i++)
x[i]=1;
jacobi(a,b,x,3,10);//Jacobi迭代法
for(i=0;i<n;i++)
printf("%f\t",x[i]);
printf("\n");

for(i=0;i<n;i++)
x[i]=1;
gs(a,b,x,n,10);//GS迭代法
for(i=0;i<n;i++)
printf("%f\t",x[i]);
printf("\n");

doolittle(a,b,x,n);//Doolittle三角分解
for(i=0;i<n;i++)
printf("%f\t",x[i]);
printf("\n");

for(i=0;i<n;i++)
delete a[i];
delete a,b,x;
return 0;
}

数值计算可以参考
http://www.library.cornell.edu/nr/bookcpdf.html

#12


楼上的,谢谢,真好,

#13


漏了把数据格式写下来了
d:/data.txt   方程的规模n=3, 左边的1,1,1;2,2,3;3,2,1为系数矩阵,最右端为右端项
3
1 1 1  2.2
2 2 3  1.1
3 2 1  3.3

#14


我自己都已经琢磨出来了,老兄,