0

问题的完整上下文可以在此处查看 详细信息

您也可以尝试我的源代码来绘制小数字的递归: Pastebin

我正在以数学方式看待这个问题,它是一个嵌套递归,如下所示:

Function Find(integer n, function func)
If n=1
   For i = 1 to a do func()
Elseif n=2
   For i = 1 to b do func()
Else Find(n-1,Find(n-2,func))

Function Main
   Find(n,funny)

我在没有模运算的 Mathematica 中的实现是:

$IterationLimit = Infinity
Clear[A]

A [a_, b_, f_, 1] := A [a, b, f, 1, p] = (f a);
A [a_, b_, f_, 2] := A [a, b, f, 2, p] = (f b);
A [a_, b_, f_, n_] := 
A [a, b, f, n, p] = (A[a, b, A[a, b, f, n - 2], n - 1]);

这揭示了一般ab的一些不错的输出

A[a, b, funny, 1]
a funny
A[a, b, funny, 2]
b funny
A[a, b, funny, 3]
a b funny
A[a, b, funny, 4]
a b^2 funny
A[a, b, funny, 5]
a^2 b^3 funny
A[a, b, funny, 6]
a^3 b^5 funny

因此,当我们查看调用 Func 的频率时,它看起来像 a^(F(n)) * b^(F(n+1)),其中 F(n) 作为第 n 个斐波那契数。所以我的问题是:我如何获得非常大的斐波那契数模 p,我对此做了很多研究,通读了斐波那契的周期长度,尝试了一些递归:

F(a+b) = F(a+1) * F(b) + F(a)*F(b-1)

但似乎递归深度 (log_2(1.000.000.000) ~=30 ) 将 p 分成两个数字时要多得多,即使是第一次递归也是如此。

a= floor(n/2)
b= ceiling(n/2)

当我有 Fib 数字时,乘法和求幂在我看来应该不是问题。

不幸的是:/

我仍然坚持这个问题。首先计算指数中的斐波那契数并没有正确解决问题,这是我在那里应用的错误数学公式:/

所以我想到了其他计算公式的方法:

(a^(Fibonacci(n-2))*b^(Fibonacci(n-1))) mod p

但是随着斐波那契数变得非常大,我假设必须有一种比计算整个斐波那契数然后使用 BigInteger/BigFloat 应用离散指数函数更简单的方法。有人对我有提示吗,我看不到进一步的进展。谢谢

所以这就是我到目前为止的地方,可能只是我错过的一件小事,所以期待你的回复

谢谢

4

2 回答 2

0

您可能会发现我对计算斐波那契数和卢卡斯数的各种方法的思考很有帮助。在那里,我展示了如何使用基本上为 O(log2(n)) 的递归方案进行计算。它非常适用于大型斐波那契数。而且,如果您将所有这些都以某个小数为模,您甚至不需要使用大整数工具进行计算。即使是巨大的斐波那契数字,这也将是非常快的。下面这个只是中等大小。

fibonacci(10000)
ans =
    33644764876431783266621612005107543310302148460680063906564769974680
081442166662368155595513633734025582065332680836159373734790483865268263
040892463056431887354544369559827491606602099884183933864652731300088830
269235673613135117579297437854413752130520504347701602264758318906527890
855154366159582987279682987510631200575428783453215515103870818298969791
613127856265033195487140214287532698187962046936097879900350962302291026
368131493195275630227837628441540360584402572114334961180023091208287046
088923962328835461505776583271252546093591128203925285393434620904245248
929403901706233888991085841065183173360437470737908552631764325733993712
871937587746897479926305837065742830161637408969178426378624212835258112
820516370298089332099905707920064367426202389783111470054074998459250360
633560933883831923386783056136435351892133279732908133732642652633989763
922723407882928177953580570993691049175470808931841056146322338217465637
321248226383092103297701648054726243842374862411453093812206564914032751
086643394517512161526545361333111314042436854805106765843493523836959653
428071768775328348234345557366719731392746273629108210679280784718035329
131176778924659089938635459327894523777674406192240337638674004021330343
297496902028328145933418826817683893072003634795623117103101291953169794
607632737589253530772552375943788434504067715555779056450443016640119462
580972216729758615026968443146952034614932291105970676243268515992834709
891284706740862008587135016260312071903172086094081298321581077282076353
186624611278245537208532365305775956430072517744315051539600905168603220
349163222640885248852433158051534849622434848299380905070483482449327453
732624567755879089187190803662058009594743150052402532709746995318770724
376825907419939632265984147498193609285223945039707165443156421328157688
908058783183404917434556270520223564846495196112460268313970975069382648
706613264507665074611512677522748621598642530711298441182622661057163515
069260029861704945425047491378115154139941550671256271197133252763631939
606902895650288268608362241082050562430701794976171121233066073310059947
366875

诀窍很简单。只需将第 2 个斐波那契数和卢卡斯数与第 n 个这样的数关联起来。它允许我们向后工作。所以要计算 F(n) 和 L(n),我们需要知道 F(n/2) 和 L(n/2)。显然,只要 n 是偶数,这就会起作用。对于奇数 n,有类似的方案可以让我们递归地向下移动。

为了踢球,我只是修改了上面的工具,接受一个模数。因此,要计算索引为 1e15 的斐波那契数的最后 6 位数字,大约需要 1/6 秒。

tic,[Fn,Ln] = fibonacci(1e15,1000000),toc
Elapsed time is 0.161468 seconds.

Fn =
    546875

Ln =
    328127

注意:在我对递归计算斐波那契数的讨论中,我确实对所需的递归调用数做了一些评论。看到这个数字确实与斐波那契数列本身非常相关。这很容易推导出来。

于 2012-05-03T17:19:56.537 回答
0

如果是关于计算斐波那契数,则有一个非递归、非迭代的公式。它在荷兰维基百科关于斐波那契数的页面上很突出,但在英文页面上却没有那么多。

F(n) = ( ( 1 + sqrt(5) ) ^ n - ( 1- sqrt(5) ) ^ n ) / (2 ^ n * sqrt(5))

http://upload.wikimedia.org/wikipedia/nl/math/1/7/4/1747ee745fbe1fbf10fb3d9de36b8927.png

资料来源: http: //nl.wikipedia.org/wiki/Rij_van_Fibonacci

也许你可以用这个公式做点什么。

于 2012-05-03T10:42:42.193 回答