Ⅰ <演算法圖解>
二分查找、大O分析法;數組和鏈表;遞歸、快速排序;分治、動態規劃、貪婪演算法;散列表(鍵值對組成的數據結構);圖演算法(模擬網路的方法):廣度優先搜索、迪傑斯特拉演算法(計算網路中兩點之間最短距離);K近鄰(KNN,用於創建推薦系統、OCR引擎、預測股價、物件分類)。
二分查找的時間復雜度為log2n,多少個2相乘等於n。
有序數組,定義low和high,非一個元素,猜中,大了,小了。
選擇排序:o(n方),快速排序:o(nlogn),存儲最小的值,存儲最小元素的索引,找出最小的值,加到新數組中。
循環,程序的性能更好,遞歸,程序更容易理解。棧有兩種操作:壓入和彈出。
每個遞歸函數都有兩部分:基線條件和遞歸條件,遞歸條件指的是函數調用自己,基線條件指的是函數不再調用自己,避免無限循環。
編程概念,調用棧,計算機在內部使用被稱為調用棧的棧,遞歸是調用自己的函數。
調用棧可能佔用大量內存,解決方案是編寫循環代碼,或者使用尾遞歸,但並非所有的語言都支持尾遞歸。
分治-遞歸式問題解決辦法:步驟:找出基線條件,確定如何縮小問題的規模,使其符合基線條件。
涉及數組的遞歸函數,基線條件通常是數組為空或只包含一個元素。
快速排序-D&C演算法:步驟:設置基線條件,數組小於2,選擇基準值,將數組分成兩個子數組:小於和大於基準值的元素,對這兩個子數組進行快速排序,遞歸調用。
合並排序:o(nlogn),快速排序:o(nlogn):層數o(logn)乘每層需要的時間o(n),但最差情況為o(n方)。
散列表-基本數據結構之一:內部機制:實現、沖突、散列函數。
散列表無序,數據結構:數組、列表、(棧、不能用於查找)、散列表(包含額外邏輯)。
數組和鏈表都直接映射到內存,但散列表使用散列函數來確定元素存儲位置。
散列函數:不同的輸入映射到不同的索引,輸出不同的數字,散列表是散列函數和數組的結合,也稱散列映射、映射、字典、關聯數組。
緩存的數據存儲在散列表中,訪問頁面時,先檢查散列表是否存儲了頁面。
如果兩個鍵映射到了同一個位置引發沖突,可以在這個位置存儲一個鏈表,好的散列函數可以減少沖突。
填裝因子為散列表元素/位置總數,因子越低,發生沖突的可能性越小,性能越高。
廣度優先搜索(BFS)的含義:解決最短路徑問題的演算法。
步驟:使用圖來建立問題模型,使用廣度優先搜索演算法(是否有路徑,哪個路徑最短)。
所有演算法中,圖演算法是最有用的。
隊列(數據結構):類似於棧,不能隨機訪問隊列中元素,只支持入隊和出隊(壓入和彈出),先加入的先出隊,即先進先出(FIFO),而棧是後進先出(LIFO)。
有向圖:關系是單向的,無向圖:沒有箭頭,直接相連的節點互為鄰居。
拓撲排序:根據圖創建一個有序列表。
迪傑斯特拉演算法:適用於加權圖(提高或降低某些邊的權重),找出加權圖中的最短路徑。
只適用於有向無環圖,如果有負權邊,不能使用迪傑斯特拉演算法,因為演算法假設處理過的節點,沒有前往終點的最短路徑,故,有負權邊的可用貝爾曼-福特演算法。
在未處理的節點找到開銷最小的節點,遍歷當前節點的所有鄰居,如果經當前節點前往該鄰居更近,就更新鄰居開銷,同時將該鄰居的父節點設置為當前節點,將當前節點標記為處理過,找出接下來要處理的節點,並循環。
貪婪演算法:每步都選擇局部最優解,最終就是全局最優解,易於實現,運行快,是個不錯的近似演算法。
集合類似於列表,但是不包含重復的元素。
貪婪演算法:o(n方),NP完全問題:需要計算所有的解,從中選出最小距離,計算量大,最佳做法是使用近似演算法。
動態規劃:約定條件下找到最優解,在問題可分解為彼此獨立且離散的子問題時,就可使用動態規劃來解決。
動態規劃解決方案涉及網路,每個單元格都是子問題,需考慮如何將問題分解為子問題。
最長公共序列。
K最近鄰演算法(KNN):電影推薦系統。
特徵抽取:指標打分,計算距離(相似程度),N維。
KNN的基本工作:分類和回歸。
應用:OCR光學字元識別(optical character recognition),提取線段、點、曲線特徵,找出與新圖像最近的鄰居;語音識別,人臉識別。
垃圾郵件過濾器:樸素貝葉斯分類器。
二叉查找樹(binary search tree):有序樹狀數據結構。
二叉查找樹插入和刪除操作快於有序數組,但不能隨機訪問(沒有索引)。
紅黑樹是處於平衡狀態的特殊二叉樹,不平衡時,如向右傾斜時性能不佳。
B樹是一種特殊的二叉樹。
反向索引:一個散列表,將單詞映射到包含他的頁面,常用於創建搜索引擎。
並行演算法:速度的提升非線性,因為並行性管理開銷和負載均衡。
分布式演算法:特殊的並行演算法,maprece(映射和歸並函數),映射:任務多時自動分配多台計算機完成,將一個數組轉換成另一個數組,歸並是將一個數組轉換成一個元素。
線性規劃:在給定約束條件下最大限度的改善指定指標,使用simplex演算法,圖演算法為線性規劃子集。
Ⅱ Dijkstra演算法時間復雜度
我們可以用大O符號將Dijkstra演算法的運行時間表示為邊數m和頂點數n的函數。
Dijkstra演算法最簡單的實現方法是用一個鏈表或者數組來存儲所有頂點的集合Q,所以搜索Q中最小元素的運算(Extract-Min(Q))只需要線性搜索Q中的所有元素。這樣的話演算法的運行時間是O(n2)。
對於邊數少於n2稀疏圖來說,我們可以用鄰接表來更有效的實現Dijkstra演算法。同時需要將一個二叉堆或者斐波納契堆用作優先隊列來尋找最小的頂點(Extract-Min)。當用到二叉堆的時候,演算法所需的時間為O((m+n)log n),斐波納契堆能稍微提高一些性能,讓演算法運行時間達到O(m + n log n)。相關問題和演算法
在Dijkstra演算法的基礎上作一些改動,可以擴展其功能。例如,有時希望在求得最短路徑的基礎上再列出一些次短的路徑。為此,可先在原圖上計算出最短路徑,然後從圖中刪去該路徑中的某一條邊,在餘下的子圖中重新計算最短路徑。對於原最短路徑中的每一條邊,均可求得一條刪去該邊後子圖的最短路徑,這些路徑經排序後即為原圖的一系列次短路徑。
OSPF(open shortest path first, 開放最短路徑優先)演算法是Dijkstra演算法在網路路由中的一個具體實現。
與Dijkstra演算法不同,Bellman-Ford演算法可用於具有負花費邊的圖,只要圖中不存在總花費為負值且從源點 s 可達的環路(如果有這樣的環路,則最短路徑不存在,因為沿環路循環多次即可無限制的降低總花費)。
與最短路徑問題有關的一個問題是旅行商問題(traveling salesman problem),它要求找出通過所有頂點恰好一次且最終回到源點的最短路徑。該問題是NP難的;換言之,與最短路徑問題不同,旅行商問題不太可能具有多項式時間演算法。
如果有已知信息可用來估計某一點到目標點的距離,則可改用A*演算法,以減小最短路徑的搜索范圍。
Ⅲ dijkstra演算法是什麼
迪傑斯特拉演算法用來解決從頂點v0出發到其餘頂點的最短路徑,該演算法按照最短路徑長度遞增的順序產生所以最短路徑。
對於圖G=(V,E),將圖中的頂點分成兩組:第一組S:已求出的最短路徑的終點集合(開始為{v0})。第二組V-S:尚未求出最短路徑的終點集合(開始為V-{v0}的全部結點)。
堆優化
思考
該演算法復雜度為n^2,我們可以發現,如果邊數遠小於n^2,對此可以考慮用堆這種數據結構進行優化,取出最短路徑的復雜度降為O(1);每次調整的復雜度降為O(elogn);e為該點的邊數,所以復雜度降為O((m+n)logn)。
實現
1、將源點加入堆,並調整堆。
2、選出堆頂元素u(即代價最小的元素),從堆中刪除,並對堆進行調整。
3、處理與u相鄰的,未被訪問過的,滿足三角不等式的頂點
1):若該點在堆里,更新距離,並調整該元素在堆中的位置。
2):若該點不在堆里,加入堆,更新堆。
4、若取到的u為終點,結束演算法;否則重復步驟2、3。
Ⅳ 弗洛伊德與地傑斯特拉演算法的區別
最大的區別是演算法的時間復雜度
弗洛伊德演算法的復雜度最低也是N的三次方 如果是競賽的話你用弗洛伊德很不幸 你會超時
但是地傑斯特拉演算法的復雜度就很低了可以達到期望logn級別 比N的三次方的演算法就快了很多
還有一個區別就是在做最短路問題的時候迪傑斯特拉演算法不適用於邊有負權值的圖
當碰到邊有負權時 你可以選擇SPFA演算法 這是迪傑斯特拉演算法的優化版 對稀疏圖有不錯的效果
順帶一提 SPFA是中國人優化的
Ⅳ 克魯斯卡爾和迪傑斯特拉演算法區別
克魯斯卡爾演算法和迪傑斯特拉演算法是兩種常用的圖演算法,主要區別如下:
1. 目標不同: - 克魯斯卡爾演算法用於求解最小生成樹問題(即連接所有節點的邊的權重之和最小),適用於無向加權圖。 - 迪傑斯特拉演算法用於求解單源最短路徑問題(即從一個源節點到其他所有節點的最短路徑),適用於有向或無向帶權圖。
2. 邊的處理方式不同: - 克魯斯卡爾演算法通過不斷選擇權重最小的邊,並將邊加入最小生成樹中,直到連接所有節點。 - 迪傑斯特拉演算法通過不斷選擇當前距離源節點最近的節點,並更新其鄰居節點的距離,直到求解出所有節點到源節點的最短路徑。
3. 數據結構和時間復雜度不同: - 克魯斯卡爾演算法通常使用並查集來判定邊的兩個節點是否處於同一個連通分量中,時間復雜度為O(ElogE)。 - 迪傑斯特拉演算法通常使用優先隊列(如最小堆)來實現比較和選擇當前距離源節點最近的節點,時間復雜度為O((|V|+|E|)log|V|)。總結來說,克魯斯卡爾演算法解決的是最小生成樹問題,迪傑斯特拉演算法解決的是單源最短路徑問題。兩者的核心思想和操作方式有所不同,適用場景也不同。
Ⅵ Dijkstra演算法
迪傑斯特拉演算法(Dijkstra)是由荷蘭計算機科學家狄克斯特拉在1959年提出的。它是一種求解有權圖中最短路徑的演算法,主要特點是採用貪心演算法的策略,從起始點開始,每次遍歷到距離始點最近且未訪問過的頂點的鄰接節點,直到擴展到終點為止。
迪傑斯特拉演算法求的是單源最短路問題。其實現過程如下:
示例中我們可以發現,這里的迪傑斯特拉演算法只適用於邊權均為正的圖。Dijkstra模板題如下:
給定一個有n個點m條邊的有向圖,圖中可能存在重邊和自環,所有邊權均為正值。請你求出1號點到n號點的最短距離,如果無法從1號點走到n號點,則輸出-1。輸入格式:第一行包含整數n和m。接下來m行每行包含三個整數x,y,z,表示存在一條從點x到點y的有向邊,邊長為z。輸出格式:輸出一個整數,表示1號點到n號點的最短距離。如果路徑不存在,則輸出-1。數據范圍:[公式],[公式],圖中涉及邊長均不超過10000。輸入樣例:3 3 1 2 2 2 3 1 1 3 4 輸出樣例:3
分析:由本題的點和邊的數據范圍可知,這是一個稠密圖,因此使用鄰接矩陣來存儲圖。(樸素Dijkstra正是用來處理稠密圖的)注意:本題有重邊和自環。由於邊權為正,所以自環一定不會在最短路中。而對於重邊,我們存下最短邊即可。
代碼實現:時間復雜度為[公式]。對於稀疏圖(m與n數據范圍接近時),Dijkstra還有另外一種形式:堆優化Dijkstra。優化主要在尋找距離最小的點的操作上。堆有兩種實現方式,之前已經有寫過手寫堆,這里使用另外一種堆的實現方式:優先隊列。由於是稀疏圖,存儲方式需要改成鄰接表形式。其思路和樸素Dijkstra一致。
代碼實現:時間復雜度為[公式]。
以上就是樸素Dijkstra演算法和堆優化Dijkstra演算法。都是用於單源正權邊最短路。未必優化版的就是更好的,樸素版適合稠密度,堆優化版適合稀疏圖。