跳转至

局部搜索

局部搜索的基本思想

首先就需要对“局部”和“搜索”这两个名词进行定义:

Definition

  • 局部:为了定义局部,需要定义“邻居”这个概念。假设 \(S\) 是一个可行解,那么 \(S\) 的邻居是如下的集合:
\[ N(S) = \{S' | S' \text{ 是通过对 } S \text{ 进行一个小的改变得到的} \} \]

这里的“小的改变”需要根据具体的问题来定义。例如背包问题可以设置为进行一个物品的替换,旅行商问题可能是交换两个顶点的途径顺序等等;于是所谓的解 \(S\) 的局部也就是 \(S\) 的邻居集合 \(N(S)\)

  • 所谓的搜索就是从任意一个可行解开始,不断在当前所处的解的局部(也就是邻居)中选择一个最优解,直到我们无法在局部找到更优解为止,这样我们就能得到一个局部最优解。

顶点覆盖问题

顶点覆盖问题的描述为:给定一个无向图 \(G = (V, E)\),找到最小的一个顶点集合 \(C \subseteq V\),使得对于每一条边 \((u, v) \in E\),至少有一个顶点 \(u\) 或者 \(v\) \(C\) 中。

在讨论局部搜索前先给出一个基于贪心的近似算法 \(A\):选择任意一条边 \((u, v)\),将 \(u\) \(v\) 都加入到 \(C\) 中,然后删除所有与 \(u\) 或者 \(v\) 相关的边,下一轮继续在剩下的边中随机选择一条重复上述操作,直到所有的边都被删除为止。

Theorem

\(A\) 是一个 \(2\text{-}\) 近似算法 .

Proof

设最优解为 \(C^*\)\(A\) 的解为 \(C\)\(S\) \(A\) 的每一步选择的边的集合。为了覆盖 \(S\) 中的边,任意一个顶点覆盖都必须至少包含 \(S\) 中的一个顶点 . 又因为每次把边选进 \(S\) 后就会把所有与选入的边的端点相关联的所有边,所以 \(S\) 中不存在两条边具有共同的端点,从而就有

\[ \lvert C^* \rvert \geqslant \lvert S \rvert. \]

又因为 \(S\) 中每一条边的两个顶点都被选入了 \(C\),所以有

\[ \lvert C \rvert = 2 \lvert S \rvert \leqslant 2 \lvert C^* \rvert. \]

而这个问题采用局部搜索的思路就是:

Design

  • 初始解设置为图 \(G\) 全部的顶点,即 \(C = V\)
  • 随机从 \(C\) 中选择一个顶点 \(v\),将其从 \(C\) 中删除,检查新的解 \(C - \{v\}\) 是否是一个顶点覆盖 .
  • 是则继续,否则 \(C\) 就是一个局部最优解。

这样的算法也被称作“梯度下降法”,此处借用了它的思想,我们的梯度下降其实就是任选一个点从现有解中删除。

但这一算法所得到的局部最优解并不一定是全局最优解,甚至可以差得很远,它没有任何的近似比保证。因此我们需要对其进行改进,能够跳出一些很差的局部最优解,换条路继续搜索。这就涉及了 Metropolis 算法与模拟退火。

在统计物理中有一个假设,当一个系统的能量为 \(E\) 时,它出现的概率为 \(P(E) = e^{-E/kT}\),其中 \(k\) 是玻尔兹曼常数,\(T\) 是温度,这个假设被称为 Boltzmann 分布。Metropolis 算法就是基于 Boltzmann 分布的一种算法。

Metropolis Algorithm

  • 初始解设置为随机的一个可行解 \(S\),设能量函数为 \(E(S)\),并确定一个温度 \(T\)
  • 随机选择 \(S\) 的一个邻居 \(S'\)(可以按均匀分布随机选择
  • \(E(S') \leqslant E(S)\),则接受 \(S'\) 作为新的解;若 \(E(S') > E(S)\),则以概率 \(e^{-\Delta E / kT}\) 接受 \(S'\) 作为新的解,其中 \(\Delta E = E(S') - E(S)\)
  • 重复上述步骤直到满足终止条件。

但是 Metropolis 算法的一个问题是,因为是基于概率的,所以它很可能在并非最优解的情况来回打转但无法达到最优解。因此我们设计了模拟退火这一过程。也就是说,在一开始的时候将温度 \(T\) 设定得比较高,这样我们就能在开始的时候跳到一个比较好的局部,然后随着搜索的进行,逐渐降低温度,最终达局部最优解。

Metropolis 算法还拥有如下的性质:

theorem

\(Z = \sum_{S} e^{-E(S) / kT}\). 对于任意状态 \(S\),记 \(f_S(t)\) 为在 \(t\) 轮迭代中选到了状态 \(S\) 的比例,则 \(t \to \infty\) 时,\(f_S(t)\) 将依概率 1 收敛到 \(e^{-E(S) / kT} / Z\).

Hopfield Neural Networks

Hopfield 神经网络是一种反馈神经网络,它的每一个神经元都是一个二值的变量,每一个神经元都与其他所有的神经元相连,每一个连接都有一个权重。我们在此处讨论的是 Hopfield 神经网络的稳定构型问题(stable configurations,首先给出一些相关的定义:

Definition

  • Hopfield 神经网络可以抽象为一个无向图 \(G = (V, E)\),其中 \(V\) 是神经元的集合,\(E\) 是连接的集合,每条边 \(e\) 都有一个权重 \(w_e\),可能为正也可能为负;
  • Hopfield 神经网络的一个构型(configuration)是指对网络中每个神经元(即图的顶点)的状态的一个赋值,赋值可能为 1 -1,我们记顶点 \(u\) 的状态为 \(s_u\)
  • 如果对于边 \(e = (u, v)\) \(w_e > 0\),则我们希望 \(u\) \(v\) 具有相反的状态;如果 \(w_e < 0\),则我们希望 \(u\) \(v\) 具有相同的状态;综合而言,我们希望
\[ w_e s_u s_v < 0. \]
  • 我们将满足上述条件的边 \(e\) 称为 “好的(good)”,否则称为 “坏的(bad)”;
  • 我们称一个点 \(u\) 是 “满意的(satisfied)”,当且仅当 \(u\) 所在的边中,好边的权重绝对值之和大于等于坏边的权重绝对值之和,即
\[ \sum_{v:e = (u, v) \in E} w_e s_u s_v \leqslant 0. \]

反之,如果 \(u\) 不满足上述条件,我们称 \(u\) 是 “不满意的(unsatisfied)”。

  • 称一个构型是稳定的,当且仅当所有的点都是满意的。

那么自然地,对于每个构型而言,它的“邻居”就是将其中一个点的状态取反得到的构型,那么我们的想法就与顶点覆盖问题类似,先随机初始化每个点的状态,开始检查每个点是否满意,如果有不满意的点,我们就翻转这个点的状态(那么这个点自然就变得满意了,然后继续检查,直到所有的点都满意为止。如果这个算法可以停止,那我们最后就能获得一个稳定的构型。我们将这一算法称为 \(State\_flipping\)。那么问题就在于,这个算法是否真的会停止?

为了解答这一问题,我们需要引入势能函数 \(\Phi\),它输入一个构型 \(S\),返回这个构型下所有好边的权重的绝对值的和,即

\[ \Phi (S) = \sum_{ e \text{ is good } } \lvert w_e \rvert. \]

那么显然 \(\Phi\) 是有界,最小值为 \(0\),最大值为所有边的权重的绝对值之和,也就是有 \(0 \leqslant \Phi(S) \leqslant \sum_{e \in E} \lvert w_e \rvert\)。那么我们考察翻转一个不满意的点后势能函数的变化。设当前状态为 \(S\),有一个不满意点 \(u\),翻转 \(u\) 的状态后得到 \(S'\),那么有

\[ \Phi(S') - \Phi(S) = \sum_{ e = (u, v) \in E, e \text{ is bad } } \lvert w_e \rvert - \sum_{ e = (u, v) \in E, e \text{ is good } } \lvert w_e \rvert. \]

这是因为翻转后原先与 \(u\) 相连的好边都变成了坏边,坏边都变成了好边,其余边没有变化。而 \(u\) 是不满意的,因此与 \(u\) 相连的坏边比好边权重绝对值之和大,上式的值便大于 \(0\)。而势能函数只能取整数值,所以 \(\Phi(S') \geqslant \Phi(S) + 1\)。这就意味着我们每次翻转一个不满意的点,势能函数就会增加至少 1。又因为势能函数的取值范围是有限的,所以我们的局部搜索算法一定会停止:

Theorem

\(State\_flipping\) 算法最多翻转 \(\sum_{e \in E} \lvert w_e \rvert\) 次后停止 .

由此也可以得出,势能函数的局部最大值实际上对应了一个稳定构型:

Theorem

\(S\) 是一个构型,如果 \(\Phi(S)\) 是局部最大值,那么 \(S\) 是一个稳定构型 .

最大割问题