【问题标题】:Fibonacci Range Calculation: C# Approach [duplicate]斐波那契范围计算:C# 方法 [重复]
【发布时间】:2014-01-09 20:52:39
【问题描述】:

我正在研究斐波那契范围计算算法。

我已经尝试过简单的方法 - 增加 for 循环和矩阵相乘,还尝试使用 TaskParallel 和其他 TPL 功能重构它们。

但最简单的(for 循环中的增量)仍然胜过所有其他的。

public static IEnumerable<int> FibonacciSimple(uint x)
    {
        int prev = -1;
        int next = 1;
        for (uint i = 0; i < x; i++)
        {
            int sum = prev + next;
            prev = next;
            next = sum;
            yield return sum;
        }
    }

这是否意味着 CLR 关心所有这些并且没有挑战的空间,或者有什么可以玩的?

【问题讨论】:

  • 您是在问为什么它不能作为并行任务运行得更快?如果是这样,那是由于斐波那契数列的迭代性质。使用变量 next 和 prev(在 for 循环之外)强制执行有效的串行执行。
  • 提到的是最简单最快的。我对可以改进的方式感兴趣
  • 斐波那契不能并行化,除非你提前知道一些相邻的斐波那契数对
  • Binet's 允许您计算斐波那契数,而不是通过 prev + next 而是通过您想要的索引。这可以很容易地并行化。示例实现:en.wikibooks.org/wiki/Algorithm_Implementation/Mathematics/…
  • 此外,指数版本可以轻松并行化。 :-)

标签: c# .net task-parallel-library fibonacci


【解决方案1】:

您是否尝试过使用 LINQ,仅供参考:

int n = 10;
int result = Enumerable.Range(1, n)
                       .Skip(2)
                       .Aggregate(new { Current = 1, Prev = 1 },
                                  (x, index) => new { Current = x.Prev + x.Current, Prev = x.Current })
                       .Current;

比添加AsParallel 后快大约两倍:

int fib2 = Enumerable.Range(1, n)
                     .AsParallel()
                     .Skip(2)
                     .Aggregate(new { Current = 1, Prev = 1 },
                                (x, index) => new { Current = x.Prev + x.Current, Prev = x.Current })
                     .Current;

因为斐波那契计算不容易并行化,它只是增加了线程开销。

【讨论】:

  • 很酷的一个。您能否重新制作它以获取整个序列,而不是最后一个数字?
  • @Elliot,使用 unfolding 可以在单个 LINQ 查询中生成整个序列(无需任何其他辅助方法),但默认情况下不可用。 this article你有很好的解释。
  • 我相信Aggregate() 的这种重载根本无法并行化。
猜你喜欢
  • 2013-03-31
  • 2012-12-03
  • 1970-01-01
  • 2016-09-01
  • 2020-01-18
  • 2017-11-18
  • 1970-01-01
  • 2016-07-29
  • 1970-01-01
相关资源
最近更新 更多