python - 快速计算在整数范围内定义的函数的总和 - (0,2^52)
问题描述
我正在查看特定加密货币赌场游戏的代码(EthCrash - 如果您有兴趣)。游戏使用一个函数(我称之为 crash(x))生成崩溃点,其中 x 是一个从整数空间 (0,2^52) 中随机抽取的整数。
我想计算崩溃点的预期值。下面的代码应该解释一切,但函数的清晰图片在这里: https ://i.imgur.com/8dPBALa.png ,我要计算的是在这里:https://i.imgur。 com/nllykDQ.png(抱歉 - 还不能粘贴图片)。
我写了以下代码:
import math
two52 = 2**52
def crash(x):
crash_point = math.floor((100*two52-x)/(two52-x))
return(crash_point/100)
crashes_sum = 0
for i in range(two52+1):
crashes_sum += crash(i)
expected_crash = crashes_sum/two52
不幸的是,循环运行时间太长 - 关于如何更快地做到这一点的任何想法?
解决方案
好吧,如果你不能直接做到这一点,是时候变聪明了,对吧?所以想法得到可以快速计算整个总和的范围。我会放一些甚至无法编译的伪代码,可能有错误等。用它作为说明。
首先,让我们将总和中的术语重写为
地板(100 + 99*x/(2 52 - x))
第一个想法 - 由于术语 n =< 99*x/(2 52 - x) < n+1的事实,得到 floor 不变的范围。显然,对于整个范围,我们可以将 range_length*(100 + n) 添加到 sum range_length*(100 + n),无需逐项进行
sum = 0
r_lo = 0
for k in range(0, 2*52): # LOOP OVER RANGES
r_hi = floor(2**52/(1 + 99/n))
sum += (100 + n -1)*(r_hi - r_lo)
if r_hi-r_lo == 1:
break
r_lo = r_hi + 1
显然,范围大小会缩小到等于1,然后这种方法就没有用了,我们突破。显然,到那时,每个术语都将与前一个术语相差 1 或更多。
好的,第二个想法 - 再次是范围,其中 sum 是算术级数。首先,我们必须找到增量等于 1 的范围。然后是增量等于 2 的范围,等等。看起来你必须为此找到二次方程的根,但代码大致相同
r_lo = pos_for_increment(1)
t_lo = ... # term at r_lo
for n in range(2, 2*52): # LOOP OVER RANGES
r_hi = pos_for_increment(n) - 1
t_hi = ... # term at r_lo
sum += (t_lo + t_hi)*(r_hi - r_lo) / 2 # arith.series sum
if r_hi > 2**52:
break
r_lo = r_hi + 1
t_lo = t_hi + n
可能会考虑其他事情,但这些技巧值得一试
推荐阅读
- python - 使用 VL 格式从 Python 将字符串列表存储到 HDF5 数据集
- c# - 在库项目中使用 .NET Core 中的 AutoMapper
- javascript - 使用字符串引用导入的模块
- reactjs - DatePicker 在初始状态下显示 fromat/custom 消息
- authentication - 尝试使用 UiPath Orchestrator 的智能卡远程启动机器人时出错
- create-react-app - 是否可以在不弹出的情况下将 devextreme 与 create-react-app 一起使用?
- selenium - 在我的移动应用程序的 appium 中找不到任何元素
- scala - 如何在 Akka 中限制发送给 IO(Tcp) 角色的消息
- angular - Angular Cli:带有水平分隔线的图表
- python - Pandas - 查找行的空列并在一列中更新