算法之矩陣計算斐波那契數列

算法之矩陣計算斐波那契數列

本節內容

  1. 斐波那契介紹
  2. 普通方式求解斐波那契
  3. 矩陣概念
  4. 矩陣求冪
  5. 矩陣求解斐波那契

1.斐波那契介紹

斐波那契數列有關十分明顯的特點,那是:前面相鄰兩項之和,構成了后一項。即f(n)=f(n-1)+f(n-2),f(0)=0,f(1)=f(2)=1,推導下去f(3)=2,f(4)=3,f(5)=5。。。。。。

2.普通方式求解斐波那契

按照上面提供的推導公式,普通方式求解斐波那契數列代碼如下:

1 def normal(n):
2     a,b,c=0,1,1
3     while n:
4         a,b,c=b,c,b+c
5         n-=1
6     return a

?

使用上面的方式求解第n項斐波那契數列的時間復雜度為O(n),也就是說,時間復雜度隨著n的增長而線性增長。

3.矩陣概念

開始,先來介紹一下矩陣的概念:在數學中,矩陣(Matrix)是一個按照長方陣列排列的復數或實數集合,最早來自于方程組的系數及常數所構成的方陣。

這里不介紹矩陣的各方面知識了,如果那樣的話。。。就是一篇數學筆記了。。。這里只講解矩陣相乘的概念。

矩陣相乘:矩陣相乘最重要的方法是一般矩陣乘積。它只有在第一個矩陣的列數(column)和第二個矩陣的行數(row)相同時才有意義。一般單指矩陣乘積時,指的便是一般矩陣乘積。一個m×n的矩陣就是m×n個數排成m行n列的一個數陣。由于它把許多數據緊湊的集中到了一起,所以有時候可以簡便地表示一些復雜的模型。

設A為m*p的矩陣,B為p*n的矩陣,那么稱m*n的矩陣C為矩陣A與B的乘積,記作C=AB:

4.矩陣求冪

上面已經介紹過了矩陣相乘的概念了,那么,斐波那契該怎么由矩陣標示呢?

從第三項開始,每一項都是前兩項之和。 F(n)=F(n?1)+F(n?2), n?3 把斐波那契數列中 相鄰的兩項F(n)和F(n?1)寫成一個2×1的矩陣。

斐波那契數列用矩陣推導如下:

求F(n)等于求二階矩陣的n - 1次方,結果取矩陣第一行第一列的元素。

問題轉換為二階矩陣的n次冪。

而計算二階矩陣的N次冪運算,由于二階矩陣乘法滿足結合律,這樣,可以快速計算二階矩陣的n次冪運算。

假設A為一個二階矩陣,則A的冪運算滿足下面的條件:

A**6=A**3?A**3

A**7=A**3?A**3?A**1=A**4*A**2*A**1

在這里,我們可以類似地把A看做是二進制中的2,2**7=2**4*2**2*2**1也就是說可以把矩陣的冪轉換成二進制來表示。從而可以將n次冪拆解成長度為logn的二進制數來表示:7=111(二進制)。

這就是快速求二階矩陣的核心方法。

5. 矩陣求解斐波那契

前戲做足了,下面就該秀代碼了。

 1 def multi(a,b):  # 計算二階矩陣的相乘
 2     c=[[0,0],[0,0]]  # 定義一個空的二階矩陣
 3     for i in range(2):
 4         for j in range(2):
 5             for k in range(2):  # 新二階矩陣的值計算
 6                 c[i][j]=c[i][j]+a[i][k]*b[k][j]
 7     return c
 8 
 9 
10 def matrix(n):
11     base=[[1,1],[1,0]]  # 元矩陣,這里可以把元矩陣看做是2**0=1
12     ans=[[1,0],[0,1]]  # 結果矩陣  最開始的結果矩陣也可以看做是1,因為這個矩陣和任意二階A矩陣相乘結果都是A
13     while n:
14         if n&1:  # 取n的二進制的最后一位和1做與運算,如果最后一位是1,則進入if體內部
15             ans=multi(ans,base)  # 如果在該位置n的二進制為1,則計算ans和base矩陣
16         base=multi(base,base)  # base矩陣相乘,相當于初始base矩陣的冪*2
17         n>>=1  # n的二進制往右移一位
18     return ans[0][1]  # 最后獲取到的二階矩陣的[0][1]即f(n)的值

?

最后把例子的完整代碼貼出來:

 1 import time
 2 
 3 
 4 def multi(a,b):
 5     c=[[0,0],[0,0]]
 6     for i in range(2):
 7         for j in range(2):
 8             for k in range(2):
 9                 c[i][j]=c[i][j]+a[i][k]*b[k][j]
10     return c
11 
12 
13 def matrix(n):
14     base=[[1,1],[1,0]]
15     ans=[[1,0],[0,1]]
16     while n:
17         if n&1:
18             ans=multi(ans,base)
19         base=multi(base,base)
20         n>>=1
21     # for i in range(2):
22     #     print(ans[i])
23     return ans[0][1]
24 
25 def normal(n):
26     a,b,c=0,1,1
27     while n:
28         a,b,c=b,c,b+c
29         n-=1
30     return a
31 
32 n=int(input(">>>"))
33 start=time.time()
34 print("Normal:",normal(n))
35 print("use:",time.time()-start)
36 start=time.time()
37 print("Matrix:",matrix(n))
38 print("use:",time.time()-start)
39 #計算結果
40 >>>65536
41 Normal: 731992144602......
42 use: 0.07219505310058594
43 Matrix: 731992144602......
44 use: 0.023076772689819336

?

可以看出來當n的值越來越大的時候,兩種方式計算出結果的時間差距將越來越大,正常的計算時間復雜度是O(n),矩陣求值的時間復雜度是O(logn)。

后記:

由此可以看出,使用推導式f(n)=f(n-1)+f(n-2)求斐波那契的第n項的算法復雜度極限為O(n),這是一維世界下的極限。將其從一維上升到二維,用二階矩陣推導斐波那契數列時,計算的算法復雜度為O(logn),也就是說,使用升維的手段將一維空間進行扭曲從而將距離縮短,可以更快的計算出結果。

由此推導出如果人來要突破光速的極限,需要將現有的三維空間升級到四維空間,扭曲空間從而縮短距離,達到突破光速的目的。

轉載于:https://www.cnblogs.com/huxianglin/p/5995649.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/260273.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/260273.shtml
英文地址,請注明出處:http://en.pswp.cn/news/260273.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python中去除字符串中首尾空格的函數_Python中去除字符串首尾特定字符的函數:strip()...

Python中strip()函數的作用是去除一個字符串前導和尾部的特定字符,并返回結果字符串。Python中strip()函數默認是刪除字符串前導和尾部空格,通過設定參數,也可以去除字符串前導和尾部的其它特定字符。strip()函數的語法格式str.strip( [ char…

SeekBar和RatingBar

1. SeekBar的主要屬性 2. OnSeekBarChangeListener 3. RatingBar的主要屬性 4. OnRatingBarChangeListener 1. SeekBar的主要屬性 2. OnSeekBarChangeListener 1 <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"2 xmlns:tools&qu…

用“Web的思想”做PC客戶端

一直在想&#xff0c;用HTML搭建前端頁面這么方便&#xff0c;而且效果這么炫&#xff0c;為什么在PC端的軟件要如此麻煩呢&#xff1f;就連C#也是&#xff0c;更何況C了。 盡管C有DirectUI這樣優秀的圖形庫&#xff0c;但是開發起來仍然非常吃力。C#的WPF雖然工具鏈完善&#…

Java點擊按鈕div縮放_[Java教程]怎樣給div增加resize事件

[Java教程]怎樣給div增加resize事件0 2016-10-31 11:00:04當瀏覽器窗口被調整到一個新的高度或寬度時&#xff0c;就會觸發resize事件,這個事件在window上面觸發,那么如何給div元素增加resize事件&#xff0c;監聽div的高度或寬度的改變呢&#xff1f;某位大神用jquery實現的方…

python判斷題題庫大數據技術_智慧樹_大數據分析的python基礎_搜題公眾號

智慧樹_大數據分析的python基礎_搜題公眾號更多相關問題社會公眾可以查閱煙草專賣行政主管部門的監督檢查記錄。()公民、法人或者其他組織不得利用自動售貨機銷售煙草制品。()煙草廣告中不得有下列情形()。A、社會公益廣告B、遷址、換房、更名等啟事廣告C、表示吸煙有利人體健公…

Java并發中常用同步工具類

為什么80%的碼農都做不了架構師&#xff1f;>>> 同步工具類可以是任何一個對象&#xff0c;只要它根據其自身的狀態來協調線程控制流。阻塞隊列&#xff08;BlockingQueue&#xff09;可以作為同步工具類&#xff0c;其他類型的同步工具類還包括信號量&#xff08;…

Linux平臺Oracle多個實例啟動說明

環境說明:oracle實例1的SID為orcl(為默認啟動的實例),第二個實例的SID為orcl2 啟動步驟&#xff1a; 1&#xff09;啟動數據庫實例完成后&#xff0c;啟動數據庫監聽服務 #lsnrctl start 2&#xff09;切換到需要啟動的數據庫實例下&#xff0c;如下表示啟動的是orcl數據庫…

RTMP協議發送H.264編碼及AAC編碼的音視頻,實現攝像頭直播

RTMP協議發送H.264編碼及AAC編碼的音視頻&#xff0c;實現攝像頭直播 摘要: RTMP協議發送H.264編碼及AAC編碼的音視頻&#xff0c;實現攝像頭直播  RTMP&#xff08;Real Time Messaging Protocol&#xff09;是專門用來傳輸音視頻數據的流媒體協議&#xff0c;最初由Macrome…

java消息順序執行_Apache Flink:如何并行執行但保持消息順序?

請在下面找到使用側輸出和插槽組進行本地擴展的示例 .package org.example/** Licensed to the Apache Software Foundation (ASF) under one* or more contributor license agreements. See the NOTICE file* distributed with this work for additional information* regardi…

python的字符串定界符可以使用_使用Template格式化Python字符串的方法

對Python字符串&#xff0c;除了比較老舊的%&#xff0c;以及用來替換掉%的format&#xff0c;及在python 3.6中加入的f這三種格式化方法以外&#xff0c;還有可以使用Template對象來進行格式化。from string import Template&#xff0c;可以導入Template類。實例化Template類…

【ES實戰】ES6.7的tar包離線安裝幫助手冊

Elasticsearch6.7部署幫助手冊 校驗時間&#xff1a;2023年12月19日 文章目錄 Elasticsearch6.7部署幫助手冊安裝前準備安裝包安裝要求鎖定內存,修改最大文件描述符,最大線程數內核參數 部署規劃端口規劃用戶規劃目錄規劃 安裝步驟每個服務器配置JDK配置文件master角色node角色…

jenkins 部署文檔

Jenkins是一個非常出色的持續集成服務器&#xff0c;本文主要介紹在CentOS系統中Jenkins的基本安裝配置方法&#xff0c;供參考。一. 軟件包&#xff1a;1. 下載apache-maven-2.2.1-bin.tarhttp://www.apache.org/dyn/closer.cgi/maven/binaries/apache-maven-2.2.1-bin.tar.gz…

牛人,多看看他們寫的東西

計算機大師 Donald E. Knuth&#xff08;高德納&#xff09; 算法大師&#xff0c;我最崇拜的計算機科學家&#xff0c;沒有之一&#xff01;不認識高爺爺的人別說自己是學計算機的。《The Art of Computer Programming》絕對是計算機科學的圣經。對高爺爺的崇敬&#xff0c;對…

System.Math.Min(System.Threading.Interlocked.Increment(i), i - 1)

System.Math.Min(System.Threading.Interlocked.Increment(i), i - 1) 在vb里面 等價于ii-1 在C#里面 等價于i-- 是有C#自動轉VB時轉換的轉載于:https://www.cnblogs.com/YaDi/archive/2012/11/08/2759802.html

java快速查找中位數_用QuickSort快速查找中位數(median)

中位數(median)是一個排好序的元素中中間位置的元素&#xff0c;如果元素個數為偶數&#xff0c;則是中間兩個元素的平均值。例如(3,1,5)的中位數是3&#xff0c;而(2,1,3,5)的中位數是2.5。查找中位數屬于SelectionAlgorithms的一種。用快速排序可以做到每次divide之后&#x…

python安裝mysql數據庫_windows10安裝mysql-8.0.13(zip安裝)~Python安裝mysql

windows10安裝mysql-8.0.13(zip安裝)安裝環境說明系統版本&#xff1a;windows10mysql版本&#xff1a;mysql-8.0.13-winx64.zip下載地址&#xff1a;http://mirrors.163.com/mysql/Downloads/MySQL-8.0/mysql-8.0.13-winx64.zip解壓安裝包解壓路徑&#xff1a;D:\develop\soft…

centos 下使用sublime

CentOS 之 Sublime text3 安裝及配置&#xff08;不支持中文輸入&#xff09; sublime text 的界面友好&#xff0c;自動補全功能也不錯。 &#xff08;本來用vimphp_function.txt的形式進行補全的&#xff0c;但是配置后的補全不太滿意&#xff0c;放棄了。 具體參見&#xff…

20121108團隊博客(蘇若)

PS&#xff1a;這本是屬于昨晚的帖子&#xff0c;對不住忠仔。現在補上。 忠仔&#xff0c;終于交給了我一個實實在在的任務&#xff0c;很是欣喜&#xff0c;也很是忐忑&#xff0c;生怕自己不能及時完成任務。 好了&#xff0c;廢話不多說&#xff0c;步入正題。 接下任務【畫…

python 倒排索引 性能_python 實現倒排索引的方法

代碼如下&#xff1a;#encoding:utf-8fin open(1.txt, r)建立正向索引:“文檔1”的ID > 單詞1&#xff1a;出現位置列表&#xff1b;單詞2&#xff1a;出現位置列表&#xff1b;…………“文檔2”的ID > 此文檔出現的關鍵詞列表。forward_index {}for line in fin:line…

pythonnet下載_Python for .NET

Python for .NET 是一個可以讓 Python 程序員近乎無縫的集成 .NET 通用語言環境 CLR 和以及為 .NET 開發者提供一個強大的應用腳本工具。通過這個項目你可在 .NET 中完全使用 Python 來編寫整個應用&#xff0c;使用 .NET 服務和組件。這個包并沒有用 CLR 語言實現一個 Python&…