搜索算法
可以说几百年没去练过的东西了。但事实证明还挺有用的。
Meet in the Middle
以前一直没想通过双向搜索是怎么优化复杂度的。
我称其为合法子集计数问题。
双向搜索就是把集合劈成两半,两边分别枚举子集,然后再记两两匹配的合法关系。
当后者可以快速统计时,双向搜索就优化了复杂度。
三种状态:-1,1,0 在第一个、在第二个和根本不在。
合法子集计数,考虑劈成两半。于是任意两边可以获得 pair,然后就做完了。
A*
又名“启发式搜索”。
A* 理论其实蛮有意思的。
\(f_i=g_i+h_i\)
其中 \(g_i\) 表示从启示状态到来的实际代价,\(h_i\) 表示到达终止状态的估价函数。
要求 \(h_i\le d_i\),\(d_i\) 是到底终止状态的实际代价。
每次选取 \(f_i\) 最小的转移。
如果 \(h_i\) 满足三角不等式,则状态不会重复。
当 \(h_i=0\) 时,相当于做 dij。
\(h_i\) 的相对关系越接近 \(d_i\) 的相对关系,效率越高。
ID
又名“迭代加深搜索”。
其实就是设定深度以后 dfs 代替 bfs。
常用于空间不足时或是答案大概率存在于较浅深度时。
IDA*
将迭代加深的深度用 A* 的估价函数表示。
相较于 A* 的优势是更好写,且答案层数小的时候飞快。
一个显然的想法是设 \(h_i\) 为当前局面每个点到目标的曼哈顿距离。
容易证明 \(h_i\le d_i\)。
\(h_i\) 表示有几个骑士该动。

浙公网安备 33010602011771号