算法学习之——LRU最近最少使用

LRU缓存算法c++实现     在如今的项目开发中,缓存是一种必不可少的存储方式,目前在各种后台开发中,比较常见的一种缓存算法就是LRU了,LRU名为最近最少使用算法。它会将最近不常用的缓存数据淘汰掉,是一种Cache替换算法。      本文通过c++简单的实现这种算法,代码不长,但能很好的体现这种思想      思路:  map  存储数据 ,实现查找效率O(1),双向链表实现算法逻辑      算法逻辑: 1.... 阅读详情
概念

LRU (Least Recently Used-最近最少使用)​​ 是一种常见的缓存淘汰算法,其核心思想是:当缓存空间不足时,优先淘汰​​最久未被使用​​的数据。它基于"局部性原理"——最近被访问的数据未来更可能被再次访问。

核心特点
  1. ​​有序性​​:维护数据项的访问顺序
  2. ​​快速访问​​:需要快速查找、插入和删除
  3. ​​淘汰机制​​:缓存满时删除最久未使用的数据
时间复杂度要求
  • 查找操作:O(1)
  • 插入操作:O(1)
  • 删除操作:O(1)
实现方案

使用 ​​双向链表 + 哈希表​​ 的组合:

  • ​​双向链表​​:维护访问顺序(头节点存放最近访问,尾节点存放最久未访问)
  • ​​哈希表​​:提供O(1)的键值查找能力
Java代码实现示例
import java.util.HashMap;
import java.util.Map;

public class LRUCache<K, V> {
    // 双向链表节点
    class Node {
        K key;
        V value;
        Node prev;
        Node next;
        
        Node() {}
        Node(K key, V value) {
            this.key = key;
            this.value = value;
        }
    }
    
    // 缓存容量
    private final int capacity;
    // 哈希表用于快速查找
    private final Map<K, Node> cache;
    // 链表头尾指针
    private final Node head, tail;
    // 当前缓存大小
    private int size;
    
    public LRUCache(int capacity) {
        this.capacity = capacity;
        this.size = 0;
        cache = new HashMap<>();
        
        // 创建虚拟头尾节点(哨兵节点)
        head = new Node();
        tail = new Node();
        head.next = tail;
        tail.prev = head;
    }
    
    // 获取数据
    public V get(K key) {
        Node node = cache.get(key);
        if (node == null) return null;
        
        // 移动到链表头部(表示最近使用)
        moveToHead(node);
        return node.value;
    }
    
    // 添加数据
    public void put(K key, V value) {
        Node node = cache.get(key);
        
        if (node != null) {
            // 键已存在:更新值并移到头部
            node.value = value;
            moveToHead(node);
        } else {
            // 键不存在:创建新节点
            Node newNode = new Node(key, value);
            cache.put(key, newNode);
            addToHead(newNode);
            size++;
            
            // 超出容量时删除尾部节点
            if (size > capacity) {
                Node removed = removeTail();
                cache.remove(removed.key);
                size--;
            }
        }
    }
    
    // === 辅助方法 ===
    
    // 添加节点到头部
    private void addToHead(Node node) {
        node.prev = head;
        node.next = head.next;
        head.next.prev = node;
        head.next = node;
    }
    
    // 从链表中移除节点
    private void removeNode(Node node) {
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }
    
    // 移动节点到头部
    private void moveToHead(Node node) {
        removeNode(node);
        addToHead(node);
    }
    
    // 移除尾部节点(最久未使用)
    private Node removeTail() {
        Node node = tail.prev;
        removeNode(node);
        return node;
    }
}
实现说明
  • ​​数据结构选择​​

    • 双向链表:维护访问顺序
    • 哈希表:提供O(1)的键查找
  • ​​哨兵节点​​

    • 虚拟头节点(head)和尾节点(tail)简化边界操作
    • 避免空指针检查和特殊处理
  • ​​关键操作

  • // 插入新节点
    head → newNode → nextNode
              ↑          ↑
            head      nextNode
    
    // 移动节点到头部
    prevNode → node → nextNode  →  head → node → nextNode
    
    // 删除尾部节点
    tail.prev → tail  → 删除tail.prev
  • ​​时间复杂度​​

    • get(): O(1) (哈希查找 + 链表操作)
    • put(): O(1) (哈希操作 + 链表操作)

 使用示例

public class Main {
    public static void main(String[] args) {
        LRUCache<Integer, String> cache = new LRUCache<>(2);
        
        cache.put(1, "Apple");
        cache.put(2, "Banana");
        System.out.println(cache.get(1)); // 返回 "Apple"
        
        cache.put(3, "Cherry");  // 淘汰 key=2
        System.out.println(cache.get(2)); // 返回 null
        
        cache.put(4, "Durian");  // 淘汰 key=1
        System.out.println(cache.get(1)); // 返回 null
        System.out.println(cache.get(3)); // 返回 "Cherry"
        System.out.println(cache.get(4)); // 返回 "Durian"
    }
}
处理流程示意图
初始状态: 
head ↔ tail

插入A: 
head → A ↔ tail

插入B:
head → B ↔ A ↔ tail

访问A:
head → A ↔ B ↔ tail

插入C (容量满时):
1. 移除尾部B
2. head → C ↔ A ↔ tail
实际应用场景
  1. 数据库查询缓存
  2. 页面置换算法
  3. Redis内存管理
  4. 浏览器缓存管理
  5. CPU缓存系统
附:为什么要用双向列表+哈希表组合

LRU算法需要同时满足两个关键需求:

  1. ​​快速查找​​(O(1)时间复杂度)
  2. ​​快速维护访问顺序​​(O(1)移动/删除)
单数据结构无法同时满足:
数据结构查找效率维护顺序效率问题
数组O(1)随机访问O(n)移动元素移动元素成本高
单向链表O(n)查找O(1)移动节点查找效率低下
哈希表O(1)查找无法维护顺序无序存储
双向链表O(n)查找O(1)移动/删除查找效率低下
组合方案的优势:
  1. ​​哈希表​​:提供O(1)的键值查找能力
  2. ​​双向链表​​:提供O(1)的节点操作能力
    • 快速移动节点到头部(最近使用)
    • 快速删除尾部节点(淘汰最久未使用)
关键操作分析(O(1)时间复杂度):
1. 访问元素(get)

2. 插入元素(put)

为什么必须用双向链表?(单向链表的问题)

假设使用单向链表:

  • ​​删除节点需要O(n)时间​​:

    • 需要遍历找到前驱节点才能删除
    • 伪代码:
      // 删除node需要的前驱节点
      Node prev = head;
      while(prev.next != node) {
          prev = prev.next; // O(n)遍历
      }
      prev.next = node.next;

  • ​​无法直接操作尾部节点​​:

    • 删除LRU项时,无法快速访问前驱节点
关键实现细节解析
1. 节点删除(双向链表O(1))
private void removeNode(Node node) {
    node.prev.next = node.next; // 前驱指向后继
    node.next.prev = node.prev; // 后继指向前驱
}

2. 节点插入头部(双向链表O(1))
private void addToHead(Node node) {
    // 新节点连接原首节点
    node.next = head.next;
    node.prev = head;
    
    // 原首节点连接新节点
    head.next.prev = node;
    head.next = node;
}

设计决策总结
需求解决方案
O(1)查找哈希表存储键到节点的映射
O(1)插入新元素哈希表插入 + 链表头部插入
O(1)移动元素到前端双向链表节点删除/插入
O(1)删除最久未使用双向链表尾部指针 + 哈希表同步删除
避免边界条件虚拟头/尾节点(哨兵节点)

这种经典的组合实现了时间复杂度与空间效率的最佳平衡(O(1)操作 + O(n)空间),是现代系统中实现LRU缓存的黄金标准。Java的LinkedHashMap也是基于相同的原理实现的。

 

Java实现LRU(最近最少使用)算法 通过实现LRU算法,我们可以在有限的缓存容量下,有效地提高数据的命中率,减少不必要的数据访问开销。在Java中,我们可以选择使用双向链表和哈希表的组合,或者直接利用来实现LRU缓存。前者提供了更多的灵活性和控制能力,而后者则更加简洁和高效。根据具体的应用场景和需求,我们可以选择合适的实现方式。版权声明:本博客内容为原创,转载请保留原文链接及作者信息。 阅读详情

相关推荐

操作系统页面置换算法之最近最少使用算法(LRU)

LRU是Least Recently Used的缩写,即最近最少使用页面置换算法,是为虚拟页式存储管理服务的,是根据页面调入内存后的使用情况进行决策了。由于无法预测各页面将来的使用情况,只能利用“最近的过去”作为“最近的将来”的近似,因此,LRU算法就是将最近最久未使用的页面予以淘汰。 下面以java语言模拟实现LRU算法,其中,引用串中不包含0号页号。 代码如下: import java.

wanna_wsl的博客 4658

​​​​​​​LRU算法(最近最久未使用/最近最少使用算法)

根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高” 1、最常见的实现是使用一个链表保存缓存数据 1. 新数据插入到链表头部; 2. 每当缓存命中(即缓存数据被访问),则将数据移到链表头部; 3. 当链表满的时候,将链表尾部的数据丢弃。   【命中率】 当存在热点数据时,LRU的效率很好,但偶发性的、周期性的批量操作会导致LRU命...

张花生的博客 3961

别再怕非观测区了!手把手教你用移相法搞定PMSM单电阻FOC的电流重构难题

本文详细解析了永磁同步电机(PMSM)单电阻FOC系统中非观测区的电流重构难题,重点介绍了移相法的工程实践。通过STM32平台的具体实现和调试指南,帮助工程师有效解决相电流检测中的采样窗口不足问题,提升系统稳定性和性能。

weixin_27252001的博客 433

最近最少使用(LRU)与最近最不常用(LFU)的区别

来源:https://blog.youkuaiyun.com/qq_18671205/article/details/107286777 1.最近最不常用(LFU) 此题中页号为22需要淘汰,因为T时间只访问了11次 2.最近最少使用(LRU) 此题中需要淘汰15号,因为访问位为0,并且在T时间被访问了43次是最多的,说明很久已经没有被访问使用了。 ...

Johnson_Marteest的博客 4900

Python爬取天天基金网历史数据

前言 最近开始学习基金????,感觉需要收集一些数据统计分析才靠谱????毕竟给A股交学费的感觉可不好受???? 网上有很多公开的数据,我这里选择的是天天基金网进行爬取 页面分析 接口我分析过了,有些验证不太好获取数据,所以直接从html提取 在天天基金网中随便选择一款基金,然后点击进入历史数据页面 容易定位出日增长率的css选择器 还有翻页按钮 程序编写 使用selenium打开chrome浏览器进行爬取,全代码如下 from selenium import webdriver from sel

JiajunBernoulli的博客 2950

回归预测 | MATLAB实现SVR(支持向量机回归)K折交叉验证

回归预测 | MATLAB实现SVR(支持向量机回归)K折交叉验证 目录回归预测 | MATLAB实现SVR(支持向量机回归)K折交叉验证基本介绍划分原理留一划分交叉验证K折交叉数据下载程序设计参考资料致谢 基本介绍 在机器学习里,通常来说我们不能将全部用于数据训练模型,否则我们将没有数据集对该模型进行验证,从而评估我们的模型的预测效果。为了解决这一问题,有如下常用的方法: 第一种是最简单的,也是很容易就想到的。我们可以把整个数据集分成两部分,一部分用于训练,一部分用于验证,这也就是我们经常提到的训练集

机器学习之心的博客,关注并私信文章链接,获取对应文章源码和数据。 6375

最近最久未使用和最少使用置换算法的区别

采用同一硬件,算法不同

和我一起学习 3419

基于STM32设计的便携式心电信号监测系统_474

本课题设计并实现了一种基于STM32单片机的便携式心电信号监测系统。系统以STM32F103C8T6为核心控制单元,结合PulseSensor心率传感器,实现对人体心率信号的采集与处理。通过单片机内部ADC模块对传感器输出的模拟电压信号进行采样,并对采集数据进行分析处理,从而计算得到实时心率值。

161

简单模拟Lur 算法

简单模拟Lur 算法

LVM23的博客 549

【异常】OpenClaw 项目 `fetch failed` 报错问题排查与解决方案Response interrupted: TypeError: fetch failed

针对无超时控制、异常兜底缺失导致的请求中断,封装标准化的安全请求工具,一次性解决超时控制、异常捕获、日志埋点三大问题,全项目替换原生。:将项目运行的 Node.js 版本升级至 18.x 及以上 LTS 版本,使用 Node.js 内置的稳定版。实现的网络请求环节,包括但不限于:第三方开放接口调用、内部服务接口通信、跨域资源请求、外部配置拉取等场景。:针对无法升级 Node.js 版本的存量环境,通过社区稳定兼容包替换原生。类型异常,直接造成业务请求响应中断。第二步:业务代码改造,替换原生。

奶爸的编程之路,也就一周冷个三天 367

PX4实战(四):PX4 uorb模块详解

本节主要讲解PX4中的uorb消息,主要包括uorb的基本概念使用、PX4内重要的uorb消息、如何自定义uorb消息以及使用uorb消息的注意点等,其中讲解重要uorb消息是为了对PX4内重要数据结构有初步的了解,有助于后期算法理解。uORB(micro Object Request Broker)是PX4中用于模块间通信的轻量级发布-订阅(Publish/Subscribe)机制。模块之间可以通过uORB传递消息,无需直接调用对方函数;提高系统模块化与解耦性;

PX4-SLAM-PNC 1931

详解LRU(最近最少使用)算法及Java实现

1、基本介绍 LRU(Least Recently Used)即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。对于缓存来说,容量是有限的,当容量满时,就需要清理一些对于当前情景来说没用的内容,从而为新来的腾出位置,如何选择就对应了某种策略,而LRU采取的是一种选择最近最久未使用作为淘汰的策略。 最近即当前,最久未使用也即最少使用,要实现如此特征,我们有所规定,每当访问了缓存中存在的数据或向缓存中新增数据,该数据就得移至最前面(表头),如果新增数据时,缓存已满,就要删除当前位于最后

weixin_45685353的博客 5548

T527 uart串口配置导致系统进不去

T527 s_uart串口配置导致系统进不去。

Linux驱动开发工程师,熟悉Linux/Android底层驱动、TP、显示、IIC、网络等通用外设调试适配,Linux上层应用开发。常用平台瑞芯微、全志、恩智浦等。 676

算法学习记录——LRU(最近最少使用)算法的简单应用实现(JAVA实现)

LRU(最近最少使用)算法的简单应用实现——针对内存的使用情况,防止缓存的溢出问题。 import java.util.HashMap; //LRU(最近最少使用)算法的简单应用实现——针对内存的使用情况,防止缓存的溢出问题。 //数据结构为--->具有链表功能的哈希表(哈希链表),而且是双向链表。 public class LRUCache { private Node he...

一夜笑舟的专栏 406

Silvaco TCAD 半导体器件仿真全攻略:从入门到精通

本文介绍了Silvaco TCAD半导体器件仿真平台的核心功能与应用方法。主要内容包括: Silvaco TCAD的核心模块组成(ATHENA工艺仿真和ATLAS器件仿真)及其在半导体研发中的重要作用,能够通过数值仿真预测器件电学特性,显著降低研发成本。 环境配置要点,包括内存分配、文件目录管理和许可证验证,为仿真工作提供基础保障。 仿真核心概念:详细讲解了网格划分策略和物理模型选择原则,强调基于物理直觉的自适应加密网格方法。 以PN结二极管为例,提供了完整的仿真代码示例,涵盖从网格定义、掺杂设置到结果分析

huanghm88的专栏 201

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

【Python学习笔记】3:LRU(最近最少使用页面置换)算法

LRU(最近最少使用页面置换)算法 题目描述:一进程刚获得3个主存块的使用权,若该进程访问页面的次序是1,2,3,4,1,2,5,1,2,3,4,5。当采用LRU算法时发生的缺页次数是多少? LRU是最近最少使用页面置换算法,该算法用一个开放的栈来保存当前正在使用的各个页面号。当有一个新的页面要被访问时,就将该页面号加入栈顶(如果分配的内存不够,就将栈底页面号删除,其它页面号前移以给新页面腾出...

大桔骑士的学习笔记 4634

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

fifo算法_学会LRU算法,该拿去秀一波面试官了

首先呢,为什么前端要学习LRU算法呢?在浏览器缓存淘汰策略中以及Vue 的 keep-alive 等等场景中都用到了这个LRU算法。那么你说它重不重要?这个也是前端技能的一大亮点,在以后中当面试官在问到你前端开发中遇到过哪些算法,这是不是一个很好的骚操作。那么我们接着来学习一下这个LRU算法吧。了解LRU算法LRU是Least Recently Used 的缩写,即最近最少使用,是一种常...

weixin_39743414的博客 179

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

章节八:缓存“新陈代谢”:LRU的巧妙实现 - (最近最少使用 / LRU Cache)

本文介绍了LRU缓存淘汰算法的核心思想和高效实现。LRU策略通过优先淘汰最近最少使用的数据来优化缓存性能,其关键在于哈希表与双向链表的结合——哈希表实现O(1)快速查找,双向链表维护访问顺序。新访问数据移至链表头部,淘汰数据从尾部删除。文章详细解析了get/put操作流程,并通过Java代码示例展示了虚拟头尾节点的实现技巧。该设计完美满足了缓存系统对快速查询、插入、删除和顺序维护的核心需求。

杨小扩的博客 754

Android LRU缓存算法实现

什么是LRU算法? LRU是Least Recently Used的缩写,即最少使用页面置换算法,是为虚拟页式存储管理服务的。 可以参考这两篇: 说说Android LRU缓存算法实现学习笔记(一) 说说Android LRU缓存算法实现笔记(二)--LRU的应用

牛崽的博客 696

LRU算法解析

在项目中用到了common-collections中LRUMap,最近有空看了一下源码,对LRU算法有了更具体的认识,LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。 LRUMap实现的核心思想是使用一个链表,将经常使用的放在链表的尾部,如果LRUMap的size已经到最...

litongtong1028的博客 469

什么是LRU(最近最少使用)算法?

一、什么是LRU? LRU(Least Recently Used),最近最少使用。 是一种【内存管理】算法。 LRU算法基于一种假设: 长期不被使用的数据,在未来被用到的几率也不大。因此,当数据所占内存达到一定阈值时,要移除掉最近最少使用的数据。 LRU算法使用了一种有趣的数据结构,叫做【哈希链表】 二、什么是【哈希链表】呢? 1)【哈希表】是由若干个【Key-Value】所组成的。 ...

qq_34343254的博客 1万+

LRU算法

1.什么是LRU算法 LRU算法又称最近最少使用算法,它的基本思想是长期不被使用的数据,在未来被用到的几率也不大,所以当新的数据进来时我们可以优先把这些数据替换掉。 在LRU算法中,使用了一种有趣的数据结构,称为哈希链表。我们知道哈希表是由多个<Key,Value>对组成的,哈希链表是将这写节点链接起来,每一个节点都有一个前驱结点和后驱节点,就像双向链表中的节点一样。哈希表拥有了固定的排列顺序。 基于哈希链表的有序性,我们就可以把<Key,Value>按照最后的使用时间来排列。 2

Listen·Rain的博客 4万+

LRU算法原理及实现,最近最少使用算法

LRU算法原理及实现,最近最少使用算法

26857259 1376

什么是LRU算法

什么是LRU算法

似水流年QC的博客 3万+

缓存置换:用c++实现最近最少使用(LRU)算法

在计算机的世界里,缓存就像一个“快速仓库”,它存储着我们频繁访问的数据,大大提升了数据的读取速度。但这个 “仓库” 空间有限,当它被装满时,就得决定舍弃一些数据,为新数据腾出位置,这个决策过程就由缓存置换算法来掌控。今天,就让我们探索常见的缓存置换算法中的最近最少使用算法(LRU),并使用c++实现它。

2301_76564925的博客 2046
上一篇: 发现一个挺好的项目,可以在springboot项目中快速接入DeepSeek API,有需要的可以尝试一下
下一篇: 详解web.xml中的listener与filter
Jack_abu
博客等级 码龄10年 633粉丝 78原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jack_abu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值