【算法】LFU最近最少使用算法原理分析和编码实战

简介: 【算法】LFU最近最少使用算法原理分析和编码实战

什么是LFU

  • Least Frequently Used 最近最少使用,表示以次数为参考,淘汰一定时期内被访问次数最少的数据
  • 如果数据过去被访问多次,那么将来被访问的频率也更高
  • 比LRU多了一个频次统计,需要时间和次数两个维度进行判断是否淘汰
  • 关键流程
  • 新加入数据插入到队列尾部,需要吧引用计数初始值为 1
  • 当队列中的数据被访问后,对应的元素引用计数 +1,队列按【次数】重新排序,如果相同次数则按照时间排序
  • 当需要淘汰数据时,将排序的队列末尾的数据删除,即访问次数最少
  • c8bbc6efafcf42ed96b57fa902626545.jpg
  • 编码实战
public class LFUCache<K,V> {
    //定义缓存容量
    private  int capacity;
    //定义存储key,value数值
    private Map<K,V> cacheValue;
    //存储key的使用频次
    private Map<K, CacheObj> count;
    //定义构造方法
    public LFUCache(int capacity){
        this.capacity = capacity;
        cacheValue =  new HashMap<>();
        count =  new HashMap<>();
    }
    //存储数据
    public void put(K key, V value) {
        V objValue = cacheValue.get(key);
        if(objValue == null){
            //新元素插入,需要判断是否超过缓存容量大小
            if (cacheValue.size() == capacity) {
                removeElement();
            }
            count.put(key, new CacheObj(key, 1, System.currentTimeMillis()));
        } else {
            addCount(key);
        }
        cacheValue.put(key, value);
    }
    //读取某个key,如果这个key存在就count++
    public V get(K key) {
        V value = cacheValue.get(key);
        //如果key获取的value不为空,则对这个key的使用次数++
        if (value != null) {
            addCount(key);
        }
        return value;
    }
    //删除元素
    private void removeElement() {
        CacheObj cacheObj = Collections.min(count.values());
        cacheValue.remove(cacheObj.getKey());
        count.remove(cacheObj.getKey());
    }
    //更新相关统计频次和时间
    private void addCount(K key) {
        CacheObj cacheObj = count.get(key);
        cacheObj.setCount(cacheObj.getCount()+1);
        cacheObj.setLastTime(System.currentTimeMillis());
    }
    //展示信息
    public void showInfo(){
        cacheValue.forEach((key,value)->{
            CacheObj cacheObj = count.get(key);
            System.out.println("key:"+key+",value:"+value+",count:"+cacheObj.getCount()+",lastTime:"+cacheObj.getLastTime());
        });
    }
    //定义比较对象
    class CacheObj implements Comparable<CacheObj>{
        //定义使用的key
        private K key;
        //定义访问次数
        private int count;
        //定义最后访问的时间
        private long lastTime;
        public K getKey() {
            return key;
        }
        public void setKey(K key) {
            this.key = key;
        }
        public int getCount() {
            return count;
        }
        public void setCount(int count) {
            this.count = count;
        }
        public long getLastTime() {
            return lastTime;
        }
        public void setLastTime(long lastTime) {
            this.lastTime = lastTime;
        }
        //定义构造方法
        public CacheObj(K key, int count, long lastTime) {
            this.key = key;
            this.count = count;
            this.lastTime = lastTime;
        }
        //用于比较大小,如果使用次数一样,则比较时间大小
        @Override
        public int compareTo(CacheObj o) {
            int value = Integer.compare(this.count,o.count);
            return value == 0 ? Long.compare(this.lastTime,o.lastTime): value;
        }
    }
    public static void main(String[] args) {
        LFUCache<String,String> cache = new LFUCache(2);
        cache.put("A","任务A");
        cache.put("A","任务AA");
        cache.showInfo();
        System.out.println("---------");
        String cacheValue = cache.get("A");
        System.out.println(cacheValue);
        cache.showInfo();
        System.out.println("---------");
        cache.put("B","任务B");
        cache.put("B","任务BB");
        cache.showInfo();
        System.out.println("---------");
        //插入新元素,由于a的count是3,b的count是2,所以淘汰了b
        cache.put("C","任务C");
        cache.showInfo();
    }
}


0df754d885b7402397f937978fb0ce5b.jpg

相关文章
|
5天前
|
算法 开发者 Python
惊呆了!Python算法设计与分析,分治法、贪心、动态规划...这些你都会了吗?不会?那还不快来学!
【7月更文挑战第10天】探索编程巅峰,算法至关重要。Python以其易读性成为学习算法的首选。分治法,如归并排序,将大问题拆解;贪心算法,如找零问题,每步求局部最优;动态规划,如斐波那契数列,利用子问题解。通过示例代码,理解并掌握这些算法,提升编程技能,面对挑战更加从容。动手实践,体验算法的神奇力量吧!
26 8
|
4天前
|
算法 搜索推荐 编译器
算法高手养成记:Python快速排序的深度优化与实战案例分析
【7月更文挑战第11天】快速排序是编程基础,以O(n log n)时间复杂度和原址排序著称。其核心是“分而治之”,通过选择基准元素分割数组并递归排序两部分。优化包括:选择中位数作基准、尾递归优化、小数组用简单排序。以下是一个考虑优化的Python实现片段,展示了随机基准选择。通过实践和优化,能提升算法技能。**
8 3
|
5天前
|
算法 Java
Java面试题:解释垃圾回收中的标记-清除、复制、标记-压缩算法的工作原理
Java面试题:解释垃圾回收中的标记-清除、复制、标记-压缩算法的工作原理
13 1
|
5天前
|
算法 Python
决策树算法详细介绍原理和实现
决策树算法详细介绍原理和实现
|
5天前
|
算法 Java 开发者
Java面试题:Java内存探秘与多线程并发实战,Java内存模型及分区:理解Java堆、栈、方法区等内存区域的作用,垃圾收集机制:掌握常见的垃圾收集算法及其优缺点
Java面试题:Java内存探秘与多线程并发实战,Java内存模型及分区:理解Java堆、栈、方法区等内存区域的作用,垃圾收集机制:掌握常见的垃圾收集算法及其优缺点
8 0
|
5天前
|
存储 算法 Java
Java面试题:解释JVM的内存结构,并描述堆、栈、方法区在内存结构中的角色和作用,Java中的多线程是如何实现的,Java垃圾回收机制的基本原理,并讨论常见的垃圾回收算法
Java面试题:解释JVM的内存结构,并描述堆、栈、方法区在内存结构中的角色和作用,Java中的多线程是如何实现的,Java垃圾回收机制的基本原理,并讨论常见的垃圾回收算法
7 0
|
6天前
|
机器学习/深度学习 数据采集 算法
Python基于Lasso特征选择、GM算法和SVR回归算法进行财政收入影响因素分析及预测
Python基于Lasso特征选择、GM算法和SVR回归算法进行财政收入影响因素分析及预测
|
6天前
|
数据采集 算法 搜索推荐
Python基于RFM模型和K-Means聚类算法进行航空公司客户价值分析
Python基于RFM模型和K-Means聚类算法进行航空公司客户价值分析
|
2天前
|
算法 数据安全/隐私保护
基于GA遗传优化算法的Okumura-Hata信道参数估计算法matlab仿真
在MATLAB 2022a中应用遗传算法进行无线通信优化,无水印仿真展示了算法性能。遗传算法源于Holland的理论,用于全局优化,常见于参数估计,如Okumura-Hata模型的传播损耗参数。该模型适用于150 MHz至1500 MHz的频段。算法流程包括选择、交叉、变异等步骤。MATLAB代码执行迭代,计算目标值,更新种群,并计算均方根误差(RMSE)以评估拟合质量。最终结果比较了优化前后的RMSE并显示了SNR估计值。
16 7
|
4天前
|
算法 数据挖掘
MATLAB数据分析、从算法到实现
MATLAB数据分析、从算法到实现