分别输入方程a*X*X+b*X+C=0的参数a、b、c,计算出方程的解。
参考代码如下:
print("请输入方程a*X*X+b*X+C=0的参数,")a=float(input('a:'))b=float(input('b:'))c=float(input('c:'))dlt=b*b-4*a*cprint("%g*X*X+%g*X+%g=0的解:"%(a,b,c))if a==0: if b==0: if c==0: print('x取任意值!') else: print('方程无解!') else: print('x=%g'%(-c/b))else: if dlt>=0: x1=(-b+(dlt)**0.5)/(2*a) x2=(-b-(dlt)**0.5)/(2*a) print("x1=%g,x2=%g"%(x1,x2)) else: print("没有实数根!")
本题其实没啥难度,主要是训练一下解决问题的思维完备性,比如需要判断能否构成一元二次方程、如果构不成会有什么情况等等。这些你都考虑到了吗?
一元二次方程求解平时最常用的就是求根公式,但还有没有其他方法?显然是有的,比如牛顿迭代法。什么?你不知道牛顿迭代法?呵呵,那就普及一下吧。
上面的函数y=f(x)图像与x轴有一个交点,这个就是方程f(x)=0解X,那么附近任意取一个Xn,对应的作函数图像的切线,再取得该切线与x轴的交点,把这个点叫做Xn+1,发现没有?这时候是不是Xn+1比Xn更逼近于X?如果一直做下去,是不是就可以无限逼近X了呢?
这就是牛顿迭代法的原理,很简单吧?那么Xn对应的切线方程是什么呢?这个在高等代数中大家应该学过,就是对f(x)求导得f'(x),带入Xn就可以得到切点处的斜率k,那么方程就可以写作:y=k(x-Xn)+Yn。这样也就可以计算出它与x轴的交点xn+1=-Yn/k+Xn.
所以回到a*X*X+b*X+C=0的求解,我们先对y=a*X*X+b*X+C求导,得到y’=2*a*X+b,那么xn对应的切线方程为y=(2*a*Xn+b)(x-Xn)+(a*Xn*Xn+b*Xn+C),它和x轴的交点Xn+1=-(a*Xn*Xn+b*Xn+C)/(2*a*Xn+b)+Xn,这个就是迭代式。不停跌代,直到Xn,Xn+1很接近为止。
print("请输入方程a*X*X+b*X+C=0的参数,")a=float(input('a:'))b=float(input('b:'))c=float(input('c:'))def nt(x):#迭代函数 return -(a*x*x+b*x+c)/(2*a*x+b)+xdlt=b*b-4*a*cprint("%g*X*X+%g*X+%g=0的解:"%(a,b,c))if a==0: if b==0: if c==0: print('x取任意值!') else: print('方程无解!') else: print('x=%g'%(-c/b))else: if dlt>=0: middle=-b/(2*a)#对称轴 x_1=middle+0.000001#轴右边初始取值 x_2=middle-0.000001#轴左边初始取值 t=x_1+1 while abs(x_1-t)>0.000001:#迭代求右边的解 ,要求最后间隔精度0.000001 t=x_1 x_1=nt(x_1) print('x1=%g'%x_1) t=x_2+1 while abs(x_2-t)>0.000001:#迭代求左边的解,要求最后间隔精度0.000001 t=x_2 x_2=nt(x_2) print('x2=%g'%x_2) else: print("没有实数根!")
要注意的问题:
(1)如果存在解,那么在解附近的迭代肯定是收敛的。但一个初始值开始的迭代只可以逼近一个解,所以需要从函数图像入手分析方程会有几个解,然后对应取得临近的初始值。比如二次方程如果有解,则对应的二次函数对称轴两边要分别取得初始值(2个)。
(2)牛顿迭代法是解决一元高次方程的有效方法,不局限于解一元二次方程,这也正是我们这里研究他的意义所在。