From 426cec0a7683bc6b1182b0f8aef428c40422e377 Mon Sep 17 00:00:00 2001 From: zhangsan <646228430@qq.com> Date: Tue, 8 Apr 2025 12:00:24 +0800 Subject: [PATCH] =?UTF-8?q?Commit=20on=202025/04/08=20=E5=91=A8=E4=BA=8C?= =?UTF-8?q?=2012:00:24.57?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 科研/循环神经网络.md | 74 ++++++++++++++- 科研/数学基础.md | 31 ++++--- 科研/草稿.md | 97 +++++++------------- 科研/郭款论文.md | 2 - 科研/颜佳佳论文.md | 205 ++++++++++++++++++++++++++++++++++++++++-- 自学/Java笔记本.md | 45 ++++++++++ 自学/力扣Hot 100题.md | 204 +++++++++++++++++++++++++++++++++++------ 自学/草稿.md | 70 +++++++++------ 8 files changed, 588 insertions(+), 140 deletions(-) diff --git a/科研/循环神经网络.md b/科研/循环神经网络.md index e309be0..cae1a67 100644 --- a/科研/循环神经网络.md +++ b/科研/循环神经网络.md @@ -244,4 +244,76 @@ $$ **类比**:阅读时遇到关键情节,输入门打开,将新信息写入长期记忆(如角色关系),同时候选状态 $\tilde{c}_t$提供新信息的候选内容。 - **输出门 $o_t$**: 控制从细胞状态中输出多少信息作为当前时间步的隐藏状态。隐藏状态 $h_t$ 通常用于后续计算(例如,生成输出、参与下一时刻计算)。 - **类比**:根据当前任务(如预测下一个词),输出门决定暴露细胞状态的哪部分(如只关注时间、地点等关键信息)。 \ No newline at end of file + **类比**:根据当前任务(如预测下一个词),输出门决定暴露细胞状态的哪部分(如只关注时间、地点等关键信息)。 + + + +## 时序卷积网络TCN + +TCN是一种专为处理序列数据设计的深度学习架构。它通过结合因果卷积、扩张卷积和残差连接,解决了传统RNN和LSTM在并行化能力和梯度稳定性上的局限性。 + +### 1. 因果卷积(Causal Convolution) + +因果卷积确保模型在预测时刻$t$的数据时,仅使用$t$时刻之前的信息,避免未来数据泄漏。 + +因果卷积类似于一个滑动窗口(窗口大小=$k$),每次用当前和过去的$k-1$个值加权求和,生成当前时刻的输出。 + +**公式定义**: +$$ +F(x_{t}) = \sum_{i=0}^{k-1} f_{i} \cdot x_{t - i} +$$ + +- $x_t$:时刻$t$的输入数据 +- $f_i$:一维卷积核的第$i$个权重 +- $k$:卷积核大小 + +**举例:** + +1. **输入序列**:$x = [x_0, x_1, x_2, x_3, x_4] = [1, 3, 2, 5, 4]$ + (长度为5的时间序列,$x_t$表示$t$时刻的值) +2. **卷积核**:$f = [f_0, f_1] = [0.5, -1]$ + (大小为$k=2$,权重分别为$0.5$和$-1$) + +| 时刻 $t$ | 输入 $x_t$ | 计算过程 | 输出 $F(x_t)$ | +| -------- | ---------- | ---------------------------- | -------------------- | +| 0 | 1 | $0.5 \cdot 1 + (-1) \cdot 0$ | $0.5 \times 1 = 0.5$ | +| 1 | 3 | $0.5 \cdot 3 + (-1) \cdot 1$ | $1.5 - 1 = 0.5$ | +| 2 | 2 | $0.5 \cdot 2 + (-1) \cdot 3$ | $1 - 3 = -2$ | +| 3 | 5 | $0.5 \cdot 5 + (-1) \cdot 2$ | $2.5 - 2 = 0.5$ | +| 4 | 4 | $0.5 \cdot 4 + (-1) \cdot 5$ | $2 - 5 = -3$ | + +**最终输出序列**: +$$ +F(x) = [0.5, 0.5, -2, 0.5, -3] +$$ + + + +### 2. 扩张卷积(Dilated Convolution) + +通过**膨胀因子 $d$**在卷积核元素之间插入空洞(间隔),从而在不增加参数量的情况下**扩大感受野**。 + +- **传统卷积**($d=1$):连续覆盖 $k$ 个时间步(如 $x_t, x_{t-1}, x_{t-2}$)。 +- **扩张卷积**($d>1$):跳跃式覆盖,跳过中间部分时间步(如 $x_t, x_{t-d}, x_{t-2d}$)。 + +**公式定义**: +$$ +F(x_{t}) = \sum_{i=0}^{k-1} f_{i} \cdot x_{t - d \cdot i} +$$ + + + +### 3. 残差连接(Residual Connection) + +TCN借鉴ResNet,通过残差块缓解梯度消失问题。 + +**公式定义**: +$$ +\text{Output} = \sigma\bigl(F(x) + W_{1\times1} x \bigr) +$$ + +- $F(x)$:卷积层的输出 +- $\sigma$:激活函数(通常为ReLU) +- $W_{1\times1}$:1×1卷积核,用于调整输入$x$的维度 +- $x$:原始输入 + diff --git a/科研/数学基础.md b/科研/数学基础.md index 376f827..c28f1c4 100644 --- a/科研/数学基础.md +++ b/科研/数学基础.md @@ -868,7 +868,7 @@ $$ 谱聚类的基本思想是通过图的特征向量将数据点映射到低维空间中,然后在这个低维空间中使用传统的聚类技术。 -1.构造相似性图 +**1.构造相似性图** - **数据表示**: 给定数据点 $\{x_1, x_2, \ldots, x_n\}$。 @@ -877,9 +877,11 @@ $$ 根据数据点之间的距离或相似性构造矩阵 $W$。常见方法包括: - **Gaussian 核函数**: + $$ W_{ij} = \exp\Bigl(-\frac{\|x_i - x_j\|^2}{2\sigma^2}\Bigr), $$ + 只有当 $x_i$ 与 $x_j$ 彼此接近时, $W_{ij}$ 才较大;衡量数据点之间的距离并将其映射为一个 [0, 1] 之间的相似性值。 其中 $\sigma$ 为尺度参数,当 $\sigma$ 较小时,只有非常接近的数据点才会被认为是相似的 @@ -888,35 +890,42 @@ $$ -2.构造图拉普拉斯矩阵 +**2.构造图拉普拉斯矩阵** - 对称归一化拉普拉斯矩阵 - 未归一化的拉普拉斯矩阵 -3.计算特征向量 -​ 对选定的拉普拉斯矩阵(例如 $L_{sym}$)进行特征分解,求出前 $k$ 个最小特征值对应的特征向 量。 -​ 注意:对于未归一化的拉普拉斯矩阵,零特征值对应的特征向量通常是常数向量,所以在分 解时忽略这个解,选择第二小开始的 $k$ 个特征向量。 -4.构造嵌入空间 +**3.计算特征向量** + +​ 对选定的拉普拉斯矩阵(例如 $L_{sym}$)进行特征分解,求出**前 $k$ 个最小特征值**对应的特征向量。 +​ 注意:对于未归一化的拉普拉斯矩阵,零特征值对应的特征向量通常是常数向量,所以在分解时忽略这个解,选择第二小开始的 $k$ 个特征向量。 + + + +**4.构造嵌入空间** - **形成矩阵 $U$**: - 将求得的 $k$ 个特征向量作为列组成矩阵 + 将求得的 $k$ 个特征向量作为**列**组成矩阵 + $$ - U = \begin{pmatrix} +U = \begin{pmatrix} u_1(1) & u_2(1) & \cdots & u_k(1) \\ u_1(2) & u_2(2) & \cdots & u_k(2) \\ \vdots & \vdots & \ddots & \vdots \\ u_1(n) & u_2(n) & \cdots & u_k(n) \end{pmatrix}. $$ + 其中,每一行对应原数据点在低维空间中的表示。 - 例: - **归一化(可选)**: 对于对称归一化的情况,可以对 $U$ 的每一行做归一化处理,使得每一行变为单位向量,这一步有助于后续聚类的稳定性。 -5.聚类 + + +**5.聚类** ​ **使用 k-means 等传统聚类算法**: ​ 在低维嵌入空间中,每一行表示一个数据点的低维表示,然后对这些点进行聚类。 @@ -1102,7 +1111,7 @@ $$ 1. **特征值和特征向量的定义** 对于一个对称矩阵 $A$,其特征值和特征向量满足: $$ - A x_i = \lambda_i x_i +A x_i = \lambda_i x_i $$ 其中,$\lambda_i$ 是特征值,$x_i$ 是对应的特征向量。 diff --git a/科研/草稿.md b/科研/草稿.md index c4fb4fd..49eea95 100644 --- a/科研/草稿.md +++ b/科研/草稿.md @@ -1,74 +1,43 @@ -### 4.2.3 ADMM求解的变量与步骤详解 +# 物理连通性约束说明 -#### 1. 变量定义与作用 -- **输入变量**: - - $A_{pre}$:初始邻接矩阵(优化前的网络拓扑)。 - - $P$:对称的0-1矩阵,用于标记 $A_{pre}$ 中非零元素的位置(保持已有边不变)。 - - $A'_{max}$:功率最大时的邻接矩阵的补集($A'_{maxij} = 1$ 表示 $A_{maxij} = 0$,即不允许新增边)。 - - $\alpha$:权衡稀疏性($L_1$ 范数)和低秩性(核范数)的系数。 - - **iters**:ADMM迭代次数。 +## 约束目的 +**禁止在物理上不可能连通的位置新增链路**,确保网络拓扑优化的合理性。 -- **中间变量**: - - **$D_1, D_2$**:临时变量,用于投影步骤的中间计算。 - - $D_1 = A^*$:来自附录A的推导(可能是对偶变量或中间解)。 - - $D_2 = R^* + A_{pre}$:结合残差 $R^*$ 和初始矩阵 $A_{pre}$ 的中间结果。 - - **$M$**:残差计算的辅助矩阵,可能与约束 $A \odot P = A_{pre} \odot P$ 相关。 - - **$temp\_R, temp\_A$**:内层循环的临时变量,用于梯度投影的残差计算。 - - **$X, Y$**:对偶变量(拉格朗日乘子),分别对应两个约束: - - $X$:约束 $A \odot P = A_{pre} \odot P$ 的对偶变量。 - - $Y$:约束 $A \odot A'_{max} = 0$ 的对偶变量。 - - **$Z1, Z2$**:辅助变量,用于解耦目标函数中的核范数和 $L_1$ 范数: - - $Z1$:与核范数 $\|A\|_*$ 相关的辅助变量。 - - $Z2$:与 $L_1$ 范数 $\|A\|_1$ 相关的辅助变量。 - - **$U1, U2$**:拉格朗日乘子,用于ADMM的对偶上升步骤: - - $U1$:对应 $Z1$ 的约束 $A = Z1$。 - - $U2$:对应 $Z2$ 的约束 $A = Z2$。 +## 矩阵定义 ---- +1. **最大功率连通矩阵** $A_{\max}$: + - 表示节点在最大发射功率下的连通性 + - 非零元素:$A_{\max,ij} \neq 0$ 表示可连通 + - 零元素:$A_{\max,ij} = 0$ 表示即使满功率也无法连通 -#### 2. 算法步骤详解 -##### (S.1) 更新原始变量 $A$(ADMM的 $x$ 步) -通过内层循环(投影和对偶上升)更新 $A$,确保其满足两个约束: -1. **投影到 $A \odot P = A_{pre} \odot P$**(保持已有边不变): - - **行4-11**:梯度投影法迭代更新 $R$(残差)。 - - $temp\_R^{k+1} = M - X^k \odot A_{pre}$:计算当前残差($M$ 可能是约束的右端项)。 - - $X^{k+1} = X^k + \beta (A_{pre} \odot temp\_R^{k+1})$:对偶变量 $X$ 的梯度上升(步长 $\beta$)。 - - **本质**:通过迭代强制 $A$ 在 $P$ 标记的位置与 $A_{pre}$ 一致。 +2. **互补矩阵** $A'_{\max}$: + $$ + A'_{\max,ij} = + \begin{cases} + 0, & A_{\max,ij} \neq 0 \\ + 1, & A_{\max,ij} = 0 + \end{cases} + $$ + - 在物理不可连通位置为1,其他位置为0 -2. **投影到 $A \odot A'_{max} = 0$**(禁止新增边): - - **行13-17**:类似地,更新 $Y$: - - $temp\_A^{k+1} = D_2 - Y^k \odot A'_{max}$:残差计算。 - - $Y^{k+1} = Y^k + \gamma (A'_{max} \odot temp\_A^{k+1})$:对偶变量 $Y$ 的更新(步长 $\gamma$)。 +## 约束条件 +$$ +A \odot A'_{\max} = 0 +$$ -##### (S.2) 更新辅助变量 $Z1, Z2$(ADMM的 $z$ 步) -通过阈值操作分离目标函数的两部分: -1. **$Z1^{t+1} = T_r(A^{t+1} + U1^t)$**: - - $T_r(\cdot)$:奇异值阈值算子(核范数投影)。 - - 对 $A + U1$ 做SVD分解,保留前 $r$ 个奇异值($r$ 由低秩性需求决定)。 - - **作用**:强制 $A$ 低秩。 +**解释**: +- $\odot$ 表示Hadamard积(逐元素相乘) +- 约束强制要求:对于所有满足 $A'_{\max,ij}=1$ 的位置(即物理不可连通的节点对),必须有 $A_{ij}=0$ -2. **$Z2^{t+1} = S_{\alpha}(A^{t+1} + U2^t)$**: - - $S_{\alpha}(\cdot)$:软阈值算子($L_1$ 范数投影)。 - - 对 $A + U2$ 的每个元素:$\text{sign}(x) \cdot \max(|x| - \alpha, 0)$。 - - **作用**:促进 $A$ 的稀疏性。 +## 实际效果 -##### (S.3) 更新拉格朗日乘子 $U1, U2$(ADMM的对偶上升) -通过残差调整乘子: -- $U1^{t+1} = U1^t + A^{t+1} - Z1^{t+1}$:核范数约束的乘子更新。 -- $U2^{t+1} = U2^t + A^{t+1} - Z2^{t+1}$:$L_1$ 范数约束的乘子更新。 -- **作用**:惩罚 $A$ 与辅助变量 $Z1, Z2$ 的偏差,推动收敛。 +1. **可调连接**: + - 原本能连通的节点对($A_{\max,ij} \neq 0$)可以根据优化目标自由调整 ---- +2. **固定断开**: + - 物理上无法连通的节点对($A_{\max,ij} = 0$)始终保持断开($A_{ij} = 0$) -#### 3. 关键点总结 -1. **投影步骤**:内层循环通过梯度法将 $A$ 投影到两个约束集合(保持已有边 + 禁止新增边)。 -2. **变量解耦**:$Z1, Z2$ 分离低秩和稀疏目标,ADMM通过交替更新协调二者。 -3. **凸性保证**:核范数和 $L_1$ 范数均为凸函数,ADMM能收敛到全局最优解。 -4. **并行性**:每个节点可独立运行算法(行1注释),适合分布式网络优化。 - ---- - -#### 可能的疑问与验证 -- **$M$ 的具体定义**:文中未明确,可能是 $A_{pre} \odot P$ 或其他约束右端项。 -- **$D_1, D_2$ 的推导**:需参考附录A的公式(4-33)和(4-40),可能涉及对偶问题的转换。 -- **步长 $\beta, \gamma$**:通常需手动调参或通过线搜索确定。 +## 应用意义 +- 保证网络拓扑优化不违反物理层连接限制 +- 避免算法建议不切实际的通信链路 +- 维持网络部署的可行性 diff --git a/科研/郭款论文.md b/科研/郭款论文.md index d2ad261..c8a4143 100644 --- a/科研/郭款论文.md +++ b/科研/郭款论文.md @@ -719,8 +719,6 @@ $V$ 和 $H$ 是 $r \times r$。 $\mathcal{O}(r^3)$ - - (3) 由于通常 $n \gg r$,$\mathcal{O}(n r^2)$ 是主导项,故总复杂度(其中 $T$ 为迭代次数) $$ T \cdot \mathcal{O}(nr^2) diff --git a/科研/颜佳佳论文.md b/科研/颜佳佳论文.md index e8a2a56..08cedd3 100644 --- a/科研/颜佳佳论文.md +++ b/科研/颜佳佳论文.md @@ -1,6 +1,32 @@ -## 颜佳佳论文 +# 颜佳佳论文 -### 网络结构优化 +## 多智能体随机网络结构的实时精确估算 + +### 基于扰动理论的特征向量估算方法 + +**计算特征值扰动** + +$$\Delta \lambda_{A_i} = \lambda_{A2} - \lambda_{A1}$$ + +**特征向量修正项** +$$ +U_B = \sum_{k=1}^{n} \frac{\Delta \lambda_{A_i} U_k}{(\lambda_{A_i} - \lambda_{A_k})} +$$ + +- **解释**: + - $U_k$ 是 $A_{t1}$ 的第 $k$ 个特征向量 + - 分母 $(\lambda_{A_i} - \lambda_{A_k})$ 表示特征值差异,避免奇异(需假设 $\lambda_{A_i} \neq \lambda_{A_k}$) + - 分子 $\Delta \lambda_{A_i}$ 反映特征值变化对特征向量的影响 + +**更新特征向量** +$$ +U_{A2} = U_{A1} + U_B +$$ +**意义**:通过一阶扰动修正当前特征向量,得到未来时刻的 $U_{A2}$ + + + +## 网络结构优化 **直接SNMF分解(无优化)** @@ -23,7 +49,7 @@ -#### 网络优化中的邻接矩阵重构问题建模与优化 +### 网络优化中的邻接矩阵重构问题建模与优化 **可行解集合定义(公式4-4)** $$ @@ -31,7 +57,7 @@ $$ $$ - **$A^T = A$**:确保邻接矩阵对称 -- **$A \odot P = A_{\text{pre}} \odot P$**:掩码矩阵$P$ ,指定位置的原始值($\odot$为Hadamard积) +- **$A \odot P = A_{\text{pre}} \odot P$**:掩码矩阵$P$ ,**原来已有的连接不变,只让优化原本没有连接的地方**。($\odot$为Hadamard积) - **$A \odot A_{\max}' = 0$**:功率约束矩阵$\ A_{\max}'$ 禁止在原本无连接的节点间新增边 @@ -45,7 +71,9 @@ A'_{\max, ij} = \end{cases} $$ -- 通过$A_{\max}'$​标记禁止修改的零元素位置 +- $A_{\max, ij}$表示在最大发射功率下哪些节点对之间能连通(非零表示可连通,零表示即便满功率也连不通) +- $A_{\max}'$在“连不通”的位置上是1,其他位置是0。通过$A_{\max}'$标记禁止修改的零元素位置 +- 对于所有满足 $A'_{\max,ij}=1$ 的位置(即物理不可连通的节点对),必须有 $A_{ij}=0$,即始终保持断开 @@ -80,9 +108,9 @@ $$ -#### ADMM核心算法 +### ADMM核心算法 -##### **变量定义与作用** +#### **变量定义与作用** - **输入变量**: - $A_{pre}$:初始邻接矩阵(优化前的网络拓扑)。 @@ -97,12 +125,12 @@ $$ -##### **算法步骤详解** +#### **算法步骤详解** **(S.1) 更新原始变量 $A$(对应ADMM的$x$步)** - **代码行4-17**:通过内层循环(投影和对偶上升)更新 $A$。 - - **行4-11**:将 $A$ 投影到约束 $A \odot P = A_{\text{pre}} \odot P$ 的集合。 + - **行4-11**: - 通过内层循环(行8-11)迭代更新 $R$,本质是**梯度投影法**: - $temp_R^{k+1} = M - X^k \odot A_{\text{pre}}$(计算残差)。 - $X^{k+1} = X^k + \beta(A_{\text{pre}} \odot temp_R^{k+1})$(梯度上升步,$\beta$ 为步长)。 @@ -128,3 +156,162 @@ $$ - $U_1^{t+1} = U_1^t + A^{t+1} - Z_1^{t+1}$(核范数约束的乘子更新)。 - $U_2^{t+1} = U_2^t + A^{t+1} - Z_2^{t+1}$($L_1$ 范数约束的乘子更新)。 - **作用**:惩罚 $A$ 与辅助变量 $Z1, Z2$ 的偏差(迫使$A$更贴近$Z$),推动收敛。 + + + +## 网络结构控制 + +- **核心目标**:将优化后的低秩稀疏矩阵 $A$ 转化为**实际网络参数**(如功率、带宽),并维持动态网络的**连通性**和**稳定性**。 +- **具体实现**: + 1. 通过PID控制调整发射/接收功率,使实际链路带宽匹配矩阵 $A$ 的优化值。 + 2. 结合CSMA/CA协议处理多节点竞争,确保稀疏网络下的高效通信。 + +```plaintext +优化模型(4.2节) + ↓ 生成目标带宽矩阵A +香农公式 → 计算目标Pr → 自由空间公式 → 计算目标Pt + ↓ +PID控制发射机(AGC电压) → 实际Pt ≈ 目标Pt + ↓ +PID控制接收机(AAGC/DAGC) → 实际Pr ≈ 目标Pr + ↓ +实际带宽 ≈ Aij (闭环反馈) +``` + +- **发射机**: + + - **功能**:将数据转换为无线信号并通过天线发射。 + - **关键参数**:发射功率($P_t$)、天线增益($G_t$)、工作频率(决定波长$\lambda$)。 + - **控制目标**:通过调整AGC电压,动态调节发射功率,以匹配优化后的带宽需求(矩阵$A$中的$A_{ij}$)。 + +- **接收机**: + + - **功能**:接收无线信号并转换为可处理的数据。 + - **关键参数**:接收功率($P_r$)、噪声($N_0$)、天线增益($G_r$)。 + - **控制目标**:通过AAGC/DAGC增益调整,确保接收信号强度适合解调,维持链路稳定性。 + + + +### 具体步骤 + +**步骤1:生成目标带宽矩阵 $A$(4.2节优化模型)** + +- **数学建模**: + + - 通过凸松弛优化问题(公式4-7)得到低秩稀疏矩阵 $A$: + $$ + \min_A (1-\alpha) \|A\|_* + \alpha \|A\|_1 \quad \text{s.t.} \quad A \in \Omega + $$ + + - 约束集 $\Omega$ 确保矩阵对称性、保留原有链路($A \odot P = A_{\text{pre}} \odot P$)、禁止不可达链路($A \odot A'_{\max} = 0$)。 + +- **物理意义**: + + - 非零元素 $A_{ij}$ 直接表示 **目标信道带宽** $C_{ij}$(单位:bps),即: + $$ + A_{ij} = C_{ij} = W \log_2\left(1 + \frac{P_r}{N_0 W}\right) \quad \text{(香农公式4-10)} + $$ + +**步骤2:从带宽 $A_{ij}$ 反推功率参数** + +- **接收功率 $P_r$ 计算**: + + - 根据香农公式解耦: + $$ + P_r = (2^{A_{ij}/W} - 1) N_0 W + $$ + + - **输入**:噪声 $N_0$、带宽 $W$、目标带宽 $A_{ij}$。 + +- **发射功率 $P_t$ 计算**: + + - 通过自由空间公式(4-11): + $$ + P_t = \frac{P_r L (4\pi d)^2}{G_t G_r \lambda^2} + $$ + + - **输入**:距离 $d$、天线增益 $G_t, G_r$、波长 $\lambda$、损耗 $L$。 + +- **逻辑分支**: + + - 若 $A_{ij} \neq A_{\text{pre}ij}$(需调整链路): + - 计算 $P_r$ 和 $P_t$; + - 若 $A_{ij} = 0$(无连接): + - 直接设 $P_r = P_t = 0$。 + +**步骤3:发射机功率调整(图4-2a)** + +1. **定义目标**:$P_t$(来自步骤2)。 +2. **测量实际**:通过传感器获取当前发射功率 $P_{t,\text{actual}}$。 +3. **计算偏差**:$e(t) = P_t - P_{t,\text{actual}}$。 +4. **PID调节**:通过AGC电压改变发射功率,逼近 $P_t$。 + +**步骤4:接收机功率调整(图4-2b)** + +1. **定义目标**:$P_r$(来自步骤2)。 +2. **测量实际**:检测空口信号功率 $P_{r,\text{actual}}$。 +3. **计算偏差**:$e(t) = P_r - P_{r,\text{actual}}$。 +4. **PID调节**: + - 调整AAGC(模拟增益)和DAGC(数字增益),持续监测直至 $|e(t)| < \epsilon$。 + + + +## 智能体随机网络结构实时表示的应用 + +### (1) 谱聚类分组Spectral_Clustering(表5.1) + +**目标**:将无人机和充电站划分为 $K$ 个簇,使充电站位于簇中心。 +**步骤**: + +1. **输入**:带权邻接矩阵 $A$(权值=无人机间距离)、节点数 $N$、充电站数 $K$。 +2. **拉普拉斯矩阵**: + $$L = D - A, \quad D_{ii} = \sum_j A_{ij}$$ +3. **归一化**: + $$L_{norm} = D^{-\frac{1}{2}}LD^{\frac{1}{2}}$$ +4. **谱分解**:求 $L_{norm}$ 前 $K$ 小特征值对应的特征向量矩阵 $V \in \mathbb{R}^{N \times K}$。 +5. **聚类**:对 $V$ 的行向量进行 k-means 聚类,得到标签 $\text{labels}$。 + +**输出**:每个无人机/充电站的簇编号 $\text{labels}$。 + +### (2) 无人机选择充电站(表5-2) + +**目标**:电量低的无人机前往对应簇中心的充电站。 +**步骤**: + +1. **周期性运行**(间隔 $\Delta t$): + - 通过 `Push_Sum` 协议获取所有无人机位置 `Positions`。 + - 计算距离矩阵 $A$。 +2. **动态聚类**:调用 `Spectral_Clustering(A)` 更新簇标签。 +3. **充电触发**:若电量 $E < P_{th}$,向簇中心请求坐标 $\text{CS\_point}$ 并前往。 + +**关键公式**: +$$A_{ij} = \| \text{Position}_i - \text{Position}_j \|_2$$ + +### (3) 充电站跟踪算法(表5-3) + +**目标**:充电站动态调整位置至簇中心。 +**步骤**: + +1. **周期性运行**(间隔 $\Delta t$): + - 同无人机算法获取 $A$ 和 `labels`。 +2. **定位簇中心**: + - 充电站根据编号匹配簇标签。 + - 计算簇内无人机位置均值: + $$\text{CS\_point} = \frac{1}{|C_k|} \sum_{i \in C_k} \text{Position}_i$$ + 其中 $C_k$ 为第 $k$ 簇的节点集合。 +3. **移动至新中心**并广播位置。 + +--- + +### (4) 算法改进 + +**替换通信协议**:用第3章的卡尔曼滤波 替代 `Push_Sum`,获取特征值、特征向量重构全局矩阵 $A$,减少消息传递。 + + + + + + + + + diff --git a/自学/Java笔记本.md b/自学/Java笔记本.md index e878f40..f7b0b45 100644 --- a/自学/Java笔记本.md +++ b/自学/Java笔记本.md @@ -156,6 +156,51 @@ IDEA快捷键: +5. switch-case + + ```java + public class SwitchCaseExample { + public static void main(String[] args) { + // 定义一个 int 类型变量,作为 switch 的表达式 + int day = 3; + String dayName; + + // 根据 day 的值执行相应的分支 + switch(day) { + case 1: + dayName = "Monday"; // 当 day 为 1 时 + break; // 结束当前 case + case 2: + dayName = "Tuesday"; // 当 day 为 2 时 + break; + case 3: + dayName = "Wednesday"; // 当 day 为 3 时 + break; + case 4: + dayName = "Thursday"; // 当 day 为 4 时 + break; + case 5: + dayName = "Friday"; // 当 day 为 5 时 + break; + case 6: + dayName = "Saturday"; // 当 day 为 6 时 + break; + case 7: + dayName = "Sunday"; // 当 day 为 7 时 + break; + default: + // 如果 day 不在 1 到 7 之间 + dayName = "Invalid day"; + } + + // 输出最终结果 + System.out.println("The day is: " + dayName); + } + } + + ``` + + #### Java传参方式 diff --git a/自学/力扣Hot 100题.md b/自学/力扣Hot 100题.md index de79c0c..2f8e1ef 100644 --- a/自学/力扣Hot 100题.md +++ b/自学/力扣Hot 100题.md @@ -351,49 +351,154 @@ public class PriorityQueueExample { -**自己实现大根堆:** +**自定义排序:按第二个元素的值构建小根堆** + +如何比较器返回负数,则第一个数排在前面->优先级高->在堆顶 ```java -class Solution { - public int findKthLargest(int[] nums, int k) { - int heapSize = nums.length; - buildMaxHeap(nums, heapSize); - for (int i = nums.length - 1; i >= nums.length - k + 1; --i) { - swap(nums, 0, i); - --heapSize; - maxHeapify(nums, 0, heapSize); +public class CustomPriorityQueue { + public static void main(String[] args) { + // 定义一个 PriorityQueue,其中每个元素是 int[],并且按照数组第二个元素升序排列 + PriorityQueue minHeap = new PriorityQueue<>( + (a, b) -> return a[i]-b[i]; + ); + + // 添加数组 + minHeap.offer(new int[]{1, 2}); + minHeap.offer(new int[]{3, 4}); + minHeap.offer(new int[]{0, 5}); + + // 依次取出元素,输出结果 + while (!minHeap.isEmpty()) { + int[] arr = minHeap.poll(); + System.out.println(Arrays.toString(arr)); } - return nums[0]; + } +} +``` + +不用lambda版本: + +```java +PriorityQueue minHeap = new PriorityQueue<>(new Comparator() { + @Override + public int compare(int[] a, int[] b) { + return a[1] - b[1]; + } +}); +``` + + + +##### **自己实现小根堆:** + +**父节点**:对于任意索引 `i`,其父节点的索引为 `(i - 1) // 2`。 + +**左子节点**:索引为 `i` 的节点,其左子节点的索引为 `2 * i + 1`。 + +**右子节点**:索引为 `i` 的节点,其右子节点的索引为 `2 * i + 2`。 + +**上滤与下滤操作** + +- **上滤**(Sift-Up): + 用于插入操作。将新加入的元素与其父节点不断比较,若小于父节点则交换,直到满足堆序性质。 +- **下滤**(Sift-Down): + 用于删除操作或建堆。将根节点或某个节点与其子节点中较小的进行比较,若大于子节点则交换,直至满足堆序性质。 + +**建堆:**从数组中最后一个非叶节点开始(索引为 `heapSize/2 - 1`),对每个节点执行**下滤**操作(sift-down) + +**插入元素:**将新元素插入到堆的末尾,然后执行**上滤**操作(sift-up),以保持堆序性质。 + +**弹出元素(删除堆顶):**弹出操作一般是删除堆顶元素(小根堆中即最小值),然后用堆尾元素替代堆顶,再进行**下滤**操作。 + + + +```java +class MinHeap { + private int[] heap; // 数组存储堆元素 + private int size; // 当前堆中元素的个数 + + // 构造函数,初始化堆,capacity为堆的最大容量 + public MinHeap(int capacity) { + heap = new int[capacity]; + size = 0; } - public void buildMaxHeap(int[] a, int heapSize) { + // 插入元素:先将新元素添加到数组末尾,然后执行上滤操作恢复堆序性质 + public void insert(int value) { + if (size >= heap.length) { + throw new RuntimeException("Heap is full"); + } + // 将新元素放到末尾 + heap[size] = value; + int i = size; + size++; + + // 上滤操作:不断与父节点比较,若新元素小于父节点则交换 + while (i > 0) { + int parent = (i - 1) / 2; + if (heap[i] < heap[parent]) { + swap(heap, i, parent); + i = parent; + } else { + break; + } + } + } + + // 弹出堆顶元素:移除堆顶(最小值),用最后一个元素替换堆顶,然后下滤恢复堆序 + public int pop() { + if (size == 0) { + throw new RuntimeException("Heap is empty"); + } + int min = heap[0]; + // 将最后一个元素移到堆顶 + heap[0] = heap[size - 1]; + size--; + // 对新的堆顶执行下滤操作,恢复堆序性质 + minHeapify(heap, 0, size); + return min; + } + + // 建堆:将无序数组a构造成小根堆,heapSize为数组长度 + public static void buildMinHeap(int[] a, int heapSize) { for (int i = heapSize / 2 - 1; i >= 0; --i) { - maxHeapify(a, i, heapSize); - } - } - - public void maxHeapify(int[] a, int i, int heapSize) { - int l = i * 2 + 1, r = i * 2 + 2, largest = i; - if (l < heapSize && a[l] > a[largest]) { - largest = l; - } - if (r < heapSize && a[r] > a[largest]) { - largest = r; - } - if (largest != i) { - swap(a, i, largest); - maxHeapify(a, largest, heapSize); + minHeapify(a, i, heapSize); } } - public void swap(int[] a, int i, int j) { + // 下滤操作:从索引i开始,将子树调整为小根堆 + public static void minHeapify(int[] a, int i, int heapSize) { + int l = 2 * i + 1, r = 2 * i + 2; + int smallest = i; + // 判断左子节点是否存在且比当前节点小 + if (l < heapSize && a[l] < a[smallest]) { + smallest = l; + } + // 判断右子节点是否存在且比当前最小节点小 + if (r < heapSize && a[r] < a[smallest]) { + smallest = r; + } + // 如果最小值不是当前节点,交换后继续对被交换的子节点执行下滤操作 + if (smallest != i) { + swap(a, i, smallest); + minHeapify(a, smallest, heapSize); + } + } + + // 交换数组中两个位置的元素 + public static void swap(int[] a, int i, int j) { int temp = a[i]; a[i] = a[j]; a[j] = temp; } + } + ``` +改为大根堆只需要把里面 ''<'' 符号改为 ''>'' + #### **`ArrayList`** @@ -571,7 +676,14 @@ public class ArrayExample { ``` int[] source = {1, 2, 3, 4, 5}; int[] destination = Arrays.copyOf(source, source.length); -int[] partialArray = Arrays.copyOfRange(source, 1, 4); //不包括索引4 +int[] partialArray = Arrays.copyOfRange(source, 1, 4); //复制指定元素,不包括索引4 +``` + +初始化: + +``` +int[] memo = new int[nums.length]; +Arrays.fill(memo, -1); ``` @@ -1348,3 +1460,39 @@ public class Permute { } ``` + + +#### 大小根堆 + +**题目描述**:给定一个整数数组 `nums` 和一个整数 `k`,返回出现频率最高的前 `k` 个元素,返回顺序可以任意。 + +**解法一:大根堆(最大堆)** + +**思路**: + +1. 使用 `HashMap` 统计每个元素的出现频率。 +2. 构建一个**大根堆**(`PriorityQueue` + 自定义比较器),根据频率降序排列。 +3. 将所有元素加入堆中,**弹出前 `k` 个元素**即为答案。 + +**适合场景**: + +- 实现简单,适用于对全部元素排序后取前 `k` 个。 +- 时间复杂度:**O(n log n)**,因为需要将所有 `n` 个元素都加入堆。 + +------ + +**解法二:小根堆(最小堆)** + +**思路**: + +1. 使用 `HashMap` 统计频率。 +2. 构建一个**小根堆**,堆中仅保存前 `k` 个高频元素。 +3. 遍历每个元素: + - 如果堆未满,直接加入。 + - 如果当前元素频率大于堆顶(最小频率),则弹出堆顶,加入当前元素。 +4. 最终堆中保存的就是前 `k` 个高频元素。 + +| 方法 | 适合场景 | 时间复杂度 | 空间复杂度 | +| ------ | --------------- | ---------- | ---------- | +| 大根堆 | k ≈ n,简单易写 | O(n log n) | O(n) | +| 小根堆 | k ≪ n,更高效 | O(n log k) | O(n) | diff --git a/自学/草稿.md b/自学/草稿.md index e85c57d..93f7d7f 100644 --- a/自学/草稿.md +++ b/自学/草稿.md @@ -1,33 +1,53 @@ -ConcurrentHashMap 不同JDK版本的实现对比 +- 当然可以!下面是你可以直接记到笔记里的内容: -1. 数据结构 + ------ -- **JDK1.7**: - - 使用 `Segment(分段锁) + HashEntry数组 + 链表` 的数据结构 - -- **JDK1.8及之后**: - - 使用 `数组 + 链表/红黑树` 的数据结构(与HashMap类似) + ### 🧠 题型:**Top K 高频元素**(LeetCode 347) -2. 锁的类型与宽度 + **题目描述**:给定一个整数数组 `nums` 和一个整数 `k`,返回出现频率最高的前 `k` 个元素,返回顺序可以任意。 -- **JDK1.7**: - - 分段锁(Segment)继承了 `ReentrantLock` - - Segment容量默认16,不会扩容 → 默认支持16个线程并发访问 + ------ -- **JDK1.8**: - - 使用 `synchronized + CAS` 保证线程安全 - - 空节点:通过CAS添加 - - 非空节点:通过synchronized加锁 + ### 📌 解法一:大根堆(最大堆) -3. 渐进式扩容(JDK1.8+) + **思路**: -- **触发条件**:元素数量 ≥ `数组容量 × 负载因子(默认0.75)` -- **扩容过程**: - 1. 创建2倍大小的新数组 - 2. 线程操作数据时,逐步迁移旧数组数据到新数组 - 3. 使用 `transferIndex` 标记迁移进度 - 4. 直到旧数组数据完全迁移完成 + 1. 使用 `HashMap` 统计每个元素的出现频率。 + 2. 构建一个**大根堆**(`PriorityQueue` + 自定义比较器),根据频率降序排列。 + 3. 将所有元素加入堆中,**弹出前 `k` 个元素**即为答案。 -### 关键改进点: -- 降低大数据量扩容时的性能开销 -- 允许读写操作与扩容并发进行 \ No newline at end of file + **适合场景**: + + - 实现简单,适用于对全部元素排序后取前 `k` 个。 + - 时间复杂度:**O(n log n)**,因为需要将所有 `n` 个元素都加入堆。 + + ------ + + ### 📌 解法二:小根堆(最小堆) + + **思路**: + + 1. 使用 `HashMap` 统计频率。 + 2. 构建一个**小根堆**,堆中仅保存前 `k` 个高频元素。 + 3. 遍历每个元素: + - 如果堆未满,直接加入。 + - 如果当前元素频率大于堆顶(最小频率),则弹出堆顶,加入当前元素。 + 4. 最终堆中保存的就是前 `k` 个高频元素。 + + **适合场景**: + + - 当 `k ≪ n` 时效率更高。 + - 时间复杂度:**O(n log k)**,因为堆中最多维护 `k` 个元素。 + + ------ + + ### ✅ 总结对比: + + | 方法 | 适合场景 | 时间复杂度 | 空间复杂度 | + | ------ | --------------- | ---------- | ---------- | + | 大根堆 | k ≈ n,简单易写 | O(n log n) | O(n) | + | 小根堆 | k ≪ n,更高效 | O(n log k) | O(n) | + + ------ + + 需要我再写成代码模板笔记也可以,随时说! \ No newline at end of file