【RL Latest Tech】分层强化学习:Option-Critic架构算法
📢本篇文章是博主强化学习RL领域学习时,用于个人学习、研究或者欣赏使用,并基于博主对相关等领域的一些理解而记录的学习摘录和笔记,若有不当和侵权之处,指出后将会立即改正,还望谅解。文章分类在👉强化学习专栏:
【强化学习】(22)---《分层强化学习:Option-Critic架构算法》
分层强化学习:Option-Critic架构算法
目录
1. 基本概念
2. Option-Critic框架的核心要素
2.1 选项(Option)
2.2 Intra-Option Q-Learning
2.3 选项的终止条件
3. Option-Critic算法工作流程
[Python] Option-Critic实现
算法训练代码
测试和可视化代码
[Notice] 注意事项
4. Option-Critic的优势
5. 相关的挑战
6. 总结
分层强化学习(Hierarchical Reinforcement Learning, HRL)通过将复杂问题分解为更小的子问题,显著提高了强化学习算法在解决高维状态空间和长期目标任务中的效率。Option-Critic架构是分层强化学习中一种非常有影响力的方法,专门用于自动发现和优化子策略(称为“Option”)。它是在经典的Options框架基础上提出的,用来处理分层决策问题,特别是可以在没有明确的子目标定义的情况下自动学习子策略。
1. 基本概念
在Option-Critic架构中,最核心的思想是使用 “选项” 来建模高级行为策略。每个选项代表一段策略或行为,负责特定的子任务。具体地说,选项包括三个部分:
- 初始条件(Initiation set):智能体可以选择该选项的状态集合。
- 内部策略(Intra-option policy):智能体在选项激活时的行动策略,即在特定状态下采取的行动。
- 终止条件(Termination condition):定义选项何时终止或结束。
在这种架构下,智能体不再直接学习每个状态下的单一动作,而是学习 何时选择选项以及如何在选项内行动。这使得学习更加抽象化和高效化。
2. Option-Critic框架的核心要素
2.1 选项(Option)
- 选项 是智能体可以执行的一个序列动作,这些动作组成一个子策略。选项不仅包含具体的操作步骤,还包含 何时开始选项 以及 何时终止选项。
- 在每一个时间步,智能体可以选择:执行一个基础动作或选择一个更高级别的选项。在选项内,智能体执行动作直到达到终止条件,然后选择新的选项。
2.2 Intra-Option Q-Learning
Option-Critic框架引入了 Intra-Option Q-Learning 算法,用于更新选项的内部策略。在传统的强化学习中,Q-learning用于评估在特定状态下选择某个动作的价值。而在Option-Critic中,Intra-Option Q-Learning则用于评估 在选项内 如何选择动作。具体步骤如下:
- 对于每个选项,有一个内部策略,它定义了在选项激活时的动作选择方式。
- Q函数代表在状态选择选项的期望回报。
- 当智能体在执行选项时,内部策略根据当前状态选择具体动作,并且根据Intra-Option Q-Learning规则更新Q值。
2.3 选项的终止条件
选项的终止条件决定了何时退出当前选项并返回上层策略。例如,一个选项可能在达到某个目标状态时终止,或者在经过一定的时间步数后自动终止。终止条件的优化同样是Option-Critic框架中的一个关键部分。
3. Option-Critic算法工作流程
Option-Critic算法通过以下步骤完成学习过程:
- 选项初始化:初始化选项的初始条件、内部策略和终止条件。
- 执行过程:
- 智能体基于当前状态和Q值函数选择某个选项。
- 执行选项的内部策略,在环境中采取具体行动,直到终止条件触发。
- Q值更新:使用Intra-Option Q-Learning更新每个选项的Q值函数。
- 策略更新:同时更新选项的内部策略和终止条件,使得智能体能够更好地进行决策。
- 重复以上过程,直至收敛。
[Python] Option-Critic实现
🔥若是下面代码复现困难或者有问题,欢迎评论区留言;需要以整个项目形式的代码,请在评论区留下您的邮箱📌,以便于及时分享给您(私信难以及时回复)。
Option-Critic架构在CartPole环境中的Python代码,使用了OpenAI Gym和PyTorch进行实现。
步骤:
- 设置 CartPole 环境。
- 定义选项的策略网络。
- 定义用于估计每个选项值的Q 网络。
- 实现选项内策略梯度和终止梯度。
- 创建经验回放缓冲区,用于存储和采样经验。
- 使用时间差分学习和策略梯度训练智能体。
- 测试和可视化智能体的表现。
算法训练代码
"""《Option-Critic实现》时间:2024.10.01环境:CartPole 作者:不去幼儿园
"""
import gym
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
from collections import deque
import random# 超参数调整
GAMMA = 0.98 # 稍微减少折扣因子,减少远期奖励影响
LEARNING_RATE = 0.0005 # 降低学习率,提高训练的稳定性
BATCH_SIZE = 128 # 增加批次大小以稳定训练
MEMORY_SIZE = 20000 # 增大经验回放缓冲区
EPSILON_DECAY = 0.99 # 减慢 epsilon 的衰减速度
MIN_EPSILON = 0.05 # 增大最小 epsilon,保持一定探索
NUM_OPTIONS = 2
NUM_EPISODES = 1000 # 增加训练回合数# 修改后的网络结构
class CriticNetwork(nn.Module):def __init__(self, state_dim, num_options):super(CriticNetwork, self).__init__()self.fc1 = nn.Linear(state_dim, 256) # 增加隐藏层神经元数量self.fc2 = nn.Linear(256, num_options)def forward(self, state):x = torch.relu(self.fc1(state))return self.fc2(x)class IntraOptionPolicyNetwork(nn.Module):def __init__(self, state_dim, num_options, action_dim):super(IntraOptionPolicyNetwork, self).__init__()self.fc1 = nn.Linear(state_dim, 256) # 增加神经元数量self.fc2 = nn.Linear(256, num_options * action_dim)self.num_options = num_optionsself.action_dim = action_dimdef forward(self, state, option):x = torch.relu(self.fc1(state))policy_logits = self.fc2(x)option_policy = policy_logits.view(-1, self.num_options, self.action_dim)return option_policy[:, option, :]class TerminationNetwork(nn.Module):def __init__(self, state_dim, num_options):super(TerminationNetwork, self).__init__()self.fc1 = nn.Linear(state_dim, 256) # 增加神经元数量self.fc2 = nn.Linear(256, num_options)def forward(self, state):x = torch.relu(self.fc1(state))termination_probs = torch.sigmoid(self.fc2(x))return termination_probs# 经验回放缓冲区
class ReplayBuffer:def __init__(self, capacity):self.buffer = deque(maxlen=capacity)def push(self, state, option, action, reward, next_state, done):self.buffer.append((state, option, action, reward, next_state, done))def sample(self, batch_size):states, options, actions, rewards, next_states, dones = zip(*random.sample(self.buffer, batch_size))return np.stack(states), options, actions, rewards, np.stack(next_states), donesdef size(self):return len(self.buffer)# 选择动作
def select_action(policy_net, state, option, epsilon):if random.random() < epsilon:return random.choice([0, 1]) # CartPole 动作空间为 2(0 或 1)else:state = torch.FloatTensor(state).unsqueeze(0)action_probs = torch.softmax(policy_net(state, option), dim=-1)return torch.argmax(action_probs).item()# Option-Critic 智能体
class OptionCriticAgent:def __init__(self, state_dim, action_dim, num_options):self.policy_net = IntraOptionPolicyNetwork(state_dim, num_options, action_dim)self.q_net = CriticNetwork(state_dim, num_options)self.termination_net = TerminationNetwork(state_dim, num_options)self.optimizer_policy = optim.Adam(self.policy_net.parameters(), lr=LEARNING_RATE)self.optimizer_q = optim.Adam(self.q_net.parameters(), lr=LEARNING_RATE)self.optimizer_term = optim.Adam(self.termination_net.parameters(), lr=LEARNING_RATE)self.epsilon = 1.0self.num_options = num_optionsself.memory = ReplayBuffer(MEMORY_SIZE)def train(self, batch_size):if self.memory.size() < batch_size:returnstates, options, actions, rewards, next_states, dones = self.memory.sample(batch_size)states = torch.FloatTensor(states)next_states = torch.FloatTensor(next_states)rewards = torch.FloatTensor(rewards)options = torch.LongTensor(options)actions = torch.LongTensor(actions)dones = torch.FloatTensor(dones)# 更新 Q 函数q_values = self.q_net(states)next_q_values = self.q_net(next_states).detach()target_q_values = rewards + GAMMA * next_q_values.max(1)[0] * (1 - dones)loss_q = nn.functional.mse_loss(q_values.gather(1, options.unsqueeze(1)).squeeze(), target_q_values)self.optimizer_q.zero_grad()loss_q.backward()self.optimizer_q.step()# 更新选项内策略for option in range(self.num_options):policy_logits = self.policy_net(states, option)action_probs = torch.softmax(policy_logits, dim=-1)log_action_probs = torch.log(action_probs)policy_loss = -log_action_probs.gather(1, actions.unsqueeze(1)).mean()self.optimizer_policy.zero_grad()policy_loss.backward()self.optimizer_policy.step()# 更新终止概率terminations = self.termination_net(states)termination_loss = nn.functional.binary_cross_entropy(terminations.gather(1, options.unsqueeze(1)).squeeze(),dones)self.optimizer_term.zero_grad()termination_loss.backward()self.optimizer_term.step()def remember(self, state, option, action, reward, next_state, done):self.memory.push(state, option, action, reward, next_state, done)# 训练智能体
env = gym.make('CartPole-v1')
state_dim = env.observation_space.shape[0]
action_dim = env.action_space.nagent = OptionCriticAgent(state_dim, action_dim, NUM_OPTIONS)for episode in range(NUM_EPISODES):state, _ = env.reset()option = random.choice(range(NUM_OPTIONS)) # 随机选择一个选项done = Falseepisode_reward = 0while not done:action = select_action(agent.policy_net, state, option, agent.epsilon)next_state, reward, done, _, __ = env.step(action)agent.remember(state, option, action, reward, next_state, done)agent.train(BATCH_SIZE)# 选项终止时选择新选项if random.random() < agent.termination_net(torch.FloatTensor(state))[option].item():option = random.choice(range(NUM_OPTIONS))state = next_stateepisode_reward += rewardagent.epsilon = max(MIN_EPSILON, agent.epsilon * EPSILON_DECAY)print(f"Episode {episode + 1}: Total Reward: {episode_reward}")env.close()# Option-Critic 智能体
class OptionCriticAgent:def __init__(self, state_dim, action_dim, num_options):self.policy_net = IntraOptionPolicyNetwork(state_dim, num_options, action_dim)self.q_net = CriticNetwork(state_dim, num_options)self.termination_net = TerminationNetwork(state_dim, num_options)self.optimizer_policy = optim.Adam(self.policy_net.parameters(), lr=LEARNING_RATE)self.optimizer_q = optim.Adam(self.q_net.parameters(), lr=LEARNING_RATE)self.optimizer_term = optim.Adam(self.termination_net.parameters(), lr=LEARNING_RATE)self.epsilon = 1.0self.num_options = num_optionsself.memory = ReplayBuffer(MEMORY_SIZE)def train(self, batch_size):if self.memory.size() < batch_size:returnstates, options, actions, rewards, next_states, dones = self.memory.sample(batch_size)states = torch.FloatTensor(states)next_states = torch.FloatTensor(next_states)rewards = torch.FloatTensor(rewards)options = torch.LongTensor(options)actions = torch.LongTensor(actions)dones = torch.FloatTensor(dones)# 更新 Q 函数q_values = self.q_net(states)next_q_values = self.q_net(next_states).detach()target_q_values = rewards + GAMMA * next_q_values.max(1)[0] * (1 - dones)loss_q = nn.functional.mse_loss(q_values.gather(1, options.unsqueeze(1)).squeeze(), target_q_values)self.optimizer_q.zero_grad()loss_q.backward()self.optimizer_q.step()# 更新选项内策略for option in range(self.num_options):policy_logits = self.policy_net(states, option)action_probs = torch.softmax(policy_logits, dim=-1)log_action_probs = torch.log(action_probs)policy_loss = -log_action_probs.gather(1, actions.unsqueeze(1)).mean()self.optimizer_policy.zero_grad()policy_loss.backward()self.optimizer_policy.step()# 更新终止概率terminations = self.termination_net(states)termination_loss = nn.functional.binary_cross_entropy(terminations.gather(1, options.unsqueeze(1)).squeeze(),dones)self.optimizer_term.zero_grad()termination_loss.backward()self.optimizer_term.step()def remember(self, state, option, action, reward, next_state, done):self.memory.push(state, option, action, reward, next_state, done)# 在 CartPole 环境中训练智能体
env = gym.make('CartPole-v1')
state_dim = env.observation_space.shape[0]
action_dim = env.action_space.nagent = OptionCriticAgent(state_dim, action_dim, NUM_OPTIONS)for episode in range(NUM_EPISODES):state, _ = env.reset()option = random.choice(range(NUM_OPTIONS)) # 初始化为随机选项done = Falseepisode_reward = 0while not done:action = select_action(agent.policy_net, state, option, agent.epsilon)next_state, reward, done, _, __ = env.step(action)agent.remember(state, option, action, reward, next_state, done)agent.train(BATCH_SIZE)if random.random() < agent.termination_net(torch.FloatTensor(state))[option].item():option = random.choice(range(NUM_OPTIONS)) # 终止当前选项并选择新选项state = next_stateepisode_reward += rewardagent.epsilon = max(MIN_EPSILON, agent.epsilon * EPSILON_DECAY)print(f"Episode {episode + 1}: Total Reward: {episode_reward}")env.close()
测试和可视化代码
要在 CartPole 环境中测试 Option-Critic 模型并显示动画,需要利用 gym
库中的 render()
方法。以下代码演示了如何在训练完模型后进行测试,并实时显示动画。
import gym
import torch# 测试 Option-Critic 模型并显示动画
def test_option_critic(agent, env, num_episodes=5):for episode in range(num_episodes):state, _ = env.reset()option = random.choice(range(agent.num_options)) # 随机选择一个选项done = Falseepisode_reward = 0env.render() # 初始化渲染环境while not done:env.render() # 渲染环境,显示动画action = select_action(agent.policy_net, state, option, epsilon=0.0) # 使用已学策略选择动作next_state, reward, done, _, __ = env.step(action)# 检查选项是否应终止,并在终止时重新选择新选项if random.random() < agent.termination_net(torch.FloatTensor(state))[option].item():option = random.choice(range(agent.num_options))state = next_stateepisode_reward += rewardprint(f"测试 Episode {episode + 1}: Total Reward: {episode_reward}")env.close()# 创建 CartPole 环境并调用测试函数
env = gym.make('CartPole-v1', render_mode='human')
test_option_critic(agent, env)
[Notice] 注意事项
确保您使用的环境和库版本支持 render_mode
参数。如果使用的 Gym 版本较旧,可能不支持此选项。在这种情况下,建议更新 gym
库。
上述采用的是gym == 0.26.2
pip install --upgrade gym
注意 :env.step(action)的返回参数数量,多则删除__
由于博文主要为了介绍相关算法的原理和应用的方法,缺乏对于实际效果的关注,算法可能在上述环境中的效果不佳,一是算法不适配上述环境,二是算法未调参和优化,三是等。上述代码用于了解和学习算法足够了,但若是想直接将上面代码应用于实际项目中,还需要进行修改。
4. Option-Critic的优势
Option-Critic架构的优点主要体现在以下几方面:
- 层次化决策:通过分层的结构,智能体能够进行更高级别的决策,不必在每一步都从头开始学习。
- 策略的可重用性:通过选项,智能体可以学习可重复使用的策略片段,用于不同的任务场景。
- 提升效率:在复杂任务中,分层策略减少了动作空间的复杂度,使得学习过程更加高效。
5. 相关的挑战
尽管Option-Critic架构在理论上具备优势,但在实际应用中仍面临一些挑战:
- 选项的设计与优化:选择合适的选项数量和复杂度对于模型性能有很大影响。
- 探索与利用的平衡:在不同的选项之间,如何平衡探索新选项与利用已有的选项是一个难题。
- 终止条件的优化:如何合理地学习选项的终止条件,避免选项过早或过晚终止,同样是一个挑战。
6. 总结
Option-Critic架构通过引入 选项 这一中间层次,将复杂问题分解为多个子任务,并通过学习这些子任务的策略与终止条件来实现有效的分层强化学习。它是一种非常有前景的强化学习框架,适用于处理复杂、长期依赖的任务。
参考文献
Bacon, P.-L., Harb, J., & Precup, D. (2017). The Option-Critic Architecture. Proceedings of the 31st AAAI Conference on Artificial Intelligence (AAAI-17).
完整项目代码:
【RL Latest Tech】分层强化学习:Option-Critic架构算法项目代码实现
Option-Critic架构通过整合选项策略和Q学习算法,提供了一种优雅的解决方案,使得智能体能够高效地在复杂环境中进行学习和决策。
文章若有不当和不正确之处,还望理解与指出。由于部分文字、图片等来源于互联网,无法核实真实出处,如涉及相关争议,请联系博主删除。如有错误、疑问和侵权,欢迎评论留言联系作者,或者关注VX公众号:Rain21321,联系作者。✨
相关文章:
【RL Latest Tech】分层强化学习:Option-Critic架构算法
📢本篇文章是博主强化学习RL领域学习时,用于个人学习、研究或者欣赏使用,并基于博主对相关等领域的一些理解而记录的学习摘录和笔记,若有不当和侵权之处,指出后将会立即改正,还望谅解。文章分类在…...
分布式数据库
前言 分布式数据库系统(DDBS)包含分布式数据库管理系统(DDBMS)和分布式数据库(DDB)。在分布式数据库系统中,一个应用程序可以对数据库进行透明操作,数据库中的数据分别在不同的…...
MySQL(2)【库的操作】
阅读导航 引言一、创建数据库1. 基本语法2. 创建数据库案例📌创建名为db1的数据库📌创建一个使用utf8字符集的db2数据库📌创建一个使用utf8字符集,并带校对规则的db3数据库 二、字符集和校验规则1. 查看系统默认字符集以及校验规则…...
python pip更换(切换)国内镜像源
国内镜像源列表(个人推荐清华大学的源) 清华大学: https://pypi.tuna.tsinghua.edu.cn/simple阿里云: http://mirrors.aliyun.com/pypi/simple豆瓣: http://pypi.douban.com/simple中国科技大学: https://pypi.mirrors.ustc.e…...
阿里云镜像源无法访问?使用 DaoCloud 镜像源加速 Docker 下载(Linux 和 Windows 配置指南)
🚀 作者主页: 有来技术 🔥 开源项目: youlai-mall 🍃 vue3-element-admin 🍃 youlai-boot 🍃 vue-uniapp-template 🌺 仓库主页: GitCode💫 Gitee …...
使用 BERT 和逻辑回归进行文本分类及示例验证
使用 BERT 和逻辑回归进行文本分类及示例验证 一、引言 在自然语言处理领域中,文本分类是一项至关重要的任务。本文将详细介绍如何结合 BERT 模型与逻辑回归算法来实现文本分类,并通过实际示例进行验证。 二、环境准备 为了运行本文中的代码…...
【skywalking 】监控 Spring Cloud Gateway 数据
使用Spring Cloud 开发,用Skywalking 监控服务,但是Skywalking 默认是不支持 Spring Cloud Gateway 网关服务的,需要手动将 Gateway 的插件添加到 Skywalking 启动依赖 jar 中。 skywalking相关版本信息 jdk:17skywalking&#x…...
SpringWeb
SpringWeb SpringWeb 概述 SpringWeb 是 spring 框架中的一个模块,基于 Servlet API 构建的 web 框架. springWeb 是 Spring 为 web 层开发提供的一整套完备的解决方案。 在 web 层框架历经 Strust1,WebWork,Strust2 等诸多产品的历代更…...
嵌入式刷题(day21)
MySQL和sqlite的区别 MySQL和SQLite是两种常见的关系型数据库管理系统(RDBMS),但它们在特性、使用场景和架构方面有显著的区别: 1. 架构 MySQL:是一个基于服务器的数据库系统,遵循客户端-服务器架构。MySQL服务器运行在主机上,客户端通过网络连接并发送查询。它可以并…...
OpenAI 下一代旗舰模型现身?奥尔特曼亲自辟谣“猎户座“传闻
在人工智能领域最受瞩目的ChatGPT即将迎来两周岁之际,一场关于OpenAI新旗舰模型的传闻再次引发业界热议。然而,这场喧嚣很快就被OpenAI掌门人奥尔特曼亲自澄清。 事件源于科技媒体The Verge的一则报道。据多位知情人士透露,OpenAI可能会在11…...
【C++】STL初识
【C】STL初识 文章目录 【C】STL初识前言一、STL基本概念二、STL六大组件简介三、STL三大组件四、初识STL总结 前言 本篇文章将讲到STL基本概念,STL六大组件简介,STL三大组件,初识STL。 一、STL基本概念 STL(Standard Template Library,标准…...
框架篇补充(东西多 需要重新看网课)
什么是AOP 面向切面编程 降低耦合 提高代码的复用 Spring的bean的生命周期 实例化bean 赋值 初始化bean 使用bean 销毁bean SpringMVC的执行流程 Springboot自动装配原理 实际上就是为了从spring.factories文件中 获取到对应的需要 进行自动装配的类 并生成相应的Bean…...
合约门合同全生命周期管理系统:企业合同管理的数字化转型之道
合约门合同全生命周期管理系统:企业合同管理的数字化转型之道 1. 引言 在现代企业中,合同管理已经不再是简单的文件存储和审批流程,而是企业合规性、风险管理和业务流程的关键环节之一。随着企业规模的扩大和合同数量的增加,传统…...
等保测评与风险管理:识别、评估和缓解潜在的安全威胁
在信息化时代,数据已成为企业最宝贵的资产之一,而信息安全则成为守护这份资产免受侵害的重中之重。等保测评(信息安全等级保护测评)作为保障信息系统安全的重要手段,其核心在于通过科学、规范、专业的评估手段…...
Golang Agent 可观测性的全面升级与新特性介绍
作者:张海彬(古琦) 背景 自 2024 年 6 月 26 日,ARMS 发布了针对 Golang 应用的可观测性监控功能以来,阿里云 ARMS 团队与程序语言与编译器团队一直致力于不断优化和提升该系统的各项功能,旨在为开发者提…...
SpringBoot的开篇 特点 初始化 ioc 配置文件
文章目录 前言SpringBoot发展历程SpringBoot前置准备SpringBoot特点 SpringBoot项目初始化项目启动Springboot的核心概念IOC概念介绍Bean对象通过注解扫描包 例子配置文件 前言 SpringBoot发展历程 最初,Spring框架的使用需要大量的XML配置,这使得开发…...
docker 可用镜像服务地址(2024.10.25亲测可用)
1.错误 Error response from daemon: Get “https://registry-1.docker.io/v2/” 原因:镜像服务器地址不可用。 2.可用地址 编辑daemon.json: vi /etc/docker/daemon.json内容修改如下: {"registry-mirrors": ["https://…...
【SQL实验】表的更新和简单查询
完整代码在文章末尾 在上次实验创建的educ数据库基础上,用SQL语句为student表、course表和sc表中添加以下记录 【SQL实验】数据库、表、模式的SQL语句操作_创建一个名为educ数据库,要求如下: (下面三个表中属性的数据类型需要自己设计合适-CSDN博客在这篇博文中已经…...
【C++】 string的了解及使用
标准库中的string类 在使用string类时,必须包含#include头文件以及using namespace std; string类的常用接口说明 C中string为我们提供了丰富的接口来供我们使用 – string接口文档 这里我们只介绍一些常见的接口 string类对象的常见构造 #include <iostrea…...
【K8S】kubernetes-dashboard.yaml
https://raw.githubusercontent.com/kubernetes/dashboard/v3.0.0-alpha0/charts/kubernetes-dashboard.yaml 以下链接的内容: 由于国内访问不了,找到一些方法下载了这个文件内容, 部署是mages 对象的镜像 WEB docker.io/kubernetesui/dash…...
远程root用户访问服务器中的MySQL8
一、Ubuntu下的MySQL8安装 在Ubuntu系统中安装MySQL 8.0可以通过以下步骤进行1. 更新包管理工具的仓库列表: sudo apt update 2. 安装MySQL 8.0,root用户默认没有密码: sudo apt install mysql-server sudo apt install mysql-client 【…...
解释一下 Java 中的静态变量(Static Variable)和静态方法(Static Method)?
今天来和大家深入探讨一下 Java 中的静态变量和静态方法,并通过一些具体的例子来理解它们在实际开发中的应用。 静态变量(Static Variable) 静态变量,也称为类变量,是在类的层次上共享的变量。这意味着无论创建了多少…...
【Linux】————磁盘与文件系统
作者主页: 作者主页 本篇博客专栏:Linux 创作时间 :2024年10月17日 一、磁盘的物理结构 磁盘的物理结构如图所示: 其中具体的物理存储结构如下: 磁盘中存储的基本单位为扇区,一个扇区的大小一般为512字…...
平衡控制——直立环——速度环
目录 平衡控制原理 平衡控制模型 平衡控制中基于模型设计与自动代码生成技术 速度环应用原理 速度控制模型 平衡控制原理 下图是一个单摆模型,对其进行受力分析如图。 在重力作用下,单摆受到和角度成正比,运动方向相反的回复力。而且在空气中运动的单摆,由于受…...
面试简要介绍hashMap
jdk8之前,hashmap采用的数据结构是数组链表,jdk8之后采用的数据结构是数组链表/红黑树。hashmap的数据以键值对的形式存在,如果两个元素的hash值相同,就会发生hash冲突,被放到同一个链表上--->如何解决hash冲突---&…...
HTTPS如何实现加密以及SSL/TSL加密的详细过程
通过将服务器从 HTTP 提升到 HTTPS 加密,数据在客户端和服务器之间的传输过程中的确得到了安全保护。以下是这种实现加密的机制以及客户端需要做的事情的详细说明。 为什么这样就实现了加密 SSL/TLS 协议: HTTPS 使用 SSL(安全套接层&#x…...
Golang | Leetcode Golang题解之第516题最长回文子序列
题目: 题解: func longestPalindromeSubseq(s string) int {n : len(s)dp : make([][]int, n)for i : range dp {dp[i] make([]int, n)}for i : n - 1; i > 0; i-- {dp[i][i] 1for j : i 1; j < n; j {if s[i] s[j] {dp[i][j] dp[i1][j-1] …...
(done) 什么 RPC 协议? remote procedure call 远程调用协议
来源:https://www.bilibili.com/video/BV1Qv4y127B4/?spm_id_from333.337.search-card.all.click&vd_source7a1a0bc74158c6993c7355c5490fc600 可以理解为,调用远程服务器上的一个方法/函数/服务的方式,同时隐藏网络细节 一个 python3 …...
PCL 基于Ransac提取误匹配点对
目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 基于RANSAC的误匹配点对提出函数 2.1.2 点云可视化函数 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接: PCL点云算法与项目实战案例汇总(长期更新) 一、…...
光速写作 2.0.5 | 专注AI写作,海量素材库
光速写作是一款专为解决写作难题设计的应用。它具有以下功能:- 「AI写作」:帮助分析题目、整理写作思路,合成作文,写出好文章。- 「作文批改」:拍照上传作文后,进行全文点评和分句点评,并进行全…...
能用织梦做动态网站么/软文推广公司
关于刷抖音、打游戏为什么上瘾有个著名的嗑瓜子理论:就是如果你在嗑瓜子的时候,随随便便几个小时就没了,但如果换成学习,时间就是过得很慢。因为一粒瓜子,从你磕到吃只需要几秒钟,吃就是你得到的反馈。你觉…...
网站用社交图标做链接侵权吗/百度浏览器官方网站
911. 在线选举 给你两个整数数组 persons 和 times 。在选举中,第 i 张票是在时刻为 times[i] 时投给候选人 persons[i] 的。 对于发生在时刻 t 的每个查询,需要找出在 t 时刻在选举中领先的候选人的编号。 在 t 时刻投出的选票也将被计入我们的查询之…...
奶茶车网站建设/b2b网站大全免费
单页面VS多页面应用 单页应用 优点:页面切换快(通过js来进行页面切换,并不请求html文件,使页面切换快) 缺点:首屏时间稍慢 (浏览器一开始会加载必需的HTML、CSS和JavaScript,然后在…...
b2b免费发布信息网站/如何免费自己创建网站
随着互联网的深入发展,前端开发工程师已成为市场上极具竞争力的人才。许多学生,包括以前的UI,java,或完全零基础,想学习的前端。那么话不多说,直接上干货,希望能帮助到大家。 前端开发受欢迎程度…...
做外贸哪些网站可以发免费信息/百度文库个人登录
set 不允许重复 无序 hashset->hashmap LinkedHashSet—LinkedHashMap TreeSet----TreeMap实现了SortedSet接口 return map.put(e, PRESENT)null; //PRESENT始终是一个new object 将元素作为key存储,这也是为什么Set元素无序,不重复,不为n…...
风铃网站具体是做那方面的/北京网站优化公司
在Linux当中有一些命令只有root账户才能使用,怎么样才能使普通的用户可以执行root权限的命令呢,就是要使用一个名字叫做sudo的命令,下面是对sudo命令的一些介绍sudo是linux系统管理指令,是允许系统管理员让普通用户执行一些或者全部的root命令的一个工具,…...