论文解读(NWR)《Graph Auto-Encoder via Neighborhood Wasserstein Reconstruction》
论文信息
论文标题:Graph Auto-Encoder via Neighborhood Wasserstein Reconstruction
论文作者:Shaked Brody, Uri Alon, Eran Yahav
论文来源:2022,ICLR
论文地址:download
论文代码:download
1 Abstract
图神经网络(GNNs)近年来引起了广泛的研究关注,主要是在半监督学习的背景下。当任务不可知的表示是首选或监督完全不可用时,自动编码器框架与无监督GNN训练的自然图重建目标一起使用。然而,现有的图自动编码器是通过设计来重建直接链路的,因此以这种方式训练的gnn只针对面向邻近的图挖掘任务进行优化,当拓扑结构很重要时就会失败。在本研究中,我们重新讨论了gnn的图编码过程,它本质上学习了将每个节点的邻域信息编码为一个嵌入向量,并提出了一种新的图解码器,通过邻域瓦瑟斯坦重建(NWR)来重建关于邻近性和结构的整个邻域信息。
具体来说,NWR从每个节点的GNN嵌入中,联合预测其节点度和邻居特征分布,其中分布预测采用了基于瓦瑟斯坦距离的最优传输损失。在合成网络数据集和真实网络数据集上的大量实验表明,使用NWR学习的无监督节点表示在面向结构的图挖掘任务中具有更大的优势,同时在面向接近的图挖掘任务中也具有竞争性能。
2 Introduction
现有的图自动编码:
- 例如 GAE(Kipf & Welling, 2016)学习的节点表示由于其优化简单的重建目标以至无法区分像 (2, 4) 和 (3, 5)这样的点;
- 例如 GraphWave (Donnat et al., 2018) 这样的面向结构的嵌入模型不考虑节点特征和空间接近度,无法区分像 (0, 1), (2, 4) 和 (3,5) 这样的节点对;
具体地说,本文将解码过程描述为从通过 GNN 编码器获得的多跳邻居表示上定义的一系列概率分布中进行迭代采样。然后,将重构损失分解为三个部分,即采样数(节点度)、邻居表示分布和节点特征。本文最重要的术语是“ 邻居表示分布重建”(neighborrepresentation distribution reconstruction),本文采用了基于 Wasserstein distance 的最优传输损失,因此将这个新的框架命名为 Neighborhood Wasserstein Reconstruction Graph Auto-Encoder (NWR-GAE).。如 Figure1 所示,NWR-GAE可以有效地在不同的角度区分所有不同的节点对,并简明地反映出它们在低维嵌入空间中的相似性。
为了更好地理解这一点,我们仔细分析了通过GNN在每个节点表示中编码的信息源。假设采用一个标准的消息传递 GNN (Gilmer等人,2017) 作为编码器,这是一个通用框架,包括 GCN 、GraphSAGE、GAT、GIN 等等。在 k-hop 消息传递后,在节点 $v$ 的表示中编码的信息来源本质上来自于 $v$ 的 $k-hop$ 邻域(Fig.2)。因此,节点 $v$ 的良好表示应该捕获其 $k$ 跳邻域中所有节点的特征信息,这与下游任务是无关的。请注意,这可能不是理想的,因为 $k-hop$ 邻域外的节点也可能提供有用的信息,但由于 GNN 编码器的架构,这是基于 GNN 的图自动编码器可以期望做的。这一观察结果促使我们研究了一种新的图解码器,该解码器可以更好地促进基于 GNN 的图自动编码器的目标。我们将在 Sec3 中正式确立这一原则。
最近,DGI、EGI 在无监督GNN训练方法中使用了对比学习,并可能捕获定向链接之外的信息。它们采用了互信息最大化规则 (InfoMax),它本质上是为了最大化学习到的表示和原始数据之间的某些对应关系。例如,DGI 最大化了节点表示与节点所属的图之间的对应关系,但这并不能保证重建节点邻域的结构信息。最近的研究甚至表明,最大化这种对应关系可能只捕获与下行任务无关的噪声信息,因为噪声信息本身足以让模型实现 InfoMax,我们的实验再次证明了这一点。相反,我们的目标是让节点表示不仅捕获信息来区分节点,而且捕获尽可能多的信息来重建邻域的特征和结构。
许多机器学习问题依赖于两个概率测度量之间的距离的描述。当两个分布有非重叠的部分时,$f$ 散度存在非连续的问题。
Suppose we have two probability distributions, $P$ and $Q$ :
$\forall(x, y) \in P, x=0 \text { and } y \sim U(0,1) \forall(x, y) \in Q, x=\theta, 0 \leq \theta \leq 1 \text { and } y \sim U(0,1)$
When $\theta \neq 0$ :
$D_{K L}(P \| Q) =\sum\limits _{x=0, y \sim U(0,1)} 1 \cdot \log \frac{1}{0}=+\infty$
$D_{K L}(Q \| P) =\sum\limits_{x=0, y \sim U(0,1)} 1 \cdot \log \frac{1}{0}=+\infty$
$D_{J S}(P, Q) =\frac{1}{2}\left(\sum\limits_{x=0, y \sim U(0,1)} 1 \cdot \log \frac{1}{1 / 2}+\sum\limits_{x=0, y \sim U(0,1)} 1 \cdot \log \frac{1}{1 / 2}\right)=\log 2$
$W(P, Q) =|\theta| $But when $\theta = 0$, two distributions are fully overlapped:
$D_{K L}(P \| Q) =D_{K L}(Q \| P)=D_{J S}(P, Q)=0$
$W(P, Q) =0=|\theta|$
因此,OT 损失经常被采用,并在生成模型和领域适应中取得了巨大的成功。OT 损失已被用于构建非图形数据的变分自动编码器。但应该注意的是,我们的工作并不是这些工作的面向图数据的泛化:他们使用 OT 损失来描述变分分布和数据经验分布之间的距离,而我们的模型甚至不使用变分分布。我们的模型可以进一步改进为一个变分自编码器,但我们把它作为一个未来的方向。
在这里,我们给出了一个基于 2-Wasserstein distance 的常用的 OT 损失,这将在稍后使用。
Definition 2.1. Let $\mathcal{P}$, $\mathcal{Q}$ denote two probability distributions with finite second moment defined on $\mathcal{Z} \subseteq \mathbb{R}^{m}$ . The 2-Wasserstein distance between $\mathcal{P}$ and $\mathcal{Q}$ defined on $\mathcal{Z}$, $\mathcal{Z}^{\prime} \subseteq \mathbb{R}^{m}$ is the solution to the optimal mass transportation problem with $\ell_{2}$ transport cost (Villani, 2008):
$\mathcal{W}_{2}(\mathcal{P}, \mathcal{Q})=\left(\inf _{\gamma \in \Gamma(\mathcal{P}, \mathcal{Q})} \int_{\mathcal{Z} \times \mathcal{Z}^{\prime}}\left\|Z-Z^{\prime}\right\|_{2}^{2} d \gamma\left(Z, Z^{\prime}\right)\right)^{1 / 2}$
where $\Gamma(\mathcal{P}, \mathcal{Q})$ contains all joint distributions of $\left(Z, Z^{\prime}\right)$ with marginals $\mathcal{P}$ and $\mathcal{Q}$ respectively.
3 Methods
预先定义 :
- Encoder:$\phi$
- Decoder:$\psi$
Encoder 可以是任何基于消息传递的 GNNs,Decoder 可以分成三部分:$\psi=\left(\psi_{s}, \psi_{p}, \psi_{d}\right)$
3.1 Neighborhood peconstruction principle
为了简化阐述,我们从 1 跳邻域重建开始。我们基于 $X$ 用 $H^{(0)}$ 初始化节点表示。对于每个节点 $v \in V$,在被一个GNN层编码后,其节点表示h $h_{v}^{(1)}$ 从 $h_{v}^{(0)}$ 及其邻居的表示 $H_{\mathcal{N}_{v}}^{(0)}=\left\{h_{u}^{(0)} \mid u \in \mathcal{N}_{v}\right\}$ 中收集信息。因此,我们考虑以下原则,即重构来自 $h_{v}^{(0)}$ 和 $H_{\mathcal{N}_{v}}^{(0)}$ 的信息。因此,我们有了
$\begin{array} {l}\underset{\phi, \psi}{\text{min}} & \sum\limits _{v \in V} \mathcal{M}\left(\left(h_{v}^{(0)}, H_{\mathcal{N}_{v}}^{(0)}\right), \psi\left(h_{v}^{(1)}\right)\right)\\\text { s.t. } & h_{v}^{(1)}=\phi\left(h_{v}^{(0)}, H_{\mathcal{N}_{v}}^{(0)}\right), \forall v \in V\end{array} \quad\quad\quad(2)$
式中,$\mathcal{M}(\cdot, \cdot)$ 定义了重建损失。$M$ 可以分为两部分,分别测量自特征重建和邻域重建:
$\mathcal{M}\left(\left(h_{v}^{(0)}, H_{\mathcal{N}_{v}}^{(0)}\right), \psi\left(h_{v}^{(1)}\right)\right)=\mathcal{M}_{s}\left(h_{v}^{(0)}, \psi\left(h_{v}^{(1)}\right)\right)+\mathcal{M}_{n}\left(H_{\mathcal{N}_{v}}^{(0)}, \psi\left(h_{v}^{(1)}\right)\right)\quad\quad\quad(3)$
请注意,$\mathcal{M}_{s}$ 的工作原理就像一个基于标准的前馈神经网络(FNN)的自动编码器的重建损失一样,所以我们采用了
$\mathcal{M}_{s}\left(h_{v}^{(0)}, \psi\left(h_{v}^{(1)}\right)\right)=\left\|h_{v}^{(0)}-\psi_{s}\left(h_{v}^{(1)}\right)\right\|^{2}\quad\quad\quad(4)$
$\mathcal{M}_{n}$ 很难被描述,因为它测量的是重建一组特征 $H_{\mathcal{N}_{v}}^{(0)}$ 的损失。有两个基本的挑战:首先,在现实网络中,节点度的分布通常是长尾的,节点邻居的集合可能有非常不同的大小。其次,为了比较甚至两个大小相等的集合,也必须解决一个匹配问题,因为可以假定集合中没有固定的元素顺序。如果集合的大小较大,则解决匹配问题的复杂性很高。我们通过将邻域信息解耦为概率分布和采样数来解决上述挑战。具体来说,对于节点 $v$,邻域信息被表示为 i.i.d .的经验实现从 $\mathcal{P}_{v}^{(0)}$ 中采样 $d_{v}$ 元素,其中 $\mathcal{P}_{v}^{(0)} \triangleq \frac{1}{d_{v}} \sum\limits _{u \in \mathcal{N}_{v}} \delta_{h_{u}^{(0)}}$。基于这一观点,我们可以将重建分别分解为节点度和分布的部分,其中不同大小的节点邻域得到了正确的处理。具体来说,我们采用
$\mathcal{M}_{n}\left(H_{\mathcal{N}_{v}}^{(0)}, \psi\left(h_{v}^{(1)}\right)\right)=\left(d_{v}-\psi_{d}\left(h_{v}^{(1)}\right)\right)^{2}+\mathcal{W}_{2}^{2}\left(\mathcal{P}_{v}^{(0)}, \psi_{p}^{(1)}\left(h_{v}^{(1)}\right)\right)\quad\quad\quad(5)$
Generalizing to k-hop neighborhood reconstruction
根据上述对第一个情况的推导,我们可以类似地推广基于 $h_{v}^{(i)}$ 的重构 $\left(h_{v}^{(i-1)}, H_{\mathcal{N}_{v}}^{(i-1)}\right)$ 的损失。然后,如果我们将所有节点 $v \in V$ 和所有跳 $1 \leq i \leq k$ 的损失相加,我们可以实现 $k$ 跳邻域重建的目标。我们可以进一步简化这一目标。通常,只有最终的层表示 $H^{(k)}$ 被用作输出降维表示。过多的中间跳使模型难以训练,收敛速度慢。因此,我们采用了一种更经济的方式,合并了多步重建:
也就是说,我们期望 $h_{v}^{(k)}$ 直接重构 $H_{\mathcal{N}_{v}}^{(i)}$,即使 $i<k-1$。具体来说,对于每个节点 $v \in V$,我们使用重构损失
$\begin{array}{l}&\mathcal{M}^{\prime}\left(\left(h_{v}^{(0)},\left\{H_{\mathcal{N}_{v}}^{(i)} \mid 0 \leq i \leq k-1\right\}\right), \psi\left(h_{v}^{(k)}\right)\right)=\mathcal{M}_{s}\left(h_{v}^{(0)}, \psi\left(h_{v}^{(k)}\right)\right)+\sum\limits_{i=0}^{k-1} \mathcal{M}_{n}\left(H_{\mathcal{N}_{v}}^{(i)}, \psi\left(h_{v}^{(k)}\right)\right) \\&=\lambda_{s}\left\|h_{v}^{(0)}-\psi_{s}\left(h_{v}^{(k)}\right)\right\|^{2}+\lambda_{d}\left(d_{v}-\psi_{d}\left(h_{v}^{(k)}\right)\right)^{2}+\sum\limits_{i=0}^{k-1} \mathcal{W}_{2}^{2}\left(\mathcal{P}_{v}^{(i)}, \psi_{p}^{(i)}\left(h_{v}^{(k)}\right)\right)\end{array}\quad(6)$
其中 $\psi_{s}$ 是解码初始特征,$\psi_{d}$ 是度解码,$\psi_{p}^{(i)}$,$0 \leq i \leq k-1$ 是解码 $i$ 层邻域表示分布 $\mathcal{P}_{v}^{(i)}\left(: \triangleq \frac{1}{d_{v}} \sum\limits _{u \in \mathcal{N}_{v}} \delta_{h_{u}^{(i)}}\right)$。$\lambda_{s}$ 和 $\lambda_{d}$ 为非负性超参数。因此,$k$ 跳邻域重建的全部目标是
$\begin{array}{l} \underset{\phi, \psi}{\text{min}}\quad \sum\limits _{v \in V} \mathcal{M}^{\prime}\left(\left(h_{v}^{(0)},\left\{H_{\mathcal{N}_{v}}^{(i-1)} \mid 1 \leq i \leq k\right\}\right), \psi\left(h_{v}^{(k)}\right)\right)\\ \text { s.t. }\quad H^{(i)}=\phi^{(i)}\left(H^{(i-1)}\right), \quad1 \leq i \leq k\end{array}$
其中,$\phi=\left\{\phi^{(i)} \mid 1 \leq i \leq k\right\}$ 包括 $k$ 个GNN层,$\mathcal{M}^{\prime}$ 在 $\text{Eq.6}$ 中定义。
在 $\text{Eq.6}$ 中的损失并不直接推动 $k$ 层表示 $h_{v}^{(k)}$ 来重建所有直接邻居节点的特征,但它们位于 $v$ 的 $k$ 跳邻域。但是,根据定义,在这个 $k$ 跳邻域中存在一条长度不大于 $k$ 的最短路径。因为沿路径的每两个相邻节点将引入至少一项等式之和的重建损失。这就保证了在 $\text{Eq.7}$ 中的优化推动 $h_{v}^{(k)}$ 来重建 $v$ 的整个 $k-hop$ 邻域。
3.2 Decoding distributions——Decoders $\psi_{p}^{(i)}, 0 \leq i \leq k-1$
我们的 NRP 本质上是将节点邻域 $H_{\mathcal{N}_{v}}^{(i)}$ 表示为一个采样数(节点度 $d_v$ )加上一个邻居表示 $\mathcal{P}_{v}^{(i)}$ 的分布($\text{Eq.5.6}$)。我们采用 Wasserstein distance 来表征分布重构损失,因为 $\mathcal{P}_{v}^{(i)}$ 在连续空间中具有原子非零测度支持,在连续空间中不能应用 $f$ 散度族的分布重构损失。可以应用最大平均差异,但它需要指定一个核函数。
$\begin{array}{l}\psi_{p}^{(i)}\left(h_{v}^{(k)}\right)=\operatorname{FNN}_{p}^{(i)}(\xi),\quad \xi \sim \mathcal{N}\left(\mu_{v}, \Sigma_{v}\right)\\\text { where }\quad \mu_{v}=\operatorname{FNN}_{\mu}\left(h_{v}^{(k)}\right), \quad\Sigma_{v}=\operatorname{diag}\left(\exp \left(\operatorname{FNN}_{\sigma}\left(h_{v}^{(k)}\right)\right)\right)\end{array}$
Theorem 3.1. For any $\epsilon>0$ , if the support of the distribution $\mathcal{P}_{v}^{(i)}$ lies in a bounded space of $\mathbb{R}^{m}$ , there exists a $FNN u(\cdot): \mathbb{R}^{m} \rightarrow \mathbb{R}$ (and thus its gradient $\nabla u(\cdot): \mathbb{R}^{m} \rightarrow \mathbb{R}^{m}$ ) with large enough width and depth (depending on $\epsilon$ ) such that $\mathcal{W}_{2}^{2}\left(\mathcal{P}_{v}^{(i)}, \nabla u(\mathcal{G})\right)<\epsilon$ where $\nabla u(\mathcal{G})$ is the distribution generated via the mapping $\nabla u(\xi)$, $\xi \sim a$ $m$-dim non-degenerate Gaussian distribution.
另一个挑战是,$\mathcal{P}_{v}^{(i)}$ 和 $\psi_{p}^{(i)}\left(h_{v}^{(k)}\right)$ 之间的 Wasserstein distance 没有一个封闭的形式。因此,我们采用 empirical Wasserstein distance。对于每一次正向传递,模型将得到 $q$ 个采样节点 $\mathcal{N}_{v}$,记为 $v_{1}, v_{2}, \ldots, v_{q}$ 因此,$\left\{h_{v_{j}}^{(i)} \mid 1 \leq j \leq q\right\}$ 是来自 $\mathcal{P}_{v}^{(i)}$ 的 $q$ 个样本;接下来,从
$\mathcal{N}\left(\mu_{v}, \Sigma_{v}\right)$ 采样的 $q$ 个样本定义为 $\xi_{1}, \xi_{2}, \ldots, \xi_{q}$,因此 $\left\{\hat{h}_{v}^{(i, j)}=\operatorname{FNN}_{p}^{(i)}\left(\xi_{j}\right) \mid 1 \leq j \leq q\right\}$ 是从 $\psi_{p}^{(i)}\left(h_{v}^{(k)}\right)$ 中采样的 $q$ 个样本;在 $\text{Eq.6}$ 采用以下经验抵消损失 $\sum\limits _{i=0}^{k-1} \mathcal{W}_{2}^{2}\left(\mathcal{P}_{v}^{(i)}, \psi_{p}^{(i)}\left(h_{v}^{(k)}\right)\right)$
上述损失的计算是基于求解一个匹配问题,需要具有 $O(q^3)$ 复杂度的匈牙利算法。可以采用更有效的替代损失类型,如基于贪婪近似的倒角损失(Fanetal.,2017)或基于连续松弛的辛角损失(Cuturi,2013),其复杂性为 $O(q^2)$。在我们的实验中,由于 $q$ 是固定为一个小常数,比如5,我们使用等式8基于匈牙利匹配,不引入太多的计算开销。虽然没有直接相关,但我们想强调一些最近的工作,即使用 OT 损失作为两个图之间的距离,其中采用了这两个图的两组节点嵌入之间的瓦瑟斯坦距离(Xuetal.,2019a;b)。借用这样一个概念,我们可以查看我们的 OT 损失也来测量原始图和解码图之间的距离。
3.3 Further discussion-Decoders $\psi_{s}$ and $\psi_{d}$
重构初始特征 $h_{v}^{(0)}$ 的解码器 $\psi_{s}$ 是一个 FNN。重构节点度的解码器 $\psi_{d}$ 是一个 FNN+指数神经元,使其值非负。
$\begin{array}{l}\psi_{s}\left(h_{v}^{(k)}\right)&=&\mathrm{FNN}_{s}\left(h_{v}^{(k)}\right)\\\psi_{d}\left(h_{v}^{(k)}\right)&=&\exp \left(\mathrm{FNN}_{d}\left(h_{v}^{(k)}\right)\right)\end{array}\quad\quad\quad(9)$
在实际应用中,原始的节点特征 $X$ 可以是非常高维的,直接重构它们可能会在节点表示中引入大量的噪声。相反,我们可以首先将 $X$ 映射到一个潜在的空间来初始化 $H^{0}$。然而,如果 $H^{0}$ 同时用于表示学习和重建,它就有崩溃到平凡点的风险。因此,我们通过对范数对 $H^{0}$ 进行适当的归一化,以避免以下陷阱
$\begin{array}{l}\left\{h_{v}^{(0)} \mid v \in V\right\}=\text { pair-norm }\left(\left\{x_{v} W \mid v \in V\right\}\right) \\ \text {where } W \text { is a learnable parameter matrix. }\end{array}\quad\quad\quad(10)$
4 Experiments
我们设计实验来评估 NWR-GAE,重点关注以下研究问题:RQ1:与最先进的无监督图嵌入基线相比,NWR-GAE在基于结构角色的合成数据集上表现如何?RQ2:NWR-GAE及其消融如何与不同类型的真实世界图形数据集上的基线进行比较?RQ3:嵌入尺寸 $d$ 和采样尺寸 $q$ 等主要模型参数对NWR-GAE的影响是什么?
4.1 Experimental setup
4.1.1 Datasets
Synthetic datasets
4.1.2 Baselines
1) Random walk based (DeepWalk, node2vec)
2) Structural role based (RoleX, struc2vec, GraphWave)
3) Graph auto-encoder based (GAE, VGAE, ARGVA)
4) Contrastive learning based (DGI, GraphCL, MVGRL)
4.1.3 Evaluation metrics
- Homogeneity: conditional entropy of ground-truth among predicting clusters.
- Completeness: ratio of nodes with the same ground-truth labels assigned to the same cluster.
- Silhouette score: intra-cluster distance vs. inter-cluster distance.
4.2 Performance on synthetic datasets(RQ1)
4.3 Performance on real-world datasets(RQ2)
4.4 In-depth analysis of NWR-GAE
5 Conclusion
在这项工作中,我们解决了现有的无监督图表示方法的局限性,并提出了第一个能够正确地捕获图中节点的接近性、结构和特征信息的模型,并在低维嵌入空间中对其进行区分编码的模型。该模型在合成和真实基准数据集上进行了广泛的测试,结果有力地支持了其声称的优势。由于它是通用的,有效的,而且在概念上也很容易理解,我们相信它有潜力作为无监督图表示学习的实际方法。在未来,它将有望看到其在不同领域的应用研究,以及仔细分析其鲁棒性和隐私性等潜在问题。
论文解读(NWR)《Graph Auto-Encoder via Neighborhood Wasserstein Reconstruction》的更多相关文章
- 论文解读(GraphMAE)《GraphMAE: Self-Supervised Masked Graph Autoencoders》
论文信息 论文标题:GraphMAE: Self-Supervised Masked Graph Autoencoders论文作者:Zhenyu Hou, Xiao Liu, Yukuo Cen, Y ...
- 论文解读(SR-GNN)《Shift-Robust GNNs: Overcoming the Limitations of Localized Graph Training Data》
论文信息 论文标题:Shift-Robust GNNs: Overcoming the Limitations of Localized Graph Training Data论文作者:Qi Zhu, ...
- 论文解读(LG2AR)《Learning Graph Augmentations to Learn Graph Representations》
论文信息 论文标题:Learning Graph Augmentations to Learn Graph Representations论文作者:Kaveh Hassani, Amir Hosein ...
- 论文解读(GCC)《Efficient Graph Convolution for Joint Node RepresentationLearning and Clustering》
论文信息 论文标题:Efficient Graph Convolution for Joint Node RepresentationLearning and Clustering论文作者:Chaki ...
- 论文解读(KP-GNN)《How Powerful are K-hop Message Passing Graph Neural Networks》
论文信息 论文标题:How Powerful are K-hop Message Passing Graph Neural Networks论文作者:Jiarui Feng, Yixin Chen, ...
- 论文解读(AGC)《Attributed Graph Clustering via Adaptive Graph Convolution》
论文信息 论文标题:Attributed Graph Clustering via Adaptive Graph Convolution论文作者:Xiaotong Zhang, Han Liu, Qi ...
- 论文解读(g-U-Nets)《Graph U-Nets》
论文信息 论文标题:Graph U-Nets论文作者:Hongyang Gao, Shuiwang Ji论文来源:2019,ICML论文地址:download 论文代码:download 1 Intr ...
- 论文解读(SUGRL)《Simple Unsupervised Graph Representation Learning》
Paper Information Title:Simple Unsupervised Graph Representation LearningAuthors: Yujie Mo.Liang Pen ...
- 论文解读(GRCCA)《 Graph Representation Learning via Contrasting Cluster Assignments》
论文信息 论文标题:Graph Representation Learning via Contrasting Cluster Assignments论文作者:Chun-Yang Zhang, Hon ...
随机推荐
- C++:接送旅客
接送旅客 时间限制:1.00sec 内存限制:128MB 题目描述: 现在,你是一家酒店的员工,你需要帮助这家酒店的旅客运送行李离开酒店.现在,你送顶层开始往下移动,为了减少电梯移动的距 ...
- 前端3JS2
内容概要 运算符 流程控制 三元运算符 函数 自定义对象 内置对象 JSON对象 正则对象 内容详情 运算符
- sort是不稳定排序
今天才知道sort是不稳定的,WA了一个点. sort()排序不是稳定排序,sort是主要用到了快速排序(平均时间复杂度为O(nlogn)),还结合了插入排序(时间复杂度为O(n2))和堆排序(时间复 ...
- Redis初启(一)
1.数据库存存储性能优化 在mysql的文章专题中我写过了关于传统关系型数据库的一些优化思路,整体来说,通过优化之后能够提升程序访问数据库的计算性能.但是还是有一些情况,即便是优化之后,使用传统关系型 ...
- C#中常用的目录|文件|路径信息操作
更新记录 本文迁移自Panda666原博客,原发布时间:2021年5月16日. 说明 .NET的类库API设计的非常优秀,再加上文档docs.com写的非常优秀,写代码给人一种十分优雅的感觉. 获得当 ...
- Snowflake(雪花算法),什么情况下会冲突?
文章首发在公众号(龙台的技术笔记),之后同步到博客园和个人网站:xiaomage.info 分布式系统中,有一些需要使用全局唯一 ID 的场景,这种时候为了防止 ID 冲突可以使用 36 位的 UUI ...
- BUUCTF-九连环
九连环 这题还是稍微有点难度的 使用16进制打开发现压缩包,用binwalk分离看看 分离得到的压缩包同样16进制看看 可以发现多个压缩包,这种情况应该是伪加密的方式,但是直接使用修复压缩包的方式没法 ...
- 关于react的props你需要知道的一个简单方法
//注意一点:函数名必须大写 function Clock(props) { return ( <div> <h1>Hello, world!</h1> <h ...
- Java 向数组中添加元素
一般数组是不能添加元素的,因为他们在初始化时就已定好长度了,不能改变长度. 向数组中添加元素思路 第一步:把数组转化为集合 list = Arrays.asList(array); 第二步:向集合中添 ...
- HTTP Status 405 - Request method 'GET' not supported?(尚硅谷Restful案例练习关于Delete方法出现的错误)
哈罗大家好,最近在如火如荼的学习java开发----Spring系列框架,当学习到SpringMVC,动手实践RESTFUL案例时,发现了以上报错405,get请求方法没有被支持. 首先第一步,我查看 ...