我想得到Fibonacci序列的第48个元素 我可以存储64位整数。我正在使用一个递归子程序,但它需要永远完成。如果有人能够找到我的递归子程序的问题,我将非常感激。
Integer (Int8) :: n
Integer (Int64) :: fib64
n = Int (48, Int8)
Call fibonacci_genr (fib64, n)
这是我的递归子程序
Recursive &
Subroutine fibonacci_genr &
( &
fb, n &
)
Integer (Int64), Intent (Out) :: fb
Integer (Int8), Intent (In) :: n
Integer (Int64) :: fb1, fb2
If (n < 2) Then
fb = Int (n, Int64)
Else
Call fibonacci_genr (fb1, n-1)
Call fibonacci_genr (fb2, n-2)
fb = fb1 + fb2
End If
End Subroutine fibonacci_genr
答案 0 :(得分:1)
Appologies我不知道fortran我会尽我所能向你展示如何在javascript中加速它并且我在Fortran解决方案中表现最好
ggtern(data = df,aes(x = c,y = a,z = b)) +
stat_density2d(geom = "polygon", n = 400, aes(fill = ..level.., weight = d, alpha = abs(..level..))) +
geom_density2d(aes(weight = d,color = ..level..), n = 400) +
geom_point(aes(fill = d),color = "black",size = 5,shape = 21) +
geom_text(aes(label = id),size = 3) +
labs(x = "X (%)",y = "Y (%)",z = "Z (%)",title = "Title", size = 3) +
scale_fill_gradient2(low = "green", mid = "yellow", high = "red", midpoint = 10) +
scale_color_gradient2(low = "green", mid = "yellow", high = "red", midpoint = 10) +
theme_custom(base_size = 12, base_family = "", col.T = "black", col.L = "black", col.R = "black", col.BG = "white") +
tern_anticlockwise() +
tern_limits(breaks = seq(0.1,1,by = 0.1)) + #AFFECT ALL SCALES
theme(axis.tern.arrowstart = 0.4,axis.tern.arrowfinish = 0.6) +
theme(legend.justification = c(0,1), legend.position = c(0,1)) +
guides(fill = guide_colorbar(order = 1), alpha = guide_legend(order = 2), color = "none") +
labs( title = "Ternary filled contour plot", fill = "Value, V",alpha = "|V - 0|")
这是备忘的fortran
var memo = [];
function fib(n) {
if (memo[n-1]) { //check to see if you already calculated the answer
return memo[n-1];
}
memo[n-1] = n <= 1 ? 1 : fib(n - 1) + fib(n - 2);
return memo[n-1];
}
答案 1 :(得分:1)
鉴于Int8=1
和Int64=8
以及显式接口,gfortran4.7.2抱怨
call fibonacci_genr( fb1, n-1 )
1
Error: Type mismatch in argument 'n' at (1); passed INTEGER(4) to INTEGER(1)
如果实际参数被强制转换为Int8
Call fibonacci_genr (fb1, int( n-1, Int8 ) )
直接使用或Int8
文字(感谢@francescalus)
Call fibonacci_genr (fb1, n - 1_Int8 )
代码似乎工作正常。但我认为使用integer :: n
而不是integer(Int8) :: n
要简单得多,因为n
没有溢出....
BTW我还测量了n = 0
到48
调用此例程的时间。在Xeon2.6GHz(x86_64)+ gfortran4.7.2 -O2上是91秒。如果子程序被函数替换,则时间减少到72秒。为了比较,我还在Julia中尝试了以下代码
function fibo( n::Int ) # Int defaults to Int64
if n <= 1
return n
else
return fibo( n-1 ) + fibo( n-2 )
end
end
for inp = 0:48
println( fibo( inp ) )
end
花了118秒,这对于这次递归非常有用。另一方面,直接迭代(没有递归调用)当然是超快的,只需<0.001秒。
答案 2 :(得分:1)
此解决方案为您提供线性时间的斐波那契数字(调用次数==斐波纳契数字-2,数字1和2只调用1次)。这是通过使用递归函数来完成的,该函数返回序列的两个数字,以便每个调用可以计算下一个数字并重新使用前一个数字作为其返回值。如果你想调用它只接收新的数字,这确实需要一个包装函数,但这是减少递归的一小部分。
以下是功能:
integer(kind=int64) pure function fibonacci(n)
use iso_fortran_env
implicit none
integer, intent(in) :: n
integer(kind=int64), dimension(2) :: fibo
fibo = fib(int(n,int64))
fibonacci = fibo(1)
end function fibonacci
recursive pure function fib(n) result(ret)
use iso_fortran_env
implicit none
integer(kind=int64), intent(in) :: n
integer(kind=int64), dimension(2) :: tmp,ret
if (n == 1_int64) then
ret = [1_int64, 0_int64]
else if (n == 2_int64) then
ret = [1_int64, 1_int64]
else
tmp = fib(n-1)
ret = [sum(tmp), tmp(1)]
end if
end function fib
使用这些函数计算fibonacci(48)
的时间可以忽略不计。
答案 3 :(得分:0)
像这样递归地计算Fibonacci会导致重复计算Recursion vs. Iteration (Fibonacci sequence)。为避免这种情况,请使用迭代算法。
答案 4 :(得分:0)
这是用Python编写的(同样没有FORTRAN)。
def f(a):
if (a < 2):
return a;
return _f(a-2, 2, 1)
def _f(a, n1 , n2) :
if(a==0) :
return n1+n2
return _f(a-1, n1+n2, n1)
每个数字只计算一次而不是多次。 _f是一个私人函数f是你调用的函数,
注意:这仍然是递归的,但只会调用自己48次(N次)