python基于雙向鏈表實(shí)現(xiàn)LFU算法
本文實(shí)例為大家分享了python實(shí)現(xiàn)LFU算法的具體代碼,供大家參考,具體內(nèi)容如下
在第一節(jié)中實(shí)現(xiàn)了雙向鏈表DoubleLinkedList類(lèi),上一節(jié)中基于雙向鏈表實(shí)現(xiàn)了LRU算法,本節(jié)課我們繼續(xù)基于雙向鏈表實(shí)現(xiàn)LFU(Least frequently used 最不經(jīng)常使用)算法。
一、重寫(xiě)Node節(jié)點(diǎn)類(lèi)
構(gòu)建LFUNode類(lèi) 繼承自第一節(jié)中的Node類(lèi),添加freq屬性用來(lái)表示節(jié)點(diǎn)使用頻率
class LFUNode(Node): ? ? def __init__(self, key, value): ? ? ? ? """ ? ? ? ? LFU節(jié)點(diǎn) 增加頻率屬性 ? ? ? ? :param key: ? ? ? ? :param value: ? ? ? ? """ ? ? ? ? self.freq = 0 ? ? ? ? super(LFUNode, self).__init__(key, value)
二、LFU實(shí)現(xiàn)
LFU的實(shí)現(xiàn)除了get和put之外還有一個(gè)私有的__update_freq更新節(jié)點(diǎn)頻率方法,讀寫(xiě)某節(jié)點(diǎn)時(shí)都需要對(duì)該節(jié)點(diǎn)的頻率屬性進(jìn)行更新。除了map之外新增加一個(gè)freq_map來(lái)存儲(chǔ)每個(gè)頻率下的雙向鏈表,當(dāng)達(dá)到最大容量時(shí)移除最小頻率下的頭部的節(jié)點(diǎn)。
class LFUCache(object): ? ? def __init__(self, capacity=0xffffffff): ? ? ? ? """ ? ? ? ? LFU緩存置換算法 最不經(jīng)常使用 ? ? ? ? :param capacity: ? ? ? ? """ ? ? ? ? self.capacity = capacity ? ? ? ? self.size = 0 ? ? ? ? self.map = {} ? ? ? ? self.freq_map = {} ? ? def __update_freq(self, node): ? ? ? ? """ ? ? ? ? 更新節(jié)點(diǎn)頻率 ? ? ? ? :param node: ? ? ? ? :return: ? ? ? ? """ ? ? ? ? freq = node.freq ? ? ? ? # 當(dāng)前節(jié)點(diǎn)所在頻率存在 在當(dāng)前頻率鏈表中移除當(dāng)前節(jié)點(diǎn) ? ? ? ? if freq in self.freq_map: ? ? ? ? ? ? node = self.freq_map[freq].remove(node) ? ? ? ? ? ? # 當(dāng)前頻率鏈表為空時(shí)刪除該頻率鏈表 ? ? ? ? ? ? if self.freq_map[freq].size == 0: ? ? ? ? ? ? ? ? del self.freq_map[freq] ? ? ? ? # 將節(jié)點(diǎn)按照新頻率寫(xiě)入頻率鏈表 ? ? ? ? freq += 1 ? ? ? ? node.freq = freq ? ? ? ? if freq not in self.freq_map: ? ? ? ? ? ? self.freq_map[freq] = DoubleLinkedList() ? ? ? ? self.freq_map[freq].append(node) ? ? ? ? return node ? ? def get(self, key): ? ? ? ? """ ? ? ? ? 獲取元素 ? ? ? ? :return: ? ? ? ? """ ? ? ? ? # 節(jié)點(diǎn)不存在 ? ? ? ? if key not in self.map: ? ? ? ? ? ? return None ? ? ? ? # 節(jié)點(diǎn)存在 更新使用頻率 ? ? ? ? old_node = self.map.get(key) ? ? ? ? new_node = self.__update_freq(old_node) ? ? ? ? self.map[key] = new_node ? ? ? ? return new_node.value ? ? def put(self, key, value): ? ? ? ? """ ? ? ? ? 設(shè)置元素 ? ? ? ? :param key: ? ? ? ? :param value: ? ? ? ? :return: ? ? ? ? """ ? ? ? ? # 節(jié)點(diǎn)已存在 更新頻率 ? ? ? ? if key in self.map: ? ? ? ? ? ? old_node = self.map.get(key) ? ? ? ? ? ? old_node.value = value ? ? ? ? ? ? new_node = self.__update_freq(old_node) ? ? ? ? ? ? self.map[key] = new_node ? ? ? ? else: ? ? ? ? ? ? # 節(jié)點(diǎn)容量達(dá)到上限 移除最小頻率鏈表頭部的節(jié)點(diǎn) ? ? ? ? ? ? if self.size >= self.capacity: ? ? ? ? ? ? ? ? min_freq = min(self.freq_map) ? ? ? ? ? ? ? ? node = self.freq_map[min_freq].pop() ? ? ? ? ? ? ? ? del self.map[node.key] ? ? ? ? ? ? ? ? self.size -= 1 ? ? ? ? ? ? # 構(gòu)建新的節(jié)點(diǎn) 更新頻率 ? ? ? ? ? ? new_node = LFUNode(key, value) ? ? ? ? ? ? new_node = self.__update_freq(new_node) ? ? ? ? ? ? self.map[key] = new_node ? ? ? ? ? ? self.size += 1 ? ? ? ? return new_node ? ? def print(self): ? ? ? ? """ ? ? ? ? 打印當(dāng)前鏈表 ? ? ? ? :return: ? ? ? ? """ ? ? ? ? for freq, link in self.freq_map.items(): ? ? ? ? ? ? print("frequencies: %d" % freq) ? ? ? ? ? ? link.print()
三、測(cè)試邏輯
if __name__ == '__main__': ? ? lfu_cache = LFUCache(4) ? ? lfu_cache.put(1, 1) ? ? lfu_cache.print() ? ? lfu_cache.put(2, 2) ? ? lfu_cache.print() ? ? print(lfu_cache.get(1)) ? ? lfu_cache.print() ? ? lfu_cache.put(3, 3) ? ? lfu_cache.print() ? ? lfu_cache.put(4, 4) ? ? lfu_cache.print() ? ? lfu_cache.put(5, 5) ? ? lfu_cache.print() ? ? print(lfu_cache.get(2)) ? ? lfu_cache.put(4, 400) ? ? lfu_cache.print()
測(cè)試結(jié)果:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Python實(shí)現(xiàn)讀取機(jī)器硬件信息的方法示例
這篇文章主要介紹了Python實(shí)現(xiàn)讀取機(jī)器硬件信息的方法,涉及Python針對(duì)計(jì)算機(jī)注冊(cè)表、操作系統(tǒng)、處理器、網(wǎng)絡(luò)等常見(jiàn)硬件信息讀取操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2018-06-06pip 錯(cuò)誤unused-command-line-argument-hard-error-in-future解決辦法
這篇文章主要介紹了Python包管理器pip安裝軟件時(shí)出現(xiàn)unused-command-line-argument-hard-error-in-future錯(cuò)誤的解決辦法,需要的朋友可以參考下2014-06-06Python的matplotlib繪圖如何修改背景顏色的實(shí)現(xiàn)
這篇文章主要介紹了Python的matplotlib繪圖如何修改背景顏色的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07安裝pycurl報(bào)錯(cuò)Could not run curl-config: &ap
這篇文章主要為大家介紹了安裝pycurl報(bào)錯(cuò)Could not run curl-config: 'curl-config'解決方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12pycharm遠(yuǎn)程連接服務(wù)器調(diào)試tensorflow無(wú)法加載問(wèn)題
最近打算在win系統(tǒng)下使用pycharm開(kāi)發(fā)程序,并遠(yuǎn)程連接服務(wù)器調(diào)試程序,其中在import tensorflow時(shí)報(bào)錯(cuò),本文就來(lái)介紹一下如何解決,感興趣的可以了解一下2021-06-06Python GUI庫(kù)PyQt5圖形和特效樣式QSS介紹
這篇文章主要介紹了Python GUI庫(kù)PyQt5圖形和特效樣式QSS介紹,需要的朋友可以參考下2020-02-02Python?urllib?入門(mén)使用詳細(xì)教程
urllib?庫(kù),它是?Python?內(nèi)置的?HTTP?請(qǐng)求庫(kù),不需要額外安裝即可使用,這篇文章主要介紹了Python?urllib?入門(mén)使用,需要的朋友可以參考下2022-11-11django為Form生成的label標(biāo)簽添加class方式
這篇文章主要介紹了django為Form生成的label標(biāo)簽添加class方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-05-05教你利用PyTorch實(shí)現(xiàn)sin函數(shù)模擬
這篇文章主要給大家介紹了關(guān)于教你利用PyTorch實(shí)現(xiàn)sin函數(shù)模擬的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-01-01C++和python實(shí)現(xiàn)阿姆斯特朗數(shù)字查找實(shí)例代碼
這篇文章主要給大家介紹了關(guān)于C++和python實(shí)現(xiàn)阿姆斯特朗數(shù)字查找的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12