惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 聂微东
S
Schneier on Security
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Latest news
Latest news
Cyberwarzone
Cyberwarzone
Cisco Talos Blog
Cisco Talos Blog
T
The Exploit Database - CXSecurity.com
T
Tenable Blog
I
Intezer
T
Threat Research - Cisco Blogs
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cybersecurity and Infrastructure Security Agency CISA
P
Privacy International News Feed
P
Palo Alto Networks Blog
The Register - Security
The Register - Security
IT之家
IT之家
Google DeepMind News
Google DeepMind News
C
Cyber Attacks, Cyber Crime and Cyber Security
L
LINUX DO - 最新话题
S
Securelist
WordPress大学
WordPress大学
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Hugging Face - Blog
Hugging Face - Blog
N
News and Events Feed by Topic
H
Help Net Security
Project Zero
Project Zero
K
Kaspersky official blog
博客园 - 三生石上(FineUI控件)
L
LINUX DO - 热门话题
大猫的无限游戏
大猫的无限游戏
G
GRAHAM CLULEY
F
Full Disclosure
博客园 - 叶小钗
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
TaoSecurity Blog
TaoSecurity Blog
N
News | PayPal Newsroom
Forbes - Security
Forbes - Security
博客园 - 司徒正美
I
InfoQ
Recent Announcements
Recent Announcements
Attack and Defense Labs
Attack and Defense Labs
P
Privacy & Cybersecurity Law Blog
S
Security @ Cisco Blogs
人人都是产品经理
人人都是产品经理
The GitHub Blog
The GitHub Blog
Simon Willison's Weblog
Simon Willison's Weblog
G
Google Developers Blog
N
Netflix TechBlog - Medium
U
Unit 42
阮一峰的网络日志
阮一峰的网络日志

博客园_首页

Linux实操--组管理、权限管理和定时任务 Java + EasyExcel 实现单个接口导出多个Excel Mem0 源码解析系列(二):提示词工程的深度剖析 Openclaw TaskFlow究竟是什么?和普通Skill技能有什么区别 博文阅读密码验证 - 博客园 嘉立创开源:应该是全网MicroPython教程最多的开发板 Hermes Agent 集成实践:从协议到生产 2026年AI编程工具横评:Cursor、Codex、Claude Code、Zed、Windsurf Java程序员必看的RAG入门教程 2026 AI效率神器:Superpowers + Claude Code 保姆级教程 本地大模型部署全攻略:从 0 到 1 玩转 Ollama 【从0到1构建一个ClaudeAgent】内存管理-上下文压缩 .NET 高级开发 | 设计、实现一个事件总线框架 电子小白入门之NE555 3. WorkBuddy:隐藏玩法,一键召唤专家,让 AI 以"专家身份"给你干活 和AI一起搞事情#3:Claude Teammate 游戏开发翻车实录 【OpenClaw】通过 Nanobot 源码学习架构---(7)Memory C# .NET 周刊|2026年3月3期 我在 Debian 11 上把 K8s 单机搭起来了,过程没你想的那么顺(/opt 目录版) 深度学习进阶(七)Data-efficient Image Transformer CLI+Skill搭建浏览器AI自动化框架,告别一切重复枯燥任务 告别Token账单无底洞:OpenClaw本地部署,重塑企业数据主权的唯一解 FastAPI+Vue:文件分片上传+秒传+断点续传,这坑我帮你踩平了! SBTI 爆火后,我做了个程序员版的 CBTI。。已开源 + 附开发过程 多模态检索开始进入工程期:用 Sentence Transformers 搭建可落地的 Multimodal RAG 100多行代码实现一个最简单的Agent(用ReAct) Claude Code 通关手册(八):推荐 5 个 Hooks,代码质量提升 3 倍 老板:“有人截图了!”。安全部门:“收到,马上查暗水印!” - why技术 技术之外,皆是人间 C#/.NET/.NET Core技术前沿周刊 | 第 69 期(2026年4.01-4.12) Snack JSONPath 项目架构分析 Claude Code Buddy 小析:一个非核心功能,如何体现产品的细节完成度 AI新时代下的图床管理方案-Cloudflare图床+MCP+Skills方案指南 化繁为简:顺丰速运App如何通过 HarmonyOS SDK实现专业级空间测量 从零实现富文本编辑器#13-React非编辑节点的内容渲染 AI开发-python-langchain框架(3-23-OpenAI Functions风格Tool Calling智能助手) .NET + AI 进阶实战:基于类的技能开发 - 打造可治理的 Agent 能力模块 【从0到1构建一个ClaudeAgent】规划与协调-技能 上周热点回顾(4.6-4.12) 电子小白的工具三件套:面包板、杜邦线、万能板 单表五亿数据的查询优化 | Mysql、StarRocks 2. WorkBuddy:从“我是谁”到“帮我干活” C# 如何减少代码运行时间:7 个实战技巧 基于HelixToolkit.SharpDX 渲染3D模型 - 笺上知微 从零开始的双臂具身VLA起源及现阶段发展综述 - SkyXZ 记对 xonsh shell 的使用, 脚本编写, 迁移及调优 - pluvium27 受够了Vibe Coding的失控?换个起点,让AI事半功倍 从开始配置漏洞环境到漏洞复现流程 - 難しい 关于10年工作经验的程序员对OpenClaw的实战经验分享以及看法 - 虚无境 Any metadata 的内存布局 C# .NET 周刊|2026年3月2期 - InCerry 我帮你测过了,测试圈排名第二的 Skill 依然很牛逼 Skill Discovery | 无监督技能发现的经典工作总结 - MoonOut PbootCMS 网站内容数量多导致访问慢?这些实用优化方案帮你提速! - 家兴网络技术工作室 上下文工程是什么?过时了么?一文讲明白! - 一枫说码 网站漏洞怎么发现并修复?一篇实用指南(附完整流程) - 家兴网络技术工作室 开了 TUN 模式还是直连?90% 的人都踩过这个坑 Github日报|2026年04月12日 - AI一族 AScript扩展多种脚本语言 - rockey627 AI 学习笔记:Agent 的记忆机制 你能被装进一个文件里吗?——7 万人把同事"蒸馏"成了 AI - 我没有三颗心脏 Claude Code 通关手册(七):给 AI 装上技能包——Skills 完全指南 - 暮色之狐 在浏览器中快速编辑代码:VSCode Web 集成实践 - Newbe36524 蒸馏自己 skill?基于 Deepseek 的蒸馏器,丐版蒸馏方式,简单便捷 - To_Carpe_Diem Spring AI Aliababa和AgentScope,哪个更好? - 苏三说技术 Etsy 把 1000 个 MySQL 分片迁进 Vitess:425TB 数据背后的真正问题不是性能,而是运维规模 MicroPython LVGL基础知识和概念:底层渲染与性能优化 - FreakStudio 数据库草图算法 Python 潮流周刊#146:CPython 引入 Rust 的进展 - 豌豆花下猫 最小生成树 - mofei1116 红日靶场七:从外网入口、容器逃逸到 AD 接管的完整利用链复盘 - YouDiscovered1t 分享四款开源且实用的 Kafka 管理工具 - 追逐时光者 vLLM 权重加载机制全解析:从挑战到理想架构 LCT 学习笔记 - ACehomoxue Avalonia UI 12.0.0 正式发布:架构演进和性能飞跃 - 张善友 当 AI Agent 把调用链拉长,延迟开始成为一门生意 conhost.exe 无法显示 U+2717 - 145a 太秀了,我把自己蒸馏成了 Skill!已开源 - 程序员鱼皮 ASP.NET Core 内存缓存实战:一篇搞懂该怎么配、怎么避坑 基于 Ghostty 带有分割标签页和为 Claude 编程设计的通知终端 - BugShare AI 焊死入口:教育的“操作系统级”重塑 - 郝hai 初级Java开发工程师使用sql脚本编写代码的过程是简单而且不糊涂 - CoderOilStation Claude Code通关手册(六):MCP协议完全指南 - 暮色之狐 边框灯光环绕动画特效实现指南 - Newbe36524 开源:子木蒸馏版的 SEO 审计工具 seo-audit-skill v1.0 我所理解的Python元模型 【从0到1构建一个ClaudeAgent】规划与协调-TodoWrite - 程序员Seven Claude 和 Codex 在审计 Skill 上性能差异探究 - ACai_sec AScript如何实现中文脚本引擎 - rockey627 【渗透测试】HTB Season10 Garfield 全过程wp - dynasty_chenzi Android 开发者为什么必须掌握 AI 能力?端侧视角下的技术变革 树状数组正确性证明 - AC-wyr 你的 AI 焦虑,可能比 AI 本身更危险——ATM 机没有消灭银行柜员,但恐慌消灭了你的判断力 - 我没有三颗心脏 一个拉胯的分库分表方案有多绝望?整个部门都在救火! - 冰河团队 动态规划入门必学之走方格问题 - Ofnoname PostgREST 与 PostgreSQL 角色权限配置全解析(生产级实践) - SheepDog1998 使用 UEFI 图形输出协议 GOP 在屏幕上显示图像的方法 - 阿源- Claude Code通关手册(五):组建你的AI专家团队,子代理系统 - 暮色之狐 一个程序员到架构师的催婚路之感悟(整整10年后的催婚相亲感悟) - MisterLip 用 Agent Skill 自动生成工作周报 - 赵康
Vertex Cover 的两倍边界
Ofnoname · 2026-06-27 · via 博客园_首页

在很多图问题里,边代表一种关系:依赖、冲突、通信、覆盖、监控、约束。Vertex Cover 问的是一个很直接的问题:能不能选出尽量少的一批点,使得每条边至少有一个端点被选中?

给定无向图 \(G=(V,E)\),若点集 \(C\subseteq V\) 满足对任意边 \((u,v)\in E\),都有 \(u\in C\)\(v\in C\),那么 \(C\) 就是一个 vertex cover。

要做到最优,就要选出最少的点。无权版本的目标是最小化 \(|C|\)。带权版本 Weighted Vertex Cover Problem 进一步给每个点 \(v\) 一个非负权重 \(w_v\),目标变成最小化 \(\sum_{v\in C} w_v\)

从最小化问题开始

Vertex Cover 是一个最小化型组合优化问题。它是 NP-complete 问题。带权版本也完全一样。

对于树、二分图、很小的参数 \(k\)、有特殊结构的图,可以有更好的精确算法。真正困难的是一般图上的最优解:输入只给你一个普通无向图,不附带额外结构,要求多项式时间内总是找出最小 vertex cover 是非常困难的。到这里,通常就要接受一个现实:精确最优很难,近似解是这个问题的主战场

对最小化问题,\(\rho\) 近似的意思是算法输出 \(A\) 满足 \(\text{cost}(A)\le \rho\cdot \text{OPT}\)。Vertex Cover 最经典的结论是 \(\rho=2\)。这不是一个随便冒出来的数字,它来自一个非常简单的下界:匹配。

无权覆盖的 2 近似:先抓一批互不相碰的边

先看无权版本。一个常见算法是:

  1. 从图中找一条还没有被覆盖的边 \((u,v)\)
  2. \(u\)\(v\) 都加入答案;
  3. 删除所有已经被 \(u\)\(v\) 覆盖的边;
  4. 重复,直到所有边都被覆盖。

换一种说法,这个算法实际上是在构造一个极大匹配。每次取到的边之间不会共享端点;当算法停下时,已经无法再加入新的边。最后,把这些匹配边的两个端点全部选入 \(C\)

这里要区分“极大”和“最大”。极大匹配 maximal matching 只是说不能再往里面加边了;最大匹配 maximum matching 才是边数真正最多的匹配。这个 2 近似算法求出的只是一个极大匹配,因此实现非常轻。

为什么它一定是一个覆盖

上面的算法先求出一个图匹配,再转化成对应的覆盖方案。设算法得到的匹配为 \(M\),输出 \(C\)\(M\) 中所有边的端点集合。假设存在一条边 \((a,b)\) 没有被 \(C\) 覆盖,也就是说 \(a\)\(b\) 都没有出现在任何匹配边里。那么 \((a,b)\) 可以直接加入 \(M\),并且不会和原来的匹配边冲突。这和 \(M\) 已经极大矛盾。

所以,输出一定是一个 vertex cover。算法停机条件本身就是正确性的一部分。只要还有一条未覆盖边,就继续抓;如果停了,说明不存在未覆盖边。

为什么它最多差两倍

接下来证明近似比。匹配 \(M\) 里的边两两不共享端点。任何 vertex cover 都必须覆盖 \(M\) 中的每条边,而覆盖一条匹配边至少要选它的一个端点。由于这些边互不相交,不可能用同一个点同时覆盖两条匹配边。因此任意最优解都至少要选 \(|M|\) 个点,即 \(\text{OPT}\ge |M|\)

算法输出时,每条匹配边选两个端点,所以 \(|C|=2|M|\)。于是有 \(|C|=2|M|\le 2\text{OPT}\)

这个证明很简单,并且这个比率对该算法来说是紧的。我们可以构造一个星形图,一个中心连出很多叶子。如果算法先拿到某条边 \((c,\ell)\),它会把中心 \(c\) 和叶子 \(\ell\) 都选进去。最优解只需要选中心 \(c\),所以这一次就已经是 \(2\)\(1\)。当然,输出仍然合法,只是多选了一个叶子。

带权覆盖情形

Weighted Vertex Cover 的难点在于,“拿一条边的两个端点”可能非常亏。假设只有一条边 \((u,v)\)\(w_u=1\)\(w_v=10^6\)。如果无脑选两个端点,代价是 \(1000001\);最优解只选 \(u\),代价是 \(1\)。这显然不是 2 近似。

带权版本常用的 2 近似解法巧妙的利用 LP 对偶和 primal-dual 。先写出整数规划的转换:令 \(x_v\in{0,1}\) 表示点 \(v\) 是否被选中,每条边 \((u,v)\) 要求 \(x_u+x_v\ge 1\)。放松 \(x_v\) 的整数约束后,得到线性规划:

\[\begin{aligned} \min \quad & \sum_{v\in V} w_v x_v \ \text{s.t.}\quad & x_u+x_v\ge 1,\quad \forall (u,v)\in E \ & x_v\ge 0,\quad \forall v\in V \end{aligned} \]

它的对偶可以理解成给每条边设置一个“价格” \(y_e\)

\[\begin{aligned} \max \quad & \sum_{e\in E} y_e \ \text{s.t.}\quad & \sum_{e\ni v} y_e\le w_v,\quad \forall v\in V \ & y_e\ge 0,\quad \forall e\in E \end{aligned} \]

对偶约束的意思是:所有压到点 \(v\) 身上的边价格之和,不能超过这个点的权重 \(w_v\)。任何可行的对偶解都会给出一个下界,因为任意 vertex cover 都要为每条边至少付一次账。

定价法的直觉

primal-dual 算法可以这样写:

C = ∅
所有边价格 y_e = 0
while 还有未被覆盖的边 e=(u,v):
    同时提高 y_e,直到 u 或 v 至少有一个点的预算被用满
    把预算用满的端点加入 C
    标记所有被 C 覆盖的边
return C

更具体地说,每个点 \(v\) 有剩余预算 \(\text{slack}(v)=w_v-\sum_{e\ni v}y_e\)。当处理未覆盖边 \((u,v)\) 时,令 \(\delta=\min(\text{slack}(u),\text{slack}(v))\),把 \(y_{(u,v)}\) 增加 \(\delta\)。此时至少一个端点变成 tight,也就是预算刚好用满,把这些 tight 的端点加入 \(C\)

如果某个点权重是 \(0\),它一开始就是 tight;只要它能覆盖边,选它没有坏处。权重为负通常不在标准定义里,因为那会破坏“代价最小化”的正常含义。

证明为什么还是 2

算法始终保持对偶可行:任何点的 incident edge 价格总和都不会超过它的权重。设最终边价格为 \(y\)。对任意最优 vertex cover \(C^*\),由于 \(C^*\) 覆盖每条边,所有边价格之和不会超过被 \(C^*\) 选中顶点的预算总和,所以 \(\sum_e y_e\le \text{OPT}\)

另一方面,算法选入 \(C\) 的每个点都是 tight 的,因此

\[\sum_{v\in C}w_v=\sum_{v\in C}\sum_{e\ni v}y_e \]

右边是在数“被选中端点承担了多少边价格”。一条边最多有两个端点,所以任何 \(y_e\) 最多被数两次。因此 \(\sum_{v\in C}w_v\le 2\sum_e y_e\le 2\text{OPT}\)

这就是带权版本的 2 近似证明。它和无权匹配算法看起来不同,本质上却很接近:都在构造一个可证明的下界,然后说明自己的解最多是这个下界的两倍。无权算法的下界是匹配大小;带权算法的下界是对偶价格。

它通向哪些经典问题

Vertex Cover 不是孤立的。很多图论和组合优化问题都能从它旁边走出来。

图片

最直接的是 Independent Set。点集 \(C\) 是 vertex cover,当且仅当 \(V\setminus C\) 是 independent set。因为如果剩下的点里还有一条边,那么这条边的两个端点都没被 \(C\) 选中,\(C\) 就没有覆盖它。于是无权情形有 \(\tau(G)+\alpha(G)=|V|\),其中 \(\tau(G)\) 是最小 vertex cover 大小,\(\alpha(G)\) 是最大 independent set 大小。

再往前一步,Independent Set 又和 Clique 互为补图问题:图 \(G\) 中的 independent set,对应补图 \(\overline{G}\) 中的 clique。所以 Vertex Cover、Independent Set、Clique 这三者在判定复杂度上几乎是同一枚硬币的不同面。给定是否存在大小不超过 \(k\) 的 vertex cover,可以转成是否存在大小至少 \(|V|-k\) 的 independent set,也可以转成补图中是否存在大小至少 \(|V|-k\) 的 clique。

但这个互补关系不能随便拿来转移近似比。最小化 vertex cover 的一个 2 近似,并不会自动给最大 independent set 一个好近似。原因是补集会把乘法误差变成很难控制的差值。比如 \(|V|-\tau(G)\) 很小的时候,vertex cover 的一点点误差都可能把 independent set 的质量彻底冲掉。这也是近似算法里常见的坑:精确解之间能互相转换,不代表近似解之间也能保持比例。

Vertex Cover 也可以看成 Set Cover 的一个特例。把边集 \(E\) 看成 universe,每个顶点 \(v\) 对应一个集合 \(S_v\),里面包含所有 incident edges。选择一批顶点覆盖所有边,就是选择一批集合覆盖整个 universe。特殊之处在于,每条边恰好属于两个集合,也就是它的两个端点。一般 Set Cover 的元素可能出现在很多集合里,所以它的近似行为更差;Vertex Cover 的“频率为 2”正是 2 近似能自然出现的原因。

如果把普通边推广成超边,就得到 Hypergraph Vertex Cover,也常被看成 Hitting Set。每条超边可能包含多个顶点,目标是选点打中每条超边。若每条超边大小最多为 \(f\),类似的 primal-dual 思路会给出 \(f\) 近似。普通 Vertex Cover 就是 \(f=2\) 的情况。

Matching 则提供了另一个方向。一般图里,最大匹配大小只是最小 vertex cover 的下界,不一定相等。二分图里情况突然变好:由 Kőnig 定理,二分图的最小 vertex cover 大小等于最大匹配大小。因此二分图上的 Vertex Cover 可以多项式时间精确求解。带权二分图版本也能通过 LP 或最小割等方法解决。这是一个很好的边界:问题本身没有变,只是图类从一般图收缩到二分图,困难性就消失了。

有没有越过“两倍”的算法?

虽然 2 倍太宽了,但是暂时没有很好的办法。

在一般图上,基于“唯一博弈猜想”(UGC)成立的理论前提下,“2倍”被公认是一个无法越过的理论壁垒,有的研究放宽了目标,只追求“渐近”意义上的突破,即对顶点数 $ n $ 极大的图,能做到 \(2 - \Theta(1/\sqrt{\log n})\) 倍,虽然小于 2,但差距会随 $ n $ 增大而无限缩小,并非一个固定的常数)。

至于那些声称在一般图上实现了 1.999999 倍的算法,它属于理论计算机科学前沿的探索性成果,虽然学术上有价值,但目前尚未成为像“2倍算法”那样被广泛公认和写入教科书的标准结论。