【算法】斐波那契数列与台风的故事

这篇具有很好参考价值的文章主要介绍了【算法】斐波那契数列与台风的故事。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在小岛的一个海滨小镇上,住着一个名叫苏菲的女孩。苏菲一家人靠海为生,她的生活简单而朴素,与大自然和谐共生。每天,苏菲都会来到海边,欣赏那美丽的日出和日落,感受着大海的呼吸。

然而,小岛的美丽风光并非一成不变。每年夏季,热带气旋活跃,台风频繁登陆,给小岛带来了严重的危害。

有一天,苏菲经历了一场猛烈的台风。台风带来的狂风暴雨席卷了整个小镇,树木被连根拔起,房屋倒塌,街道一片狼藉。苏菲的家也被摧毁了,她无家可归,生活陷入了困境。

在台风的影响下,苏菲失去了亲人,她感到孤独和无助。然而,她并没有放弃,她决定勇敢面对生活的挑战。

在台风过后,苏菲积极参与灾后重建工作,帮助邻居们重建家园。她用自己的双手清理废墟、种植树木,为小镇重新带来了生机。

在成长过程中,她遇到了一个气象专家,教会她一些数学知识。她决定要用自己的知识和力量去保护家园,减少自然灾害带来的损失。

她对斐波那契数列有着浓厚的兴趣,在闲暇时会用海滩上的贝壳摆出斐波那契数列的形状。

有一天,苏菲注意到一个有趣的现象:台风的路径似乎与斐波那契数列有关。她开始研究台风的形成和运动原理,发现台风的生命周期与斐波那契数列的规律有着奇妙的联系。

为了更准确地预测台风,苏菲需要处理大量的数据,进行复杂的计算。然而,她意识到传统的计算方法效率低下,无法满足实时预测的需求。于是,她开始寻找更高效的计算方法。

在一次数学课程中,苏菲学到了矩阵乘法的知识,她突然想到可以利用矩阵乘法来降低计算复杂度。她将台风的数据整理成矩阵形式,并利用矩阵乘法的快速幂算法来计算台风的运动轨迹和强度变化。

通过实践,苏菲发现利用矩阵乘法快速幂算法可以将计算复杂度降低到原来的十分之一以下,大大提高了计算效率。她将这种方法应用于台风预测模型中,取得了显著的成果。

苏菲将她的发现告诉了她的老师,得到了赞赏和支持。气象学家们将苏菲的方法应用于更广泛的天气预测中,取得了良好的效果。利用这一发现,政府可以提前做好防灾减灾的准备,减少台风带来的损失。

斐波那契数列的递推公式为:F(n) = F(n-1) + F(n-2),其中F(1) = 1,F(2) = 1。
以10为例,斐波那契数列的前10项为:
2 3 5 8 13 21 34 55

苏菲面临一个问题,当n=2000000的时候,就算用超级计算机来计算也会超时,等运算完毕,台风已经消失了,怎么处理这个问题呢?


算法实现:

 1 public static BigInteger fib(int n)
 2 {
 3     Console.WriteLine(n);  // 打印输入的参数n,用于调试
 4 
 5     BigInteger semn = 1;  // 定义一个BigInteger类型的变量semn,用于存储符号
 6     BigInteger t = 0;  // 定义BigInteger类型的变量t,用于临时存储中间计算结果
 7     BigInteger i = 1;  // 定义BigInteger类型的变量i,初始化为1
 8     BigInteger j = 0;  // 定义BigInteger类型的变量j,初始化为0
 9     BigInteger k = 0;  // 定义BigInteger类型的变量k,初始化为0
10     BigInteger h = 1;  // 定义BigInteger类型的变量h,初始化为1
11 
12     if (n < 0)  // 如果n小于0,表示需要计算负数的斐波那契数
13     {
14         n *= -1;  // 将n取绝对值
15         semn = n % 2 == 0 ? -1 : 1;  // 判断n的绝对值是否为偶数,如果是偶数,semn为-1,否则为1
16     }
17 
18     while (n > 0)  // 当n大于0时,进行循环计算斐波那契数
19     {
20         if (n % 2 != 0)  // 如果n是奇数
21         {
22             t = j * h;  // 计算j乘以h的结果,并赋值给t
23             j = i * h + j * k + t;  // 更新j的值,根据斐波那契数列的递推公式计算
24             i = i * k + t;  // 更新i的值,根据斐波那契数列的递推公式计算
25         }
26         t = h * h;  // 计算h的平方,并赋值给t
27         h = 2 * k * h + t;  // 更新h的值,根据斐波那契数列的递推公式计算
28         k = k * k + t;  // 更新k的值,根据斐波那契数列的递推公式计算
29         n = n / 2;  // 将n除以2,用于控制循环次数
30     }
31 
32     return j * semn;  // 返回计算得到的斐波那契数乘以符号semn,得到最终结果
33 }

这段代码使用了数论中的快速幂算法来计算斐波那契数,通过减少循环次数来降低计算量。让我们以n=2000000为例来解释算法的步骤。

首先,我们初始化变量i、j、h和k的值为0、1、1和0。然后,我们进入循环,当n大于0时,进行迭代计算。

在第一次迭代中,由于n=2000000是一个偶数,我们只需要更新h和k的值。我们计算h的平方并将结果存储在t中,然后更新h的值为2*k*h + t,更新k的值为k*k + t。此时,n被除以2,变为1000000。

在第二次迭代中,由于n仍然是一个偶数,我们再次只需要更新h和k的值。我们计算h的平方并将结果存储在t中,然后更新h的值为2*k*h + t,更新k的值为k*k + t。此时,n被除以2,变为500000。

依此类推,我们继续进行迭代,每次将n除以2,直到n变为1。在这个过程中,我们只需要更新h和k的值,而不需要更新i和j的值。

当n变为1时,我们进行最后一次迭代。由于n是奇数,我们需要更新i和j的值。我们计算j*h的结果并将其存储在t中,然后更新j的值为i*h + j*k + t,更新i的值为i*k + t。

最后,当n变为0时,循环终止。此时,i的值就是斐波那契数列中第2000000个数的值。

通过使用快速幂算法,我们只需要进行log(n)次循环,而不是n次循环,从而大大降低了计算量。在这个例子中,由于n=2000000,我们只需要进行log(2000000) ≈ 21次循环,而不是2000000次循环,从而提高了计算效率。


 

测试用例:

 1 using NUnit.Framework;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Numerics;
 5 
 6 public class FibonacciTest
 7 {
 8 
 9     [Test]
10     public void testFib()
11     {
12         List<int> tests = new List<int> { 0, 1, 2, 3, 4, 5, -6, -96, 1000, 1001 };
13 
14         Random rnd = new Random();
15         for (int i = 0; i < 10; ++i)
16         {
17             tests.Add(rnd.Next(-100, 0));
18         }
19         tests.Add(rnd.Next(10000, 100000));
20         tests.Add(rnd.Next(1000000, 1500000));
21 
22         foreach (int n in tests)
23         {
24             BigInteger found = Fibonacci.fib(n);
25             Assert.AreEqual(FibonacciRef.fib(n), found);
26         }
27     }
28     
29     private static class FibonacciRef
30     {
31         private static IDictionary<int, BigInteger> fibs = new Dictionary<int, BigInteger>();
32 
33         static FibonacciRef()
34         {
35             fibs[0] = BigInteger.Zero;
36             fibs[1] = BigInteger.One;
37             fibs[2] = BigInteger.One;
38             fibs[3] = fibs[2] + fibs[1];
39             fibs[4] = fibs[3] + fibs[2];
40             fibs[5] = fibs[4] + fibs[3];
41         }
42 
43         private static BigInteger calcFib(int n)
44         {
45             BigInteger result;
46             if (fibs.TryGetValue(n, out result))
47                 return result;
48 
49             if ((n & 1) == 1)
50             {
51 
52                 int k = (n + 1) / 2;
53                 BigInteger fk = BigInteger.Pow(calcFib(k), 2);
54                 BigInteger fkm1 = BigInteger.Pow(calcFib(k - 1), 2);
55                 result = fk + fkm1;
56             }
57             else
58             {
59                 int k = n / 2;
60                 BigInteger fk = calcFib(k);
61                 BigInteger fkm1 = calcFib(k - 1);
62                 result = (fkm1 * fibs[3] + fk) * fk;
63             }
64 
65             fibs[n] = result;
66             return result;
67         }
68 
69         public static BigInteger fib(int n)
70         {
71             bool neg = n < 0;
72 
73             if (neg)
74                 n = -n;
75 
76             BigInteger result = calcFib(n);
77 
78             if (neg && (n & 1) == 0)
79                 result = -result;
80 
81             return result;
82         }
83     }
84 }

 文章来源地址https://www.toymoban.com/news/detail-695047.html

到了这里,关于【算法】斐波那契数列与台风的故事的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++算法 —— 动态规划(1)斐波那契数列模型

    每一种算法都最好看完第一篇再去找要看的博客,因为这样会帮你梳理好思路,看接下来的博客也就更轻松了。当然,我也会尽量在写每一篇时都可以让不懂这个算法的人也能边看边理解。 动规的思路有五个步骤,且最好画图来理解细节,不要怕麻烦。当你开始画图,仔细阅

    2024年02月10日
    浏览(44)
  • 一分钟学算法-递归-斐波那契数列递归解法及优化

    一分钟学一个算法题目。 今天我们要学习的是用递归算法求解斐波那契数列。 视频教程链接:https://www.bilibili.com/video/BV1Wu4y1i7JJ/ 首先我们要知道什么是斐波那契数列。 斐波那契数列,又称黄金分割数列,是一个经典的数学数列,其特点是第一项,第二项为1,后面每个数字都

    2024年02月11日
    浏览(48)
  • 递归以及斐波那契数列递归算法和迭代算法的实现与分析

    程序调用自身的编程技巧称为递归( recursion) 递归有两个过程,简单地说一个是 递的过程 ,一个是 归的过程 。 递归的两个必要条件 1. 存在限制条件 ,当满足这个限制条件的时候,递归便不再继续。 2.每次递归调用之后越来越 接近这个限制条件 . 递归本质就是函数调用

    2024年02月12日
    浏览(37)
  • Java数据结构与算法:动态规划之斐波那契数列

    大家好,我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编。在这寒冷的季节里,让我们一同探讨Java中的动态规划,重点关注解决问题的经典代表之一——斐波那契数列。 动态规划简介 动态规划是一种解决问题的数学方法,通常用于优化递归算法。它通过将问

    2024年01月22日
    浏览(47)
  • 线性代数 --- 计算斐波那契数列第n项的快速算法(矩阵的n次幂)

    The n-th term of Fibonacci Numbers:         斐波那契数列的是一个古老而又经典的数学数列,距今已经有800多年了。关于斐波那契数列的计算方法不难,只是当我们希望快速求出其数列中的第100,乃至第1000项时,有没有又准又快的方法,一直是一个值得探讨和研究的问题。笔者

    2024年04月27日
    浏览(44)
  • JAVA-斐波那契数列

    输入一个整数 n ,求斐波那契数列的第 n 项。 假定从 0 开始,第 0 项为 0 。 数据范围 0≤n≤39 样例

    2024年02月10日
    浏览(50)
  • Python斐波那契数列

    斐波那契数列是一个经典的数学问题,在 Python 中可以使用多种方法来实现,下面是几个常见的实现方式: 1. 使用递归 ```python def fibonacci_recursive(n):     if n = 1:         return n     else:         return fibonacci_recursive(n-1) + fibonacci_recursive(n-2) ``` 2. 使用循环 ```python def fibonacci_i

    2024年02月02日
    浏览(44)
  • 斐波那契数列应用2

    目录 斐波那契数列应用2 程序设计 程序分析  系列文章 【问题描述】定义如下序列:f(1)=1,f(2)=1;f(n)=(A*f(n-1)+B*f(n-2))mod7     给定A和B,请你计算f(n)的值。 【输

    2023年04月10日
    浏览(52)
  • c 斐波那契数列输出

    在C语言中,我们可以通过递归或循环的方法来实现斐波那契数列的输出。首先,我们需要明白斐波那契数列的定义:任一项数字是前两项的和(最开始两项均定义为1)。下面是具体的实现方式。 使用递归方法: #include stdio.h int main() {     int m = 0, n = 1, sum;     printf(\\\"请输入

    2024年02月06日
    浏览(45)
  • 斐波那契数列verilog实现

     前言:         该题为睿思芯科笔试题,笔试时长20分钟。         用代码实现斐波那契数列,代码需要对对enable敏感,当enable为高几周期,sum在enble为高的下一周期输出第几个斐波那契数,斐波那契数列的生成是后一个数字是前两个数字之和,如下序列:0、1、1、

    2024年02月13日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包