问一算法题

2014-12-14 21:35:03 +08:00
 czheo

输入:
5个整数
A, B, X1, K, M

有一个random算法
Xn = (A * Xn-1 + B) % M

要输出第K到K+4的X结果

老老实实写了如下python代码,问如何优化?
~~~
A, B, X1, K, M = map(int, raw_input().split())

def myRand(seed):
return (A * seed + B) % M

seed = X1
for i in xrange(1, K+5):
if i > K-1:
print seed
seed = myRand(seed)
~~~

2790 次点击
所在节点    问与答
15 条回复
jiang42
2014-12-14 21:55:21 +08:00
不知道你想怎么优化?我能想到的就是map换成list comprehension。或者数学好的话把递归表达式直接写成直接求值的表达式。一般来说,O(n)的算法在实际生活中已经足够好了
czheo
2014-12-14 22:05:39 +08:00
我把代码提交上去,系统说运行超时,我只能想出O(n)的算法。不知道考点在哪里。
hint: 比如M极小的时候除余会不会变慢?

@jiang42 把递归表达式直接写成直接求值要怎么写?
iloahz
2014-12-14 22:24:24 +08:00
可以写出来通项公式的样子,要是嫌麻烦用矩阵也行噻
czheo
2014-12-14 22:26:53 +08:00
一软件公司出题让我求通项公式也太....

@iloahz 怎么个矩阵法?
akagi
2014-12-14 22:37:04 +08:00
同余吧 循环节是M 打个表出来 直接到里面取 —— 简单想了下 不一定对
akagi
2014-12-14 22:39:04 +08:00
好像不太对…… 再想想去
iloahz
2014-12-14 22:58:48 +08:00
@akagi 对的呀,线性递推取模肯定是有循环节的,当M比较小的时候妥妥可以

@czheo 求通项又不是很麻烦啊,矩阵就是
[1, X1] * [1, B \n 0, A] ^ (n -1) = [1, Xn]嘛,如果你这么鄙视软件公司…那没准就是递推优化优化吧
jiang42
2014-12-14 23:00:57 +08:00
@czheo 可以提供提交的地址么?我去试试

组合数学,用母函数应该可以
akagi
2014-12-15 00:26:02 +08:00
@iloahz 不过考虑到随机数发生器的场景,M通常比较大就是了。

计算时还是通项比较靠谱,
x_2 = a * x_1 + b;
x_3 = a^2 * x_1 + b * a + b;
...
x_k = [ a^k-1 * x_1 + b * (1+a+a^2+...) ];
最后取个余得到结果,前面没影响。另外计算 (a^k-1)%M 和 右侧等比数列 可以用点小技巧,差不多这样。
whalegia
2014-12-15 04:28:24 +08:00
是这样吗?……
https://gist.github.com/whaleee/4a2ae06b6e5ef348c06c

这个输入数字大小有限制吗?感觉这么写没法处理很大的输入……
czheo
2014-12-15 07:50:01 +08:00
@akagi 通项不对吧,怎么证明最后求余和每步求余结果一样?
whalegia
2014-12-15 08:20:34 +08:00
其实我也觉得同项不太对
whalegia
2014-12-15 08:27:15 +08:00
但是我觉得答案里是有循环的,搞个 list 记录一下循环吧?

我去试试
akagi
2014-12-15 09:13:13 +08:00
@czheo


y_n = k * M + c;
y_(n+1) = A * (k * M + c) + B;
y_(n+2) = A^2 * (k * M + c) + A * B + B;
=>
x_n = c;
x_(n+1) = (A * x_n + B) % M;
x_(n+2) = (A * [(A * x_n + B) % M] + B) % M = ...

核心在于求余满足分配率。
czheo
2014-12-15 18:50:36 +08:00
akagi 百度说求余不符合分配律

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/153904

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX