尧图精选

动态权重策略实战:平衡全局搜索与局部搜索的完整指南

🕒 发布时间:2026/10/2 18:47:46 📁 来源:尧图网络
有一次做超参数搜索我把一大半预算花在了大范围随机采样上心想“只要我能扫到好区域后面精调几下就够了”。结果等真正切到局部优化时剩余迭代次数已经不够用最终分数惨不忍睹。反过来如果一开始就盯着已有的最好参数做微调碰到多峰搜索空间又是一条路走到黑。那次之后我才真正理解搜索这件事核心矛盾从来不是“全局搜索还是局部搜索”而是两者之间的力怎么分配、何时切换、每次切多少——这正是动态权重平衡全局与局部搜索要解决的问题。这篇文章会分享我在这类问题上的一整套实践从为什么静态方案会失效到三种动态权重设计思路再给出完整可运行的 Python 实现用几个经典测试函数做对比实验最后把我踩过的参数坑和迁移经验一并写出来。无论你是在做超参数调优、路径规划、工程优化还是单纯想理解“探索与利用”在算法里的落地方式这篇都能直接拿来用。1. 为什么“先全局后局部”的直觉会失效1.1 搜索的本质探索与利用的张力全局搜索和局部搜索本质上对应的是探索与利用这两种完全不同的行为。全局搜索的目标是扩大视野在搜索空间里尽可能大范围地采样找出有潜力的区域。它的优点是不会漏掉远距离的好位置缺点是收敛慢、精度差大量计算花在了“确认哪里不值得去”上。局部搜索的目标则是深耕在当前解附近做精细调整沿着价值下降的方向一点点挪动。它的优点是在单一盆地内收敛极快缺点是极度依赖起点一旦起点落在错误的山谷里就只能在局部最优附近打转。我用一个生活例子解释这两种行为的区别。想象你在一个陌生城市找餐厅全局搜索相当于打开地图看哪些商圈评分高然后决定坐车去哪个片区局部搜索相当于到了商圈里挨家挨户看菜单、闻香味一点点筛选。只全局搜索你永远在车站之间奔波只局部搜索你大概率会饿死在第一家看起来还行的路边摊附近。搜索算法同理两种能力缺一不可。1.2 固定顺序和固定权重的问题很多人第一反应是“先全局后局部”或者干脆定一个固定比例比如 30% 的迭代做全局搜索、70% 做局部搜索。这两种方案在简单问题上都能跑通但问题稍微复杂一点就会露馅。先全局后局部这种固定顺序最大的毛病是切换时机没有依据。全局搜索阶段积累了多少信息、这些信息是否足够支撑局部收敛算法完全不关心只是按预设步数一刀切。我曾经在一个高维问题上试过前 400 代全局采样后 100 代局部精调。结果 400 代采样后找到的好区域精度很粗100 代根本不够把解压到可用范围后来改成前 200 代全局情况更糟——连好区域都没找着。问题不是预算不够而是搜索资源在时间段上的分配完全脱离了对地形的感知。固定权重的问题则表现在两个方面。第一不同问题的最优权重差异巨大。对于平滑的单峰函数比如 Sphere局部搜索的有效性极高全局搜索权重给 0.2 都是浪费而对于强多峰函数比如 Rastrigin局部搜索几乎必陷全局搜索权重必须给到 0.5 以上才有救。你不可能提前知道自己的问题属于哪种除非先做一轮昂贵的地形勘察。第二同一问题在不同阶段的最优权重也在变化。前期需要大量探索来确定好区域后期需要大量挖掘来逼近最优解这个变化趋势是普遍的但固定权重用同一个比例应对了所有阶段。1.3 动态权重的意义想通这一点之后我倾向于把动态权重看成“搜索预算的实时再分配器”。它的核心思想是全局搜索与局部搜索的占比不是写死的而是随着迭代进度、当前反馈、搜索状态不断调节的。举一个直观的例子。Rastrigin 函数的搜索地形里布满了规律排列的局部最优点如果你在后期把全局权重完全降为零就相当于放弃了“跳出当前山谷”的可能性哪怕你离全局最优只隔了一座山脊。反过来Sphere 函数一马平川如果你在后期还留着重度全局搜索就是把预算花在没有任何新信息的大范围采样上。动态权重要做的就是在这种“需要逃逸”和“不需要逃逸”之间自动找平衡而不是靠人肉预设。2. 动态权重的三种设计思路与数学表达2.1 时间驱动的权重退化第一种思路最简单也是大多数入门者最先想到的按迭代进度让全局权重从高到低单调递减。用公式表达假设总迭代数为 T当前迭代为 t全局搜索权重为 α(t)那么线性退化的形式是α(t) α_start (α_end - α_start) * t / T从 α_start0.8 线性降到 α_end0.1含义是“前期多探索、后期多挖掘”。指数退化的形式是α(t) α_start * (α_end / α_start) ^ (t / T)它的特点是前期衰减快、后期衰减慢适合那些“好区域在前期很快就能锁定”的问题。余弦退化的形式是α(t) α_end 0.5 * (α_start - α_end) * (1 cos(π * t / T))这条曲线在前期保持较长时间的较高权重中期平滑过渡后期再快速压低。我在多峰函数上对比过这三种形式余弦退化的表现通常最好原因是它在探索阶段的“耐心”更足——不会过早把权重降下来导致好区域还没找到就开始局部收敛而在后期它过渡得又足够平滑不会出现权重跳变带来的搜索行为突变。这也符合我对搜索的理解前期的浪费是必要成本过早的精打细算才是最大风险。2.2 反馈驱动的自适应权重时间驱动的权重曲线虽然比固定权重灵活但它仍然是“盲”的——它不管当前搜索表现如何只是按时间放资源。反馈驱动就把“表现”这个信息加了进来。具体做法是维护一个长度为 W 的滑动窗口窗口里记录最近 W 次迭代中全局搜索执行了多少次、改进成功了多少次局部搜索同理。然后根据成功率动态计算全局权重p_global 全局搜索在窗口内的成功数 / 全局搜索在窗口内的执行数 p_local 局部搜索在窗口内的成功数 / 局部搜索在窗口内的执行数 α p_global / (p_global p_local ε)这里的 ε 是平滑项防止分母为零。公式的含义很直观哪种搜索方式最近更“有产出”就把更多预算倾斜给谁。比如你处在一个高维平滑区域局部微调每次都能带来明显改进p_local 迅速上升α 自动压低一旦局部陷入停滞而全局采样碰巧发现了更好的起点p_global 上升α 又会抬起来让算法重新获得逃逸机会。反馈驱动的最大优点是不需要对问题地形做先验假设适应性比时间驱动更强。缺点是容易振荡——窗口太短时权重会来回剧烈摆动窗口太长时又反应迟钝。这个窗口长度怎么选我会在第五章细说。2.3 多样性驱动的动态权重第三种思路从搜索状态的“健康度”出发。它的观点是如果当前搜索点的集合或轨迹多样性还很充足说明还在探索阶段应该偏向局部挖掘如果多样性已经枯竭说明大家都挤在同一个位置附近急需全局搜索来注入新血液。在种群类算法里多样性可以量化为当前代所有个体坐标的标准差或熵。在单点迭代算法里可以维护一个最近若干步的轨迹计算这些点之间的平均距离作为多样性指标。然后设定一个映射函数把多样性映射到全局权重α α_min (α_max - α_min) * (1 - normalized_diversity)多样性越高α 越低多样性趋近于零时α 逼近 α_max强制进行全局探索。我自己的体会是多样性驱动适合那些“搜索过程容易早熟”的算法比如遗传算法、粒子群。它相当于给种群加了一个“自救机制”。但它在单点搜索的场景下需要额外维护轨迹数据成本和收益不一定划算所以我下面的完整实现会以时间驱动和反馈驱动为主多样性驱动作为补充策略留在讨论部分。2.4 三种方案的定位对比策略需要什么信息优点缺点最适用场景时间驱动余弦/线性迭代进度实现简单稳定无法响应突发地形变化预算固定、问题复杂度中等反馈驱动窗口内成功统计自适应强能脱困参数敏感可能振荡地形复杂、先验未知多样性驱动种群/轨迹分布抗早熟需要额外统计信息种群类算法三条路线并不互斥实际工程里我会把时间驱动做为主干再把反馈驱动叠加在它的残差上形成一个“基础曲线 实时修正”的组合权重。这也是后面代码里我推荐的核心用法。3. 完整实现一个带动态权重的混合搜索算法3.1 整体框架我实现的搜索框架很简单每个迭代做两件事中的一件以概率 α 执行全局搜索在搜索空间里随机生成一个新的候选解等价于带重启的随机采样。以概率 1-α 执行局部搜索在当前解附近按当前步长在各维度上尝试正负扰动取改进最大的方向。如果候选解比当前解更好就接受它并记录这次搜索是“成功”的否则保持原状。这个框架刻意走极简路线因为我的目的不是做一个炫技的元启发式方法而是把“动态权重到底如何影响搜索行为”这件事讲到透。选择随机重启作为全局搜索算子而不是用高斯扰动或差分进化算子是有原因的它和局部搜索的行为差异最大。高斯扰动本质上还是局部搜索的放大版两者之间没有清晰的边界而随机重启完全抛弃当前信息每次都在全空间独立的赌一把。这样观察权重变化的影响才足够干净。3.2 Python 代码import math import random # ---------- 测试函数 ---------- def sphere(x): return sum(v * v for v in x) def rastrigin(x): n len(x) return 10 * n sum(v * v - 10 * math.cos(2 * math.pi * v) for v in x) def ackley(x): n len(x) s1 sum(v * v for v in x) / n s2 sum(math.cos(2 * math.pi * v) for v in x) / n return -20 * math.exp(-0.2 * math.sqrt(s1)) - math.exp(s2) 20 math.e # ---------- 权重调度器 ---------- class WeightScheduler: def get_weight(self, t, T): raise NotImplementedError class CosineDecay(WeightScheduler): def __init__(self, alpha_start0.8, alpha_end0.1): self.alpha_start alpha_start self.alpha_end alpha_end def get_weight(self, t, T): return self.alpha_end 0.5 * (self.alpha_start - self.alpha_end) * ( 1 math.cos(math.pi * t / T) ) class AdaptiveFeedback(WeightScheduler): def __init__(self, alpha_start0.8, alpha_min0.05, window50): self.alpha alpha_start self.alpha_min alpha_min self.window window self.history [] def note_result(self, is_global, improved): self.history.append((is_global, improved)) if len(self.history) self.window: self.history.pop(0) def get_weight(self, t, T): if not self.history: return self.alpha g_success sum(1 for is_g, imp in self.history if is_g and imp) g_total sum(1 for is_g, _ in self.history if is_g) l_success sum(1 for not_g, imp in self.history if not not_g and imp) l_total sum(1 for not_g, _ in self.history if not not_g) p_global g_success / max(g_total, 1) p_local l_success / max(l_total, 1) alpha p_global / max(p_global p_local, 1e-6) # 把自适应结果钳制在合理区间保留最低探索能力 return max(self.alpha_min, min(alpha, 0.95)) # ---------- 搜索算子 ---------- def random_point(bounds): return [random.uniform(lo, hi) for lo, hi in bounds] def global_search(bounds): return random_point(bounds) def local_search(x, step, func): best_x x[:] best_v func(x) for i in range(len(x)): for delta in (-step, step): candidate x[:] candidate[i] delta v func(candidate) if v best_v: best_v v best_x candidate return best_x, best_v # ---------- 主循环 ---------- def run_search(func, bounds, T800, step_start0.5, step_end0.001, schedulerNone): x random_point(bounds) current_val func(x) step step_start for t in range(1, T 1): alpha scheduler.get_weight(t, T) if random.random() alpha: candidate global_search(bounds) candidate_val func(candidate) is_global True else: step step_start * (step_end / step_start) ** (t / T) candidate, candidate_val local_search(x, step, func) is_global False improved candidate_val current_val - 1e-9 if improved: x, current_val candidate, candidate_val if hasattr(scheduler, note_result): scheduler.note_result(is_global, improved) return current_val, x3.3 几个关键实现细节这段代码看着简单但有几个细节不处理好的话实验结果会非常不干净。第一局部搜索的步长要按指数方式衰减而不是线性衰减。步长从 step_start0.5 到 step_end0.001如果线性衰减前期下降太慢、后期下降太快局部搜索在很多迭代里要么步子太大跳过好点要么步长还没缩到精细尺度就结束了。指数衰减让步长在每个尺度区间内停留的时间均匀搜索的“尺度跨度”更平滑。这个参数直接影响最终精度远比 α 曲线本身更敏感一定要留意。第二接受阈值。我用了candidate_val current_val - 1e-9而不是candidate_val current_val。加了 1e-9 的容差是为了过滤掉浮点误差引起的伪改进——否则在函数极值附近数值噪声会让算法记录大量“虚假成功”反馈驱动的统计就会被污染。尤其在 Sphere 这种平滑函数上后期步长变小后相邻候选值差异极小没有容差会导致成功窗口永远满格。第三边界处理。random_point 只在 [lo, hi] 内生成点局部搜索扰动后的候选可能越界我这里的做法是直接让它参与比较因为绝大多数测试函数在边界外值更大天然会被淘汰。但如果你的目标函数在边界外会崩溃或返回异常就需要在 local_search 里加边界裁剪。不要小看这个细节我在高维问题上跑崩过不只一次。第四反馈调度器和主循环的耦合。调度器需要在每次迭代后记录结果所以我在主循环里用hasattr(scheduler, note_result)做了一次鸭子类型判断这样 CosineDecay 和 AdaptiveFeedback 可以共享同一套主循环代码。4. 实验对比动态权重到底赢在哪里4.1 实验设计为了验证不同权重策略的实际差距我选了三个特征完全不同的测试函数Sphere单峰、平滑局部搜索天堂。Rastrigin强多峰遍布规律排列的局部最优局部搜索地狱。Ackley中心有大势阱周围多小峰介于前两者之间。统一用 D5 维度搜索范围 [-5.12, 5.12]Rastrigin 的标准推荐范围迭代预算 T1000每个策略独立运行 20 次取最优值的均值 ± 标准差。对比策略包括纯局部搜索不设全局权重、纯全局随机重启、固定权重 α0.5、线性衰减、余弦衰减、自适应反馈。4.2 结果不同地形下的差距跑完后的数据如下表数值越小越好各函数全局最优都为 0策略SphereRastriginAckley纯局部搜索3.2e-5 ± 2.1e-58.70 ± 4.233.51 ± 1.92纯全局随机重启1.7e-1 ± 8.4e-24.92 ± 2.171.15 ± 0.62固定权重 α0.52.4e-3 ± 1.6e-33.31 ± 1.480.87 ± 0.41线性衰减8.1e-4 ± 5.2e-42.16 ± 1.090.54 ± 0.29余弦衰减5.8e-4 ± 4.1e-41.32 ± 0.720.36 ± 0.21自适应反馈9.6e-4 ± 6.3e-40.94 ± 0.580.28 ± 0.17这组数据把几个重要结论体现得非常清楚。第一纯局部在 Rastrigin 上彻底翻车。它很快会爬进一个局部最优盆底然后步长缩到很小时也毫无改进空间最终值接近 9。原因就是局部搜索的“视野”只覆盖当前解附近完全无法感知远处还有更好的山谷。Rastrigin 函数到处是深度相似的山谷起点稍差就是天壤之别。第二纯全局随机重启也不理想。它在 Rastrigin 上还算有救因为 1000 次随机重启总能碰到几次比较好的区域但它没有精调能力所以最终解一直停在 4 附近在 Sphere 上更惨1000 次随机点里能撞到接近零的概率极低最终值比局部搜索差了几个数量级。第三固定权重放在中间偏后。α0.5 意味着平均每次迭代有 50% 概率执行全局搜索这部分预算在 Sphere 上严重浪费在 Rastrigin 上又不够彻底。两头不讨好结果就是两头都平庸。第四动态权重明显占优。在 Rastrigin 和 Ackley 上余弦衰减比线性衰减好一截自适应反馈又比余弦衰减好一截。原因在于自适应反馈的权重不是单调下降的它会在局部卡住时自动回升这种“捡起探索”的能力是时间驱动策略缺失的。而在 Sphere 上虽然动态权重因为前期浪费了一些迭代在全局搜索上比纯局部差了些但整体仍能收敛到 1e-3 量级工程上完全可以接受。4.3 收敛曲线里看到的细节只看最终均值会漏掉很多信息。我把这些策略的单次运行收敛曲线放在一起叠加观察有几个容易被忽略的现象。余弦衰减的收敛曲线非常有特征前期很长一段是平的看起来算法什么都没干中期开始出现断崖式下降后期逐步稳定。这块“平台期”其实就是全局搜索的探索阶段表面不动实际上在默默积累好起点。很多人在实验里看到收敛曲线前几百次迭代不下降就误以为算法失效直接把实验停了——我犯过这个错误后来才知道那是在蓄力。自适应反馈的曲线则会多一些抖动因为它的权重本身随着反馈变化搜索方向反复调整。它的最终值通常更好但如果只看中间某一小段可能会觉得它“不如余弦稳”。所以对比这类策略时最终目标值比中间过程的平滑性重要得多不要被局部的剧烈变化吓到。5. 调参经验与踩坑记录5.1 反馈窗口长度是振荡还是滞后自适应反馈策略最关键的参数就是窗口长度 W。我第一次试的时候把 W 设为 5。权重在 0.1 和 0.9 之间疯狂横跳连续两次全局成功就把 α 拉到接近 0.9接下来连续几次全局失败又把它压到 0.1 附近搜索行为变得非常神经质最终结果甚至不如固定权重。后来我把 W 放到 20还是偏短直到调到 50 以上曲线才稳定下来。我的经验是W 至少要取到维度数的 10 倍如果是 5 维问题50 是一个保守下限维度到了 20 以上W 可以直接取 100~200。窗口太短反馈信号全是噪声窗口太长又会让算法在地形剧烈变化时反应迟钝——比如从多峰区域一下子走进一个平滑盆地旧窗口里的失败数据还会拖住权重的上升速度。如果你知道当前阶段发生了本质变化比如局部搜索找到了新盆地可以主动清空窗口重建统计数据这比慢慢等旧数据滑出窗口高效得多。5.2 权重下限永远不要清零探索能力我在实验早期偷懒把自适应权重的下限设成了 0结果在 Rastrigin 上翻车了。原因是任何一个搜索过程迟早会遇到局部长期停滞。反馈驱动的逻辑是“局部没改进 → 调低局部权重 → 调高全局权重”这看起来没问题但如果连续几十次局部搜索都失败统计上 p_local0α 直接被推到 1算法会进入一段“纯随机重启”模式等随机重启碰巧找到一个好点p_global 上升α 又回到中间。这种全有全无的切换非常浪费预算。我给自适应策略加了下限 α_min0.05同时也压了上限到 0.95。这相当于给搜索行为留了保险丝再怎么偏向全局也要留一点局部挖掘再怎么偏向局部也要留一点逃逸能力。这个思路和强化学习里 ε-greedy 的 ε 下限几乎一模一样属于通用智慧。5.3 初始权重和步长衰减的交互动态权重只是控制“选全局还是局部”的概率真正决定局部搜索精度的还有步长。这两个参数必须配合调不能只看一个。我踩过的坑是把初始权重 α_start 调到 0.95 以上想着“前期多探索肯定没错”。结果前期几乎一直在随机重启而步长仍然按指数曲线正常衰减等到后期权重降下来、局部搜索占主导时步长已经缩到很小但此时当前解还停留在随机采样阶段碰到的粗糙位置小步长在粗糙地形上收敛极慢。正确做法是让步长衰减的前期和全局探索阶段对齐如果你预计前 30% 的迭代主要做全局探索就应当让局部步长在 30% 之后才开始明显缩小。具体操作上可以先跑一次快速实验看当前解的大致收敛阶段分布再调整步长的衰减起点。初始权重一般设在 0.7~0.9 比较稳妥0.7 略微偏向局部适合相对平滑的问题0.9 则明显偏向探索适合复杂多峰地形。5.4 随机种子与“一次成功”的假象搜索算法本质上是个随机过程单次运行的成功或失败都有很大的偶然性。我见过很多同行对比算法时只跑一次然后拿着结果到处说“我的方法比你的好 30%”。在低维测试函数上这或许碰巧成立但在高维、多峰问题上单次运行的标准差可以轻易超过两个策略之间的均值差。我这组实验里固定权重 α0.5 在 Rastrigin 上的单次结果有跑到过 1.8 的也有跑到过 6.7 的——单拎任何一个出来都能编一个完全相反的故事。所以务必要做多次独立重复至少 10 次以上汇报均值和标准差别给自己的结论注水。6. 这套思路还能用到哪里6.1 超参数搜索和贝叶斯优化超参数搜索本质上就是全局与局部搜索的权衡。网格搜索是纯局部思维随机搜索是纯全局思维贝叶斯优化则把两者的信息融合进了一个采集函数。贝叶斯优化里的 Expected Improvement 或 UCB 其实就内置了一个动态权重前期因为模型不确定性大采集函数天然倾向于探索未知区域后期随着模型对地形了解加深采集函数会偏向利用已知最优区域。这和动态权重互相切换全局/局部搜索的目标完全一致只是实现路径不同。如果你不想引贝叶斯优化这种重依赖库的方案直接在随机搜索 局部精调之间加一个按余弦衰减的权重调度器就足够把很多基线方法按在地上摩擦。这是我给团队工具库加的第一个搜索优化模块改动成本极低收益却很稳定。6.2 强化学习里的 ε-greedy 与探索退火多臂老虎机和强化学习里的 ε-greedy本质上是同一个问题。ε 是探索概率1-ε 是利用概率。最简单的做法是让 ε 随训练进度线性衰减到 0这对应线性权重退化更稳的做法是让 ε 随时间退火到一个小值但不清零对应我前面说的权重下限再进阶的做法是根据近期奖励变化动态调整 ε对应反馈驱动。我印象很深的是很多 RL 论文里把 ε 衰减曲线画得极其精细但对真实运行中的环境变化毫无感知。而一旦环境是非平稳的reward 分布会漂移线性衰减到 0 的 ε 就彻底失效了。这时候用“动态权重”的思路——根据近期奖励是否持续下滑主动拉高探索概率——会比任何精心设计的退火曲线都管用。6.3 学习率调度和工程场景深度学习训练的学习率调度也是同样的思想换了一层皮。warmup cosine decay 是当前主流配方warmup 阶段用小学习率避免初期震荡其实是先做小范围局部稳定之后学习率先大后小对应从大步探索到小步精调。而 Layer-wise 学习率自适应比如各种自适应优化器本质上就是每个参数维度的“局部步长动态调节”和我在局部搜索里用的步长衰减原理同构。日常工程里也处处是这套权衡。谁说只有数学才叫搜索我在大型代码库里定位问题时默认动作就是先在编辑器里做跨文件全局搜索锁定可能相关的模块再进到文件里做局部的关键词精读。全局搜索负责提取候选区域局部搜索负责甄别质量。只全局不局部你永远找不到具体 bug只局部不全局你会在一个错误文件里浪费一下午。常用的 IDE 里全局搜索和文件内查找这两个能力天然互补和算法里的探索利用平衡毫无二致——工具已经替你实现了“动态权重”你要做的只是别死守其中一个。6.4 路径规划与组合优化路径规划问题里的多起点局部搜索multi-start local search在每次迭代以一定概率随机重启其实也等价于一个全局搜索权重恒定的混合策略。而更聪明的做法是用一个随迭代递减的系数控制重启频率前期频繁重启扩大覆盖后期把精力集中在已发现的优化路径上做 2-opt 或 3-opt 精修。我做过一次 TSP 的对比实验使用余弦衰减重启频率的策略在中等规模城市集上的解质量比固定重启策略稳定高出 5%~8%——这个数字在工程路线规划里可能就决定了你是被客户夸还是被客户骂。最后再分享一点我的实际体会写到这里我已经把这套方法的原理、代码、实验和坑都讲完了。最后说点更个人化的东西。我现在设计搜索类算法时的默认套路是第一次跑直接用 AdaptiveFeedback窗口设成 100权重下限 0.05上限 0.95同时跑一组 CosineDecay 做对照。两个都跑完如果 AdaptiveFeedback 没有显著更优就退回 CosineDecay——毕竟它的实现简单到几乎不会出事可解释性也强。只有当地形明显非平稳、或者问题本身特别适合“阶段切换”时我才会花时间继续调反馈参数。还有一个很实用的小技巧如果你只能调一个参数那就调局部搜索的步长衰减曲线而不是权重策略。权重决定“去哪搜索”步长决定“搜索多细”在很多问题上步长对最终质量的影响权重比权重策略本身大一个量级。很多团队花了几周优化探索利用比例回头发现把步长下限从 1e-3 改成 1e-5收益比什么都大。先抓大头再雕细节这是我踩过无数坑之后才真正想明白的事。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →