Implementación de Python con algoritmo LRU

Descripción del algoritmo LRU

El algoritmo LRU en realidad le permite diseñar la estructura de datos: primero necesita recibir un parámetro de capacidad como la capacidad máxima de la memoria caché, y luego implementar dos API, uno es el método put (clave, val) para almacenar pares clave-valor, y el otro es obtener (clave ) El método obtiene el valor correspondiente a la clave y devuelve -1 si la clave no existe.

Tenga en cuenta que los métodos get y put deben tener una complejidad de tiempo O (1), tomemos un ejemplo específico para ver cómo funciona el algoritmo LRU.

  

/ * La capacidad de la caché es 2 * / 
LRUCache cache = new LRUCache (2 );
 // Puedes entender la caché como una cola // Suponiendo que la izquierda es la cabeza del equipo, y la derecha es la cola del equipo /// La cola utilizada más recientemente está en la cabeza de la
 cola
 , mucho tiempo Utilizado al final de la línea
 // los paréntesis indican pares clave-valor (clave, val) 

cache.put ( 1, 1 );
 // caché = [(1, 1 )] 
cache.put ( 2, 2 );
 // cache = [(2, 2), (1, 1 )] 
cache.get ( 1); // devuelve 1 
// cache = [(1, 1), (2, 2 )]
 // explicación: debido al acceso reciente La clave 1 se ha ido , así que avance a la cabecera de la cola
 // devuelva el valor correspondiente a la clave 1 1 
cache.put ( 3, 3 );
 // cache = [(3, 3), (1, 1 )]
 // Explique: capacidad de caché Completo, necesita eliminar contenido para hacer espacio
// Prioridad eliminar los datos que no se han utilizado durante mucho tiempo, es decir, los datos al final del equipo
 // y luego insertar los nuevos datos en el encabezado de la cola 
cache.get ( 2); // devuelve -1 (no encontrado)
 // caché = [(3, 3 ), (1, 1 )]
 // Explicación: No hay datos con la clave 2 en caché 
cache.put ( 1, 4 );    
 // caché = [(1, 4), (3, 3 )]
 // Explicación : La clave 1 ya existe, sobrescribe el valor original 1 a 4 
// No olvides llevar el par clave-valor a la cabeza del equipo

 

Diseño de algoritmo LRU

Analizando el proceso de operación anterior, para hacer la complejidad temporal de los métodos de poner y obtener O (1), podemos resumir las condiciones necesarias de la estructura de datos de caché: búsqueda rápida, inserción rápida, eliminación rápida, en orden.

Debido a que está claro que la memoria caché debe ordenarse para distinguir los datos utilizados más recientemente y los que se usaron durante mucho tiempo; y debemos encontrar si la clave ya existe en la memoria caché; si la capacidad está llena, debemos eliminar los últimos datos; cada vez que tengamos que insertar los datos A la cabeza del equipo.

Entonces, ¿qué estructura de datos cumple las condiciones anteriores al mismo tiempo? La búsqueda en la tabla hash es rápida, pero los datos no tienen un orden fijo; las listas vinculadas tienen orden, la inserción y eliminación son rápidas, pero la búsqueda es lenta. Entonces combínelos para formar una nueva estructura de datos: lista enlazada hash.

La estructura central de datos del algoritmo de caché LRU es una combinación de listas enlazadas hash, listas doblemente enlazadas y tablas hash. Esta estructura de datos se ve así:

 

 Se requiere la operación de eliminación. La eliminación de un nodo no solo requiere el puntero del nodo en sí, sino que también debe operar el puntero de su nodo predecesor, y la lista doblemente vinculada puede admitir la búsqueda directa del predecesor, asegurando la complejidad temporal de la operación O (1).

'' ' 
Método uno 
clase LRUCache: 
    # @ capacidad param, un entero 
    def __init __ (self, capacidad): 
        self.cache = () 
        self.used_list = [] 
        self.capacity = capacidad 
    # @ devuelve un entero 
    def get (self, clave): 
        si la clave en self.cache: #Utilice 
            una lista para registrar el orden de acceso, el primero en acceder se coloca delante de la lista y el último en acceder se coloca detrás de la lista, por lo que cuando el caché esté lleno, elimine la lista [0 ], Y luego inserte un nuevo elemento; 
            si 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): 
        si ingresa 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 [clave] valor = 
'' ' 
 
# Segundo método: 
Importar Colecciones 
 
# orderedDict implementado con base 
de clase del LRUCache (collections.OrderedDict):
     ' '' 
    función: tipo de datos utilizando un algoritmo collection.OrdereDict menos usado recientemente 
    OrdereDict tiene un método especial popitem (Últimos = Cuando es falso), se implementa la cola y se abre el primer elemento insertado 
    . Cuando Last = True, se implementa el método de pila y se abre el último elemento insertado. 
    Se implementan dos métodos: get (key) extrae el valor correspondiente en la clave, si no devuelve None 
    set (key, value), tiene más características de LRU y agrega elementos 
    '' ' 
    def  __init__ (self, size = 5): 
        Self.size = tamaño 
        self.cache = collections.OrderedDict () # ordenó diccionario 
 
    DEF GET (Ser, Key):
         SI clave en self.cache.keys ():
             # porque también grabó en la visita de visita vez (por orden) 
            valor = self.cache.pop (clave)
             # garantía de la reciente visita de la lista está siempre en la superficie final 
            self.cache [Key] = valor
             de retorno valor de
         la persona : 
            valor = Ninguno
             de retorno valor 
 
    DEF PUT (Ser, clave, valor ):
         siclave en self.cache.keys (): 
            self.cache.pop (key) 
            self.cache [key] = value
         elif self.size == len (self.cache): 
            self.cache.popitem (last = False) 
            self .cache [clave] = valor
         más : 
            self.cache [clave] = valor 
 
si  __name__ == ' __main__ ' : 
    test = LRUCache () 
    test.put ( ' a ' , 1 ) 
    test.put ( 'b ' , 2 ) 
    test.put ( ' c ' , 3 ) 
    test.put ( ' d ' , 4 ) 
    test.put ( ' e ' , 5 )
     # test.put (' f ', 6) 
    print (prueba. obtener ( ' a ' ))

 

  Referencia: https://blog.csdn.net/qq_35810838/article/details/83035759

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

 

Supongo que te gusta

Origin www.cnblogs.com/cassielcode/p/12723024.html
Recomendado
Clasificación