用VC能求方程么?

时间:2021-08-21 19:59:06
我有一个相对有点复杂的方程,方程的两边都有未知数。要是用手工把未知数都转换到一边不很容易,而且还怕出错,在这种情况下VC能解决么?用我自己编算法么?我没有学过计算方法,是要用用迭代方法么?我只是听人说过,具体怎么用?我本想把这个式子贴上来,可是我不会在WORD里面输入对数的符号,呵呵。

37 个解决方案

#1


是线性的吗?线性方程可以把所有项移到一边,用行列式或矩阵解。

#2


在大学里我写过哦,不过现在对行列式已经忘的一干二净了。

#3


你知道WORD中怎么输入对数符号么,我把它贴上来吧

#4


可以

#5


可以什么,是用迭代么?

#6


计算机解方程不同于手工, 一般是用数据当作解来尝试解的大体数值,这方面的书很多,从一元一次方程到差分方程,积分,导数都是可以的,你可以参考  <<计算机常用算法>>(好像是叫这个名字, 封面是上面白,下面蓝) 里面写得很详细, 有程序,是C的,可以很容易用到VC中

#7


我刚学过计算方法,所以我记得还比较清楚,但叙述起来比较麻烦.
如果只是一个方程的话那么矩阵就派不上用场了,用迭代就可以了.
你的方程应该不会是一元一次方程吧,是个高次方程还是含有sinx,lgx,exp(x)
的这种?不要紧,用迭代都能解决,不过最好能知道x的约略的值,即迭代循环的初值x0,这涉及收敛的问题,如果不收敛,是解不出来的.
    把你的方程写成这种形式:x=f(x),然后
    float x1,x2;
    x1=x0;
    do
    {
      x2=x1;
      x1=f(x2);
    }while(fabs(x1-x2)>1e-6);
    循环条件为:x1,x2之差的绝对值大于1e-6(控制精度),循环完成后,x1即为解.

#8


我刚学过计算方法,所以我记得还比较清楚,但叙述起来比较麻烦.
如果只是一个方程的话那么矩阵就派不上用场了,用迭代就可以了.
你的方程应该不会是一元一次方程吧,是个高次方程还是含有sinx,lgx,exp(x)
的这种?不要紧,用迭代都能解决,不过最好能知道x的约略的值,即迭代循环的初值x0,这涉及收敛的问题,如果不收敛,是解不出来的.
    把你的方程写成这种形式:x=f(x),然后
    float x1,x2;
    x1=x0;
    do
    {
      x2=x1;
      x1=f(x2);
    }while(fabs(x1-x2)>1e-6);
    循环条件为:x1,x2之差的绝对值大于1e-6(控制精度),循环完成后,x1即为解.

#9


最好能把方程贴出来,应该不会很困难吧?如果符号不好打,可用其它符号代替,在后面说明一下即可.

#10


其实也就是一个公式,我不想手工转化。
ln(D2/D0)=(2*[A1*(T0-T1)+A2*(T1-Ta)]/q)-2*A2/D2*As
现在除了D2一切都已知,我想把每个元素对应一个EDIT,在这些编辑框里面输入那些数,按一下计算的按钮,就能得出D2的值,希望高手能教我个好办法。

#11


这个很简单嘛   
建议你用 斜率法来做 
反复迭代就可以了 
给你 一个 方法
自己写代码
很简单的 

先 设定一个X0 初始值
 K = F(Xn)   K为斜率     先求出 K的 表达式
Yn+1 = K(Xn+1 - X(n)

反复迭代
直到 ( Yn+1 - Yn)  < 0.00000000001  任意精度

#12


酋长,感谢您的回答,不过,我好象还是不太懂,我比较苯。希望您能教的细一点,在茶余饭后抽出那么一小会时间来帮我个忙,好么,我希望您能写的具体一些,谢谢。

#13


我写过一个求解N元一次方程的,但是前提是未知数全在一边

#14


这种问题 你 首先要知道有几个根
,每个根的大致范围

斜率法的 收敛速度很快的 
所以 大致 范围就可以了

你可以 令 F1(X) =ln(X/D0)
F2(X) = 2*[A1*(T0-T1)+A2*(T1-Ta)]/q)-2*A2/D2*As
然后根据 大致的 图像 可以知道 有一个交点 
我假设 D0 正值
再根据  D0 的值大致判断 交点在 (0,1) 或者 (1,+无穷)

让后把  0, 或者1 作为起点
用 高数知识求出 斜率的 表达式 
然后就可以 将 起点的值代入

 K = F(Xn)   K为斜率     先求出 K的 表达式
Yn+1 = K(Xn+1 - X(n))

不断的 循环
直到满足 条件   
把  最后的 Xn+1 作为结果,就可以了

#15


谢谢你,麻烦你了,我知道您已经很费心了,不过,我还是实现不了,我才学VC++两个星期,呵呵,惭愧。虽然我现在还不会,但等我结帖的时候会给你分的。

#16


没有其他的方法了么?也许上面的算法对于高手是很简单,但对于我这个初学者简直就是不可能完成的,呵呵,什么也不会,真郁闷

#17


可用Guass完全主元消去法:
/*------------------------------------------------------------------
                   Guass完全主元消去法
------------------------------------------------------------------*/

#include<stdio.h>
#include<stdlib.h>

void InputN(int *n);                       //输入方程个数

void Input(float **p,int n);               //输入方程增广矩阵

int Guass(float **p,int *z,int n);         //消增广矩阵为上三角

int All(float **p,int *z,int n,int s);     //完全主元

float abs(float a);                        //float的绝对值

void Y(float **p,int n);                   //解Y存入矩阵最后一列

void OutX(float **p,int *z,int n);         //输出X

void PrintEquals(float **p,int n);         //输出方程

void main()
{
int n,f;                                    //n方程个数,未知数个数
float **p;                                  //p指向方程组增广矩阵
int *z;                                     //z描述x,y对应关系

InputN(&n);                                 //取得x个数

p=(float **)malloc(n*sizeof(float *));      //分配增广矩阵内存
for(int i=0;i<n;++i)
{
p[i]=(float *)malloc((n+1)*sizeof(float));
}

z=(int *)malloc(n*sizeof(int));           //z数组描述x,y对应关系
for(int d=0;d<n;++d)                      //初始化Z数组
{
z[d]=d;
}

Input(p,n);

PrintEquals(p,n);

f=Guass(p,z,n);
if(f==1) printf("方程组系数行列式为零!");
else 
{
Y(p,n);
OutX(p,z,n);
}

for(int k=0;k<n;++k) free((void *)p[k]);   //释放内存
free((void **)p);
free((void *)z);
}

void InputN(int *n)
{
do
{
printf("请输入方程个数: ");
scanf("%d",n);
printf("\n");
}
while(*n<=0);
}

void Input(float **p,int n)
{
for(int i=0;i<n;++i)
{
for(int j=0;j<n;++j)
{
printf("请输入a[%d][%d]:  ",i,j);
scanf("%f",&p[i][j]);
}
printf("请输入B[%d]:     ",i);
    scanf("%f",&p[i][n]);
printf("\n");
}
}

int Guass(float **p,int *z,int n)
{
for(int s=0;s<n-1;++s)

        if(All(p,z,n,s)) return 1;      //选主元,行列式为零 

for(int a=s+1;a<n;++a)
{
p[a][s]=p[a][s]/p[s][s];
}

for(int i=s+1;i<n;++i)
{
for(int j=s+1;j<n+1;++j)
{
p[i][j]=p[i][j]-p[s][j]*p[i][s];

}
}
if(p[n-1][n-1]==0) return 1;        //行列式为零
return 0;               
}

int All(float **p,int *z,int n,int s)
{
int e,f,tz;
float *t,r;

e=s;
f=s;

for(int i=s;i<n;++i)
for(int j=s;j<n;++j)
{
if(abs(p[i][j])>abs(p[e][f])) 
{
e=i;
f=j;
}
}

if(p[e][f]==0) return 1;              //行列式为零

if(e!=s)                              //换行
{
t=p[e];
p[e]=p[s];
p[s]=t;
}

if(f!=s)                              //换列
{
for(int g=0;g<n;++g)
{
r=p[g][s];
p[g][s]=p[g][f];
p[g][f]=r;
}

    tz=z[f];
z[f]=z[s];
z[s]=tz;
}

return 0;
}



void Y(float **p, int n)
{
p[n-1][n]=p[n-1][n]/p[n-1][n-1];
if(n>=2)
{
for(int j=n-2;j>-1;--j)
{
float S=0;
for(int i=j+1;i<n;++i)
{
S+=p[i][n]*p[j][i];
}
p[j][n]=(p[j][n]-S)/p[j][j];
}
}
}

void OutX(float **p,int *z,int n)
{
for(int i=0;i<n;++i)     //xi
{
for(int index=0;index<n;++index)
{
if(z[index]==i) 
{
printf("X%d=%f\n",i+1,p[index][n]);
break;
}
}
}
}

void PrintEquals(float **p,int n)
{
for(int i=0;i<n;++i)
{
printf("%f*X1",p[i][0]);
for(int j=1;j<n;++j)
{
printf("+%f*X%d",p[i][j],j+1);
}

printf(" = %f*B%d",p[i][n],i+1);

printf("\n");
}
printf("\n");
}

float abs(float a)
{
if(a>=0) return a;
else return -a;
}

#18


多谢多谢。其实我感觉解决这个问题一定要有好的数学基础,咳。

#19


这样的方法本来就是利用数学方法来解决的,如果你没有学过《计算方法》或者是
《数值分析》的话,你很难理解这样的问题,我建议你先看看这方面的书籍,所谓
是“磨刀不误砍柴工”,老在****上面讨论也不是办法,别人给你方法你有看不懂,还是自己先看看书吧,---------给你的一点点小建议!

#20


是算法问题,不是VC的问题

#21


哇噻,你这方程真够复杂的,连我这数学系的都不愿意去解,顺便说一下:那个chengpu(程P)简直是所答非所问。以我之见,你要是算法实在不太懂的话,到是有一个小办法可以弥补,不过,你必须知道结果的大致范围,且这个范围一定要把结果包含在内,现设此范围为:a < D2 < b,另外还需一个条件:
当D2= a 和 D2=b 两种情况时,左边与右边各有一个大的,不能同时为大的或小的。
现假设当D2=a时,左边〈 右边(显然应有:D2=b时,左边>右边),下面是算法:
1、取D=(a+b)/2, 令D2=D,若左边<右边,则令a=D,否则令b=D;
2、重复做1,直到(左边-右边)< 误差允许值;
D就是所求解的近似值。

#22


多谢各位指教了,我其实也知道应该回头学学再去解决问题,可是时间不允许啊,我的毕业设计要用VC++去做(我为了学点东西,特意不去挑简单的题目),题目不难,就是学VC要花点时间,总共就两个月就得完成,我没有太多时间去学数学了,真愁人啊。

#23


二叉树,线索化,中序遍历。

#24


难到毕业设计不能用其它工具做吗?如果你是刚学vc,那就很麻烦了,不知你现在学的怎样了?crazy_lazy_pig的方法也可以,不过收敛速度会慢一些,代码上也不见的会简洁些。

#25


能,当然可以用其他工具,Delphi,SQL,虚拟现实,都有的,但我想学点有用的东西,反正我以后也想学VC,不如就现在开始,人都是逼出来的。

#26


真是的,要是可以用其他工具,我给你推荐一个:MAPLE。一条命令就行了:
solve(式子,变量);

#27


那我要是用这个工具MAPLE做出来,然后生成EXE,用VC调用呢?

#28


MAPLE是什么?有下载的地方么?

#29


matlab
mathematica

#30


什么?什么意思?

#31


还是帮你顶一把吧!!

#32


支持“蓝色”用matlab很方便嘛!

#33


matlab是什么东东?

#34


也没办法,其实要求是要用VC做的,还是埋头弄迭代吧,呵呵

#35


贴出来看看

#36


上面呢,上面有帖出来

#37


参见:
http://www.****.net/expert/topic/699/699556.xml?temp=.6652948

#1


是线性的吗?线性方程可以把所有项移到一边,用行列式或矩阵解。

#2


在大学里我写过哦,不过现在对行列式已经忘的一干二净了。

#3


你知道WORD中怎么输入对数符号么,我把它贴上来吧

#4


可以

#5


可以什么,是用迭代么?

#6


计算机解方程不同于手工, 一般是用数据当作解来尝试解的大体数值,这方面的书很多,从一元一次方程到差分方程,积分,导数都是可以的,你可以参考  <<计算机常用算法>>(好像是叫这个名字, 封面是上面白,下面蓝) 里面写得很详细, 有程序,是C的,可以很容易用到VC中

#7


我刚学过计算方法,所以我记得还比较清楚,但叙述起来比较麻烦.
如果只是一个方程的话那么矩阵就派不上用场了,用迭代就可以了.
你的方程应该不会是一元一次方程吧,是个高次方程还是含有sinx,lgx,exp(x)
的这种?不要紧,用迭代都能解决,不过最好能知道x的约略的值,即迭代循环的初值x0,这涉及收敛的问题,如果不收敛,是解不出来的.
    把你的方程写成这种形式:x=f(x),然后
    float x1,x2;
    x1=x0;
    do
    {
      x2=x1;
      x1=f(x2);
    }while(fabs(x1-x2)>1e-6);
    循环条件为:x1,x2之差的绝对值大于1e-6(控制精度),循环完成后,x1即为解.

#8


我刚学过计算方法,所以我记得还比较清楚,但叙述起来比较麻烦.
如果只是一个方程的话那么矩阵就派不上用场了,用迭代就可以了.
你的方程应该不会是一元一次方程吧,是个高次方程还是含有sinx,lgx,exp(x)
的这种?不要紧,用迭代都能解决,不过最好能知道x的约略的值,即迭代循环的初值x0,这涉及收敛的问题,如果不收敛,是解不出来的.
    把你的方程写成这种形式:x=f(x),然后
    float x1,x2;
    x1=x0;
    do
    {
      x2=x1;
      x1=f(x2);
    }while(fabs(x1-x2)>1e-6);
    循环条件为:x1,x2之差的绝对值大于1e-6(控制精度),循环完成后,x1即为解.

#9


最好能把方程贴出来,应该不会很困难吧?如果符号不好打,可用其它符号代替,在后面说明一下即可.

#10


其实也就是一个公式,我不想手工转化。
ln(D2/D0)=(2*[A1*(T0-T1)+A2*(T1-Ta)]/q)-2*A2/D2*As
现在除了D2一切都已知,我想把每个元素对应一个EDIT,在这些编辑框里面输入那些数,按一下计算的按钮,就能得出D2的值,希望高手能教我个好办法。

#11


这个很简单嘛   
建议你用 斜率法来做 
反复迭代就可以了 
给你 一个 方法
自己写代码
很简单的 

先 设定一个X0 初始值
 K = F(Xn)   K为斜率     先求出 K的 表达式
Yn+1 = K(Xn+1 - X(n)

反复迭代
直到 ( Yn+1 - Yn)  < 0.00000000001  任意精度

#12


酋长,感谢您的回答,不过,我好象还是不太懂,我比较苯。希望您能教的细一点,在茶余饭后抽出那么一小会时间来帮我个忙,好么,我希望您能写的具体一些,谢谢。

#13


我写过一个求解N元一次方程的,但是前提是未知数全在一边

#14


这种问题 你 首先要知道有几个根
,每个根的大致范围

斜率法的 收敛速度很快的 
所以 大致 范围就可以了

你可以 令 F1(X) =ln(X/D0)
F2(X) = 2*[A1*(T0-T1)+A2*(T1-Ta)]/q)-2*A2/D2*As
然后根据 大致的 图像 可以知道 有一个交点 
我假设 D0 正值
再根据  D0 的值大致判断 交点在 (0,1) 或者 (1,+无穷)

让后把  0, 或者1 作为起点
用 高数知识求出 斜率的 表达式 
然后就可以 将 起点的值代入

 K = F(Xn)   K为斜率     先求出 K的 表达式
Yn+1 = K(Xn+1 - X(n))

不断的 循环
直到满足 条件   
把  最后的 Xn+1 作为结果,就可以了

#15


谢谢你,麻烦你了,我知道您已经很费心了,不过,我还是实现不了,我才学VC++两个星期,呵呵,惭愧。虽然我现在还不会,但等我结帖的时候会给你分的。

#16


没有其他的方法了么?也许上面的算法对于高手是很简单,但对于我这个初学者简直就是不可能完成的,呵呵,什么也不会,真郁闷

#17


可用Guass完全主元消去法:
/*------------------------------------------------------------------
                   Guass完全主元消去法
------------------------------------------------------------------*/

#include<stdio.h>
#include<stdlib.h>

void InputN(int *n);                       //输入方程个数

void Input(float **p,int n);               //输入方程增广矩阵

int Guass(float **p,int *z,int n);         //消增广矩阵为上三角

int All(float **p,int *z,int n,int s);     //完全主元

float abs(float a);                        //float的绝对值

void Y(float **p,int n);                   //解Y存入矩阵最后一列

void OutX(float **p,int *z,int n);         //输出X

void PrintEquals(float **p,int n);         //输出方程

void main()
{
int n,f;                                    //n方程个数,未知数个数
float **p;                                  //p指向方程组增广矩阵
int *z;                                     //z描述x,y对应关系

InputN(&n);                                 //取得x个数

p=(float **)malloc(n*sizeof(float *));      //分配增广矩阵内存
for(int i=0;i<n;++i)
{
p[i]=(float *)malloc((n+1)*sizeof(float));
}

z=(int *)malloc(n*sizeof(int));           //z数组描述x,y对应关系
for(int d=0;d<n;++d)                      //初始化Z数组
{
z[d]=d;
}

Input(p,n);

PrintEquals(p,n);

f=Guass(p,z,n);
if(f==1) printf("方程组系数行列式为零!");
else 
{
Y(p,n);
OutX(p,z,n);
}

for(int k=0;k<n;++k) free((void *)p[k]);   //释放内存
free((void **)p);
free((void *)z);
}

void InputN(int *n)
{
do
{
printf("请输入方程个数: ");
scanf("%d",n);
printf("\n");
}
while(*n<=0);
}

void Input(float **p,int n)
{
for(int i=0;i<n;++i)
{
for(int j=0;j<n;++j)
{
printf("请输入a[%d][%d]:  ",i,j);
scanf("%f",&p[i][j]);
}
printf("请输入B[%d]:     ",i);
    scanf("%f",&p[i][n]);
printf("\n");
}
}

int Guass(float **p,int *z,int n)
{
for(int s=0;s<n-1;++s)

        if(All(p,z,n,s)) return 1;      //选主元,行列式为零 

for(int a=s+1;a<n;++a)
{
p[a][s]=p[a][s]/p[s][s];
}

for(int i=s+1;i<n;++i)
{
for(int j=s+1;j<n+1;++j)
{
p[i][j]=p[i][j]-p[s][j]*p[i][s];

}
}
if(p[n-1][n-1]==0) return 1;        //行列式为零
return 0;               
}

int All(float **p,int *z,int n,int s)
{
int e,f,tz;
float *t,r;

e=s;
f=s;

for(int i=s;i<n;++i)
for(int j=s;j<n;++j)
{
if(abs(p[i][j])>abs(p[e][f])) 
{
e=i;
f=j;
}
}

if(p[e][f]==0) return 1;              //行列式为零

if(e!=s)                              //换行
{
t=p[e];
p[e]=p[s];
p[s]=t;
}

if(f!=s)                              //换列
{
for(int g=0;g<n;++g)
{
r=p[g][s];
p[g][s]=p[g][f];
p[g][f]=r;
}

    tz=z[f];
z[f]=z[s];
z[s]=tz;
}

return 0;
}



void Y(float **p, int n)
{
p[n-1][n]=p[n-1][n]/p[n-1][n-1];
if(n>=2)
{
for(int j=n-2;j>-1;--j)
{
float S=0;
for(int i=j+1;i<n;++i)
{
S+=p[i][n]*p[j][i];
}
p[j][n]=(p[j][n]-S)/p[j][j];
}
}
}

void OutX(float **p,int *z,int n)
{
for(int i=0;i<n;++i)     //xi
{
for(int index=0;index<n;++index)
{
if(z[index]==i) 
{
printf("X%d=%f\n",i+1,p[index][n]);
break;
}
}
}
}

void PrintEquals(float **p,int n)
{
for(int i=0;i<n;++i)
{
printf("%f*X1",p[i][0]);
for(int j=1;j<n;++j)
{
printf("+%f*X%d",p[i][j],j+1);
}

printf(" = %f*B%d",p[i][n],i+1);

printf("\n");
}
printf("\n");
}

float abs(float a)
{
if(a>=0) return a;
else return -a;
}

#18


多谢多谢。其实我感觉解决这个问题一定要有好的数学基础,咳。

#19


这样的方法本来就是利用数学方法来解决的,如果你没有学过《计算方法》或者是
《数值分析》的话,你很难理解这样的问题,我建议你先看看这方面的书籍,所谓
是“磨刀不误砍柴工”,老在****上面讨论也不是办法,别人给你方法你有看不懂,还是自己先看看书吧,---------给你的一点点小建议!

#20


是算法问题,不是VC的问题

#21


哇噻,你这方程真够复杂的,连我这数学系的都不愿意去解,顺便说一下:那个chengpu(程P)简直是所答非所问。以我之见,你要是算法实在不太懂的话,到是有一个小办法可以弥补,不过,你必须知道结果的大致范围,且这个范围一定要把结果包含在内,现设此范围为:a < D2 < b,另外还需一个条件:
当D2= a 和 D2=b 两种情况时,左边与右边各有一个大的,不能同时为大的或小的。
现假设当D2=a时,左边〈 右边(显然应有:D2=b时,左边>右边),下面是算法:
1、取D=(a+b)/2, 令D2=D,若左边<右边,则令a=D,否则令b=D;
2、重复做1,直到(左边-右边)< 误差允许值;
D就是所求解的近似值。

#22


多谢各位指教了,我其实也知道应该回头学学再去解决问题,可是时间不允许啊,我的毕业设计要用VC++去做(我为了学点东西,特意不去挑简单的题目),题目不难,就是学VC要花点时间,总共就两个月就得完成,我没有太多时间去学数学了,真愁人啊。

#23


二叉树,线索化,中序遍历。

#24


难到毕业设计不能用其它工具做吗?如果你是刚学vc,那就很麻烦了,不知你现在学的怎样了?crazy_lazy_pig的方法也可以,不过收敛速度会慢一些,代码上也不见的会简洁些。

#25


能,当然可以用其他工具,Delphi,SQL,虚拟现实,都有的,但我想学点有用的东西,反正我以后也想学VC,不如就现在开始,人都是逼出来的。

#26


真是的,要是可以用其他工具,我给你推荐一个:MAPLE。一条命令就行了:
solve(式子,变量);

#27


那我要是用这个工具MAPLE做出来,然后生成EXE,用VC调用呢?

#28


MAPLE是什么?有下载的地方么?

#29


matlab
mathematica

#30


什么?什么意思?

#31


还是帮你顶一把吧!!

#32


支持“蓝色”用matlab很方便嘛!

#33


matlab是什么东东?

#34


也没办法,其实要求是要用VC做的,还是埋头弄迭代吧,呵呵

#35


贴出来看看

#36


上面呢,上面有帖出来

#37


参见:
http://www.****.net/expert/topic/699/699556.xml?temp=.6652948