国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

[算法分析與設(shè)計] 2. 斐波那契堆及其應(yīng)用

這篇具有很好參考價值的文章主要介紹了[算法分析與設(shè)計] 2. 斐波那契堆及其應(yīng)用。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

一個優(yōu)先隊列需要支持的操作有

  • insert 插入元素 \(x\)
  • find-min 返回最小的元素。
  • delete-min 刪除最小的元素。
  • decrease-key 將一個元素 \(x\) 減小 \(k\)。\(k \geq 0\)。

常用于實現(xiàn)優(yōu)先隊列的數(shù)據(jù)結(jié)構(gòu)是。

需要注意的是,小根堆需要支持 decrease-key,大根堆需要支持 increase-key。對于一個堆來說兩種操作的難度并不一致。以下均考慮小根堆。

還有一個可能支持的操作

  • meld 合并兩個堆。也叫做 union / merge。

定義 一個堆是一種基于樹的數(shù)據(jù)結(jié)構(gòu),滿足堆性質(zhì)

  • \(A\)\(B\) 的父親,則 \(A\) 的鍵值比 \(B\) 的鍵值小。

一些常見的優(yōu)先隊列實現(xiàn)方法的復(fù)雜度表

操作 鏈表 二叉堆 二項堆 斐波那契堆? Brodal queue
insert \(O(1)\) \(O(\log n)\) \(O(\log n)\) \(O(1)\) \(O(1)\)
delete-min \(O(n)\) \(O(\log n)\) \(O(\log n)\) \(O(\log n)\) \(O(\log n)\)
decrease-key \(O(n)\) \(O(\log n)\) \(O(\log n)\) \(O(1)\) \(O(1)\)
meld \(O(1)\) \(O(n)\) \(O(\log n)\) \(O(1)\) \(O(1)\)
find-min \(O(n)\) \(O(1)\) \(O(1)\) \(O(1)\) \(O(1)\)

delete 能歸約到 decrease-key + delete-min,并且一般不會比這倆優(yōu),所以不單獨寫了。

? 表示均攤復(fù)雜度。

我們先不介紹這些堆,先來看我們有了這些黑盒后如何優(yōu)化一些算法。一般的堆對算法的優(yōu)化是廣為人知的,Brodal queue 的實現(xiàn)又過于復(fù)雜并且只是斐波那契堆的復(fù)雜度變嚴(yán)格,所以接下來的例子均為斐波那契堆的應(yīng)用。

一個著名的例子是對 Dijkstra 算法的優(yōu)化。如果我們用 decrease-key 處理最短路數(shù)組的更新,Dijkstra 會進行 \(n\) 次 delete-min,\(n\) 次 insert,\(m\) 次 decrease-key。使用斐波那契堆可以做到 \(O(m + n \log n)\)。

類似地,Prim 算法會進行 \(n\) 次 delete-min,\(n\) 次 insert,\(m\) 次 decrease-key,因此可以做到 \(O(m + n \log n)\)。但和 Dijkstra 不同的是,這不是最優(yōu)的算法。最小生成樹問題弱于排序問題。

優(yōu)化點在于最小生成樹的割性質(zhì):對于任意的 \(S \subseteq V\),\(S\)\(V \setminus S\) 之間的邊中邊權(quán)最小的那條一定在任一最小生成樹之中。這代表著我們把點集劃分為若干個集合,每個集合作為一個新點,跨越兩個集合的邊連在新點上得到的新圖的最小生成樹也會在舊圖上成立。由此我們可以遞歸。Bor?vka 算法就是這么做的。

我們從一個點開始做 Prim,到堆的大小 \(= k\) 時停止,把涉及到的點與其連出的邊合并為一個新點,再在新圖中找一個沒有被訪問過的點繼續(xù)做 Prim(也需要考慮和新點之間的連邊,否則正確性無法保證),這樣最后每個新點的度數(shù)都 \(\geq k\),因此至多有 \(\frac {2m}k\) 個集合。根據(jù)割性質(zhì),現(xiàn)在舊圖上最小生成樹剩下的邊可以通過求新圖上的最小生成樹得到,因此可以遞歸這個過程。

考慮令 \(k = 2^{\frac {2m}n}\) 則每輪的復(fù)雜度 \(O(m + n \log k) = O(m)\),并且

\[\frac{2m}{n'} \geq k = 2^{\frac{2m}{n}} \]

因此第 \(i\) 輪滿足 \(\log^{(i)} \frac{2m}{n'} \geq \frac {2m}n\),需要的輪數(shù)與 \(\min_i\left\{\log^{(i)} n \leq \frac mn\right\} =: \beta(m, n)\) 同階,因此總復(fù)雜度為 \(O(m \beta(m, n))\)。當(dāng) \(m = O(n)\) 時,復(fù)雜度也可寫為 \(O(m \log^* n)\)

這個算法仍然不是最優(yōu)的。

  • [Karger, Klein, Tarjan '95] \(O(m)\) 的隨機算法。
  • [Chazelle '00] \(O(m\alpha(m, n))\) 的確定性算法。
  • [Pettie, Ramachandran '02] 證明了的最優(yōu)算法,但是復(fù)雜度確界沒有給出,僅知道其在 \(\Omega(m)\)\(O(m \alpha(m, n))\) 中。
  • [Dixon, Rauch, Tarjan '92] \(O(m)\) 驗證一棵樹是否是最小生成樹。

接下來我們來介紹二項堆和斐波那契堆。

二項樹 \(B_n\) 是遞歸定義的一種樹。\(B_0\) 是一個單點,\(B_n\) 把兩棵 \(B_{n-1}\) 的根節(jié)點相連,并把其中一棵的根節(jié)點認(rèn)作新的根節(jié)點。\(|B_n| = 2^n\)。定義 \(B_n\)\(\mathrm{rank}\)\(n\)。

一個二項堆包含若干棵二項樹,滿足每棵樹都滿足堆性質(zhì),且它們的的 \(\mathrm{rank}\) 互不相同。

由于 \(|B_n| = 2^n\),把二項堆的大小 \(m\) 寫成二進制,值為 \(1\) 的那些數(shù)位恰好對應(yīng)一棵二項樹。因此二項堆中樹的棵數(shù)為 \(O(\log m)\)

meld 如果有兩個相同 \(\mathrm{rank}\) 的二項樹,那么可以將兩者合并,將鍵值小的作為新的根節(jié)點,得到一個 \(\mathrm{rank}+1\) 的仍然滿足堆性質(zhì)的二項樹。我們可以將兩個堆的大小 \(m_1, m_2\) 寫成二進制,列豎式做加法,相同數(shù)位的樹便也做加法,進位到下一位上。

每一次合并的復(fù)雜度是 \(O(1)\),因此總復(fù)雜度為 \(O(\log m)\)

insert 將原樹和一個僅包含 \(B_0\) 的樹做 meld。復(fù)雜度為 \(O(\log m)\)。

delete-min 在所有二項樹中找到根節(jié)點鍵值最小的,將其所有兒子和剩下的二項樹做 meld。復(fù)雜度為 \(O(\log m)\)。

find-min 每次 delete-min 的時候維護一下。復(fù)雜度為 \(O(1)\)。

decrease-key 向上冒泡。因為樹深等于其 \(\mathrm{rank}\),復(fù)雜度為 \(O(\log m)\)

斐波那契堆基于二項堆的思路。它的大致想法是,與其每次都嚴(yán)格維護二項樹樹形,不如把需要的點直接從樹上拆下來,直到 delete-min 的時候再重構(gòu),用勢能分析得到均攤復(fù)雜度。

一個斐波那契堆 \(H\) 仍然包含若干棵樹,每一棵樹都是刪去了一些子樹的二項樹。那些被刪去了兒子的點稱為標(biāo)記點。

定義 \(\mathrm{rank}(x)\)\(x\) 的兒子個數(shù)。\(\mathrm{rank}(H) = \max_{x \in H} \mathrm{rank}(x)\)。\(\mathrm{tree}(H)\)\(H\) 擁有的樹的棵數(shù),\(\mathrm{marks}(H)\)\(H\) 的標(biāo)記點的個數(shù)。

insert 直接將一個 \(B_0\) 放入 \(H\)\(\mathrm{tree}(H)\) 加一。

delete-min 將其所有兒子放入 \(H\) 中,并將 \(\mathrm{rank}\) 相同的兩棵樹同二項樹一樣合并,直到?jīng)]有 \(\mathrm{rank}\) 相同的兩棵樹。

decrease-key 如果操作后堆性質(zhì)仍然滿足,不做任何事。否則其鍵值小于父親的鍵值,此時直接將這棵子樹從樹上拆下來,并將其父親設(shè)為標(biāo)記點。如果其父親已經(jīng)為標(biāo)記點,則將這個單點也拆下來,刪去其標(biāo)記,并再次考慮它的父親,循環(huán)這個過程直到一個未被標(biāo)記的點或者根,我們總是不標(biāo)記根。

這么做的動機是,一棵深的樹必須也得是重的。如果刪去了太多兒子,可能會導(dǎo)致其結(jié)點數(shù)很少但是深度很深,從而拖累復(fù)雜度。所以我們雖然允許拆子樹,但只允許一個結(jié)點拆一次,否則這棵子樹就要送去重構(gòu)。在之后的分析中我們會看到滿足條件的最小的樹的節(jié)點個數(shù)呈斐波那契數(shù)列(直觀地,\(|B_n| = |B_{n-1}| + |B_{n-1}| \Rightarrow |B'_n| \geq |B'_{n-1}| + |B'_{n-1\color{red}{-1}}|\)),這也是其名字的由來。

meld 把所有樹放到一起就好了。

接下來進行復(fù)雜度分析和一些實現(xiàn)細節(jié)的描述。

先來考慮形式化上面說的那段話。令 \(F_n\) 表示 \(\mathrm{rank} = n\) 的最小的樹的大小,滿足性質(zhì)

  • \(y_1, \ldots, y_k\) 是結(jié)點 \(x\) 的兒子按照 \(\mathrm{rank}\) 從小到大排序后的序列,則 \(\mathrm{rank}(y_i) \geq \max(0, i - 2)\)。

這條性質(zhì)是一個序列可以對應(yīng)斐波那契堆中一棵樹在某個時候的形態(tài)的充要條件。因為我們總是合并 \(\mathrm{rank}\) 相同的樹,當(dāng) \(x\) 已有 \(y_1, \ldots, y_{i-1}\) 時,稱其為 \(x_i\),合并了 \(y_i\) 則有 \(\mathrm{rank}(y_i) = \mathrm{rank}(x_i) \geq i - 1\),由于 \(y_i\) 至多失去一個孩子,\(\mathrm{rank}(y_i) \geq i - 2\)。而按照這個過程我們也能構(gòu)建出一棵樹與對應(yīng)的拆子樹操作來。

則一個 \(B'_n\) 可以通過某個 \(B'_{n-1}\) 加入第 \(n\) 個兒子得到,即加入某個 \(B'_{n-2}\) 得到,因此有 \(F_n = F_{n-1} + F_{n-2}\),\(F_0 = 1, F_1 = 2\),因此其是斐波那契數(shù)列,滿足 \(F_n \geq \left(\frac{1 + \sqrt 5}2\right)^n\),故樹深總是樹重的 \(\log\)

接下來考慮勢能函數(shù)。有兩個操作需要均攤分析,一個是樹的個數(shù),一個是標(biāo)記的個數(shù),前者在 delete-min 中用到,后者在 decrease-key 向上遞歸時用到。

\(\Phi(H) = \mathrm{tree}(H) + 2 \mathrm{marks}(H)\),之所以要加倍數(shù) \(2\) 是因為將標(biāo)記點拆下來時 \(-\Delta\mathrm{marks}(H) = \Delta\mathrm{tree}(H)\),但我們要統(tǒng)計這部分的實際開銷,如果不加倍數(shù)則勢能不變。因此勢能里兩者要相差一倍,加給誰都可以,但是既然 \(\mathrm{tree}(H)\) 要承擔(dān)更多的操作不如讓它是一倍的那位。

現(xiàn)在開始考慮每個操作的實際開銷與勢能變化。

insert 實際開銷 \(O(1)\),勢能變化 \(+1\),復(fù)雜度 \(O(1)\)。

delete-min 實際開銷 \(O(\mathrm{rank}(H)) + O(\mathrm{tree}(H))\),勢能變化 \(\mathrm{tree}(H') - \mathrm{tree}(H) = O(\mathrm{rank}(H')) - \mathrm{tree}(H)\),均攤復(fù)雜度 \(O(\mathrm{rank}(H)) + O(\mathrm{rank}(H')) = O(\log n)\)。

decrease-key 實際開銷 \(O(c)\),\(c\) 為涉及的標(biāo)記點個數(shù),勢能變化 \(\leq c + 2(-c + 2) = O(1) - c\),均攤復(fù)雜度 \(O(1)\)。需要對兒子維護一個 \(O(1)\) 刪除、線性時間遍歷的數(shù)據(jù)結(jié)構(gòu),一個簡單的實現(xiàn)是雙向循環(huán)鏈表。

meld 如果使用了雙向循環(huán)鏈表那 \(O(1)\) 的合并是簡單的。文章來源地址http://www.zghlxwxcb.cn/news/detail-711661.html

到了這里,關(guān)于[算法分析與設(shè)計] 2. 斐波那契堆及其應(yīng)用的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【算法學(xué)習(xí)】斐波那契數(shù)列模型-動態(tài)規(guī)劃

    【算法學(xué)習(xí)】斐波那契數(shù)列模型-動態(tài)規(guī)劃

    ? ? ? ? 我在算法學(xué)習(xí)過程中,針對斐波那契數(shù)列模型的動態(tài)規(guī)劃的例題進行了一個整理,并且根據(jù)標(biāo)準(zhǔn)且可靠一點的動態(tài)規(guī)劃解題思路進行求解類似的動歸問題,來達到學(xué)習(xí)和今后復(fù)習(xí)的必要。 ? ? ? ? 所謂的斐波那契數(shù)列模型,即當(dāng)前狀態(tài)的值等于前兩種狀態(tài)的值之和。

    2024年02月04日
    瀏覽(27)
  • 【算法】斐波那契數(shù)列與臺風(fēng)的故事

    在小島的一個海濱小鎮(zhèn)上,住著一個名叫蘇菲的女孩。蘇菲一家人靠海為生,她的生活簡單而樸素,與大自然和諧共生。每天,蘇菲都會來到海邊,欣賞那美麗的日出和日落,感受著大海的呼吸。 然而,小島的美麗風(fēng)光并非一成不變。每年夏季,熱帶氣旋活躍,臺風(fēng)頻繁登陸

    2024年02月10日
    瀏覽(24)
  • 【算法】斐波那契數(shù)列通項公式

    【算法】斐波那契數(shù)列通項公式

    如果數(shù)列 a n a_n a n ? 的遞推公式: a n = c 1 a n ? 1 + c 2 a n ? 2 a_n=c_1a_{n-1}+c_2a_{n-2} a n ? = c 1 ? a n ? 1 ? + c 2 ? a n ? 2 ? ------(1) 根據(jù)待定系數(shù)法,假設(shè) a n ? x a n ? 1 = y ( a n ? 1 ? x a n ? 2 ) a_n-xa_{n-1}=y(a_{n-1}-xa_{n-2}) a n ? ? x a n ? 1 ? = y ( a n ? 1 ? ? x a n ? 2 ?

    2023年04月24日
    瀏覽(17)
  • Java與查找算法(3):斐波那契查找

    Java面試資料 Java面試資料,涵蓋:面試前準(zhǔn)備,面試經(jīng)驗,面試真題等 鏈接:Java面試資料,面試準(zhǔn)備、面試題,面試真題 斐波那契查找是一種基于二分查找的查找算法,它使用了斐波那契數(shù)列的特性來確定查找點的位置,從而提高了查找效率。斐波那契查找的時間復(fù)雜度為

    2024年02月06日
    瀏覽(24)
  • 算法:動態(tài)規(guī)劃---斐波那契和最短路徑

    算法:動態(tài)規(guī)劃---斐波那契和最短路徑

    從本篇開始總結(jié)的是動態(tài)規(guī)劃的一些內(nèi)容,動態(tài)規(guī)劃是算法中非常重要的一個版塊,因此也是學(xué)習(xí)算法中的一個重點,在學(xué)習(xí)動態(tài)規(guī)劃前應(yīng)當(dāng)要把動態(tài)規(guī)劃的基礎(chǔ)知識學(xué)習(xí)一下 動態(tài)規(guī)劃既然是一個新的算法,這個名字也是新名字,那么就要首先明確這個算法的名字代表什么含

    2024年01月25日
    瀏覽(23)
  • 【算法系列 | 12】深入解析查找算法之—斐波那契查找

    【算法系列 | 12】深入解析查找算法之—斐波那契查找

    心若有陽光,你便會看見這個世界有那么多美好值得期待和向往。 決定開一個算法專欄,希望能幫助大家很好的了解算法。主要深入解析每個算法,從概念到示例。 我們一起努力,成為更好的自己! 今天第12講,講一下查找算法的—斐波那契查找 斐波那契查找算法是一種

    2024年02月03日
    瀏覽(26)
  • C語言經(jīng)典算法實例6:斐波那契數(shù)列

    C語言經(jīng)典算法實例6:斐波那契數(shù)列

    斐波那契數(shù)列指的是這樣一個數(shù)列:1,1,2,3,5,8,13,21,34,55,89… 這個數(shù)列從第3項開始,每一項都等于前兩項之和。 斐波那契數(shù)列的定義者,是意大利數(shù)學(xué)家萊昂納多·斐波那契(Leonardo Fibonacci),生于公元1170年,卒于1250年,籍貫是比薩。 他被人稱作“比薩的萊昂

    2024年02月02日
    瀏覽(16)
  • C++算法 —— 動態(tài)規(guī)劃(1)斐波那契數(shù)列模型

    C++算法 —— 動態(tài)規(guī)劃(1)斐波那契數(shù)列模型

    每一種算法都最好看完第一篇再去找要看的博客,因為這樣會幫你梳理好思路,看接下來的博客也就更輕松了。當(dāng)然,我也會盡量在寫每一篇時都可以讓不懂這個算法的人也能邊看邊理解。 動規(guī)的思路有五個步驟,且最好畫圖來理解細節(jié),不要怕麻煩。當(dāng)你開始畫圖,仔細閱

    2024年02月10日
    瀏覽(23)
  • 【算法優(yōu)選】 動態(tài)規(guī)劃之斐波那契數(shù)列模型

    動態(tài)規(guī)劃相關(guān)題目都可以參考以下五個步驟進行解答: 狀態(tài)表? 狀態(tài)轉(zhuǎn)移?程 初始化 填表順序 返回值 后面題的解答思路也將按照這五個步驟進行講解。 泰波那契序列 Tn 定義如下: T0 = 0, T1 = 1, T2 = 1, 且在 n = 0 的條件下 Tn+3 = Tn + Tn+1 + Tn+2 給你整數(shù) n,請返回第 n 個泰波那契

    2024年02月05日
    瀏覽(25)
  • 解鎖動態(tài)規(guī)劃:從斐波那契到高效算法

    解鎖動態(tài)規(guī)劃:從斐波那契到高效算法

    ??作者介紹:10年大廠數(shù)據(jù)經(jīng)營分析經(jīng)驗,現(xiàn)任大廠數(shù)據(jù)部門負責(zé)人。 會一些的技術(shù):數(shù)據(jù)分析、算法、SQL、大數(shù)據(jù)相關(guān)、python 歡迎加入社區(qū):碼上找工作 作者專欄每日更新: LeetCode解鎖1000題: 打怪升級之旅 python數(shù)據(jù)分析可視化:企業(yè)實戰(zhàn)案例 備注說明:方便大家閱讀,

    2024年04月15日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包