【算法】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

相关文章
|
1天前
|
负载均衡 算法 调度
负载均衡原理及算法
负载均衡原理及算法
7 1
|
3天前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于有序抖动块截断编码的水印嵌入和提取算法matlab仿真
这是一个关于数字图像水印嵌入的算法介绍。使用MATLAB2022a,该算法基于DOTC,结合抖动和量化误差隐藏,确保水印的鲁棒性和隐蔽性。图像被分为N*N块,根据水印信号进行二值化处理,通过调整重建电平的奇偶性嵌入水印。水印提取是嵌入过程的逆操作,通过重建电平恢复隐藏的水印比特。提供的代码片段展示了从块处理、水印嵌入到噪声攻击模拟及水印提取的过程,还包括PSNR和NC的计算,用于评估水印在不同噪声水平下的性能。
|
4天前
|
Arthas 监控 算法
JVM工作原理与实战(二十五):堆的垃圾回收-垃圾回收算法
JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了垃圾回收算法评价标准、标记清除算法、复制算法、标记整理算法、分代垃圾回收算法等内容。
18 0
JVM工作原理与实战(二十五):堆的垃圾回收-垃圾回收算法
|
5天前
|
机器学习/深度学习 自然语言处理 算法
Python遗传算法GA对长短期记忆LSTM深度学习模型超参数调优分析司机数据|附数据代码
Python遗传算法GA对长短期记忆LSTM深度学习模型超参数调优分析司机数据|附数据代码
|
9天前
|
机器学习/深度学习 自然语言处理 算法
机器学习算法原理与应用:深入探索与实战
【5月更文挑战第2天】本文深入探讨机器学习算法原理,包括监督学习(如线性回归、SVM、神经网络)、非监督学习(聚类、PCA)和强化学习。通过案例展示了机器学习在图像识别(CNN)、自然语言处理(RNN/LSTM)和推荐系统(协同过滤)的应用。随着技术发展,机器学习正广泛影响各领域,但也带来隐私和算法偏见问题,需关注解决。
|
11天前
|
机器学习/深度学习 算法 数据可视化
Matlab决策树、模糊C-均值聚类算法分析高校教师职称学历评分可视化
Matlab决策树、模糊C-均值聚类算法分析高校教师职称学历评分可视化
|
11天前
|
机器学习/深度学习 算法 数据挖掘
【Python机器学习专栏】层次聚类算法的原理与应用
【4月更文挑战第30天】层次聚类是数据挖掘中的聚类技术,无需预设簇数量,能生成数据的层次结构。分为凝聚(自下而上)和分裂(自上而下)两类,常用凝聚层次聚类有最短/最长距离、群集平均和Ward方法。优点是自动确定簇数、提供层次结构,适合小到中型数据集;缺点是计算成本高、过程不可逆且对异常值敏感。在Python中可使用`scipy.cluster.hierarchy`进行实现。尽管有局限,层次聚类仍是各领域强大的分析工具。
|
11天前
|
机器学习/深度学习 算法 前端开发
【Python机器学习专栏】集成学习算法的原理与应用
【4月更文挑战第30天】集成学习通过组合多个基学习器提升预测准确性,广泛应用于分类、回归等问题。主要步骤包括生成基学习器、训练和结合预测结果。算法类型有Bagging(如随机森林)、Boosting(如AdaBoost)和Stacking。Python中可使用scikit-learn实现,如示例代码展示的随机森林分类。集成学习能降低模型方差,缓解过拟合,提高预测性能。
|
1天前
|
算法 数据安全/隐私保护 计算机视觉
基于二维CS-SCHT变换和LABS方法的水印嵌入和提取算法matlab仿真
该内容包括一个算法的运行展示和详细步骤,使用了MATLAB2022a。算法涉及水印嵌入和提取,利用LAB色彩空间可能用于隐藏水印。水印通过二维CS-SCHT变换、低频系数处理和特定解码策略来提取。代码段展示了水印置乱、图像处理(如噪声、旋转、剪切等攻击)以及水印的逆置乱和提取过程。最后,计算并保存了比特率,用于评估水印的稳健性。
|
2天前
|
存储 算法 数据可视化
基于harris角点和RANSAC算法的图像拼接matlab仿真
本文介绍了使用MATLAB2022a进行图像拼接的流程,涉及Harris角点检测和RANSAC算法。Harris角点检测寻找图像中局部曲率变化显著的点,RANSAC则用于排除噪声和异常点,找到最佳匹配。核心程序包括自定义的Harris角点计算函数,RANSAC参数设置,以及匹配点的可视化和仿射变换矩阵计算,最终生成全景图像。