日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

小白的算法初识课堂(part8)--贪婪算法

發(fā)布時(shí)間:2023/12/19 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 小白的算法初识课堂(part8)--贪婪算法 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

學(xué)習(xí)筆記

學(xué)習(xí)書目:《算法圖解》- Aditya Bhargava


文章目錄

      • 教室調(diào)度問(wèn)題
      • 集合覆蓋問(wèn)題
      • 近似算法
        • 代碼實(shí)現(xiàn)
      • NP完全問(wèn)題



教室調(diào)度問(wèn)題


假如我是一個(gè)學(xué)校的校長(zhǎng),我們學(xué)校有如下課程表:

課程開(kāi)始時(shí)間結(jié)束時(shí)間
多元統(tǒng)計(jì)分析9:00AM10:00AM
時(shí)間序列分析9:30AM10:30AM
計(jì)量經(jīng)濟(jì)學(xué)10:00AM11:00AM
數(shù)據(jù)挖掘10:30AM11:30AM
統(tǒng)計(jì)實(shí)驗(yàn)11:00AM12:00PM

我設(shè)法讓這些課程都在安排在教室A001上,但是因?yàn)橛行┱n上課時(shí)間有沖突,所以我們只能盡可多的安排課程在這間教室上。


我們的具體做法如下:

(1) 選出結(jié)束最早的課,它就是要在這間教室上的第一堂課。

(2) 接下來(lái),必須選擇第一堂課結(jié)束后才開(kāi)始的課。同樣,你選擇結(jié)束最早的課,這將是要在這間教室上的第二堂課。

重復(fù)的步驟就能找到正確答案!

由此,在教室A001會(huì)上下面3堂課:

課程開(kāi)始時(shí)間結(jié)束時(shí)間
多元統(tǒng)計(jì)分析9:00AM10:00AM
計(jì)量經(jīng)濟(jì)學(xué)10:00AM11:00AM
統(tǒng)計(jì)實(shí)驗(yàn)11:00AM12:00PM

小伙伴們可能覺(jué)得這個(gè)算法比較簡(jiǎn)單,太顯而易見(jiàn)了!但這正是貪婪算法的優(yōu)點(diǎn)—簡(jiǎn)單易行!貪婪算法很簡(jiǎn)單:每步都采取最優(yōu)的做法。在這個(gè)示例中,我們每次都選擇結(jié)束最早的課。用專業(yè)術(shù)語(yǔ)說(shuō),就是每步都選擇局部最優(yōu)解,最終得到的就是全局最優(yōu)解。

顯然,貪婪算法并非在任何情況下都行之有效,但它易于實(shí)現(xiàn)。


集合覆蓋問(wèn)題


假設(shè)我要在Z國(guó)辦一個(gè)廣播節(jié)目,我想讓Z國(guó)的12個(gè)城市都聽(tīng)到我的節(jié)目。為此,我需要決定在哪些廣播臺(tái)播出,在每個(gè)廣播臺(tái)播出都需要支付一定的費(fèi)用(假設(shè)每個(gè)電臺(tái)費(fèi)用一樣),因此,我力圖在盡可能少的廣播臺(tái)播出,但一定要覆蓋Z國(guó)12個(gè)市。

廣播臺(tái)覆蓋的市
TimA、B、C、G
BlackB、E、G、J、L
AdaD、F、A、K
HuangF、H、I、J
BaiC、H
KetD、E、F、G、K
YellowL、I、A

每個(gè)廣播臺(tái)都覆蓋特定的區(qū)域,不同的廣播臺(tái)覆蓋的區(qū)域可能重疊。

如何找出覆蓋Z國(guó)12個(gè)市的最小廣播電臺(tái)集合呢?

具體方法如下:

(1) 列出每個(gè)可能的廣播臺(tái)集合,這被稱為冪集(power set),可能的子集有2n2^n2n個(gè),其中n為電臺(tái)個(gè)數(shù)。

(2) 在這些集合中,選出覆蓋Z國(guó)12個(gè)市的最小集合。

問(wèn)題是計(jì)算每個(gè)可能的廣播臺(tái)子集需要很長(zhǎng)時(shí)間。由于可能的子集有2n2^n2n個(gè),因此運(yùn)行時(shí)間為O(2n2^n2n)。如果廣播臺(tái)不多,只有5~10個(gè),這是可行的。但如果廣播臺(tái)很多,結(jié)果將如何呢?隨著廣播臺(tái)的增多,需要的時(shí)間將激增。假設(shè)我們每秒可以計(jì)算10個(gè)子集,則所需時(shí)間如下:

廣播電臺(tái)數(shù)量需要的時(shí)間
53.2秒
10102.4秒
3213.6年
1004?10214*10^{21}4?1021

現(xiàn)在,我們沒(méi)有任何算法可以足夠快地解決這個(gè)問(wèn)題,那該咋整呢?


近似算法


在有些情況下,完美是優(yōu)秀的敵人。有時(shí)候,你只需找到一個(gè)能夠大致解決問(wèn)題的算法,此時(shí)貪婪算法正好可派上用場(chǎng),因?yàn)樗鼈儗?shí)現(xiàn)起來(lái)很容易,得到的結(jié)果又與正確結(jié)果相當(dāng)接近。

使用下面的貪婪算法可得到非常接近的解:

(1) 選出這樣一個(gè)廣播臺(tái),即它覆蓋了最多的未覆蓋城市。即便這個(gè)廣播臺(tái)覆蓋了一些已覆蓋的城市,也沒(méi)有關(guān)系。

(2) 重復(fù)第一步,直到覆蓋了所有的城市。

這是一種近似算法(approximation algorithm)。在獲得精確解需要的時(shí)間太長(zhǎng)時(shí),可使用近似算法。判斷近似算法優(yōu)劣的標(biāo)準(zhǔn)如下:速度有多快;得到的近似解與最優(yōu)解的接近程度。

在這個(gè)例子中,貪婪算法的運(yùn)行時(shí)間為O(n2)O(n^2)O(n2),其中n為電臺(tái)個(gè)數(shù)。


代碼實(shí)現(xiàn)


首先,我們先創(chuàng)建一個(gè)集合,里面包含了要覆蓋的12個(gè)城市:

city_needed = set(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L'])

我們?cè)儆蒙⒘斜肀硎緩V播電臺(tái)的清單:

stations = {} stations = {} stations['Tim'] = set(['A', 'B', 'C', 'G']) stations['Black'] = set(['B', 'E', 'G', 'J', 'L']) stations['Ada'] = set(['D', 'F', 'A', 'K']) stations['Huang'] = set(['F', 'H', 'I', 'J']) stations['Bai'] = set(['C', 'H']) stations['Ket'] = set(['D', 'E', 'F', 'G', 'K']) stations['Yellow'] = set(['L', 'I', 'A'])

設(shè)置一個(gè)集合來(lái)存儲(chǔ)最終選擇的廣播電臺(tái):

final_stations = set()

python代碼:

while city_needed:best_station = Nonecity_covered = set()for station, city_for_station in stations.items():covered = city_needed & city_for_stationprint(covered)if len(covered) > len(city_covered):best_station = stationcity_covered = coveredfinal_stations.add(best_station)print(best_station)city_needed -= city_coveredprint(final_stations)

控制臺(tái)輸出:

{'Tim', 'Ada', 'Black', 'Huang'}

NP完全問(wèn)題


集合問(wèn)題屬于NP完全問(wèn)題,在NP完全問(wèn)題中,我們需要計(jì)算所有的解,并從中選出最小/最短的那個(gè)。NP完全問(wèn)題的簡(jiǎn)單定義是,以難解著稱的問(wèn)題,如旅行商問(wèn)題和集合覆蓋問(wèn)題。

NP完全問(wèn)題無(wú)處不在,如果能夠判斷出要解決的問(wèn)題屬于NP完全問(wèn)題就好了,這樣就不用去尋找完美的解決方案,而是使用近似算法即可。但要判斷問(wèn)題是不是NP完全問(wèn)題很難,易于解決的問(wèn)題和NP完全問(wèn)題的差別通常很小。

就比如我們前幾個(gè)Blog討論的最短路徑問(wèn)題,要求我們找出從A出發(fā)到B的最短路徑。但是如果題目要求我們找出經(jīng)由指定幾個(gè)點(diǎn)的最短路徑,那這個(gè)問(wèn)題就變成了旅行商問(wèn)題,也就是NP完全問(wèn)題。簡(jiǎn)而言之,沒(méi)辦法判斷問(wèn)題是不是NP完全問(wèn)題,但是還是可以從一些蛛絲馬跡中判斷的:

  • 元素較少時(shí)算法的運(yùn)行速度非常快,但隨著元素?cái)?shù)量的增加,速度會(huì)變得非常慢。
  • 涉及“所有組合”的問(wèn)題通常是NP完全問(wèn)題。
  • 不能將問(wèn)題分成小問(wèn)題,必須考慮各種可能的情況。
  • 如果問(wèn)題涉及序列(如旅行商問(wèn)題中的城市序列)且難以解決,它可能就是NP完全問(wèn)題。
  • 如果問(wèn)題涉及集合(如廣播臺(tái)集合)且難以解決,它可能就是NP完全問(wèn)題。
  • 如果問(wèn)題可轉(zhuǎn)換為集合覆蓋問(wèn)題或旅行商問(wèn)題,那它肯定是NP完全問(wèn)題。

總結(jié)

以上是生活随笔為你收集整理的小白的算法初识课堂(part8)--贪婪算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。