《机器学习数学基础》补充资料:拉格朗日乘子法

瑞士数学家欧拉(Leonhard Euler,1707-1783)的大名,如雷贯耳——欧拉,是按德文发音翻译。欧拉不仅是公认的十八世纪最伟大的数学家,还是目前史上最多产的数学家。所著的书籍及论文多达 886 部(篇),涉及非常多领域。平均每年发表约 800 页的高水平学术论文,而且和贝多芬类似,他失明以后发表论文的速度更快了!

如果你生活在十八世纪,就可以把你遇到的数学难题寄到德国柏林科学院,交给非常厉害的欧拉来解决,他几乎什么难题都能解出来。但当时有一个条件极值问题,欧拉长期没能解开。

条件极值问题是这样的,比如说我们想求 z=xyz = xyz=xy 的极值,却有条件限制:x2+xy−y3=2x^2 + xy - y^3 = 2x2+xyy3=2。也就是说,我们要从那些满足方程式 x2+xy−y3=2x^2 + xy - y^3 = 2x2+xyy3=2 的点中,选取点代入 z=xyz = xyz=xy,看看哪些点代入后会有极大值或极小值。

当时有一位初生牛犊不怕虎的青年,约瑟夫-路易・拉格朗日(Joseph-Louis Lagrange)。他 17 岁以前对数学都没有兴趣,有一天无意中读了英国埃德蒙・哈雷(Edmund Halley,就是命名一颗彗星的那个哈雷)的文章后,开始对数学产生兴趣,并开始学习数学。而在他 19 岁时,便寄了一封信给欧拉,告诉欧拉条件极值问题其实可以轻松解决。欧拉看完他的信后,抱着头说:“天啊,这么简单我怎么没想到!” 随后,拉格朗日声名大噪,当上了皇家炮兵学校的教授,一位 19 岁的教授。日后他也做出了许多非常杰出的研究,拿破仑称赞他是 “数学上高耸的金字塔”。

这个故事告诉我们,即使本来对数学没有兴趣也没关系,我们还是有可能轻松学好数学的。为了帮助你成为现代的拉格朗日,我们先来学习如何求解条件极值,这个方法称为拉格朗日乘子法(Lagrange multiplier method)。

我们先将目标函数设为 z=f(x,y)=xyz = f(x, y) = xyz=f(x,y)=xy,要求它的极值。至于条件限制,先设为 g(x,y)=x2+y2=1g(x, y) = x^2 + y^2 = 1g(x,y)=x2+y2=1​。也就是说,我们现在要从单位圆上取点,来找出哪些点会使 z=xyz = xyz=xy 取得极值。

我们先在坐标平面上,画出 x2+y2=1x^2 + y^2 = 1x2+y2=1。然后在同一张图上,画出目标函数 z=xyz = xyz=xy 的等高线图。在下图中,画出了 z=0.1,0.2,0.4,0.6,0.8z = 0.1, 0.2, 0.4, 0.6, 0.8z=0.1,0.2,0.4,0.6,0.8​ 时的等高线。

在这里插入图片描述

现在要从 x2+y2=1x^2 + y^2 = 1x2+y2=1 上取点代入 z=xyz = xyz=xy ,那么取的点,必然是 x2+y2=1x^2 + y^2 = 1x2+y2=1 和某条等高线的交点。在 z=0.1,0.2,0.4z = 0.1, 0.2, 0.4z=0.1,0.2,0.4 这几条等高线,都还与条件限制 x2+y2=1x^2 + y^2 = 1x2+y2=1 有交点。但 z=0.6,0.8z = 0.6, 0.8z=0.6,0.8 这两条,就超出范围了,我将它们标为红色,表示那不是我们关注的。

将某一条等高线,越往某个方向移动, zzz 值就会呈现某种趋势,可能是越来越大或者越来越小。在这个例子中,等高线越往圆外, zzz 值就越大。我们现在要找极值,所以就拼命地将等高线往圆外拉,一直拉到不能再拉为止。什么叫做 “不能再拉” 呢?就是仍然与 x2+y2=1x^2 + y^2 = 1x2+y2=1 有交点,但再拉就会超出范围了。什么样的状态,会是仍有交点,但再拉就会超出范围呢?就是相切的时候!

所以,我们要找的那些点,就是条件限制 x2+y2=1x^2 + y^2 = 1x2+y2=1 与目标函数 z=xyz = xyz=xy​ 的等高线相切的那些点。至于,什么叫做 “相切” 呢?相切即是,它们在某个点的法向量是平行的!而该点称为切点。于是,我们现在只要分别求条件限制 g(x,y)=x2+y2=1g(x, y) = x^2 + y^2 = 1g(x,y)=x2+y2=1 与各等高线 f(x,y)=xy=ckf(x, y) = xy = c_kf(x,y)=xy=ck 的法向量,并解出使它们平行的条件即可。

如果对一个隐函数取梯度后,再代入点 PPP ,就会得到它在点 PPP 处的法向量。而我们的条件限制 g(x,y)=x2+y2=1g(x, y) = x^2 + y^2 = 1g(x,y)=x2+y2=1 与各等高线 f(x,y)=xy=ckf(x, y) = xy = c_kf(x,y)=xy=ck ,确实都是隐函数的形式。至于两个向量平行,就是其中一个向量为另一个向量的常数倍。例如 (3,2)(3, 2)(3,2)(−6,−4)(-6, -4)(6,4) 平行,可写成 (−6,−4)=−2(3,2)(-6, -4) = -2(3, 2)(6,4)=2(3,2)

所以总结以上,我们需要求解:
∇f(x,y)=λ∇g(x,y) \nabla f(x, y) = \lambda \nabla g(x, y) f(x,y)=λg(x,y)
也就是
{fx(x,y)=λgx(x,y)fy(x,y)=λgy(x,y)\begin{cases} f_x(x, y) = \lambda g_x(x, y) \\ f_y(x, y) = \lambda g_y(x, y) \end{cases} {fx(x,y)=λgx(x,y)fy(x,y)=λgy(x,y)
解出符合条件的 (x,y)(x, y)(x,y) 。至于其中的 λ\lambdaλ ,称为拉格朗日乘子(Lagrange multiplier)。

为什么要用 λ\lambdaλ 这个符号,可能是因为拉格朗日(Lagrange)的首字母 LLL 对应的希腊字母是 λ\lambdaλ

另外也别忘了,我们所找出的点,一定要满足条件限制 g(x,y)g(x, y)g(x,y) 。所以准确地说,应该是:

Lagrange 乘子法(Lagrange multiplier method)

在条件限制 g(x,y)=kg(x,y)=kg(x,y)=k 的条件下,求目标函数 f(x,y)f(x,y)f(x,y) 的极值。先求出所有的 (x,y,λ)(x, y, \lambda)(x,y,λ) 满足:
{fx(x,y)=λgx(x,y)fy(x,y)=λgy(x,y)g(x,y)=k \begin{cases} f_x(x,y)=\lambda g_x(x,y) \\f_y(x, y)=\lambda g_y(x,y) \\g(x,y)=k \end{cases} fx(x,y)=λgx(x,y)fy(x,y)=λgy(x,y)g(x,y)=k
然后解出这些 (x,y)(x,y)(x,y),代入到目标函数 f(x,y)f(x,y)f(x,y) 中,得到最大的即为极大值,最小的即为极小值。

f(x,y)=x2+y2f(x,y) = x^2 + y^2f(x,y)=x2+y2 的极值,条件为 x2−2x+y2−4y=0x^2 - 2x + y^2 - 4y = 0x22x+y24y=0

解:

设约束条件为 g(x,y)=x2−2x+y2−4y=0g(x,y) = x^2 - 2x + y^2 - 4y = 0g(x,y)=x22x+y24y=0,根据拉格朗日乘数法,列联立方程组:
{2x=λ(2x−2)(梯度分量相等,fx=λgx)2y=λ(2y−4)(梯度分量相等,fy=λgy)x2−2x+y2−4y=0(满足约束条件) \begin{cases} 2x = \lambda (2x - 2) \quad \text{(梯度分量相等,$f_x = \lambda g_x$)} \\ 2y = \lambda (2y - 4) \quad \text{(梯度分量相等,$f_y = \lambda g_y$)} \\ x^2 - 2x + y^2 - 4y = 0 \quad \text{(满足约束条件)} \end{cases} 2x=λ(2x2)(梯度分量相等,fx=λgx2y=λ(2y4)(梯度分量相等,fy=λgyx22x+y24y=0(满足约束条件)
步骤 1:消去拉格朗日乘子 λ\boldsymbol{\lambda}λ

从前两个方程解 λ\lambdaλ​(若分母非零):

  • 2x−2≠02x - 2 \neq 02x2=0(即 x≠1x \neq 1x=1),则 λ=2x2x−2=xx−1\lambda = \dfrac{2x}{2x - 2} = \dfrac{x}{x - 1}λ=2x22x=x1x

  • 2y−4≠02y - 4 \neq 02y4=0(即 y≠2y \neq 2y=2),则 λ=2y2y−4=yy−2\lambda = \dfrac{2y}{2y - 4} = \dfrac{y}{y - 2}λ=2y42y=y2y

令两式相等:
xx−1=yy−2 \dfrac{x}{x - 1} = \dfrac{y}{y - 2} x1x=y2y
交叉相乘化简:
x(y−2)=y(x−1)  ⟹  xy−2x=xy−y  ⟹  y=2x x(y - 2) = y(x - 1) \implies xy - 2x = xy - y \implies y = 2x x(y2)=y(x1)xy2x=xyyy=2x
步骤 2:代入约束条件求解 (x,y)(x, y)(x,y)

y=2xy = 2xy=2x 代入约束条件 x2−2x+y2−4y=0x^2 - 2x + y^2 - 4y = 0x22x+y24y=0
x2−2x+(2x)2−4⋅(2x)=0x2−2x+4x2−8x=05x2−10x=05x(x−2)=0 \begin{align*} x^2 - 2x + (2x)^2 - 4 \cdot (2x) &= 0 \\ x^2 - 2x + 4x^2 - 8x &= 0 \\ 5x^2 - 10x &= 0 \\ 5x(x - 2) &= 0 \end{align*} x22x+(2x)24(2x)x22x+4x28x5x210x5x(x2)=0=0=0=0
解得:

  • x=0x = 0x=0,对应 y=2⋅0=0y = 2 \cdot 0 = 0y=20=0

  • x=2x = 2x=2,对应 y=2⋅2=4y = 2 \cdot 2 = 4y=22=4

步骤 3:验证 λ=0\boldsymbol{\lambda = 0}λ=0 的特殊情况

λ=0\lambda = 0λ=0,代入前两个方程:

  • 2x=0  ⟹  x=02x = 0 \implies x = 02x=0x=0

  • 2y=0  ⟹  y=02y = 0 \implies y = 02y=0y=0

验证约束条件:02−2⋅0+02−4⋅0=00^2 - 2 \cdot 0 + 0^2 - 4 \cdot 0 = 00220+0240=0,满足条件,故 (0,0)(0, 0)(0,0) 也是解。

步骤 4:计算函数值并判断极值

将两点代入 f(x,y)=x2+y2f(x,y) = x^2 + y^2f(x,y)=x2+y2

  • f(0,0)=02+02=0f(0, 0) = 0^2 + 0^2 = 0f(0,0)=02+02=0

  • f(2,4)=22+42=20f(2, 4) = 2^2 + 4^2 = 20f(2,4)=22+42=20

几何意义补充(辅助理解)

约束条件配方为:(x−1)2+(y−2)2=5(x - 1)^2 + (y - 2)^2 = 5(x1)2+(y2)2=5

这是 (1,2)(1, 2)(1,2) 为圆心、5\sqrt{5}5 为半径的圆

  • f(x,y)f(x,y)f(x,y) 表示点 (x,y)(x,y)(x,y)原点的距离的平方。

  • 原点到圆心 (1,2)(1, 2)(1,2) 的距离为 12+22=5\sqrt{1^2 + 2^2} = \sqrt{5}12+22=5(等于圆的半径),说明 原点在圆上(对应点 (0,0)(0,0)(0,0),距离最小为 0);

  • (2,4)(2, 4)(2,4) 是圆上离原点最远的点(距离平方为 20)。

因此,f(0,0)=0f(0, 0) = 0f(0,0)=0极小值f(2,4)=20f(2, 4) = 20f(2,4)=20​ 是极大值

拉格朗日乘子法的流程并不困难,就算你不明白它背后的原理,只是把这个方法死记下来也能使用。难就难在解联立方程的时候,技巧千变万化,没有固定的方法。

程序实现

以下是使用Python实现拉格朗日乘子法的代码。

方法1:符号解法(使用SymPy)

import sympy as spdef lagrange_multiplier(f, constraints, variables):"""符号解法实现拉格朗日乘子法:param f: 目标函数:param constraints: 等式约束列表 [g1, g2, ...]:param variables: 变量列表 [x1, x2, ...]:return: 极值点及乘子组成的字典"""# 创建拉格朗日乘子符号lambdas = sp.symbols(f'λ1:{len(constraints)+1}')# 构造拉格朗日函数L = ffor i, con in enumerate(constraints):L += lambdas[i] * con# 生成方程组equations = []for var in variables:equations.append(sp.diff(L, var))equations.extend(constraints)# 求解方程组all_vars = list(variables) + list(lambdas)solutions = sp.solve(equations, all_vars, dict=True)return solutions# 示例:求 f(x,y) = x² + 2y² 在约束 x + y - 1 = 0 下的极值
if __name__ == "__main__":# 定义变量x, y = sp.symbols('x y')# 定义目标函数和约束f = x**2 + 2*y**2constraints = [x + y - 1]  # 等式约束列表# 调用拉格朗日乘子法solutions = lagrange_multiplier(f, constraints, [x, y])# 打印结果print("符号解法结果:")for i, sol in enumerate(solutions):print(f"解{i+1}:")print(f"  x = {sol[x]}, y = {sol[y]}, λ = {sol[sp.Symbol('λ1')]}")print(f"  目标函数值: {f.subs({x: sol[x], y: sol[y]})}\n")

输出示例

符号解法结果:
解1:x = 2/3, y = 1/3, λ = -4/3目标函数值: 2/3

方法2:数值解法(使用SciPy)

import numpy as np
from scipy.optimize import minimizedef lagrange_numeric():"""数值解法实现拉格朗日乘子法"""# 目标函数def f(X):x, y = Xreturn x**2 + 2*y**2# 约束条件(字典形式)cons = ({'type': 'eq', 'fun': lambda X: X[0] + X[1] - 1})# 初始猜测点initial_guess = np.array([0.0, 0.0])# 使用SLSQP算法求解result = minimize(f, initial_guess, constraints=cons, method='SLSQP')return result# 示例求解
if __name__ == "__main__":res = lagrange_numeric()print("\n数值解法结果:")print(f"最优解: x = {res.x[0]:.6f}, y = {res.x[1]:.6f}")print(f"目标函数值: {res.fun:.6f}")print(f"是否成功: {res.success}")print(f"迭代次数: {res.nit}")

输出示例

数值解法结果:
最优解: x = 0.666667, y = 0.333333
目标函数值: 0.666667
是否成功: True
迭代次数: 2

方法3:KKT系统求解法(多约束通用)

from scipy.optimize import fsolve
import numpy as npdef lagrange_kkt(f, gradf, constraints, grad_constraints, initial_guess):"""求解KKT系统的数值方法(支持多约束):param f: 目标函数(未使用,仅为接口一致):param gradf: 目标函数梯度:param constraints: 约束函数列表 [g1, g2, ...]:param grad_constraints: 约束梯度列表 [∇g1, ∇g2, ...]:param initial_guess: 初始猜测 [x1, x2, ..., λ1, λ2, ...]:return: 解向量"""n_vars = len(initial_guess) - len(constraints)def equations(vars):# 拆分变量和乘子x = vars[:n_vars]lambdas = vars[n_vars:]# 梯度方程: ∇f + Σλi∇gi = 0grad_eq = gradf(x) for i, grad_con in enumerate(grad_constraints):grad_eq += lambdas[i] * grad_con(x)# 约束方程: gi(x) = 0con_eq = [con(x) for con in constraints]return np.concatenate([grad_eq, con_eq])return fsolve(equations, initial_guess)# 示例:求解多约束问题
if __name__ == "__main__":# 问题:min x² + y² + z²# 约束: #   x + y - 1 = 0#   y + z - 2 = 0# 定义梯度函数gradf = lambda X: np.array([2*X[0], 2*X[1], 2*X[2]])# 定义约束及其梯度constraints = [lambda X: X[0] + X[1] - 1,lambda X: X[1] + X[2] - 2]grad_constraints = [lambda X: np.array([1, 1, 0]),lambda X: np.array([0, 1, 1])]# 初始猜测 [x, y, z, λ1, λ2]initial_guess = np.array([0.0, 0.0, 0.0, 0.0, 0.0])# 求解KKT系统solution = lagrange_kkt(None, gradf, constraints, grad_constraints, initial_guess)print("\nKKT系统解法结果:")print(f"x = {solution[0]:.6f}, y = {solution[1]:.6f}, z = {solution[2]:.6f}")print(f"λ1 = {solution[3]:.6f}, λ2 = {solution[4]:.6f}")print(f"目标函数值: {sum(x**2 for x in solution[:3]):.6f}")

输出示例

KKT系统解法结果:
x = 0.000000, y = 1.000000, z = 1.000000
λ1 = 0.000000, λ2 = -2.000000
目标函数值: 2.000000

方法4:深度学习方法

import numpy as np
import tensorflow as tf
from tensorflow import keras
from scipy.optimize import minimize# 定义神经网络架构
def create_optimizer_model(input_dim, output_dim):"""创建用于预测拉格朗日乘子法解的神经网络模型参数:input_dim: 输入维度 (目标函数参数+约束参数)output_dim: 输出维度 (解向量维度)"""model = keras.Sequential([keras.layers.Input(shape=(input_dim,)),keras.layers.Dense(64, activation='relu'),keras.layers.Dense(64, activation='relu'),keras.layers.Dense(output_dim)  # 输出解向量])return model# 生成训练数据
def generate_training_data(num_samples, problem_dim):"""生成训练数据: 随机问题参数和对应的数值解参数:num_samples: 样本数量problem_dim: 问题维度 (变量数+约束数)"""# 随机生成目标函数参数和约束参数problem_params = np.random.rand(num_samples, problem_dim)# 存储数值解solutions = np.zeros((num_samples, problem_dim))# 为每个样本计算数值解for i in range(num_samples):# 使用scipy计算数值解 (替代原solve_lagrange)res = minimize(fun=lambda x: np.sum((x - problem_params[i, :problem_dim//2])**2),  # 示例目标函数x0=np.zeros(problem_dim//2),  # 初始猜测constraints={'type': 'eq', 'fun': lambda x: np.sum(x) - problem_params[i, -1]},method='SLSQP')solutions[i, :len(res.x)] = res.xreturn problem_params, solutions# 自定义损失函数
def custom_loss(y_true, y_pred):"""均方误差损失函数"""return tf.reduce_mean(tf.square(y_true - y_pred))# 主程序
if __name__ == "__main__":# 参数设置problem_dim = 6  # 问题维度 (例如: 3个变量 + 3个约束参数)output_dim = 3   # 输出维度 (解向量维度, 等于变量数)num_samples = 1000  # 训练样本数量# 创建神经网络模型optimizer_model = create_optimizer_model(problem_dim, output_dim)optimizer_model.compile(optimizer='adam', loss=custom_loss)# 生成训练数据problem_params, solutions = generate_training_data(num_samples, problem_dim)# 训练神经网络print("开始训练神经网络...")history = optimizer_model.fit(problem_params, solutions, epochs=50, batch_size=32,validation_split=0.2)print("\n训练完成!")print(f"最终训练损失: {history.history['loss'][-1]:.4f}")print(f"最终验证损失: {history.history['val_loss'][-1]:.4f}")# 测试神经网络预测test_params = np.random.rand(1, problem_dim)prediction = optimizer_model.predict(test_params)print(f"\n测试输入: {test_params[0]}")print(f"预测解: {prediction[0]}")

《机器学习数学基础》一书在各大平台有售,请认准作者、出版社
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/89596.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/89596.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【PTA数据结构 | C语言版】二叉堆的朴素建堆操作

本专栏持续输出数据结构题目集,欢迎订阅。 文章目录题目代码题目 请编写程序,将 n 个顺序存储的数据用朴素建堆操作调整为最小堆;最后顺次输出堆中元素以检验操作的正确性。 输入格式: 输入首先给出一个正整数 c(≤1…

深入解析PyQt5信号与槽的高级玩法:解锁GUI开发新姿势

信号与槽机制是PyQt框架实现组件间通信的核心技术。掌握其高级用法能极大提升开发效率和代码灵活性。本文将通过六大核心模块,结合实战案例,全方位解析信号与槽的进阶使用技巧。自定义信号与槽的完全指南 1. 信号定义规范 class CustomWidget(QWidget):#…

gitee某个分支合并到gitlab目标分支

一、克隆Gitee仓库到本地 git clone https://gitee.com/用户名/仓库名.gitcd 仓库名二、添加 GitLab 仓库作为远程仓库 git remote add gitlab https://gitlab.com/用户名/仓库名.git三、查看所有远程仓库 git remote -v四、拉取 Gitee 上的目标分支 git fetch origin 分支名五…

PyQt5信号与槽(信号与槽的高级玩法)

信号与槽的高级玩法 高级自定义信号与槽 所谓高级自定义信号与槽,指的是我们可以以自己喜欢的方式定义信号与槽函 数,并传递参数。自定义信号的一般流程如下: (1)定义信号。 (2)定义槽函数。 &a…

第5天 | openGauss中一个用户可以访问多个数据库

接着昨天继续学习openGauss,今天是第五天了。今天学习内容是使用一个用户访问多个数据库。 老规矩,先登陆墨天轮为我准备的实训实验室 rootmodb:~# su - omm ommmodb:~$ gsql -r创建表空间music_tbs、数据库musicdb10 、用户user10 并赋予 sysadmin权限 omm# CREATE…

Vue3 Anime.js超级炫酷的网页动画库详解

简介 Anime.js 是一个轻量级的 JavaScript 动画库&#xff0c;它提供了简单而强大的 API 来创建各种复杂的动画效果。以下是 Anime.js 的主要使用方法和特性&#xff1a; 安装 npm install animejs 基本用法 <script setup> import { ref, onMounted } from "vu…

苦练Python第18天:Python异常处理锦囊

苦练Python第18天&#xff1a;Python异常处理锦囊 原文链接&#xff1a;https://dev.to/therahul_gupta/day-18100-exception-handling-with-try-except-in-python-3m5a 作者&#xff1a;Rahul Gupta 译者&#xff1a;倔强青铜三 前言 大家好&#xff0c;我是倔强青铜三。是一名…

JVM——如何对java的垃圾回收机制调优?

GC 调优的核心思路就是尽可能的使对象在年轻代被回收&#xff0c;减少对象进入老年代。 具体调优还是得看场景根据 GC 日志具体分析&#xff0c;常见的需要关注的指标是 Young GC 和 Full GC 触发频率、原因、晋升的速率、老年代内存占用量等等。 比如发现频繁会产生 Ful GC&am…

正则表达式使用示例

下面以 Vue&#xff08;前端&#xff09;和 Spring Boot&#xff08;后端&#xff09;为例&#xff0c;展示正则表达式在前后端交互中的应用&#xff0c;以邮箱格式验证为场景&#xff1a;1.前端<template><div class"register-container"><h3>用户…

云端微光,AI启航:低代码开发的智造未来

文章目录前言一、引言&#xff1a;技术浪潮中的个人视角初次体验腾讯云开发 Copilot1.1 低代码的时代机遇1.1.1 为什么低代码如此重要&#xff1f;1.2 AI 的引入&#xff1a;革新的力量1.1.2 Copilot 的亮点1.3 初学者的视角1.3.1 Copilot 带来的改变二、体验记录&#xff1a;云…

图片上传实现

图片上传change函数图片上传图片上传到服务器上传的图片在该页面中显示修改界面代码最终实现效果change函数 这里我们先用输入框控件来举例&#xff1a; 姓名&#xff1a;<input typetext classname>下面我们来写 js 语句&#xff0c;对控件进行绑事件来获取输入框内的…

【PTA数据结构 | C语言版】多叉堆的上下调整

本专栏持续输出数据结构题目集&#xff0c;欢迎订阅。 文章目录题目代码题目 请编写程序&#xff0c;将 n 个已经满足 d 叉最小堆顺序约束的数据直接读入最小堆&#xff1b;随后将下一个读入的数据 x 插入堆&#xff1b;再执行删顶操作并输出删顶的元素&#xff1b;最后顺次输…

selenium后续!!

小项目案例:实现批量下载网页中的资源根据15.3.2小节中的返回网页内容可知,用户只有获取了网页中的图片url才可以将图片下载到*在使用selenium库渲染网页后,可直接通过正则表达式过滤出指定的网页图片&#xff0c;从而实现批量下载接下来以此为思路来实现一个小项目案例。项目任…

深度解析Linux文件I/O三级缓冲体系:用户缓冲区→标准I/O→内核页缓存

在Linux文件I/O操作中&#xff0c;缓冲区的管理是一个核心概念&#xff0c;主要涉及用户空间缓冲区和内核空间缓冲区。理解这两者的区别和工作原理对于高效的文件操作至关重要。 目录 一、什么是缓冲区 二、为什么要引入缓冲区机制 三、三级缓冲体系 1、三级缓冲体系全景图…

【每日算法】专题十三_队列 + 宽搜(bfs)

1. 算法思路 BFS 算法核心思路 BFS&#xff08;广度优先搜索&#xff09;使用 队列&#xff08;Queue&#xff09;按层级顺序遍历图或树的节点。以下是 C 实现的核心思路和代码模板&#xff1a; 算法框架 #include <queue> #include <vector> #include <un…

【动手实验】发送接收窗口对 TCP传输性能的影响

环境准备 服务器信息 两台腾讯云机器 t04&#xff08;172.19.0.4&#xff09;、t11&#xff08;172.19.0.11&#xff09;&#xff0c;系统为 Ubuntu 22.04&#xff0c;内核为 5.15.0-139-generic。默认 RT 在 0.16s 左右。 $ ping 172.19.0.4 PING 172.19.0.4 (172.19.0.4) …

28、鸿蒙Harmony Next开发:不依赖UI组件的全局气泡提示 (openPopup)和不依赖UI组件的全局菜单 (openMenu)、Toast

目录 不依赖UI组件的全局气泡提示 (openPopup) 弹出气泡 创建ComponentContent 绑定组件信息 设置弹出气泡样式 更新气泡样式 关闭气泡 在HAR包中使用全局气泡提示 不依赖UI组件的全局菜单 (openMenu) 弹出菜单 创建ComponentContent 绑定组件信息 设置弹出菜单样…

让老旧医疗设备“听懂”新语言:CAN转EtherCAT的医疗行业应用

在医疗影像设备的智能化升级中&#xff0c;通信协议的兼容性常成为工程师的“痛点”。例如&#xff0c;某医院的移动式X射线机采用CAN协议控制机械臂&#xff0c;而主控系统基于EtherCAT架构。两者协议差异导致数据延迟高达5ms&#xff0c;影像定位精度下降&#xff0c;甚至影响…

ubuntu基础搭建

ubuntu上docker的搭建 https://vulhub.org/zh 网站最下面找到开始使用&#xff0c;有搭建的命令//安装docker&#xff0c;连接失败多试几次 curl -fsSL https://get.docker.com | sh //验证Docker是否正确安装&#xff1a; docker version //还要验证Docker Compose是否可用&am…

动态规划 + DFS + 记忆化!Swift 解 LeetCode 329 的实战笔记

文章目录摘要描述题解答案题解代码分析代码解析示例测试及结果时间复杂度空间复杂度总结摘要 这篇文章带你用 Swift 实战一道非常经典的 DFS 记忆化搜索题目 —— LeetCode 329《矩阵中的最长递增路径》。看似一个简单的“走格子”游戏&#xff0c;实则考察了搜索顺序、剪枝策…