Commit on 2025/04/08 周二 12:00:24.57
This commit is contained in:
parent
18feba745b
commit
426cec0a76
72
科研/循环神经网络.md
72
科研/循环神经网络.md
@ -245,3 +245,75 @@ $$
|
||||
- **输出门 $o_t$**:
|
||||
控制从细胞状态中输出多少信息作为当前时间步的隐藏状态。隐藏状态 $h_t$ 通常用于后续计算(例如,生成输出、参与下一时刻计算)。
|
||||
**类比**:根据当前任务(如预测下一个词),输出门决定暴露细胞状态的哪部分(如只关注时间、地点等关键信息)。
|
||||
|
||||
|
||||
|
||||
## 时序卷积网络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$:原始输入
|
||||
|
||||
|
25
科研/数学基础.md
25
科研/数学基础.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,20 +890,25 @@ $$
|
||||
|
||||
|
||||
|
||||
2.构造图拉普拉斯矩阵
|
||||
**2.构造图拉普拉斯矩阵**
|
||||
|
||||
- 对称归一化拉普拉斯矩阵
|
||||
- 未归一化的拉普拉斯矩阵
|
||||
|
||||
3.计算特征向量
|
||||
|
||||
对选定的拉普拉斯矩阵(例如 $L_{sym}$)进行特征分解,求出前 $k$ 个最小特征值对应的特征向 量。
|
||||
|
||||
**3.计算特征向量**
|
||||
|
||||
对选定的拉普拉斯矩阵(例如 $L_{sym}$)进行特征分解,求出**前 $k$ 个最小特征值**对应的特征向量。
|
||||
注意:对于未归一化的拉普拉斯矩阵,零特征值对应的特征向量通常是常数向量,所以在分解时忽略这个解,选择第二小开始的 $k$ 个特征向量。
|
||||
|
||||
4.构造嵌入空间
|
||||
|
||||
|
||||
**4.构造嵌入空间**
|
||||
|
||||
- **形成矩阵 $U$**:
|
||||
将求得的 $k$ 个特征向量作为列组成矩阵
|
||||
将求得的 $k$ 个特征向量作为**列**组成矩阵
|
||||
|
||||
$$
|
||||
U = \begin{pmatrix}
|
||||
u_1(1) & u_2(1) & \cdots & u_k(1) \\
|
||||
@ -910,13 +917,15 @@ $$
|
||||
u_1(n) & u_2(n) & \cdots & u_k(n)
|
||||
\end{pmatrix}.
|
||||
$$
|
||||
|
||||
其中,每一行对应原数据点在低维空间中的表示。
|
||||
例:
|
||||
|
||||
- **归一化(可选)**:
|
||||
对于对称归一化的情况,可以对 $U$ 的每一行做归一化处理,使得每一行变为单位向量,这一步有助于后续聚类的稳定性。
|
||||
|
||||
5.聚类
|
||||
|
||||
|
||||
**5.聚类**
|
||||
|
||||
**使用 k-means 等传统聚类算法**:
|
||||
在低维嵌入空间中,每一行表示一个数据点的低维表示,然后对这些点进行聚类。
|
||||
|
97
科研/草稿.md
97
科研/草稿.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$**:通常需手动调参或通过线搜索确定。
|
||||
## 应用意义
|
||||
- 保证网络拓扑优化不违反物理层连接限制
|
||||
- 避免算法建议不切实际的通信链路
|
||||
- 维持网络部署的可行性
|
||||
|
@ -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)
|
||||
|
205
科研/颜佳佳论文.md
205
科研/颜佳佳论文.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$,减少消息传递。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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传参方式
|
||||
|
||||
|
194
自学/力扣Hot 100题.md
194
自学/力扣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<int[]> 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<int[]> minHeap = new PriorityQueue<>(new Comparator<int[]>() {
|
||||
@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);
|
||||
minHeapify(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;
|
||||
// 下滤操作:从索引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[largest]) {
|
||||
largest = r;
|
||||
// 判断右子节点是否存在且比当前最小节点小
|
||||
if (r < heapSize && a[r] < a[smallest]) {
|
||||
smallest = r;
|
||||
}
|
||||
if (largest != i) {
|
||||
swap(a, i, largest);
|
||||
maxHeapify(a, largest, heapSize);
|
||||
// 如果最小值不是当前节点,交换后继续对被交换的子节点执行下滤操作
|
||||
if (smallest != i) {
|
||||
swap(a, i, smallest);
|
||||
minHeapify(a, smallest, heapSize);
|
||||
}
|
||||
}
|
||||
|
||||
public void swap(int[] a, int i, int j) {
|
||||
// 交换数组中两个位置的元素
|
||||
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) |
|
||||
|
68
自学/草稿.md
68
自学/草稿.md
@ -1,33 +1,53 @@
|
||||
ConcurrentHashMap 不同JDK版本的实现对比
|
||||
- 当然可以!下面是你可以直接记到笔记里的内容:
|
||||
|
||||
1. 数据结构
|
||||
------
|
||||
|
||||
- **JDK1.7**:
|
||||
- 使用 `Segment(分段锁) + HashEntry数组 + 链表` 的数据结构
|
||||
### 🧠 题型:**Top K 高频元素**(LeetCode 347)
|
||||
|
||||
- **JDK1.8及之后**:
|
||||
- 使用 `数组 + 链表/红黑树` 的数据结构(与HashMap类似)
|
||||
**题目描述**:给定一个整数数组 `nums` 和一个整数 `k`,返回出现频率最高的前 `k` 个元素,返回顺序可以任意。
|
||||
|
||||
2. 锁的类型与宽度
|
||||
------
|
||||
|
||||
- **JDK1.7**:
|
||||
- 分段锁(Segment)继承了 `ReentrantLock`
|
||||
- Segment容量默认16,不会扩容 → 默认支持16个线程并发访问
|
||||
### 📌 解法一:大根堆(最大堆)
|
||||
|
||||
- **JDK1.8**:
|
||||
- 使用 `synchronized + CAS` 保证线程安全
|
||||
- 空节点:通过CAS添加
|
||||
- 非空节点:通过synchronized加锁
|
||||
**思路**:
|
||||
|
||||
3. 渐进式扩容(JDK1.8+)
|
||||
1. 使用 `HashMap` 统计每个元素的出现频率。
|
||||
2. 构建一个**大根堆**(`PriorityQueue` + 自定义比较器),根据频率降序排列。
|
||||
3. 将所有元素加入堆中,**弹出前 `k` 个元素**即为答案。
|
||||
|
||||
- **触发条件**:元素数量 ≥ `数组容量 × 负载因子(默认0.75)`
|
||||
- **扩容过程**:
|
||||
1. 创建2倍大小的新数组
|
||||
2. 线程操作数据时,逐步迁移旧数组数据到新数组
|
||||
3. 使用 `transferIndex` 标记迁移进度
|
||||
4. 直到旧数组数据完全迁移完成
|
||||
**适合场景**:
|
||||
|
||||
### 关键改进点:
|
||||
- 降低大数据量扩容时的性能开销
|
||||
- 允许读写操作与扩容并发进行
|
||||
- 实现简单,适用于对全部元素排序后取前 `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) |
|
||||
|
||||
------
|
||||
|
||||
需要我再写成代码模板笔记也可以,随时说!
|
Loading…
x
Reference in New Issue
Block a user