Go中使用递归和并发的第N个斐波那契数

时间:2018-11-05 01:37:00

标签: go recursion concurrency fibonacci goroutine

The Java Code I'm attempting to translate.我一直试图在 Go 中实现这种获取第n个斐波那契数的java方法,但是我似乎无法让代码超出斐波那契数35它崩溃了。 该方法应该是非常低效的,但不会那么低效以至于无法完成。

package main

import (
    "fmt"
    "time"
)

type Fibonacci struct {
    num    float64
    answer float64
}

func newFibonacci(n float64) *Fibonacci {

    f := new(Fibonacci)
    f.num = n
    c1 := make(chan float64)
    c2 := make(chan float64)

    if f.num <= 1 {
        f.answer = n
    } else {
        go func() {
            fib1 := newFibonacci(n - 1)
            c2 <- fib1.answer
        }()
        go func() {
            fib2 := newFibonacci(n - 2)
            c1 <- fib2.answer   
        }()

        f.answer = <-c2 + <-c1
    }
    close(c1)
    close(c2)

    return f
}

func main() {

    numbers := []float64{30, 35, 36, 37, 38, 39, 40}
    for _, value := range numbers{
        start := time.Now()
        fmt.Println("getting the ", value, " fibonacci number")
        f := newFibonacci(value)
        fmt.Println(f.answer)
        end := time.Now()
        totalTime := end.Sub(start)
        fmt.Println("Fibonacci number: ", value, " took ", totalTime, "\n")
    }

}

3 个答案:

答案 0 :(得分:1)

我建议您对实际启动的goroutine进行数学计算。

您的第一个调用会生成两个goroutine。这些中的每一个都产生另外两个goroutine。产生的goroutine总数为2^1 + 2^2 + 2^3 + ... + 2^n。尽管其中很多会在您到达下面的数字之前退出,但仍然是很多的goroutines。

Sum

答案 1 :(得分:1)

您编写程序创建指数形式的go例程。附带上下文切换延迟。尝试运行有限数量的go例程。请参阅以下我在其中运行它的代码,以获取有限数量的go例程:

Length     Raising factor
6          2
19         1
3          6
11         1 
14         1
8          5

答案 2 :(得分:0)

由于您创建的渠道过多。请在问题相对较小时尝试使用平凡的算法。 下面的程序在n == 45时有效,我猜想在n约为65时也会崩溃。临时fib确实是很难并行运行的问题。

func fib(n int) int {
    if n < 2 {
        return 1
    }
    return fib(n-1) + fib(n-2)
}

func fibP(n int) int {
    //base case
    if n < 25 {
        return fib(n)
    }
    fib2chan := make(chan int)
    go func() {
        fib2chan <- fibP(n - 2)
    }()
    return fibP(n-1) + <-fib2chan
}