`
Deo
  • 浏览: 32080 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Fibonacci数列

阅读更多

斐波纳契数列(Fibonacci Sequence),又称黄金分割数列。

意大利的数学家列昂那多·斐波那契在1202年研究兔子产崽问题时发现了此数列,故又称为“兔子数列”.

设一对大兔子每月生一对小兔子,每对新生兔在出生一个月后又下崽(小兔子长到第三个月后每个月又生一对兔子),假若兔子都不死亡,问每个月的兔子总数为多少?

分析一下:

    第一个月小兔子没有繁殖能力,所以还是一对;

    两个月后,生下一对小兔对数共有两对;

    三个月以后,老兔子又生下一对,因为小兔子还没有繁殖能力,所以一共是三对;现在大兔子有三对,小兔子两对;

    ------

依次类推可以列出下表:

 

    幼仔对数=前月成兔对数

    成兔对数=前月成兔对数+前月幼仔对数

    总体对数=本月成兔对数+本月幼仔对数

    可以看出幼仔对数、成兔对数、总体对数都构成了一个数列。这个数列有关十分明显的特点,那是:前面相邻两项之和,构成了后一项。

用Java实现代码:

 

import java.util.Scanner;

/**
*	Fibonacci
*
* @author weidong.feng
*/
public class Fibonacci {
	public static void main(String[] args){
		Scanner scanner = new Scanner(System.in);
		System.out.print("please input this Fibonacci n:");    
		int n = scanner.nextInt();    // 假设输入为大于0的整数

		// long startTime = System.nanoTime();  // 获取开始时间, 单位纳秒
		long startTime = System.currentTimeMillis();  // 获取开始时间,单位毫秒
		fib2(n);
		
		//for(int i=1; i<=n; i++){
		//	 System.out.println("第 " + i + " 个月的兔子对数是: " + fibonacci2(i));
		//}

		// long endTime = System.nanoTime();  // 获取结束时间, 单位纳秒
		long endTime = System.currentTimeMillis();  // 获取结束时间,单位毫秒
		System.out.println("程序运行时间: " + (endTime - startTime) + "ms");
		
	}

	// 常规算法
	private static void fib(int n){
		double x = 1, y = 1;
		System.out.println("第 1 个 Fibonacci sequence data is: " + x);
		for (int i=1; i<n; i++){
			System.out.println("第 " + (i + 1) + " 个 Fibonacci sequence data is: " + y);
			y = x + y;
			x = y - x;
		}
	}
	
	// 递归方式实现
	/*
	* 时间复杂度为2的n次方
	* 这种方式缺点: 
	*    大量迭代不断消耗栈空间,效率低,甚至可能导致web服务器崩溃;
	*    函数自闭性比较弱(优秀的接口应该对输入输出可能出现的错误信息进行捕捉,并提供清楚明了的处理结果)
	*    很容易出现错误,调试困难。
	* 实际应用中不建议使用这种方式
	*/
	private static double fibonacci(int n){
		if(n<=2) {
			return 1;
		}else {
			return fibonacci(n-1) + fibonacci(n-2);
		}
	}

	// 空间换时间,把计算过的所有数列用数组保存起来,需要用的时候直接查询即可
	// 时间复杂度: ; 空间复杂度: ;
	private static void fib2(int n){
		double arr[] = new double[n];
		arr[0] = arr[1] = 1;
		for(int i=2; i<arr.length; i++){
			arr[i] = arr[i-1] + arr[i-2];
		}
		for(int i=0; i<arr.length; i++){
			System.out.println("第 " + n + " 个Fibonacci数列值是: " + arr[i]);
		}
	}


        // 时间换空间(?还需斟酌优化?)
	private static double fibonacci2(int n){
		double result = 0, temp1 = 0, temp2 = 1;
		for(int i=0; i<=n; i++){
			if(i==0){
				result = temp1;
			}else if(i==1){
				result = temp2;
			}else{
				result = temp1 + temp2;
				if(result < 0){
					result = 0;
					break;
				}
				temp1 = temp2;
				temp2 = result;
			}
		}
		return result;
	}
	
}

 

 

斐波那契数列还有两个有趣的性质:
⒈斐波那契数列中任一项的平方数都等于跟它相邻的前后两项的乘积加1或减1;
⒉任取相邻的四个斐波那契数,中间两数之积(内积)与两边两数之积(外积)相差1.

在数学上,斐波纳契数列以如下被以递归的方法定义:F0=0,F1=1,Fn=F(n-1)+F(n-2)(n>=2,n∈N*)在现代物理、准晶体结构、化学等领域,斐波纳契数列都有直接的应用。

与黄金分割的关系

有趣的是:这样一个完全是自然数的数列,通项公式却是用无理数来表达的。而且当n趋向于无穷大时,后一项与前一项的比值的小数部分越来越逼近黄金分割0.618.

1÷1=1,2÷1=2,3÷2=1.5,5÷3=1.666...,8÷5=1.6,…………,89÷55=1.6181818…,…………233÷144=1.618055…75025÷46368=1.6180339889…...

越到后面,这些比值越接近黄金比.

  证明:

    a[n+2]=a[n+1]+a[n]

    两边同时除以a[n+1]得到:a[n+2]/a[n+1]=1+a[n]/a[n+1]

    若a[n+1]/a[n]的极限存在,设其极限为x

    则lim[n->∞](a[n+2]/a[n+1])=lim[n->∞](a[n+1]/a[n])=x

    所以x=1+1/x  即x&sup2;=x+1

    所以极限是黄金分割比

 

如果你看到有这样一个题目:

   

某人把一个8*8的方格切成四块,拼成一个5*13的长方形,故作惊讶地问你:为什么64=65?

其实就是利用了斐波那契数列的这个性质【任取相邻的四个斐波那契数,中间两数之积(内积)与两边两数之积(外积)相差1.】:5、8、13正是数列中相邻的三项,事实上前后两块的面积确实差1,只不过后面那个图中有一条细长的狭缝,一般人不容易注意到。

 

在杨辉三角中隐藏着斐波那契数列

杨辉三角左对齐,成如图所示排列,将同一斜行的数加起来,即得一数列1、1、2、3、5、8、…



 

相关数学问题

1. 排列组合

    有一段楼梯有10级台阶,规定每一步只能跨一级或两级,要登上第10级台阶有几种不同的走法?

    这就是一个斐波那契数列:

     登上第一级台阶有一种登法;登上两级台阶,有两种登法;登上三级台阶,有三种登法;登上四级台阶,有五种登法……

    1,2,3,5,8,13……所以,登上十级,有89种走法。

 

    类似的,一枚均匀的硬币掷10次,问不连续出现正面的可能情形有多少种?

    答案是(1/√5)*{[(1+√5)/2]^(10+2) - [(1-√5)/2]^(10+2)}=144种

 

2. 数字谜题

三角形的三边关系定理和斐波那契数列的一个联系:

    现有长为144cm的铁丝,要截成n小段(n>2),每段的长度不小于1cm,如果其中任意三小段都不能拼成三角形,则n的最大值为多少?

    分析:由于形成三角形的充要条件是任何两边之和大于第三边,因此不构成三角形的条件就是任意两边之和不超过最大边。截成的铁丝最小为1,因此可以放2个1,第三条线段就是2(为了使得n最大,因此要使剩下来的铁丝尽可能长,因此每一条线段总是前面的相邻2段之和),依次为:1、1、2、3、5、8、13、21、34、55,以上各数之和为143,与144相差1,因此可以取最后一段为56,这时n达到最大为10。

    我们看到,“每段的长度不小于1”这个条件起了控制全局的作用,正是这个最小数1产生了斐波那契数列,如果把1换成其他数,递推关系保留了,但这个数列消失了。这里,三角形的三边关系定理和斐波那契数列发生了一个联系。

 

 

  • 大小: 6.9 KB
  • 大小: 5.7 KB
分享到:
评论
1 楼 kyzaqlx 2015-07-31  
贴一个O(lgN)的算法吧

class Matrix:
    def __init__(self, order):
        self.order = order
        self.data = [([0] * order) for i in range(order)]
        for i in range(order):
            self.data[i][i] = 1

def multiply(a, b):
    order = a.order
    c = Matrix(order)
    for i in range(order):
        for j in range(order):
            value = 0
            for k in range(order):
                value += a.data[i][k] * b.data[k][j]
            
            c.data[i][j] = value
    
    return c

def power(a, n):
    if 0 > n:
        return Matrix()
    
    t = a
    r = Matrix(a.order)
    while 0 != n:
        if 0 != (1&n):
            r = multiply(r, t)
        
        t = multiply(t, t)
        n >>= 1
    
    return r

def fibonacci_power(n):
    if 0 > n:
        return 0
    
    a = Matrix(2)
    a.data[0][1] = 1
    a.data[1][0] = 1
    a.data[1][1] = 0
    
    return power(a, n).data[0][0]

相关推荐

    Fibonacci数列斐波那契数列PPT学习教案.pptx

    "Fibonacci数列斐波那契数列PPT学习教案.pptx" Fibonacci数列是一种非常重要的数学概念,它的应用非常广泛,包括生物学、经济学、计算机科学等领域。下面我们将详细介绍Fibonacci数列的概念、性质和应用。 1. ...

    Labview实现递归:斐波那契数列

    斐波那契数列: 在数学上它以递归的方式进行定义,指这样的一个数列:0、1、1、2、3、5、8、13、21、34、55、89、144……,即前两个数为分别为0和1,从第3项开始,每项的值都等于其前两项之和。斐波那契数列Fib(n)用...

    编写函数f,功能是用递归的方法求斐波那契数列的第n项

    【问题描述】编写函数f,功能是用递归的方法求斐波那契数列的第n项,函数原型为 int f(int n),在主函数中输入一个正整数n,调用函数f求出斐波那契数列的第n项,并在主函数中输出。 斐波那契数列:1,1,2,3,5,8,13,...

    斐波那契数列(前100项).rar

    斐波那契数列是一个经典的数学概念,在计算机科学和编程领域有着广泛的应用。这个数列由0和1开始,后面的每一项数字都是前两项数字的和。换句话说,斐波那契数列的第n项(记作F(n))可以通过F(n-1)和F(n-2)来计算。...

    Fibonacci数列(非递归的函数调用)

    cout 斐波那契数列的第" 项是:" &lt;&lt; fibonacci(n) ; return 0; } ``` 在这个程序中,我们首先检查输入的n值,如果n小于或等于0,则返回0(F0)。如果n等于1,我们直接返回1(F1)。对于n大于1的情况,我们使用一...

    (新课标)2020年高考数学 题型全归纳 斐波那契数列.doc

    斐波那契数列,又称为兔子数列,是由13世纪意大利数学家斐波那契提出的一个数学序列。这个数列的特点是每一项都等于前两项之和,起始的两项为1。具体地,斐波那契数列可以用递归公式表示:F0 = 1, F1 = 1, Fn = Fn-1...

    利用Matlab程序计算斐波那契数列的前一百项

    在这个MATLAB程序中,我们首先定义了斐波那契数列的前两项`fibonacci = [1, 2]`,然后通过`for`循环从第三项开始计算,直到第一百项。在每次循环中,我们使用`fibonacci(k)`存储当前项,它是前两项`fibonacci(k-1)`...

    斐波那契数列-C++代码

    本代码使用C++语言书写,编译环境VS2013。...斐波那契数列(Fibonacci Sequence)又称黄金分割数列,指的是这样一个数列:0、1、1、2、3、5、8、13、21、…… 本代码是练习作品,如有错误或修改,请指正,感谢感谢。

    java实现Fibonacci数列

    根据给定文件的信息,我们可以详细地探讨如何使用Java来实现Fibonacci数列,并通过具体的代码示例来深入了解这一主题。 ### Java实现Fibonacci数列 #### 1. Fibonacci数列简介 Fibonacci数列是一系列数字,其中每...

    非递归实现fibonacci数列

    使用C++非递归实现fibonacci数列,对正在学习算法的同学应该挺有帮助的

    Python实现斐波那契数列

    程序分析:斐波那契数列(Fibonacci sequence),又称黄金分割数列,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、…… 在数学上,费波那契数列是以递归的方法来定义: F0 = 0 (n=0) F1 = 1 (n=1) Fn ...

    一个标注斐波那契数列的指标--K线数量 主图指标通达信指标.doc

    斐波那契数列指标在技术分析中的应用 本文档介绍了一个基于斐波那契数列的指标,用于股票市场的技术分析。该指标结合了指数移动平均线(EMA)和斐波那契数列,旨在帮助投资者更好地分析和预测股票市场的走势。 ...

    斐波那契数列毕业设计论文斐波那契数列的应用本科论文.doc

    斐波那契数列毕业设计论文斐波那契数列的应用本科论文.doc 斐波那契数列是数学中一个非常重要的概念,它自问世以来不断显示出它在数学理论和应用上的重要作用。该数列在现代物理、准晶体结构、生物、交通、化学等...

    斐波那契数列.pdf

    斐波那契数列(Fibonacci sequence)是数学中一个非常著名的数列,其特点是每一项数值都是前两项数值的和。通常情况下,斐波那契数列的第一项为0或1,第二项也为1,后续各项则根据定义递推得到。 **基本形式:** \...

    MIPS汇编实验:斐波那契数列

    在这个"MIPS汇编实验:斐波那契数列"中,我们主要关注的是如何使用C语言和MIPS汇编来实现斐波那契数列的计算,并进行溢出和输入检测。斐波那契数列是由两个前一个数相加得到的数列,通常以0和1开始。 首先,我们看...

    求解fibonacci数列的前20项

    ### Fibonacci数列的基础概念 Fibonacci数列是数学中一个经典的数列,以其独特的性质在计算机科学、数学分析等领域有着广泛的应用。该数列由0和1开始,之后每一项都是前两项的和。即:0, 1, 1, 2, 3, 5, 8, 13, 21,...

    斐波那契数列算法分析.doc

    "斐波那契数列算法分析" 斐波那契数列是一种非常经典的数学概念,它的应用非常广泛,包括算法设计、生物学、经济学等领域。斐波那契数列的定义是:每个数都是前两个数的和,从第三个数开始,每个数都是前面两个数的...

    Fibonacci(斐波那契)数列的JAVA解法

    该序列以意大利数学家 Leonardo Fibonacci 的名字命名,故称为斐波那契数列。该序列的特点是每个数字都是前两个数字的和,以此模式无限延续下去。 下面是斐波那契数列的JAVA解法,包括递归算法、循环算法、数组保存...

    斐波那契数列

    斐波那契数列,又称为兔子数列,是由意大利数学家莱昂纳多·斐波那契在解决关于兔子繁殖问题时引入的一个数学概念。这个数列的特点是每个数字是前两个数字的和,起始的两个数字通常是0和1。用数学公式表示就是:F(0)...

    java代码实现斐波那契数列输出第n个数

    斐波那契数列是计算机科学中一个经典的概念,它在算法设计、数学以及许多其他领域都有广泛应用。斐波那契数列定义如下:第一项和第二项分别为0和1,之后每一项都是前两项之和。用数学公式表示就是F(0) = 0,F(1) = 1...

Global site tag (gtag.js) - Google Analytics