Python 预测所需的迭代次数-迭代加权平均数
对不起,我可以找一个更好的标题。请看这个超级简单的Python程序:Python 预测所需的迭代次数-迭代加权平均数,python,math,Python,Math,对不起,我可以找一个更好的标题。请看这个超级简单的Python程序: x = start = 1.0 target = 0.1 coeff = 0.999 for c in range(100000): print('{:5d} {:f}'.format(c, x)) if abs(target - x) < abs((x - start) * 0.01): break x = x * coeff + target * (1 - coeff)
x = start = 1.0
target = 0.1
coeff = 0.999
for c in range(100000):
print('{:5d} {:f}'.format(c, x))
if abs(target - x) < abs((x - start) * 0.01):
break
x = x * coeff + target * (1 - coeff)
x=start=1.0
目标=0.1
系数=0.999
对于范围(100000)内的c:
打印({:5d}{:f})。格式(c,x))
如果abs(目标-x)
简要说明:该程序将x
移向target
迭代计算x
和target
的加权平均值,并将coeff
作为权重。当x
达到初始差值的1%时停止
无论x
和target
的初始值是多少,迭代次数都保持不变
如何设置coeff
以预测将发生多少次迭代
非常感谢。让我们把它变成一个函数,
f
f(0)
是初始值(start
,在本例中为1.0
)
f(x)=f(x-1)*c+T*(1-c)
(因此,f(1)
是x的下一个值,f(2)
是之后的值,依此类推。我们想找到x的值,其中|T-f(x)|<0.01*| f(0)-f(x)
)
因此,让我们将f(x)
改写为线性:
f(x) = f(x - 1) * c + T * (1 - c)
= (f(x - 2) * c + T * (1 - c)) * c + T * (1 - c)
= (f(x - 2) * c ** 2 + T * c * (1 - c)) + T * (1 - c)
= ((f(x - 3) * c + T * (1 - c)) * c ** 2 + T * c * (1 - c)) + T * (1 - c)
= f(x - 3) * c ** 3 + T * c ** 2 * (1 - c) + T * c * (1 - c) + T * (1 - c)
= f(0) * c ** x + T * c ** (x - 1) * (1 - c) + T * c ** (x - 2) * (1 - c) + ... + T * c * (1 - c) + T * (1 - c)
= f(0) * c ** x + (T * (1 - c)) [(sum r = 0 to x - 1) (c ** r)]
# Summation of a geometric series
= f(0) * c ** x + (T * (1 - c)) ((1 - c ** x) / (1 - c))
= f(0) * c ** x + T (1 - c ** x)
因此,x的第n个值将是start*c**n+target*(1-c**n)
我们希望:
|T - f(x)| < 0.01 * |f(0) - f(x)|
|T - f(0) * c ** x - T (1 - c ** x)| < 0.01 * |f(0) - f(0) * c ** x - T (1 - c ** x)|
|(c ** x) * T - (c ** x) f(0)| < 0.01 * |(1 - c ** x) * f(0) - (1 - c ** x) * T|
(c ** x) * |T - f(0)| < 0.01 * (1 - c ** x) * |T - f(0)|
c ** x < 0.01 * (1 - c ** x)
c ** x < 0.01 - 0.01 * c ** x
1.01 * c ** x < 0.01
c ** x < 1 / 101
x < log (1 / 101) / log c
因此,对于系数c
,将有log(1/101)/log c
步骤
如果您有所需的步骤数,请将其称为I
,您有
I = log_c(1 / 101)
c ** I = 1 / 101
c = (1 / 101) ** (1 / I)
因此,应将c
设置为1/101
的I
第次根在每次执行循环时,您的代码会将x和目标之间的距离减少一个系数coeff
。因此,如果start
大于target
,我们得到公式
target - x = (x - start) * coeff ** c
其中c
是我们完成的循环数
您的结束标准是(同样,如果开始
大于目标
)
将其代入我们的第一个表达式并简化一点,使得start
和target
都从不等式中退出——现在你知道为什么这些值不重要了——我们得到
0.01 / (1 + 0.01) < coeff ** c
所以循环数的最终答案是
ceil(log(0.01 / (1 + 0.01), coeff))
或者,如果您不喜欢任意底的对数
ceil(log(0.01 / (1 + 0.01)) / log(coeff))
您可以将最后一个表达式中的第一个对数替换为它的结果,但我将其保留为这种方式,以查看如果您将结束条件中的常数从0.01
更改,将得到什么不同的结果
在您的特定情况下,该表达式的结果是
4613
这是正确的。请注意,ceil
和log
函数都在Python的math
单元中,因此请记住在进行计算之前导入这些函数。还要注意Python的浮点计算是不精确的,因此如果您更改coeff
或0.01
的值,那么实际循环数可能会与实际循环数相差一个。你所说的“设置coeff以预测将发生多少次迭代”是什么意思?我想他的意思是,如果有一个coeff函数映射到迭代次数needed@RyanLim:我猜他想知道循环将运行多少次迭代,给定start
、target
和coeff
的值,这需要求解coeff
中的不等式多项式,形式为k0*start*coeff^n+target*(k1*coeff^n+k2*coeff^(n-1)+…+kn)
,通过一些代数,可以显示n
迭代后x
的值由x\u val=lambda n:start*(coeff**n)+target*(1-coeff)*(求和)给出(coeff**i代表范围内的i(n))
。你需要找到解决你的条件的最小n。我的意思是,当coeff为0.999时,迭代次数为4613。我正在寻找从4613得到0.999的公式。另外,还有某种对数关系:0.99->460,0.999->4613,0.9999->46149。我真的很感动。谢谢1000。
c > log(0.01 / (1 + 0.01), coeff)
ceil(log(0.01 / (1 + 0.01), coeff))
ceil(log(0.01 / (1 + 0.01)) / log(coeff))
4613