我正在学习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
但是,我的函数返回一个空列表。
你可以解释一下吗?您对如何实现我的目标有任何建议吗?您的建议将不胜感激。
答案 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 :
由于您想知道criterion
是True
还是False
,您只需使用if criterion:
。
True
。以此行为例:cr1 = ( 12 == (a + 3**b)*2**(c*3+d) )
这些数字必须加起来恰好是12,否则它将是False
,然后你会得到一个空列表。
要解决实际值,必须使用参数替换。这不是一个编程问题,但数学和编程很好地结合在一起,所以这里有一个启动者:
12 = (a + 3**b)*2**(c*3+d)
12/(a+3**b) = 2**(c*3+d)
......等等。根据{{1}},a
和b
获取c
,然后使用d
替换cr2
中的数字,并根据a
和b
获得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;
在上面拟合的曲线中,蓝点是数据点,红线是带有学习参数的拟合函数,注意函数是连续的并且为{{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
嗯,哼哼。
不幸的是,这种情况对于正确演示该方法来说太容易了。一般的想法是观察渐近行为以获得一些参数的粗略估计。当你有这么粗略的估计(在一个小范围内),那么你可以以某种方式取消它的效果,以更好地看到其他的效果。
对于详尽的搜索,了解范围很重要。