LRUアルゴリズムのPython実装

LRUアルゴリズムの説明

LRUアルゴリズムを使用すると、実際にデータ構造を設計できます。最初に、容量パラメーターをキャッシュの最大容量として受け取る必要があります。次に、2つのAPIを実装します。1つはキーと値のペアを格納するput(key、val)メソッドで、もう1つはget(key )メソッドはキーに対応するvalを取得し、キーが存在しない場合は-1を返します。

getおよびputメソッドはO(1)時間の複雑さでなければならないことに注意してください。具体的な例を見て、LRUアルゴリズムがどのように機能するかを見てみましょう。

  

/ *キャッシュ容量は2です* / 
LRUCache cache = new LRUCache(2 );
 // キャッシュをキューとして理解できます // 左側がチームの先頭であり、右側がチームの末尾であると想定します /// 最近使用されたキューキューの先頭にあり
 ます
 行末で使用
 // 括弧はキーと値のペア(キー、値)を示します

cache.put( 1、1 );
 // cache = [(1、1 )] 
cache.put( 2、2 );
 // cache = [(2、2)、(1、1 )] 
cache.get( 1); // 1を返す
// cache = [(1、1)、(2、2 )]
 //説明:最近のアクセスのためキー1がなくなっているため、キューの先頭に進みます //キー1に対応する値を返します
 1 
cache.put( 3、3 );
 // cache = [(3、3)、(1、1 )]
 // 説明:キャッシュ容量完全、コンテンツを削除してスペースを確保する必要がある
// 優先度は、長期間使用されていないデータ、つまり、チームの最後のデータを削除し、
 // 新しいデータをキューヘッドに挿入します
cache.get( 2); // -1を返します(見つかりません)
 // cache = [(3、3 )、(1、1 )]
 //説明:キャッシュにキーが2のデータはありません
cache.put( 1、4 );    
 // cache = [(1、4)、(3、3 )]
 //説明:キー1は既に存在します。元の値1から4を上書きします
//キーと値のペアをチームの責任者に渡すことを忘れないでください

 

LRUアルゴリズムの設計

上記の操作プロセスを分析して、putメソッドとgetメソッドの時間の複雑さをO(1)にするために、キャッシュデータ構造の必要な条件をまとめることができます。

最近使用されたデータと長期間使用されたデータを区別するためにキャッシュを順序付ける必要があることは明らかであるため、キーがすでにキャッシュに存在するかどうかを確認する必要があります。容量がいっぱいの場合は、最後のデータを削除する必要があります。データを挿入するたびにチームの頭に。

では、どのデータ構造が上記の条件を同時に満たすのでしょうか?ハッシュテーブルの検索は高速ですが、データの順序は固定されていません。リンクリストには順序があり、挿入と削除は高速ですが、検索は低速です。それらを組み合わせて、新しいデータ構造、ハッシュリンクリストを形成します。

LRUキャッシュアルゴリズムのコアデータ構造は、ハッシュリンクリスト、二重リンクリスト、およびハッシュテーブルの組み合わせです。このデータ構造は次のようになります。

 

 削除操作が必要です。ノードを削除するには、ノード自体のポインターが必要なだけでなく、その先行ノードのポインターも操作する必要があります。また、二重リンクリストは、先行ノードの直接検索をサポートできるため、操作の時間の複雑さが保証されますO(1)。

'' ' 
メソッド1 
クラスLRUCache:
    #@ param capacity、integer 
    def __init __(self、capacity):
        self.cache =()
        self.used_list = [] 
        self.capacity = capacity 
    #@ return integer 
    def get(self、 key):
        if key in self.cache:if 
            リストを使用してアクセスの順序を記録すると、最初にアクセスしたものがリストの前に配置され、最後にアクセスしたものがリストの後ろに配置されるため、キャッシュがいっぱいになると、リストを削除します[0 ]、そして新しいアイテムを挿入します; 
            if key!= Self.used_list [-1]:
                self.used_list.remove(key)
                self.used_list.append(key)
            return self.cache [key] 
        else:
            return -1 
    def put( self、key、value):
        self.cacheのキーの場合:
            self.used_list.remove(key)
        elif len(self.cache)== self.capacity:
            self.cache.pop(self.used_list.pop(0))
        self.used_list.append(key)
        self.cache [key]値= 
「」「
 
#の方法2:
インポートコレクション
 
基づいorderedDict実装
クラスがLRUCache(collections.OrderedDict):
     」「」
    機能:最低使用頻度アルゴリズムcollection.OrdereDictを使用してタイプデータ
    OrdereDict特別な方法popitemを有する(最終= Falseの場合、キューが実装され、最初に挿入された要素ポップされます。Last = Trueの場合、スタックメソッドが実装され、最後に挿入された要素がポップされます。
    2つのメソッドが実装されています:get(キー)はキーの対応する値を取り出し、それがNone 
    set(key、value)を返さない場合、より多くのLRU特性を持ち、要素を追加します
    '' ' 
    def  __init__(self、size = 5):
        Self.sizeは = サイズ
        self.cache = collections.OrderedDict() は、注文した辞書
 
    DEF GET(セルフ、キー):
         IFキーself.cache.keys():
            も同時に訪問来院時に記録しているため番号(オーダー) 
            値= self.cache.pop(キー)
             #の保証リストの最近の訪問は、最終的な表面に常にある 
            self.cache [キー] = 値の
             戻り値は
         、他 = なし
             戻り
 
    DEFのPUT(セルフ、キー、値):
         もしキーself.cache.keys():
            self.cache.pop(キー)
            self.cache [キー] = のelif self.size == LEN(self.cache):
            self.cache.popitem(ラスト = False)が
            自己.cache [キー] = 
            self.cache [キー] = 
 
場合 __name__ == ' __main__ ' 
    試験 = LRUCache()
    test.put(' '、1 
    test.put('b '、2 
    test.put(' c '、3 
    test.put(' d '、4 
    test.put(' e '、5 test.put(' f '、6)
    print(test。 get(' a '))

 

  リファレンス:https : //blog.csdn.net/qq_35810838/article/details/83035759

                    https://labuladong.gitbook.io/algo/gao-pin-mian-shi-xi-lie/lru-suan-fa

 

おすすめ

転載: www.cnblogs.com/cassielcode/p/12723024.html