当前位置: 首页 > news >正文

【强化学习】Soft Actor-Critic (SAC) 算法

        📢本篇文章是博主强化学习(RL)领域学习时,用于个人学习、研究或者欣赏使用,并基于博主对相关等领域的一些理解而记录的学习摘录和笔记,若有不当和侵权之处,指出后将会立即改正,还望谅解。文章分类在👉强化学习专栏:

       【强化学习】- 【单智能体强化学习】(13)---《Soft Actor-Critic (SAC) 算法》

Soft Actor-Critic (SAC) 算法

目录​​​​​​​

一、Soft Actor-Critic (SAC) 算法详解

二、SAC 背景与核心思想

1. 强化学习的挑战

2. 最大熵强化学习的目标

三、SAC 算法流程

初始化:

每一回合循环:

四、公式推导

1. Q 值更新

2. 值函数更新

3. 策略网络更新

4. 目标值函数更新

[Python]  Soft Actor-Critic算法实现

[Notice] 代码核心

五、 SAC 优势


一、Soft Actor-Critic (SAC) 算法详解

        Soft Actor-Critic(SAC) 是一种最先进的强化学习算法,属于 Actor-Critic 方法的变体。它特别适合处理 连续动作空间,并通过引入最大熵(Maximum Entropy)强化学习的思想,解决了许多传统算法中的稳定性和探索问题。


二、SAC 背景与核心思想

1. 强化学习的挑战

  • 探索与利用的平衡:传统算法在初期探索新策略与后期利用已有最优策略之间难以达到平衡。
  • 不稳定性:在连续动作空间中,训练通常会出现发散或收敛缓慢的问题。
  • 样本效率:强化学习中,数据采集成本高,如何有效利用经验池中的数据是关键。

SAC 引入了以下核心思想来应对这些问题:

  1. 最大熵强化学习:在最大化累计奖励的同时,最大化策略的随机性(熵),以鼓励探索。
  2. 双 Q 网络:缓解 Q 值过估计的问题。
  3. 目标网络:使用目标网络稳定 Q 值计算。

2. 最大熵强化学习的目标

传统强化学习的目标是最大化期望累计奖励:

J(\pi) = \mathbb{E}{\pi} \left[ \sum{t=0}^T \gamma^t r(s_t, a_t) \right]

而 SAC 则通过添加一个 熵项,在奖励中加入策略随机性的权重,目标变为:

J(\pi) = \mathbb{E}{\pi} \left[ \sum{t=0}^T \gamma^t \left( r(s_t, a_t) + \alpha \mathcal{H}(\pi(\cdot|s_t)) \right) \right]

其中:

  • \mathcal{H}(\pi(\cdot|s_t)) = -\mathbb{E}_{a \sim \pi} [\log \pi(a|s_t)],表示策略的熵,鼓励策略更随机化;
  • \alpha:熵系数,控制熵和奖励之间的平衡。

效果

  • 更好的探索:熵的最大化使策略更加多样化。
  • 更稳定的学习:避免陷入次优策略。

三、SAC 算法流程

        SAC 使用了 Actor-Critic 框架,结合策略梯度和 Q 函数更新。以下是算法的关键步骤:

初始化

  1. 初始化两组 Q 网络Q_{\theta_1}, Q_{\theta_2},用于计算 Q 值。
  2. 初始化策略网络\pi_\phi和值函数网络V_\psi
  3. 创建目标值函数网络V_{\psi'},并设置其参数为 V_{\psi'} 的初始值。

每一回合循环

  1. 采样动作

    • 根据策略网络\pi_\phi 采样动作 a \sim \pi(a|s)
    • 执行动作,记录(s, a, r, s', \text{done}) 到经验池中。
  2. 更新 Q 网络

    • 使用 TD 目标更新 Q 值: y = r + \gamma (1 - \text{done}) \cdot V_{\psi'}(s')
    • 最小化以下损失函数: J_Q = \mathbb{E} \left[ \left( Q_{\theta_i}(s, a) - y \right)^2 \right] \quad (i = 1, 2)
  3. 更新值函数网络

    • 值函数V_\psi的目标是逼近以下值:
      y_V = \mathbb{E}{a \sim \pi} \left[ \min{i=1,2} Q_{\theta_i}(s, a) - \alpha \log \pi_\phi(a|s) \right]
    • 最小化值函数损失:J_V = \mathbb{E} \left[ \left( V_\psi(s) - y_V \right)^2 \right]
  4. 更新策略网络

    • 策略网络的目标是最大化奖励和熵,最小化以下损失:
      J_\pi = \mathbb{E} \left[ \alpha \log \pi_\phi(a|s) - \min_{i=1,2} Q_{\theta_i}(s, a) \right]
  5. 更新目标值函数网络

    • 使用软更新规则: \psi' \gets \tau \psi + (1 - \tau) \psi'


四、公式推导

1. Q 值更新

        Q 值通过 Bellman 方程更新,目标是最小化 TD 误差:y = r + \gamma (1 - \text{done}) \cdot V_{\psi'}(s')

        损失函数为: J_Q = \mathbb{E}{(s, a, r, s') \sim D} \left[ \left( Q{\theta_i}(s, a) - y \right)^2 \right]

2. 值函数更新

        值函数估计策略的长期价值,目标值为:

y_V = \mathbb{E}{a \sim \pi} \left[ \min{i=1,2} Q_{\theta_i}(s, a) - \alpha \log \pi_\phi(a|s) \right]

        损失函数为:J_V = \mathbb{E}{s \sim D} \left[ \left( V\psi(s) - y_V \right)^2 \right]

3. 策略网络更新

        策略网络的目标是最大化奖励和熵,等价于最小化:

J_\pi = \mathbb{E}{s \sim D, a \sim \pi} \left[ \alpha \log \pi\phi(a|s) - \min_{i=1,2} Q_{\theta_i}(s, a) \right]

4. 目标值函数更新

        目标值函数使用软更新规则:\psi' \gets \tau \psi + (1 - \tau) \psi'

        其中 \tau \in (0, 1] 控制更新步长。


[Python]  Soft Actor-Critic算法实现

        以下是PyTorch中Soft Actor-Critic (SAC)算法的完整实现:

 项目代码我已经放入GitCode里面,可以通过下面链接跳转:🔥

【强化学习】--- Soft Actor-Critic算法 

后续相关单智能体强化学习算法也会不断在【强化学习】项目里更新,如果该项目对你有所帮助,请帮我点一个星星✨✨✨✨✨,鼓励分享,十分感谢!!!

若是下面代码复现困难或者有问题,也欢迎评论区留言

 1.参数设置

"""《SAC, Soft Actor-Critic算法》时间:2024.12作者:不去幼儿园
"""
import torch  # 引入 PyTorch 库,用于构建和训练深度学习模型
import torch.nn as nn  # PyTorch 的神经网络模块
import torch.optim as optim  # PyTorch 的优化模块,用于更新模型参数
import numpy as np  # NumPy 库,用于高效的数值计算
import gym  # OpenAI Gym 库,用于创建和交互强化学习环境
import random  # Python 的随机模块,用于随机抽样
from collections import deque  # Python 的双端队列模块,用于构建经验回放缓冲区# 超参数设置
GAMMA = 0.99  # 折扣因子,用于计算未来奖励
TAU = 0.005  # 软更新目标网络的参数
ALPHA = 0.2  # 熵正则化系数,鼓励探索
LR = 0.001  # 学习率,用于优化器
BATCH_SIZE = 256  # 每次训练的样本数量
MEMORY_CAPACITY = 100000  # 经验回放缓冲区的最大容量

2.策略网络

# 策略网络(用于生成随机的策略动作)
class PolicyNetwork(nn.Module):def __init__(self, state_dim, action_dim, max_action):super(PolicyNetwork, self).__init__()self.fc1 = nn.Linear(state_dim, 256)  # 第一层全连接层,输入状态维度self.fc2 = nn.Linear(256, 256)  # 第二层全连接层self.mean = nn.Linear(256, action_dim)  # 输出动作均值self.log_std = nn.Linear(256, action_dim)  # 输出动作的对数标准差self.max_action = max_action  # 动作的最大值,用于缩放def forward(self, state):x = torch.relu(self.fc1(state))  # 激活第一层x = torch.relu(self.fc2(x))  # 激活第二层mean = self.mean(x)  # 计算动作均值log_std = self.log_std(x).clamp(-20, 2)  # 将对数标准差限制在合理范围内std = torch.exp(log_std)  # 通过对数标准差计算标准差return mean, std  # 返回均值和标准差def sample(self, state):mean, std = self.forward(state)  # 获取动作分布的均值和标准差normal = torch.distributions.Normal(mean, std)  # 正态分布x_t = normal.rsample()  # 使用重参数化技巧采样y_t = torch.tanh(x_t)  # 使用 Tanh 将动作限制在 [-1, 1]action = y_t * self.max_action  # 缩放动作到最大值范围log_prob = normal.log_prob(x_t)  # 计算动作的对数概率log_prob -= torch.log(1 - y_t.pow(2) + 1e-6)  # Tanh 的修正项log_prob = log_prob.sum(dim=-1, keepdim=True)  # 对每个维度求和return action, log_prob  # 返回动作和对数概率

 3.Q 网络

# Q 网络(价值函数,用于评估状态-动作对的价值)
class QNetwork(nn.Module):def __init__(self, state_dim, action_dim):super(QNetwork, self).__init__()self.fc1 = nn.Linear(state_dim + action_dim, 256)  # 输入包括状态和动作self.fc2 = nn.Linear(256, 256)  # 第二层全连接层self.fc3 = nn.Linear(256, 1)  # 输出单一 Q 值def forward(self, state, action):x = torch.cat([state, action], dim=-1)  # 将状态和动作连接起来作为输入x = torch.relu(self.fc1(x))  # 激活第一层x = torch.relu(self.fc2(x))  # 激活第二层x = self.fc3(x)  # 输出 Q 值return x  # 返回 Q 值

 4.经验回放缓冲区

# 经验回放缓冲区
class ReplayBuffer:def __init__(self, capacity):self.buffer = deque(maxlen=capacity)  # 初始化一个具有固定最大容量的双端队列def push(self, state, action, reward, next_state, done):  # 存储经验self.buffer.append((state, action, reward, next_state, done))def sample(self, batch_size):  # 随机采样batch = random.sample(self.buffer, batch_size)  # 随机选取 batch_size 个经验states, actions, rewards, next_states, dones = zip(*batch)  # 解压return (np.array(states), np.array(actions), np.array(rewards),np.array(next_states), np.array(dones))def __len__(self):  # 返回缓冲区当前大小return len(self.buffer)

 5.SAC 算法


# SAC 算法智能体
class SACAgent:def __init__(self, state_dim, action_dim, max_action):self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")  # 检查是否有 GPU# 初始化网络self.actor = PolicyNetwork(state_dim, action_dim, max_action).to(self.device)  # 策略网络self.q1 = QNetwork(state_dim, action_dim).to(self.device)  # 第一个 Q 网络self.q2 = QNetwork(state_dim, action_dim).to(self.device)  # 第二个 Q 网络# 初始化优化器self.actor_optimizer = optim.Adam(self.actor.parameters(), lr=LR)  # 策略网络优化器self.q1_optimizer = optim.Adam(self.q1.parameters(), lr=LR)  # Q1 优化器self.q2_optimizer = optim.Adam(self.q2.parameters(), lr=LR)  # Q2 优化器# 初始化经验回放缓冲区self.replay_buffer = ReplayBuffer(MEMORY_CAPACITY)self.max_action = max_action  # 最大动作值def select_action(self, state):  # 根据策略选择动作state = torch.FloatTensor(state).to(self.device).unsqueeze(0)  # 转换状态为张量action, _ = self.actor.sample(state)  # 从策略中采样动作return action.cpu().detach().numpy()[0]  # 转换为 NumPy 格式返回def train(self):  # 训练智能体if len(self.replay_buffer) < BATCH_SIZE:  # 如果经验回放缓冲区不足,跳过训练return# 从回放缓冲区采样states, actions, rewards, next_states, dones = self.replay_buffer.sample(BATCH_SIZE)states = torch.FloatTensor(states).to(self.device)actions = torch.FloatTensor(actions).to(self.device)rewards = torch.FloatTensor(rewards).unsqueeze(1).to(self.device)next_states = torch.FloatTensor(next_states).to(self.device)dones = torch.FloatTensor(dones).unsqueeze(1).to(self.device)# 更新 Q 网络with torch.no_grad():next_actions, log_probs = self.actor.sample(next_states)  # 计算下一步的动作及其概率target_q1 = self.q1(next_states, next_actions)  # Q1 值target_q2 = self.q2(next_states, next_actions)  # Q2 值target_q = torch.min(target_q1, target_q2) - ALPHA * log_probs  # 使用最小值更新q_target = rewards + GAMMA * (1 - dones) * target_q  # 计算目标 Q 值q1_loss = ((self.q1(states, actions) - q_target) ** 2).mean()  # Q1 损失q2_loss = ((self.q2(states, actions) - q_target) ** 2).mean()  # Q2 损失self.q1_optimizer.zero_grad()  # 清空梯度q1_loss.backward()  # 反向传播self.q1_optimizer.step()  # 更新 Q1self.q2_optimizer.zero_grad()q2_loss.backward()self.q2_optimizer.step()# 更新策略网络new_actions, log_probs = self.actor.sample(states)q1_new = self.q1(states, new_actions)q2_new = self.q2(states, new_actions)q_new = torch.min(q1_new, q2_new)actor_loss = (ALPHA * log_probs - q_new).mean()  # 策略损失self.actor_optimizer.zero_grad()actor_loss.backward()self.actor_optimizer.step()def update_replay_buffer(self, state, action, reward, next_state, done):self.replay_buffer.push(state, action, reward, next_state, done)

6.主函数循环

# 训练循环
env = gym.make("Pendulum-v1")  # 创建环境
state_dim = env.observation_space.shape[0]  # 状态空间维度
action_dim = env.action_space.shape[0]  # 动作空间维度
max_action = float(env.action_space.high[0])  # 最大动作值agent = SACAgent(state_dim, action_dim, max_action)  # 初始化智能体num_episodes = 500  # 训练的总回合数
for episode in range(num_episodes):state = env.reset()  # 重置环境episode_reward = 0  # 初始化总奖励done = Falsewhile not done:action = agent.select_action(state)  # 根据策略选择动作next_state, reward, done, _ = env.step(action)  # 执行动作agent.update_replay_buffer(state, action, reward, next_state, done)  # 更新经验agent.train()  # 训练智能体state = next_state  # 更新状态episode_reward += reward  # 累积奖励print(f"Episode {episode}, Reward: {episode_reward}")  # 打印回合奖励


[Notice] 代码核心

(SAC, Soft Actor-Critic)算法是一种支持连续动作空间的强化学习算法。核心功能包括:

  1. 策略网络(Policy Network):生成随机策略,用于采样动作。
  2. 价值网络(Q 网络):评估当前动作-状态对的价值。
  3. 经验回放缓冲区:存储并采样过往经验,提升训练稳定性。
  4. 训练循环:在环境中反复交互,学习最优策略。
​# 环境配置
Python                  3.11.5
torch                   2.1.0
torchvision             0.16.0
gym                     0.26.2

        由于博文主要为了介绍相关算法的原理和应用的方法,缺乏对于实际效果的关注,算法可能在上述环境中的效果不佳或者无法运行,一是算法不适配上述环境,二是算法未调参和优化,三是没有呈现完整的代码,四是等等。上述代码用于了解和学习算法足够了,但若是想直接将上面代码应用于实际项目中,还需要进行修改。


五、 SAC 优势

  1. 样本效率高:使用离线经验池,充分利用历史数据。
  2. 探索能力强:通过最大化熵,鼓励更广泛的探索。
  3. 稳定性好:结合双 Q 网络和目标网络,降低训练波动。
  4. 适用于连续动作空间:支持复杂控制任务,如机器人控制。

参考文献:

[Haarnoja, Tuomas, et al. "Soft actor-critic: Off-policy maximum entropy deep reinforcement learning with a stochastic actor."‌发表于2018年,详细介绍了SAC算法的基本原理和应用‌1。

Haarnoja, Tuomas, et al. "Soft actor-critic algorithms and applications."‌ 同进一步探讨了SAC算法的损失函数和最大熵框架‌

 更多强化学习文章,请前往:【强化学习(RL)】专栏


        博客都是给自己看的笔记,如有误导深表抱歉。文章若有不当和不正确之处,还望理解与指出。由于部分文字、图片等来源于互联网,无法核实真实出处,如涉及相关争议,请联系博主删除。如有错误、疑问和侵权,欢迎评论留言联系作者,或者添加VX:Rainbook_2,联系作者。✨

相关文章:

【强化学习】Soft Actor-Critic (SAC) 算法

&#x1f4e2;本篇文章是博主强化学习&#xff08;RL&#xff09;领域学习时&#xff0c;用于个人学习、研究或者欣赏使用&#xff0c;并基于博主对相关等领域的一些理解而记录的学习摘录和笔记&#xff0c;若有不当和侵权之处&#xff0c;指出后将会立即改正&#xff0c;还望谅…...

2024年博客之星主题创作|Android 开发:前沿技术、跨领域融合与就业技能展望

目录 引言 一、推动 Android 应用创新的核心力量 1.1 人工智能与机器学习的崛起 1.2 增强现实&#xff08;AR&#xff09;与虚拟现实&#xff08;VR&#xff09;的应用扩展 1.3 5G技术的推动 1.4 跨平台开发技术的成熟 1.4.1 React Native 1.4.2 Flutter 1.4.3 Taro …...

Spring Boot--@PathVariable、@RequestParam、@RequestBody

目录 声明&#xff01;&#xff01; 什么是RESTful&#xff1f; RESTful 的基本原则 无状态性&#xff08;Stateless&#xff09; 统一接口&#xff08;Uniform Interface&#xff09; 分层系统&#xff08;Layered System&#xff09; 缓存&#xff08;Cacheable&#…...

网站HTTP改成HTTPS

您不仅需要知道如何将HTTP转换为HTTPS&#xff0c;还必须在不妨碍您的网站自成立以来建立的任何搜索排名权限的情况下进行切换。 为什么应该从HTTP转换为HTTPS&#xff1f; 与非安全HTTP于不同&#xff0c;安全域使用SSL&#xff08;安全套接字层&#xff09;服务器上的加密代…...

Spring Boot + Netty + WebSocket 实现消息推送

1、关于Netty Netty 是一个利用 Java 的高级网络的能力&#xff0c;隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架。 2、Maven依赖 <dependencies><!-- https://mvnrepository.com/artifact/io.netty/netty-all --><dependency><gr…...

AI之HardWare:英伟达NvidiaGPU性价比排名(消费级/专业级/中高端企业级)以及据传英伟达Nvidia2025年将推出RTX 5090/5080、华为2025年推出910C/910D

AI之HardWare&#xff1a;英伟达NvidiaGPU性价比排名(消费级/专业级/中高端企业级)以及据传英伟达Nvidia2025年将推出RTX 5090/5080、华为2025年推出910C/910D 目录 英伟达NvidiaGPU性能排名(消费级/专业级/中高端企业级) NVIDIA中消费级和专业级 GPU NVIDIA中高端企业GPU …...

ESP32云开发二( http + led + lcd)

文章目录 前言先上效果图platformio.iniwokwi.tomldiagram.json源代码编译编译成功上传云端完结撒花⭐⭐⭐⭐⭐ 前言 阅读此篇前建议先看 此片熟悉下wokwi https://blog.csdn.net/qq_20330595/article/details/144289986 先上效果图 Column 1Column 2 platformio.ini wokwi…...

JavaScript语言的软件工程

JavaScript语言的软件工程 引言 在当今软件开发的浪潮中&#xff0c;JavaScript已不仅仅是一个简单的前端脚本语言。它的位置已经升华为全栈开发的重要语言之一&#xff0c;借助Node.js等技术&#xff0c;JavaScript不仅可以用于浏览器环境&#xff0c;还可以在后端服务器中运…...

【Qt】04-Lambda表达式

前言一、概念引入二、使用方法2.1 基本用法代码示例2.2 捕获外部变量2.3 参数列表 三、完整代码mywidget.cppsecondwidget.cppmywidget.hsecondwidget.h 总结 前言 一、概念引入 Lambda表达式&#xff08;Lambda Expressions&#xff09;是C11标准引入的一种匿名函数对象&…...

Golang 生态学习

1. Go 语言基础 在深入 Go 语言的生态之前&#xff0c;首先需要掌握 Go 语言本身的核心特性。 • Go 语言官方文档&#xff1a;https://golang.org/doc/ Go 官方文档是学习语言基础和标准库的首选资源。 • 学习内容&#xff1a; • 基础语法&#xff1a;数据类型、控制流…...

Arcgis Pro安装完成后启动失败的解决办法

场景 之前安装的Arcgis Pro 今天突然不能使用了&#xff0c;之前是可以使用的&#xff0c;自从系统更新了以后就出现了这个问题。 环境描述 Arcgis Pro 3.0 Windows 10 问题描述 打开Arcgis Pro&#xff0c;页面也不弹出来&#xff0c;打开任务管理器可以看到进程创建之后&…...

支持向量机SVM的应用案例

支持向量机&#xff08;Support Vector Machine,SVM&#xff09;是一种强大的监督学习算法&#xff0c;广泛应用于分类和回归任务。 基本原理 SVM的主要目标是周到一个最优的超平面&#xff0c;该超平面能够将不同类别的数据点尽可能分开&#xff0c;并且使离该超平面最近的数…...

Linux中的Iptables介绍

文章目录 iptables1. 概述2. **工作原理**3. 数据包处理流程与规则匹配顺序4. 常用的匹配条件5. 动作类型6. 基本命令7. 高级功能 iptables 1. 概述 Iptables 是一个用于配置 Linux 内核防火墙的用户空间工具。它能够对进出服务器的网络数据包进行过滤、修改和转发等操作&…...

14天学习微服务-->第2天:Spring Cloud深入与实践

第2天&#xff1a;Spring Cloud深入与实践 一、Spring Cloud核心组件深入 在微服务架构中&#xff0c;Spring Cloud 提供了一系列核心组件来支持服务的注册与发现、配置管理、负载均衡等功能。今天我们将深入学习其中的三个关键组件&#xff1a;Eureka/Nacos&#xff08;服务…...

使用 Box2D 库开发愤怒的小鸟游戏

使用 Box2D 库开发愤怒的小鸟游戏 Box2D 是一个开源的 2D 物理引擎&#xff0c;广泛应用于游戏开发中&#xff0c;特别是在模拟物体的运动、碰撞、重力等方面。在本文中&#xff0c;我们将利用 Box2D 库开发一个简化版的 愤怒的小鸟 游戏。我们将一步步展示如何实现物理引擎的…...

C# ComboBox 控件属性

ComboBox 的基本属性 在C#中&#xff0c;ComboBox控件具有多种属性&#xff0c;这些属性可以帮助开发者更好地控制和管理控件的各个方面。以下是一些基本的ComboBox属性及其功能&#xff1a; 公共属性 AccessibilityObject&#xff1a;获取分配给该控件的AccessibleObject。 Ac…...

《keras 3 内卷神经网络》

keras 3 内卷神经网络 作者&#xff1a;Aritra Roy Gosthipaty 创建日期&#xff1a;2021/07/25 最后修改时间&#xff1a;2021/07/25 描述&#xff1a;深入研究特定于位置和通道无关的“内卷”内核。 &#xff08;i&#xff09; 此示例使用 Keras 3 在 Colab 中查看 GitHub …...

Linux:文件描述符fd、系统调用open

目录 一、文件基础认识 二、C语言操作文件的接口 1.> 和 >> 2.理解“当前路径” 三、相关系统调用 1.open 2.文件描述符 3.一切皆文件 4.再次理解重定向 一、文件基础认识 文件 内容 属性。换句话说&#xff0c;如果在电脑上新建了一个空白文档&#xff0…...

ToDesk设置临时密码和安全密码都可以当做连接密码使用

ToDesk 在各领域办公都已经是非常常见了 为了安全 ToDesk 设置了连接密码&#xff0c;想连接 需要输入远程码和连接密码 我们刚打开 系统默认给我们用的是临时密码&#xff0c;安全性确实很强 和定时Tokey一样&#xff0c;固定时间切换。 但是 如果我们要经常连接这个电脑&a…...

C#防止重复提交

C#防止重复提交 文章目录 C#防止重复提交前言防止重复提交的思路Web API 防止重复提交代码实现代码讲解使用方法 MVC防止重复提交总结 前言 当用户在前端进行提交数据时&#xff0c;如果网络出现卡顿和前端没有给出响应的话顾客通常都会狂点提交按钮&#xff0c;这样就很容易导…...

递归算法学习v2.2

46. 全排列 class Solution {List<List<Integer>> ret;List<Integer> path;boolean[] check;public List<List<Integer>> permute(int[] nums) {ret new ArrayList<>();path new ArrayList<>();check new boolean[nums.length…...

unity插件Excel转换Proto插件-ExcelToProtobufferTool

unity插件Excel转换Proto插件-ExcelToProtobufferTool **ExcelToProtobufTool 插件文档****1. 插件概述****2. 默认配置类&#xff1a;DefaultIProtoPathConfig****属性说明** **3. 自定义配置类****定义规则****示例代码** **4. 使用方式****4.1 默认路径****4.2 自定义路径**…...

manim(manimgl)安装教学-win11(2024-08)

manim 目前的两种版本&#xff1a;★★ 稍微捋一捋【项目中的 readme.md 十分重要】 manimgl 是 Grant Sanderson&#xff08;YouTube频道 3Blue1Brown的作者&#xff09;等人开发。 现在为 manimgl&#xff0c;在维护中。 manimCE 是2020年后的 manim 分支 manim community e…...

【语言处理和机器学习】概述篇(基础小白入门篇)

前言 自学笔记&#xff0c;分享给语言学/语言教育学方向的&#xff0c;但对语言数据处理感兴趣但是尚未入门&#xff0c;却需要在论文中用到的小伙伴&#xff0c;欢迎大佬们补充或绕道。ps&#xff1a;本文不涉及公式讲解&#xff08;文科生小白友好体质&#xff09;&#xff…...

脚本工具:PYTHON

Python 是一种高级编程语言&#xff0c;以其简洁清晰的语法和强大的功能被广泛应用于各种领域&#xff0c;包括自动化脚本编写、数据分析、机器学习、Web开发等。以下是一些关于使用 Python 编写脚本工具的基本介绍、常用库以及一些实用技巧总结。 这里写目录标题 基础知识安装…...

一文讲解Redis常见使用方式

1. 单机模式部署 适用场景&#xff1a; • 开发和测试环境&#xff0c;或者对高可用性要求不高的小型项目。 部署步骤&#xff1a; 1. 拉取 Redis 镜像&#xff1a; docker pull redis:latest 2. 运行 Redis 容器&#xff1a; docker run -d --name redis-single -p 637…...

Gin 源码概览 - 路由

本文基于gin 1.1 源码解读 https://github.com/gin-gonic/gin/archive/refs/tags/v1.1.zip 1. 注册路由 我们先来看一段gin代码&#xff0c;来看看最终得到的一颗路由树长啥样 func TestGinDocExp(t *testing.T) {engine : gin.Default()engine.GET("/api/user", f…...

【计算机网络】传输层协议TCP与UDP

传输层 传输层位于OSI七层网络模型的第四层&#xff0c;主要负责端到端通信&#xff0c;可靠性保障&#xff08;TCP&#xff09;&#xff0c;流量控制(TCP)&#xff0c;拥塞控制(TCP)&#xff0c;数据分段与分组&#xff0c;多路复用与解复用等&#xff0c;通过TCP与UDP协议实现…...

iOS UIScrollView的一个特性

1如果UIScrollView 的contentSize.height > scrollView.bounds.size.height - scrollView.contentInset.top - scrollView.contentInset.bottom &#xff0c; 则scrollView就可以滚动&#xff0c;否则无法滚动 并且最大的滚动范围就是 contentSize.height - &#xff08; s…...

Docker 实现MySQL 主从复制

一、拉取镜像 docker pull mysql:5.7相关命令&#xff1a; 查看镜像&#xff1a;docker images 二、启动镜像 启动mysql01、02容器&#xff1a; docker run -d -p 3310:3306 -v /root/mysql/node-1/config:/etc/mysql/ -v /root/mysql/node-1/data:/var/lib/mysql -e MYS…...

python爬虫入门(实践)

python爬虫入门&#xff08;实践&#xff09; 一、对目标网站进行分析 二、博客爬取 获取博客所有h2标题的路由 确定目标&#xff0c;查看源码 代码实现 """ 获取博客所有h2标题的路由 """url "http://www.crazyant.net"import re…...

通过Ukey或者OTP动态口令实现windows安全登录

通过 安当SLA&#xff08;System Login Agent&#xff09;实现Windows安全登录认证&#xff0c;是一种基于双因素认证&#xff08;2FA&#xff09;的解决方案&#xff0c;旨在提升 Windows 系统的登录安全性。以下是详细的实现方法和步骤&#xff1a; 1. 安当SLA的核心功能 安…...

C 语言雏启:擘画代码乾坤,谛观编程奥宇之初瞰

大家好啊&#xff0c;我是小象٩(๑ω๑)۶ 我的博客&#xff1a;Xiao Xiangζั͡ޓއއ 很高兴见到大家&#xff0c;希望能够和大家一起交流学习&#xff0c;共同进步。* 这一课主要是让大家初步了解C语言&#xff0c;了解我们的开发环境&#xff0c;main函数&#xff0c;库…...

【Linux系统编程】—— 进程替换及其在操作系统中的应用与实现

文章目录 什么是进程替换&#xff1f;进程替换当中的接口单进程替换多进程的替换详解exec接口execlexeclpexecv 前言&#xff1a; 本篇博客将深入探讨进程替换的概念及其在操作系统中的作用。我们将介绍进程替换的基本原理&#xff0c;探讨操作系统如何通过进程的切换来实现任务…...

“裸奔”时代下该如何保护网络隐私

网络隐私的保护之道 引言 在这个信息爆炸的时代&#xff0c;网络已经深入到我们生活的每一个角落。你是否曾想过&#xff0c;在享受这些便利时&#xff0c;你的个人隐私正面临着严峻的挑战&#xff1f;网络隐私的现状警示着我们&#xff0c;信息泄露的事件屡见不鲜&#xff0…...

分类问题(二元,多元逻辑回归,费歇尔判别分析)spss实操

分类模型&#xff1a; 二分类和多分类&#xff1a; 对于二分类模型 &#xff0c;我们将介绍逻辑回归和Fisher线性判别分析两种分类算法; 对于多分类模型&#xff0c;我们将简单介绍Spss中的多分类线性判别分析和多分类逻辑回归的操作步骤 二分类: 基于广义线性模型&#x…...

推荐一个开源的轻量级任务调度器!TaskScheduler!

大家好&#xff0c;我是麦鸽。 这次推荐一款轻量级的嵌入式任务调度器&#xff0c;目前已经有1.4K的star&#xff0c;这个项目比较轻量化&#xff0c;只有5个源文件&#xff0c;可以作为学习的一个开源项目。 核心文件 项目概述&#xff1a; 这是一个轻量级的协作式多任务处理&…...

Spring 核心技术解析【纯干货版】- IV:Spring 切面编程模块 Spring-Aop 模块精讲

随着软件开发技术的不断进步&#xff0c;面向切面编程&#xff08;AOP&#xff09;作为一种重要的编程思想&#xff0c;已经在现代开发中占据了重要地位。它通过将横切逻辑从业务逻辑中分离出来&#xff0c;使得代码更加清晰、易于维护。Spring AOP 作为 Spring 框架的核心模块…...

STM32之FreeRTOS开发介绍(十九)

STM32F407 系列文章 - freertos&#xff08;十九&#xff09; 目录 前言 一、简述 二、开源网址 三、原理及功能特性 1.原理简介 2.功能介绍 1.任务调度 2.任务管理 3.中断管理 4.消息队列 3.特点说明 4.优缺点 四、参考书籍 五、实现方式 总结 前言 FreeRTOS是…...

2024年美赛C题评委文章及O奖论文解读 | AI工具如何影响数学建模?从评委和O奖论文出发-O奖论文做对了什么?

模型假设仅仅是简单陈述吗&#xff1f;允许AI的使用是否降低了比赛难度&#xff1f;还在依赖机器学习的模型吗&#xff1f;处理题目的方法有哪些&#xff1f;O奖论文的优点在哪里&#xff1f; 本文调研了当年赛题的评委文章和O奖论文&#xff0c;这些问题都会在文章中一一解答…...

第14篇:从入门到精通:掌握python上下文管理器

第14篇&#xff1a;上下文管理器 内容简介 本篇文章将深入探讨Python中的上下文管理器&#xff08;Context Manager&#xff09;。您将了解上下文管理器的概念与用途&#xff0c;学习如何实现自定义的上下文管理器&#xff0c;以及如何使用contextlib模块来简化上下文管理器的…...

cuda从零开始手搓PB神经网络

cuda实现PB神经网络 基于上一篇的矩阵点乘&#xff0c;实现了矩阵的加减乘除、函数调用等。并且复用之前元编程里面写的梯度下降、Adam、NAdam优化方法。实现PB神经网络如下&#xff1a; #ifndef __BP_NETWORK_HPP__ #define __BP_NETWORK_HPP__ #include "matrix.hpp&quo…...

Java 大视界 -- Java 大数据物联网应用:数据处理与设备管理(八)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...

大模型之三十三- 开源Melo 语音合成

大模型之三十三- 开源Melo 语音合成 文本到语音(TTS)系统从基于基础音素的模型演变成复杂的端到端神经方法,这种方法可以直接将文本转换为语音。这一变革得益于深度学习的进步和计算能力的提升,已经在语音的自然度、韵律控制和跨语言能力方面取得了重大进展 。现代TTS系统…...

全同态加密理论、生态现状与未来展望(上)

《全同态加密理论、生态现状与未来展望》系列由lynndell2010gmail.com和mutourend2010gmail.com整理原创发布&#xff0c;分为上中下三个系列&#xff1a; 全同态加密理论、生态现状与未来展望&#xff08;上&#xff09;&#xff1a;专注于介绍全同态加密理论知识。全同态加密…...

cursor重构谷粒商城02——30分钟构建图书管理系统【cursor使用教程番外篇】

前言&#xff1a;这个系列将使用最前沿的cursor作为辅助编程工具&#xff0c;来快速开发一些基础的编程项目。目的是为了在真实项目中&#xff0c;帮助初级程序员快速进阶&#xff0c;以最快的速度&#xff0c;效率&#xff0c;快速进阶到中高阶程序员。 本项目将基于谷粒商城…...

提升大语言模型的三大策略

1.概述 随着大语言模型&#xff08;LLMs&#xff09;在技术和应用上的不断发展&#xff0c;它们已经深刻地改变了我们与计算机的互动方式。从文本生成到语言理解&#xff0c;LLMs的应用几乎涵盖了各个行业。然而&#xff0c;尽管这些模型已展现出令人印象深刻的能力&#xff0c…...

Ubuntu 24.04 LTS 安装 Docker Desktop

Docker 简介 Docker 简介和安装Ubuntu上学习使用Docker的详细入门教程Docker 快速入门Ubuntu版&#xff08;1h速通&#xff09; Docker 安装 参考 How to Install Docker on Ubuntu 24.04: Step-by-Step Guide。 更新系统和安装依赖 在终端中运行以下命令以确保系统更新并…...

mysql查看binlog日志

mysql 配置、查看binlog日志&#xff1a; 示例为MySQL8.0 1、 检查binlog开启状态 SHOW VARIABLES LIKE ‘log_bin’; 如果未开启&#xff0c;修改配置my.ini 开启日志 安装目录配置my.ini(mysql8在data目录) log-binmysql-bin&#xff08;开启日志并指定日志前缀&#xff…...

2. Flink分区策略

一. Flink分区策略概述 Flink任务在执行过程中&#xff0c;一个流(stream)包含一个或多个分区(Stream partition)&#xff0c;TaskManager中的一个slot的SubTask就是一个stream partition(流分区)。 Flink分区之间进行数据传递模式有两种。 1. one-to-one模式 数据不需要重新…...