西瓜书学习笔记——流形学习(公式推导+举例应用)

文章目录

      • 等度量映射(仅保留点与其邻近点的距离)
        • 算法介绍
        • 实验分析
      • 局部线性嵌入(不仅保留点与其邻近点的距离还要保留邻近关系)
        • 算法介绍
        • 实验分析

等度量映射(仅保留点与其邻近点的距离)

算法介绍

等度量映射(Isomap)的基本思想是通过保持数据点之间的测地距离(沿着数据流形的最短路径测量的距离)来近似保持数据流形的局部几何结构。这与传统的多维缩放(MDS)不同,MDS通常保持点之间的欧几里德距离,而这可能在流形结构下失效。

而流形是指在高维空间中嵌入的低维结构,这种结构可能是非线性的、弯曲的,而不是简单的线性关系。

接着利用流行在局部上与欧式空间同胚这个性质,对每个点基于欧式距离找出其近邻点,然后将近邻点连接起来,构成一个无向图,接着使用DijkstraFloyd求解最短路径构成距离矩阵,最终使用MDS算法求解。

其中同胚是指,一个 n n n维流形是指每个点都有一个邻域,该邻域与 n n n维欧式空间中的开集同胚。这意味着在每个点的附近,流形的局部结构可以用欧式空间的坐标系统来描述。虽然整个流形可能是非欧式的,但在每个点处,我们可以找到一个局部的坐标系统,使得该点附近的结构与欧式空间中的结构相似。(这与微积分的定义很相似,都是在某一邻域上的近似)

下图是Isomap的算法流程图:

在这里插入图片描述

Isomap 只提供了训练样本在低维空间的坐标,对于新样本,一种通用的方法是使用回归学习器。通过将训练样本的高维空间坐标作为输入,相应的低维空间坐标作为输出,训练一个回归模型。该模型可用于对新样本的低维空间坐标进行预测,尽管这只是一种权宜之计,目前似乎还没有更好的方法来处理 Isomap 在新样本上的映射问题。

构建近邻图有两种常见方法:一是指定K近邻点,二是指定距离阈值得到d近邻图。但两者存在问题,过大的近邻范围可能导致“短路”,将远距离点误认为近邻;反之,过小的范围可能导致“断路”,某些区域与其他区域失去连接。这可能对后续最短路径计算产生误导。选择构建方法时需要权衡参数以避免这些问题。

实验分析
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt# 读取数据
data = pd.read_csv('data/correlated_dataset.csv')# 计算欧氏距离
def euclidean_distance(point1, point2):return np.sqrt(np.sum((point1 - point2)**2))# 计算近邻图
def compute_neighbors(data, k=5):num_samples = len(data)neighbors = np.zeros((num_samples, k), dtype=int)for i in range(num_samples):distances = [euclidean_distance(data.iloc[i], data.iloc[j]) for j in range(num_samples) if i != j]indices = np.argsort(distances)[:k]neighbors[i] = indicesreturn neighbors# 计算测地距离
def compute_geodesic_distances(neighbors, data):num_samples = len(data)geodesic_distances = np.zeros((num_samples, num_samples))for i in range(num_samples):for j in range(num_samples):if i != j:path_distance = 0current = inext_neighbor = neighbors[i, 0]while next_neighbor != j:path_distance += euclidean_distance(data.iloc[current], data.iloc[next_neighbor])current = next_neighbornext_neighbor = neighbors[current, 0]geodesic_distances[i, j] = path_distancereturn geodesic_distances# Isomap算法
def isomap(data, k_neighbors=5, low_dim=2):# 计算近邻图neighbors = compute_neighbors(data, k_neighbors)# 计算测地距离geodesic_distances = compute_geodesic_distances(neighbors, data)# 使用MDS算法降维n = len(data)H = np.eye(n) - np.ones((n, n)) / nB = -0.5 * H @ geodesic_distances**2 @ Heigvals, eigvecs = np.linalg.eigh(B)# 取最小的low_dim个特征值对应的特征向量indices = np.argsort(eigvals)[:low_dim]low_dim_eigvecs = eigvecs[:, indices]return low_dim_eigvecs# 降维
low_dim_data = isomap(data.drop(columns=['Target']))# 可视化降维结果
plt.scatter(low_dim_data[:, 0], low_dim_data[:, 1], c=data['Target'], cmap='viridis')
plt.title('Isomap降维结果')
plt.xlabel('主成分1')
plt.ylabel('主成分2')
plt.show()

在这里插入图片描述

局部线性嵌入(不仅保留点与其邻近点的距离还要保留邻近关系)

算法介绍

与Isomap算法不同,局部线性嵌入(LLE)算法是要保留邻近关系。

如下图所示:

在这里插入图片描述
假定样本点 x i x_i xi的坐标能通过它的领域内的样本 x j , x k , x l x_j,x_k,x_l xj,xk,xl的坐标通过线性组合而重构出来的,即:

x i = w i j x j + w i k x k + w i l x l (1) x_i=w_{ij}x_j+w_{ik}x_k+w_{il}x_l\tag{1} xi=wijxj+wikxk+wilxl(1)

而LLE算法希望式(1)这种关系能在低维空间中依然存在。

LLE算法先对每个样本 x i x_i xi找出其近邻的下标集合 Q i Q_i Qi,然后计算出基于 Q i Q_i Qi中的样本点对 x i x_i xi进行线性重构的系数 w i w_i wi
min ⁡ w 1 , w 2 , … , w m ∑ i = 1 m ∥ x i − ∑ j ∈ Q i w i j x j ∥ 2 2 s.t.  ∑ j ∈ Q i w i j = 1 (2) \begin{aligned} \min _{\boldsymbol{w}_1, \boldsymbol{w}_2, \ldots, \boldsymbol{w}_m} & \sum_{i=1}^m\left\|\boldsymbol{x}_i-\sum_{j \in Q_i} w_{i j} \boldsymbol{x}_j\right\|_2^2 \\ \text { s.t. } & \sum_{j \in Q_i} w_{i j}=1 \end{aligned} \tag{2} w1,w2,,wmmin s.t. i=1m xijQiwijxj 22jQiwij=1(2)

我们可以将式(2)进行恒等变形:

∑ i = 1 m ∥ x i − ∑ j ∈ Q i w i j x j ∥ 2 2 = ∑ i = 1 m ∥ ∑ j ∈ Q i w i j x i − ∑ j ∈ Q i w i j x j ∥ 2 2 = ∑ i = 1 m ∥ ∑ j ∈ Q i w i j ( x i − x j ) ∥ 2 2 = ∑ i = 1 m ∥ X i w i ∥ 2 2 = ∑ i = 1 m w i T X i T X i w i (3) \begin{aligned} \sum_{i=1}^m\left\|\boldsymbol{x_i}-\sum_{j \in Q_i} w_{i j} \boldsymbol{x}_j\right\|_2^2 & =\sum_{i=1}^m\left\|\sum_{j \in Q_i} w_{i j} \boldsymbol{x}_i-\sum_{j \in Q_i} w_{i j} \boldsymbol{x}_j\right\|_2^2 \\ & =\sum_{i=1}^m\left\|\sum_{j \in Q_i} w_{i j}\left(\boldsymbol{x}_i-\boldsymbol{x}_j\right)\right\|_2^2 \\ & =\sum_{i=1}^m\left\|\mathbf{X}_i \boldsymbol{w}_{\boldsymbol{i}}\right\|_2^2 \\ & =\sum_{i=1}^m \boldsymbol{w}_{\boldsymbol{i}}{ }^{\mathrm{T}} \mathbf{X}_i^{\mathrm{T}} \mathbf{X}_i \boldsymbol{w}_{\boldsymbol{i}} \end{aligned} \tag{3} i=1m xijQiwijxj 22=i=1m jQiwijxijQiwijxj 22=i=1m jQiwij(xixj) 22=i=1mXiwi22=i=1mwiTXiTXiwi(3)

其中 w i = ( w i q i 1 , w i q i 2 , … , w i q i n ) ∈ R n × 1 , X i = ( x i − x q i 1 , x i − x q i 2 , … , x i − x q i n ) ∈ R d × n \boldsymbol{w}_{\boldsymbol{i}}=\left(w_{i q_i^1}, w_{i q_i^2}, \ldots, w_{i q_i^n}\right) \in \mathbb{R}^{n \times 1}, \mathbf{X}_i=\left(\boldsymbol{x}_i-\boldsymbol{x}_{q_i^1}, \boldsymbol{x}_i-\boldsymbol{x}_{q_i^2}, \ldots, \boldsymbol{x}_i-\boldsymbol{x}_{q_i^n}\right) \in \mathbb{R}^{d \times n} wi=(wiqi1,wiqi2,,wiqin)Rn×1,Xi=(xixqi1,xixqi2,,xixqin)Rd×n。约束条件可进行如下恒等变形:

∑ j ∈ Q i w i j = w i T E = 1 (4) \sum_{j\in Q_i}w_{ij}=w_i^T\mathbf{E}=1\tag{4} jQiwij=wiTE=1(4)

其中 E = ( 1 , 1 , . . . , 1 ) ∈ R n × 1 \mathbf{E}=(1,1,...,1)\in \mathbb{R}^{n\times 1} E=(1,1,...,1)Rn×1 n n n行1列的单位向量。

故优化问题可重写成:
min ⁡ w 1 , w 2 , … , w m ∑ i = 1 m w i T X i T X i w i s.t.  w i T E = 1 (5) \begin{aligned} \min _{\boldsymbol{w}_1, \boldsymbol{w}_2, \ldots, \boldsymbol{w}_m} & \sum_{i=1}^m \boldsymbol{w}_{\boldsymbol{i}}{ }^{\mathrm{T}} \mathbf{X}_i^{\mathrm{T}} \mathbf{X}_i \boldsymbol{w}_{\boldsymbol{i}} \\ \text { s.t. } & w_i^T\mathbf{E}=1 \end{aligned} \tag{5} w1,w2,,wmmin s.t. i=1mwiTXiTXiwiwiTE=1(5)

采用拉格朗日乘子法求解,有:

L ( w 1 , w 2 , … , w m , λ ) = ∑ i = 1 m w i T X i T X i w i + λ ( w i T E − 1 ) (6) L\left(\boldsymbol{w}_1, \boldsymbol{w}_2, \ldots, \boldsymbol{w}_m, \lambda\right)=\sum_{i=1}^m \boldsymbol{w}_{\boldsymbol{i}}^{\mathrm{T}} \mathbf{X}_i^{\mathrm{T}} \mathbf{X}_i \boldsymbol{w}_{\boldsymbol{i}}+\lambda\left(\boldsymbol{w}_{\boldsymbol{i}}^{\mathrm{T}} \boldsymbol{E}-1\right)\tag{6} L(w1,w2,,wm,λ)=i=1mwiTXiTXiwi+λ(wiTE1)(6)

式(6)对 w i w_i wi求偏导并令其为零,有:
∂ L ∂ w i = 2 X i T X i w i + λ E = 0 (8) \frac{\partial L}{\partial w_i}=2 \mathbf{X}_i^T \mathbf{X}_i w_i+\lambda \boldsymbol{E}=0 \tag{8} wiL=2XiTXiwi+λE=0(8)

则:

w i = − 1 2 λ ( X i T X i ) − 1 E (9) w_i=-\frac{1}{2}\lambda (\mathbf{X}_i^T\mathbf{X}_i)^{-1}\boldsymbol{E}\tag{9} wi=21λ(XiTXi)1E(9)

又因为 w i T E = E T w i = 1 w_i^T\mathbf{E}=\mathbf{E}^Tw_i=1 wiTE=ETwi=1,故式(9)两边同时左乘 E T \mathbf{E}^T ET,有:

E T w i = − 1 2 λ E T ( X i T X i ) − 1 E − 1 2 λ = 1 E T ( X i T X i ) − 1 E (10) \begin{aligned} \boldsymbol{E}^Tw_i&=-\frac{1}{2}\lambda \boldsymbol{E}^T(\mathbf{X}_i^T\mathbf{X}_i)^{-1}\boldsymbol{E}\\ -\frac{1}{2}\lambda&=\frac{1}{\boldsymbol{E}^T(\mathbf{X}_i^T\mathbf{X}_i)^{-1}\boldsymbol{E}} \end{aligned}\tag{10} ETwi21λ=21λET(XiTXi)1E=ET(XiTXi)1E1(10)

然后回代入式(9)中,有:

w i = ( X i T X i ) − 1 E E T ( X i T X i ) − 1 E (11) w_i=\frac{(\mathbf{X}_i^T\mathbf{X}_i)^{-1}\boldsymbol{E}}{\boldsymbol{E}^T(\mathbf{X}_i^T\mathbf{X}_i)^{-1}\boldsymbol{E}}\tag{11} wi=ET(XiTXi)1E(XiTXi)1E(11)

令矩阵 ( X i T X i ) − 1 (\mathbf{X}_i^T\mathbf{X}_i)^{-1} (XiTXi)1 i i i行第 k k k列的元素为 C j k − 1 C_{jk}^{-1} Cjk1,即 C j k = ( x i − x j ) T ( x i − x j ) C_{jk}=(x_i-x_j)^T(x_i-x_j) Cjk=(xixj)T(xixj),则:

w i j = w i q i j = ∑ k ∈ Q i C j k − 1 ∑ l , s ∈ Q i C l s − 1 (12) w_{i j}=w_{i q_i^j}=\frac{\sum_{k \in Q_i} C_{j k}^{-1}}{\sum_{l, s \in Q_i} C_{l s}^{-1}} \tag{12} wij=wiqij=l,sQiCls1kQiCjk1(12)

其中 w i j w_{ij} wij原始数据集中的某个数据点 x i \boldsymbol{x}_i xi的邻近集合 Q i Q_i Qi中的某个邻居点 x j \boldsymbol{x}_j xj对重构 x i \boldsymbol{x}_i xi的权重。

由于LLE在低维空间中保持 w i w_i wi不变,于是 x i x_i xi对应的低维空间坐标 z i z_i zi可通过下式求解:

min ⁡ w 1 , w 2 , … , w m ∑ i = 1 m ∥ z i − ∑ j ∈ Q i w i j z j ∥ 2 2 (13) \begin{aligned} \min _{\boldsymbol{w}_1, \boldsymbol{w}_2, \ldots, \boldsymbol{w}_m} & \sum_{i=1}^m\left\|\boldsymbol{z}_i-\sum_{j \in Q_i} w_{i j} \boldsymbol{z}_j\right\|_2^2 \\ \end{aligned} \tag{13} w1,w2,,wmmini=1m zijQiwijzj 22(13)

Z = ( z 1 , z 2 , … , z m ) ∈ R d ′ × m , ( W ) i j = w i j \mathbf{Z}=\left(\boldsymbol{z}_1, \boldsymbol{z}_2, \ldots, \boldsymbol{z}_m\right) \in \mathbb{R}^{d^{\prime} \times m},(\mathbf{W})_{i j}=w_{i j} Z=(z1,z2,,zm)Rd×m,(W)ij=wij
M = ( E − W ) T ( E − W ) (14) \mathbf{M}=\mathbf{(E-W)^T(E-W)}\tag{14} M=(EW)T(EW)(14)

故式(13)可重写为:
min ⁡ Z ∑ i = 1 m ∥ z i − ∑ j ∈ Q i w i j z j ∥ 2 2 = ∑ i = 1 m ∥ Z E i − Z W i ∥ 2 2 = ∑ i = 1 m ∥ Z ( E i − W i ) ∥ 2 2 = ∑ i = 1 m ( Z ( E i − W i ) ) T Z ( E i − W i ) = ∑ i = 1 m ( E i − W i ) T Z T Z ( E i − W i ) = tr ⁡ ( ( E − W ) T Z T Z ( E − W ) ) = tr ⁡ ( Z ( E − W ) ( E − W ) T Z T ) = tr ⁡ ( Z M Z T ) (15) \begin{aligned} \min _{\boldsymbol{Z}} \sum_{i=1}^m\left\|\boldsymbol{z}_i-\sum_{j \in Q_i} w_{i j} \boldsymbol{z}_j\right\|_2^2 & =\sum_{i=1}^m\left\|\boldsymbol{Z} \boldsymbol{E}_i-\boldsymbol{Z} \boldsymbol{W}_i\right\|_2^2 \\ & =\sum_{i=1}^m\left\|\boldsymbol{Z}\left(\boldsymbol{E}_i-\boldsymbol{W}_i\right)\right\|_2^2 \\ & =\sum_{i=1}^m\left(\boldsymbol{Z}\left(\boldsymbol{E}_i-\boldsymbol{W}_i\right)\right)^T \boldsymbol{Z}\left(\boldsymbol{E}_i-\boldsymbol{W}_i\right) \\ & =\sum_{i=1}^m\left(\boldsymbol{E}_i-\boldsymbol{W}_i\right)^T \boldsymbol{Z}^T \boldsymbol{Z}\left(\boldsymbol{E}_i-\boldsymbol{W}_i\right) \\ & =\operatorname{tr}\left((\boldsymbol{E}-\boldsymbol{W})^T \boldsymbol{Z}^T \boldsymbol{Z}(\boldsymbol{E}-\boldsymbol{W})\right) \\ & =\operatorname{tr}\left(\boldsymbol{Z}(\boldsymbol{E}-\boldsymbol{W})(\boldsymbol{E}-\boldsymbol{W})^T \boldsymbol{Z}^T\right) \\ & =\operatorname{tr}\left(\boldsymbol{Z} \boldsymbol{M} \boldsymbol{Z}^T\right)\\ \end{aligned}\tag{15} Zmini=1m zijQiwijzj 22=i=1mZEiZWi22=i=1mZ(EiWi)22=i=1m(Z(EiWi))TZ(EiWi)=i=1m(EiWi)TZTZ(EiWi)=tr((EW)TZTZ(EW))=tr(Z(EW)(EW)TZT)=tr(ZMZT)(15)

其约束条件为 Z T Z = E \mathbf{Z^TZ=E} ZTZ=E是为了得到标准化的低维数据。

整理一下可得:

min ⁡ Z tr ⁡ ( Z M Z T ) s.t.  Z T Z = E (16) \begin{aligned} \min _{\mathbf{Z}} & \operatorname{tr}\left(\boldsymbol{Z} \boldsymbol{M} \boldsymbol{Z}^T\right) \\ \text { s.t. } & \mathbf{Z^TZ=E} \end{aligned} \tag{16} Zmin s.t. tr(ZMZT)ZTZ=E(16)

最终可通过对 M \mathbf{M} M进行特征值分解,取 M \mathbf{M} M最小的 d ′ d^\prime d个特征值所对应的特征向量组成的矩阵即为 Z T \mathbf{Z^T} ZT

LLE算法流程图如下所示:

在这里插入图片描述

实验分析
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt# 读取数据
data = pd.read_csv('data/correlated_dataset.csv')# LLE算法实现
def lle(X, n_neighbors, n_components):m, d = X.shapeW = np.zeros((m, m))# Step 1: 选择近邻for i in range(m):indices = find_neighbors(X[i], X, n_neighbors)W[i, indices] = compute_weights(X[i], X[indices], indices)# Step 2: 计算低维表示M = np.identity(m) - Weigenvalues, eigenvectors = np.linalg.eigh(M)idx = np.argsort(eigenvalues)[1:n_components + 1]embedding = eigenvectors[:, idx]return embedding# 找到近邻
def find_neighbors(x, X, n_neighbors):distances = np.linalg.norm(X - x, axis=1)indices = np.argsort(distances)[:n_neighbors]return indices# 计算权重
def compute_weights(x, X, indices):Z = X - xC = Z @ Z.Tones = np.ones(len(indices))w = np.linalg.solve(C + 1e-3 * np.identity(len(indices)), ones)w /= np.sum(w)return w# 降维并可视化
embedding = lle(data.values[:, :-1], n_neighbors=10, n_components=2)plt.scatter(embedding[:, 0], embedding[:, 1], c=data['Target'], cmap='viridis')
plt.title('LLE Visualization')
plt.show()

在这里插入图片描述

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

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

相关文章

树莓派5一键安装C++版本OpenCV

安装环境 本人当前的安装环境: 树莓派5Raspberry Pi os (64-bit) Debian12 Bookworm 镜像下载地址 我这里是将镜像安装好后直接安装opencv,如果不是刚安装好的镜像需要注意是否有openCV的python之类的安装过,不然可能出现编译错误 一、扩展内…

SpringBoot中数据库的连接及Mybatis的配置和使用

目录 1 在pom.xml中引入相关依赖 2 对数据库进行配置 2.1 配置application.yml 2.2 idea连接数据库 (3.2.1有用到) 3 Mybatis的使用 3.1 测试文件的引入 3.2 使用 3.2.1 使用注解(有小技巧(✪ω✪)) 3.2.2 使用动态sql 1 在pom.xml中引入相关依赖 <dependencies&g…

海外多语言盲盒开发:打破语言障碍,连接全球消费者

随着全球化的加速和互联网的普及&#xff0c;语言障碍成为了影响跨国交流和商业活动的重要因素。为了满足跨国市场的需求&#xff0c;海外多语言盲盒开发成为了一个新兴的领域。本文将探讨海外多语言盲盒开发的意义、现状和未来发展。 一、海外多语言盲盒开发的意义 在全球化…

RedHat8.4安装邮件服务器

一、配置发件服务器 1.1 根据现场IP&#xff0c;配置主机名 vim /etc/hosts 192.168.8.120 mail.test.com 将主机名更改为邮件服务器域名mail.test.com 1.2 关闭防火墙&#xff0c;禁止开机启动 systemctl stop firewalld systemctl disable firewalld 1.3 关闭selinux v…

基于springboot就业信息管理系统源码和论文

随着信息化时代的到来&#xff0c;管理系统都趋向于智能化、系统化&#xff0c;就业信息管理系统也不例外&#xff0c;但目前国内仍都使用人工管理&#xff0c;市场规模越来越大&#xff0c;同时信息量也越来越庞大&#xff0c;人工管理显然已无法应对时代的变化&#xff0c;而…

InnoDB 锁系统(小白入门)

1995年 &#xff0c;MySQL 1.0发布&#xff0c;仅供内部使用&#xff01; 开发多用户、数据库驱动的应用时&#xff0c;最大的一个难点是&#xff1a;一方面要最大程度地利用数据库的并发访问&#xff0c;另一方面还要确保每个用户能以一致性的方式读取和修改数据。 MVCC 并发…

基于python+控制台的员工信息管理系统

基于python控制台的员工信息管理系统 一、系统介绍二、效果展示三、其他系统实现四、获取源码 一、系统介绍 1.添加职工数据 2.显示职工数据 3.查询职工数据 4.修改职工数据 5.删除职工数据 6.保存职工数据 7.排序职工数据 8.统计职工工资数据 9.退出 二、效果展示 三、其他系…

从搜索引擎到答案引擎:LLM驱动的变革

在过去的几周里&#xff0c;我一直在思考和起草这篇文章&#xff0c;认为谷歌搜索正处于被颠覆的边缘&#xff0c;它实际上可能会影响 SEO 作为业务牵引渠道的可行性。 考虑到谷歌二十多年来的完全统治地位&#xff0c;以及任何竞争对手都完全无力削弱它&#xff0c;坦率地说&…

CSS transition(过渡效果)详解并附带示例

CSS过渡效果&#xff08;CSS transitions&#xff09;是一种在元素属性值发生变化时&#xff0c;通过指定过渡效果来实现平滑的动画效果的方法。通过定义起始状态和结束状态之间的过渡属性&#xff0c;可以使元素的变化更加流畅和可视化。 过渡效果的基本语法如下&#xff1a;…

乐意购项目前端开发 #6

一、商品详情页面 代码模版 创建Detail文件夹, 然后创建index.vue文件 <script setup> import { getDetail } from "/api/goods/index"; import { ref, onMounted } from "vue"; import { useRoute } from "vue-router"; import { useCar…

SpringBoot 登录检验JWT令牌 生成与校验

JWT官网 https://jwt.io/ 引入依赖 <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version> </dependency>设置过期时间 LocalDateTime localDateTime LocalDateTime.now().…

STM32--SPI通信协议(1)SPI基础知识总结

前言 I2C (Inter-Integrated Circuit)和SPI (Serial Peripheral Interface)是两种常见的串行通信协议&#xff0c;用于连接集成电路芯片之间的通信&#xff0c;选择I2C或SPI取决于具体的应用需求。如果需要较高的传输速度和简单的接口&#xff0c;可以选择SPI。如果需要连接多…

css1字体属性

一.font-family(字体系列&#xff09; 不同字体系统用&#xff0c;隔开&#xff1b; 多个字母的字体系统用“”&#xff1b; 二.font-size&#xff08;字体大小&#xff09;&#xff08;有单位px&#xff09;&#xff08;默认字体16px&#xff09; 三.font-weight&#xff08…

Leetcode—535. TinyURL 的加密与解密【中等】

2024每日刷题&#xff08;110&#xff09; Leetcode—535. TinyURL 的加密与解密 实现代码 class Solution { public:// Encodes a URL to a shortened URL.string encode(string longUrl) {while(!urlToCode.count(longUrl)) {string code;for(int i 0; i < 6; i) {code…

Blender使用Rigify和Game Rig Tool基础

做动画需要的几个简要步骤&#xff1a; 1.建模 2.绑定骨骼 3.绘制权重 4.动画 1.Rigify是干嘛用的&#xff1f; 》 绑定骨骼 2.Game Rig Tool干嘛用的&#xff1f; 》 修复Rigify绑定骨骼做的动画导入游戏引擎的问题&#xff0c;如果Rigify自身修复了就不需要这个插件了&#…

Python算法100例-1.2 兔子产子

完整源代码项目地址&#xff0c;关注博主私信’源代码’后可获取 1&#xff0e;问题描述 有一对兔子&#xff0c;从出生后的第3个月起每个月都生一对兔子。小兔子长到第3个月后每个月又生一对兔子&#xff0c;假设所有的兔子都不死&#xff0c;问30个月内每个月的兔子总对数为…

ele-h5项目使用vue3+vite+vant4开发:第四节、业务组件-SearchView组件开发

需求分析 展示切换动画搜索框输入文字&#xff0c;自动发送请求搜索结果展示搜索状态维护历史搜索展示&#xff0c;点击历史搜索后发送请求历史搜索更多切换动画效果 <script setup lang"ts"> import OpSearch from /components/OpSearch.vue import { ref } f…

IDEA2023打开新项目默认SDK变成了17

问题描述 项目安装了2个sdk版本&#xff0c;jdk8和jdk17 自从升级IDEA版本到2023以后&#xff0c;每次打开新项目&#xff0c;sdk都被默认选择成了jdk17, 每次都得手动修改 &#xff08;File--Project Structure&#xff09;&#xff0c;超级麻烦。 没有用的解决方法 以下这…

2. 路由 Vue-Router

目录 2.1 Vue-Router 介绍 2.2 路由配置 2.3 嵌套路由 Vue1&#xff1a;基础跟使用方式 2.1 Vue-Router 介绍 vue 属于单页面应用&#xff0c;所谓路由&#xff0c;就是根据浏览器路径不同&#xff0c;用不同的视图组件替换这个页面内容。 在vue应用中使用路由功能&#x…

Unity 渲染管线自动转换的实现 支持HDRP转URP,URP转HDRP

HDRP和URP无法平滑切换&#xff0c;因为属性、功能差异巨大。 本脚本仅对可对应的默认脚本和属性做了转换处理。细节调整还需自己搞。 自动转换可以节省手动更换shader、texture、通用属性的劳动成本。 操作步骤 使用前确保当前项目中存在HDRP和URP的包&#xff0c;没有请到p…