使用Python for循环用数值方法求解方程

时间:2017-02-08 14:45:05

标签: python algorithm numerical-methods

我正在学习Python和概率。<​​/ p>

我有一个表达式:

c = n! /((n-1)!1!) + 2*n! /((n-2)*2!) + 3*n!/((n-3)*3!) + ...+ n*n!/((n-n)*n!

其中0! = 1和!表示“阶乘”,即n! = 1 * 2 * 3 * ... *(n-1)* n。 等于:

(a + n^b)*2^(c*n + d).  (^ signifies exponent)

我的目标是使用“蛮力”确定参数a,b,c,d。

我使用上面的公式c计算n = 3(12),n = 4(38),n = 5(80),n = 6(192),n = 7(448)。

然后我将参数表示为两个整数的比率:即 a = a1 / a2,b = b1 / b2,c = c1 / c2,d = d1 / d2。

最后我定义了以下功能:

def com():
    parms = []
    for a1 in range(-10, 10):
        for a2 in range(1,11):
            for b1 in range(-10,10):
                for b2 in range(1, 11):
                    for c1 in range(-10,10):
                        for c2 in range(1, 11):
                            for d1 in range(-10 , 10):
                                for d2 in range(1 , 11):
                                    a = a1/a2
                                    b = b1/b2
                                    c = c1/c2
                                    d = d1/d2
                                    cr1 = ( 12 == (a + 3**b)*2**(c*3+d) )
                                    cr2 = ( 38 == (a + 4**b)*2**(c*4+d) )
                                    cr3 = ( 80 == (a + 5**b)*2**(c*5+d) )
                                    cr4 = ( 192 == (a + 6**b)*2**(c*6+d) )
                                    cr5 = ( 448 == (a + 7**b)*2**(c*7+d) )
                                    criterion = cr1 & cr2 & cr3 & cr4 & cr5
                                    if criterion == 1 :
                                        parms = [a, b, c, d]
                                        break
    return parms

但是,我的函数返回一个空列表。

你可以解释一下吗?您对如何实现我的目标有任何建议吗?

您的建议将不胜感激。

4 个答案:

答案 0 :(得分:1)

首先,让我们看一下代码中的一些错误:

criterion = cr1 & cr2 & cr3 & cr4 & cr5

这是对值执行bitwise操作。你可能想要:

criterion = cr1 and cr2 and cr3 and cr4 and cr5

Python还提供all函数,您可以检查all内容是True

criterion = all([cr1,cr2,cr3,cr4,cr5])

现在,让我们看一下你的if声明:

if criterion == 1 :

由于您想知道criterionTrue还是False,您只需使用if criterion:

现在最后,这种方法不可能是True。以此行为例:

cr1 = ( 12 == (a + 3**b)*2**(c*3+d) )

这些数字必须加起来恰好是12,否则它将是False,然后你会得到一个空列表。

此外,computers can't do decimal maths accurately

要解决实际值,必须使用参数替换。这不是一个编程问题,但数学和编程很好地结合在一起,所以这里有一个启动者:

12 = (a + 3**b)*2**(c*3+d)
12/(a+3**b) = 2**(c*3+d)

......等等。根据{{​​1}},ab获取c,然后使用d替换cr2中的数字,并根据ab获得c

重复几次,你有四个值的数字。

答案 1 :(得分:0)

您可以使用a,b,c,d并使用非线性最小二乘法将函数f拟合到数据并查找参数(a,b,c,d)值。您提供的示例数据更适合函数import numpy as np from scipy.optimize import curve_fit xdata = np.array(range(3,8)) ydata = np.array([12,38,80,192,448]) def func(n, a, b, c, d): return (a + n**b)+2**(c*n + d) popt, pcov = curve_fit(func, xdata, ydata, p0=(1,1,1,1)) a, b, c, d = popt print a, b, c, d # learnt parameters # -5.62374782967 1.79345876905 1.29232902743 -0.328778229316 import matplotlib.pyplot as plt plt.scatter(xdata, ydata) plt.plot(xdata, func(xdata, a, b, c, d), '-r', label='np.poly') plt.show() 。请注意,最适合n值的是浮点数,而不是整数。

label3.Text = label1.Text + " = " + label2.Text;

enter image description here

在上面拟合的曲线中,蓝点是数据点,红线是带有学习参数的拟合函数,注意函数是连续的并且为{{1}}的所有值定义。

答案 2 :(得分:0)

用大脑代替Python:

您识别修改后的二项和,Sum k.Cnk而不是Sum Cnk

然后注意

k.n!/(k!(n-k)!) = n!/((k-1)!(n-k)!) = n.(n-1)!/(k-1)!(n-1-k+1)!) = n.Cn-1,k+1.

所以你的总和将是n.2^(n-1)

答案 3 :(得分:0)

在闯入蛮力之前,尝试估计参数的紧密范围可能更明智。

总和的第一个值是

1, 4, 12, 32, 80, 192, 448, 1024, 2304, 5120, 11264

采用成对比率,您会发现它们越来越接近2。

由于比率(a + (n+1)^b)/(a + n^b)趋于1且比率2^(c(n+1)+d)/2^(cn+d)趋于2^c,因此您暗示c可能接近1.您可以查看通过尝试越来越大的n值来估算此值(例如,n=1000会产生比率2.002002... = 2^1.00144...)。

然后为了降低表达式的增长率以使其更容易处理,查看Sum/2^n的值可能会很有趣,我们得到

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
嗯,哼哼。

不幸的是,这种情况对于正确演示该方法来说太容易了。一般的想法是观察渐近行为以获得一些参数的粗略估计。当你有这么粗略的估计(在一个小范围内),那么你可以以某种方式取消它的效果,以更好地看到其他的效果。

对于详尽的搜索,了解范围很重要。