Fibonacii数列,兔子问题
生活随笔
收集整理的这篇文章主要介绍了
Fibonacii数列,兔子问题
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
Fibonacci数列<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> v Fibonacci背景知识 斐波那契:比萨德列奥纳多,又称斐波那契(Leonardo Pisano ,Fibonacci, Leonardo Bigollo,1175年-1250年),意大利数学家,西方第一个研究斐波那契数,并将现代书写数和乘数的位值表示法系统引入欧洲。 v Fibonacci 引出 斐波那契在《算盘书》中提出了一个有趣的兔子问题:一般而言,兔子在出生两个月后,就有繁殖能力,一对兔子每个月能生出一对小兔子来。如果所有兔都不死,那么一年以后可以繁殖多少对兔子? 我们不妨拿新出生的一对小兔子分析一下:第一个月小兔子没有繁殖能力,所以还是一对;两个月后,生下一对小兔总数共有两对; 三个月以后,老兔子又生下一对,因为小兔子还没有繁殖能力,所以一共是三对; 类推表如下:
{
int []result = new int[]{ 0, 1 };
if(n<2) return result[n];
return Fib1(n-1)+Fib1(n-2);
}
2. 非递归实现(迭代法)
{
int[] result = new int[] { 0, 1 };
if (n < 2) return result[n];
int n1=0,n2=1,retTemp=0;
for (int i = 2; i <=n; i++)
{
retTemp = n1 + n2;
n1 = n2;
n2 = retTemp;
}
return retTemp;
}
2. 创新法(矩阵公式)
{
Debug.Assert(n > 0);
Matrix matrix = new Matrix();
if (n == 1)
{
return matrix=new Matrix(1,1,1,0);
}
if(n%2==0)
{
matrix = MatrixPower(n / 2);
matrix = MatrixMuti(matrix, matrix);
}
if (n % 2 == 1)
{
matrix = MatrixPower((n-1) / 2);
matrix = MatrixMuti(matrix, matrix);
matrix = MatrixMuti(matrix, new Matrix(1, 1, 1, 0));
}
return matrix;
}
利用Fibonacci矩阵恒等式方法就Fibonacci数列: internal class MaxtrixBy
{
public struct Matrix
{
public int m00, m01, m10, m11;
public Matrix(int _m00, int _m01, int _m10, int _m11)
{
m00 = _m00;
m01 = _m01;
m10 = _m10;
m11 = _m11;
}
}
public static Matrix MatrixMuti(Matrix m1, Matrix m2)
{
return new Matrix(m1.m00 * m2.m00 + m1.m10 * m2.m01, m1.m00 * m2.m10 + m1.m10 * m2.m11,
m1.m10 * m2.m00 + m1.m11 * m2.m01, m1.m10 * m2.m00 + m1.m11 * m2.m11);
}
public static Matrix MatrixPower(int n)
{
Debug.Assert(n > 0);
Matrix matrix = new Matrix();
if (n == 1)
{
return matrix=new Matrix(1,1,1,0);
}
if(n%2==0)
{
matrix = MatrixPower(n / 2);
matrix = MatrixMuti(matrix, matrix);
}
if (n % 2 == 1)
{
matrix = MatrixPower((n-1) / 2);
matrix = MatrixMuti(matrix, matrix);
matrix = MatrixMuti(matrix, new Matrix(1, 1, 1, 0));
}
return matrix;
}
public static int Fib3(int n)
{
int[] result = new int[] { 0, 1 };
if(n<2) return result[n];
// MaxtrixBy matrixby=new MaxtrixBy();
Matrix m = MaxtrixBy.MatrixPower(n - 1);
return m.m00;
}
}
3. 运行效率分析
| 经过月数 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 幼仔对数 | 1 | 0 | 1 | 1 | 2 | 3 | 5 | 8 | 13 | 21 | 34 | 55 | 89 |
| 成兔对数 | 0 | 1 | 1 | 2 | 3 | 5 | 8 | 13 | 21 | 34 | 55 | 89 | 144 |
| 总体对数 | 1 | 1 | 2 | 3 | 5 | 8 | 13 | 21 | 34 | 55 | 89 | 144 | 233 |
从一年的总体对数中可以发现,从第二个月开始,其数量是前两个月的数量的和,所以得出递推公式为: F(n)=F(n-1)+F(n-2)(n>=2) (1) v Fibonacci数列的性质 1. F(n)=F(n-1)+F(n-2) 2. 其任意一项平方数为其前项和后项的积加一或者减一 F(n)*F(n)=F(n-1)*F(n+1)+/-1 3.任取相邻的四个斐波那契数,中间两数之积(内积)与两边两数之积(外积)相差1 v Fibonacci数列的程序实现 1. 递归实现 static int Fib1(int n)
{
int []result = new int[]{ 0, 1 };
if(n<2) return result[n];
return Fib1(n-1)+Fib1(n-2);
}
2. 非递归实现(迭代法)
static int Fib2(int n)
{
int[] result = new int[] { 0, 1 };
if (n < 2) return result[n];
int n1=0,n2=1,retTemp=0;
for (int i = 2; i <=n; i++)
{
retTemp = n1 + n2;
n1 = n2;
n2 = retTemp;
}
return retTemp;
}
2. 创新法(矩阵公式)
存在一个Fibonacii的矩阵恒等式,其形式如下所示:
对于F(n)来说,只需要求右边的矩阵的n次幂,然后F(n-1)即为所求结果的第一行第一列的值。 对于右边的矩阵的n次幂可以将n化为: public static Matrix MatrixPower(int n)
{
Debug.Assert(n > 0);
Matrix matrix = new Matrix();
if (n == 1)
{
return matrix=new Matrix(1,1,1,0);
}
if(n%2==0)
{
matrix = MatrixPower(n / 2);
matrix = MatrixMuti(matrix, matrix);
}
if (n % 2 == 1)
{
matrix = MatrixPower((n-1) / 2);
matrix = MatrixMuti(matrix, matrix);
matrix = MatrixMuti(matrix, new Matrix(1, 1, 1, 0));
}
return matrix;
}
利用Fibonacci矩阵恒等式方法就Fibonacci数列: internal class MaxtrixBy
{
public struct Matrix
{
public int m00, m01, m10, m11;
public Matrix(int _m00, int _m01, int _m10, int _m11)
{
m00 = _m00;
m01 = _m01;
m10 = _m10;
m11 = _m11;
}
}
public static Matrix MatrixMuti(Matrix m1, Matrix m2)
{
return new Matrix(m1.m00 * m2.m00 + m1.m10 * m2.m01, m1.m00 * m2.m10 + m1.m10 * m2.m11,
m1.m10 * m2.m00 + m1.m11 * m2.m01, m1.m10 * m2.m00 + m1.m11 * m2.m11);
}
public static Matrix MatrixPower(int n)
{
Debug.Assert(n > 0);
Matrix matrix = new Matrix();
if (n == 1)
{
return matrix=new Matrix(1,1,1,0);
}
if(n%2==0)
{
matrix = MatrixPower(n / 2);
matrix = MatrixMuti(matrix, matrix);
}
if (n % 2 == 1)
{
matrix = MatrixPower((n-1) / 2);
matrix = MatrixMuti(matrix, matrix);
matrix = MatrixMuti(matrix, new Matrix(1, 1, 1, 0));
}
return matrix;
}
public static int Fib3(int n)
{
int[] result = new int[] { 0, 1 };
if(n<2) return result[n];
// MaxtrixBy matrixby=new MaxtrixBy();
Matrix m = MaxtrixBy.MatrixPower(n - 1);
return m.m00;
}
}
3. 运行效率分析
|
| 递归表示 | 迭代法 | 矩阵恒等式 |
| 时间复杂度 | O(2 exp n) | O(n) | O(logn) |
转载于:https://blog.51cto.com/jizhonglee/1151077
总结
以上是生活随笔为你收集整理的Fibonacii数列,兔子问题的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: MySQL数据库备份及二进制文件恢复
- 下一篇: 前台特效(3) 编辑表格