Skip to content

算法Algorithm

字典序广度优先搜索

Lexicographic breadth-first search · LexBFS · Lex-BFS

按全部已选邻接历史的字典序选择顶点,以有序块实现线性搜索,并证明弦图上的反序为完美消去序。

形式陈述 ​

先约定标签方向 ​

输入是顶点为0,…,n−1的有限简单无向图,没有自环或平行边。开始时所有顶点未选,标签均为空序列。第t轮从0开始:选择标签字典序最大的未选顶点v,把v记入搜索序σ;随后对每个未选邻居,把整数n−t追加在标签末尾。

每个标签因此是严格递减的整数序列。字典序先比较第一处不同项,数大者优先;若一个序列是另一个的真前缀,较长者优先。例如 [6,4] > [6,3] > [6] > [5,4,3] > []。标签相同可以任意选择,但应记录实际并列规则以便重放。

算法输出全部n个顶点的排列。对弦图,反序π=reverse(σ)一定是完美消去序:每个顶点在π中排在它后面的邻居两两相邻。一般图也有搜索序,只是反序可能不满足这个条件。[1, PDF pp.10–16]

直觉

当前邻居只在原来的并列组里优先 ​

第一轮选v后,所有邻居得到标签[n],排在空标签之前。第二轮的新数n−1比此前任何数都小,因此只能打破原来相同标签之间的并列;它不能推翻第一处已有差异。一个刚更新的低优先块,不能整体跑到此前的高优先块前面。

利用有序划分精化,用一个块保存同标签顶点,块按标签从大到小排列。取第一块里的元素作为v;移除v,再用v的未选邻居精化所有触及块。每块的邻居交集在前,非邻居余集在后。初始化只有一个全体顶点块,归纳可得每轮维护的正是概念标签次序。

python
part = OrderedPartition(n)
order = []
for _ in range(n):
    v = part.pop_first()
    order.append(v)
    part.refine(u for u in adj[v] if part.owner[u] is not None)

代码核心不真的构造长标签。附件块内链初始按编号,交块按当前邻接列表首次出现的顺序排列,所以并列选择受输入邻接次序影响。任意合法并列都保持定理;不同次序并不要求给出同一排列。

为何弦图不容许一个坏的反序 ​

把搜索反序编号为α:V→{1,…,n},所以实际搜索从编号n向1选择。假设反序不是完美消去序。存在三点无弦路径x,v,y,其中α(v)小于两端编号。更一般地,考虑所有无弦路径

u0,u1,…,ur,r≥2,

使端点编号都大于内部编号;把编号较小的端点放在u₀,并令i=α(u₀)。刚才的三点路径保证这种路径存在。选一个i尽可能大的例子。于是α(uᵣ)>i,所有内部编号<i。

在算法选择u₀的时刻,编号>i的顶点已经选过。记S为u₀在这些已选顶点中的邻居。无弦路径长度至少2,u₀不邻接uᵣ,所以uᵣ∉S。

取任意z∈S。先证明z邻接uᵣ:否则在路径中取与z相邻的最后一个uⱼ;至少u₀满足。路径z,uⱼ,…,uᵣ仍无弦,两个端点编号均>i,内部编号至多i,给出更大的较小端点编号,违背i的选择。

再证明z邻接uᵣ₋₁:若不相邻,在u₀,…,uᵣ₋₁中取最后一个与z相邻的uⱼ,必有j≤r−2。z,uⱼ,…,uᵣ,z构成至少四点的无弦圈:原路径内部无弦,而z除了这段的两端外没有邻接点。这与图是弦图矛盾。

所以S中每个顶点都是uᵣ₋₁的已选邻居,而且uᵣ₋₁还邻接已经选过的uᵣ,后者不在S中。uᵣ₋₁的已选邻居集合严格包含u₀的集合。按递减编号列出这两个集合,第一项额外出现的编号使前者标签更大;若没有中途差异,则后者是前者的真前缀,同样前者更大。uᵣ₋₁此时尚未选,算法不可能舍弃它而选择u₀,得到矛盾。

这个证明只用了“已选邻居集合严格包含时标签必更大”,没有假定并列取最小编号。路径极值思路来自[2, §2.4]对最大基数搜索的证明;这里用标签严格包含推出字典序选择的矛盾。

例子与边界

六点图的块轨迹 ​

取边01、02、12、23、04、14、45,按此顺序建立两向邻接表。初始块为 [0,1,2,3,4,5]。附件得到:

选中的顶点 选择并精化后的块序列
0 [1,2,4];[3,5]
1 [2,4];[3,5]
2 [4];[3];[5]
4 [3];[5]
3 [5]
5 空

因此σ=[0,1,2,4,3,5],π=[5,3,4,2,1,0]。选2之后,4保持在3之前:4在第一轮已经得到6,而3此时才得到4。把所有当前邻居一律推到队首,会错误地让3越过4。

普通BFS的并列还不够细 ​

取边ab、ad、bc、be、de。普通广度优先搜索允许序列a,b,d,c,e:b先发现c、e,后续d不会改动它们的队列次序。LexBFS在选a,b,d之后,却必须让e先于c,因为二者都见过b,只有e又见过d。因此a,b,d,e,c合法,而前一个BFS序不合法。

这里的“字典序”比较的是邻接历史,不是顶点名字。按字母顺序扫描每份邻接表,只规定普通BFS的局部并列,不能自动实现LexBFS。

失败的排序与失败的图 ​

无弦四圈01、12、23、30可得到σ=[0,1,3,2],反序[2,3,1,0]中,顶点2的更晚邻居3和1不相邻,违反完美消去条件。由于刚才已证明弦图上每次LexBFS都成功,这一次失败足以判定图非弦。

换成三点路径0—1—2,随意给出的顺序[1,0,2]也失败,但这张图是弦图,它有完美消去序[0,2,1]。所以必须同时记录“候选确由LexBFS得到”与“候选未通过检查”,不能让任意坏排序单独充当非弦证据。

非连通图不需要特殊失败出口:一个分量处理完后,余下顶点重新在空历史块里并列。孤立顶点可在相应轮被取出;空图输出空排列。

推论与应用

线性的是搜索核心,不是全部调试输出 ​

在已准备好的无重复邻接表上,每个顶点取出一次,每份邻接记录扫描一次。无向边uv只有较早选择的端点会把仍活动的另一端放进精化集合,所以总移动次数恰为m。精化有n次基本调用成本,故单位成本RAM下时间O(n+m),辅助空间O(n)。连同输入邻接表,总空间O(n+m)。

从任意边列表检查自环、重复无向边并建立邻接表,附件另用哈希集合完成,期望O(n+m)。这段输入校验与已经准备好邻接表时的确定性线性核心分开。record_trace=True会在每轮枚举完整分区,最坏另有O(n²)时间和输出空间;关闭轨迹不构造标签或快照。

将反序交给弦图与完美消去序中的线性验证器,便得到O(n+m)的识别流程。通过后可构造最优着色及最大团证书;没有通过时,三点违例易于重算,若还要求直接展示一个诱导长圈,则应另计圈提取算法的成本。

终结任务要求交换边表输入次序后重跑:搜索排列允许改变,弦性、最优颜色数及全部极大团必须保持。这比只重放同一个并列顺序更能检验接口是否写对。

参考资料
  1. David Eppstein,CS 163 & CS 265, Lecture 7a,2026,讲义PDF,物理第10–16页:反序识别流程、字典序历史、块精化和线性数据结构。
  2. Jean R. S. Blair、Barry W. Peyton,An Introduction to Chordal Graphs and Clique Trees,ORNL/TM-12203,1992,原报告PDF,§2.4:最大基数搜索的路径极值证明,供本页改写邻居严格包含论证。
关系图谱6 个相邻概念 · 2 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
类型化关系

使用的工具

被这些条目使用