树的基本搜索策略
爬山法(有点类似于广度优先搜索,只是加上了边的权重)
(
1
)
构
造
由
根
组
成
的
单
元
素
栈
S
;
(
2
)
I
f
T
o
p
(
S
)
是
目
标
节
点
T
h
e
n
停
止
;
(
3
)
P
o
p
(
S
)
;
(
4
)
S
的
子
节
点
按
照
其
启
发
测
度
由
大
到
小
的
顺
序
压
入
S
;
(
5
)
I
f
S
空
T
h
e
n
失
败
E
l
s
e
g
o
t
o
2.
(1) 构造由根组成的单元素栈S;\\ (2) If\quad Top(S)是目标节点 \quad Then\quad 停止;\\ (3) Pop(S);\\ (4) S的子节点按照其启发测度由大到小的顺序压入S; \\ (5) If\quad S空\quad Then\quad 失败\quad Else\quad goto 2.
(1)构造由根组成的单元素栈S;(2)IfTop(S)是目标节点Then停止;(3)Pop(S);(4)S的子节点按照其启发测度由大到小的顺序压入S;(5)IfS空Then失败Elsegoto2.
Best-First Search算法(就是在全局找到目前情况下最好的,往下进行一步,然后再重复上述操作)
(
1
)
使
用
评
价
函
数
构
造
一
个
堆
H
,
首
先
构
造
由
根
组
成
的
单
元
素
堆
;
(
2
)
I
f
H
的
根
r
是
目
标
节
点
T
h
e
n
停
止
;
(
3
)
从
H
中
删
除
r
,
把
r
的
子
节
点
插
入
H
;
(
4
)
I
f
H
空
T
h
e
n
失
败
E
l
s
e
g
o
t
o
2.
(1) 使用评价函数构造一个堆H, 首先构造由根组成的单元素堆;\\ (2) If\quad H的根r是目标节点\quad Then\quad 停止;\\ (3) 从H中删除r, 把r的子节点插入H; \\ (4) If\quad H空\quad Then\quad 失败\quad Else\quad goto 2.
(1)使用评价函数构造一个堆H,首先构造由根组成的单元素堆;(2)IfH的根r是目标节点Then停止;(3)从H中删除r,把r的子节点插入H;(4)IfH空Then失败Elsegoto2.
人事安排问题
拓朴序列树的生成算法
输入: 偏序集合
S
S
S, 树根
r
o
o
t
root
root.
输出: 由
S
S
S的所有拓朴排序序列构成的树.
(
1
)
生
成
树
根
r
o
o
t
;
(
2
)
选
择
偏
序
集
中
没
有
前
序
元
素
的
所
有
元
素
,
作
为
r
o
o
t
的
子
节
点
;
(
3
)
F
o
r
r
o
o
t
的
每
个
字
节
点
v
D
o
(
4
)
S
=
S
−
v
;
(
5
)
把
v
作
为
根
,
递
归
地
处
理
S
.
(1) 生成树根root;\\ (2) 选择偏序集中没有前序元素的所有元素, 作为root的子节点;\\ (3) For\quad root的每个字节点v\quad Do\\ (4) \quad\quad S=S-{v};\\ (5) \quad\quad把v作为根, 递归地处理S.
(1)生成树根root;(2)选择偏序集中没有前序元素的所有元素,作为root的子节点;(3)Forroot的每个字节点vDo(4)S=S−v;(5)把v作为根,递归地处理S.
改进:代价矩阵的每行(列)减去同一个数(该行或列的最小数), 使得每行和每列至少有一个零, 其余各元素非负.每行(列)减去的数的和即为解的下界.然后使用爬山法或者BestFirst法
旅行商售货问题
输入: 无向连通图
G
=
(
V
,
E
)
G=(V, E)
G=(V,E),每个节点都没有到自身的边,每对节点之间都有一条非负加权边.
输出: 一条由任意一个节点开始经过每个节点一次最后返回开始节点的路径,该路径的代价(即权值之和)最小.
先将代价矩阵的每行(列)减去同一个数(该行或列的最小数), 使得每行和每列至少有一个零, 其余各元素非负.得到初始的代价 C o s t Cost Cost,然后对每一个 C o s t Cost Cost是0的边,找矩阵中同行和同列两个最小的数中的最大的那个边 [ i , j ] [i,j] [i,j],左子树就是选这个边的,右子树就是不选这个边的,左子树中,删除第 i i i行第 j j j列然后将 [ j , i ] [j,i] [j,i]变成 ∞ \infin ∞,右子树中将 [ i , j ] [i,j] [i,j]变成 ∞ \infin ∞,然后重新初始化 C o s t Cost Cost,然后递归。
0-1 背包问题
输入:
C
>
0
,
w
i
>
0
,
v
i
>
0
,
1
≤
i
≤
n
C>0, wi>0, vi>0, 1\le i\le n
C>0,wi>0,vi>0,1≤i≤n
输出:
(
x
1
,
x
2
,
…
,
x
n
)
,
x
i
∈
{
0
,
1
}
,
满
足
∑
1
≤
i
≤
n
w
i
x
i
≤
C
,
∑
1
≤
i
≤
n
v
i
x
i
最
大
(x_1, x_2, …, x_n), x_i\in\{0, 1\}, 满足\sum_{1\le i\le n}w_ix_i\le C,\sum_{1\le i\le n}v_ix_i最大
(x1,x2,…,xn),xi∈{0,1},满足∑1≤i≤nwixi≤C,∑1≤i≤nvixi最大
空包为树根,代价下界 L B LB LB,代价的上界 U B UB UB(贪心算法可行解得 L B LB LB,分数背包问题的优化解代价 U B UB UB)左子树,将第 k + 1 k+1 k+1个物品放入背包;右子树,将第 k + 1 k+1 k+1个物品舍弃
用爬山法取舍第
k
+
1
k+1
k+1个物品,递归地划分解空间
划分过程:
(
x
1
,
.
.
.
,
x
k
)
→
(
x
1
,
.
.
.
,
x
k
,
x
k
+
1
)
(x_1,...,x_k)\rightarrow(x_1,...,x_k,x_{k+1})
(x1,...,xk)→(x1,...,xk,xk+1)
(
1
)
C
<
w
1
x
1
+
…
+
w
k
+
1
x
k
+
1
,
(
x
1
,
.
.
.
,
x
k
,
x
k
+
1
)
不
可
行
,
舍
弃
(
2
)
U
B
=
L
B
—
记
录
o
p
t
=
U
B
,
终
止
扩
展
(
x
1
,
.
.
.
,
x
k
,
x
k
+
1
)
;
在
剩
下
的
子
问
题
C
−
w
1
x
1
+
…
+
w
k
+
1
x
k
+
1
上
,
贪
心
策
略
将
得
到
最
优
解
贪
心
算
法
的
解
(
x
k
+
2
,
.
.
.
,
x
n
)
,
与
(
x
1
,
.
.
.
,
x
k
,
x
k
+
1
)
构
成
优
化
解
(
3
)
U
B
<
o
p
t
,
扩
展
(
x
1
,
.
.
.
,
x
k
,
x
k
+
1
)
得
不
到
优
于
o
p
t
的
解
,
舍
弃
(
4
)
其
他
情
况
,
继
续
扩
展
(1) C<w_1x_1+…+w_{k+1}x_{k+1},(x_1,...,x_k,x_{k+1})不可行,舍弃\\ (2)UB=LB—记录opt=UB,终止扩展(x_1,...,x_k,x_{k+1});在剩下的子问题C-w_1x_1+…+w_{k+1}x_{k+1}上,贪心策略将得到最优解\\ 贪心算法的解(x_{k+2},...,x_n),与(x_1,...,x_k,x_{k+1})构成优化解\\ (3)UB<opt, 扩展(x_1,...,x_k,x_{k+1})得不到优于opt的解,舍弃\\ (4)其他情况,继续扩展
(1)C<w1x1+…+wk+1xk+1,(x1,...,xk,xk+1)不可行,舍弃(2)UB=LB—记录opt=UB,终止扩展(x1,...,xk,xk+1);在剩下的子问题C−w1x1+…+wk+1xk+1上,贪心策略将得到最优解贪心算法的解(xk+2,...,xn),与(x1,...,xk,xk+1)构成优化解(3)UB<opt,扩展(x1,...,xk,xk+1)得不到优于opt的解,舍弃(4)其他情况,继续扩展
A*算法
( 1 ) 使 用 B e s t − f i r s t 策 略 搜 索 树 ; ( 2 ) 节 点 n 的 代 价 函 数 为 f ( n ) = g ( n ) + h ( n ) , g ( n ) 是 从 根 到 n 的 路 径 代 价 , h ( n ) 是 从 n 到 某 个 目 标 节 点 的 优 化 路 径 代 价 ; ( 3 ) 对 于 所 有 n , h ( n ) ≤ h ∗ ( n ) ; ( 4 ) 当 选 择 到 的 节 点 是 目 标 节 点 时 , 算 法 停 止 , 返 回 一 个 优 化 解 . (1)使用Best-first策略搜索树;\\ (2)节点n的代价函数为f(n)=g(n)+h(n), g(n)是从根到n的路径代价, h(n)是从n到某个目标节点的优化路径代价;\\ (3)对于所有n, h(n)\le h^*(n);\\ (4)当选择到的节点是目标节点时, 算法停止,返回一个优化解. (1)使用Best−first策略搜索树;(2)节点n的代价函数为f(n)=g(n)+h(n),g(n)是从根到n的路径代价,h(n)是从n到某个目标节点的优化路径代价;(3)对于所有n,h(n)≤h∗(n);(4)当选择到的节点是目标节点时,算法停止,返回一个优化解.
字符串处理算法
Rabin-Karp算法
t
k
=
P
[
k
+
m
−
1
]
+
d
(
P
[
k
+
m
−
2
]
+
d
(
P
[
k
+
m
−
3
]
+
…
+
d
P
[
k
]
)
…
)
t_k = P[k+m-1]+d(P[k+m-2]+ d (P[k+m-3]+…+dP[k])…)
tk=P[k+m−1]+d(P[k+m−2]+d(P[k+m−3]+…+dP[k])…)
t
k
+
1
=
P
[
k
+
m
]
+
d
(
P
[
k
+
m
−
1
]
+
d
(
P
[
k
+
m
−
2
]
+
…
+
d
P
[
k
+
1
]
)
…
)
t_{k+1} = P[k+m]+ d ( P[k+m-1]+ d (P[k+m-2]+…+dP[k+1])…)
tk+1=P[k+m]+d(P[k+m−1]+d(P[k+m−2]+…+dP[k+1])…)
t
k
+
1
−
d
t
k
=
P
[
k
+
m
]
−
d
m
P
[
k
+
1
]
t_{k+1}-dt_k=P[k+m]-d^mP[k+1]
tk+1−dtk=P[k+m]−dmP[k+1]
I n p u t : 文 本 T , 模 式 P , 基 数 d , 素 数 q O u t p u t : P 在 T 中 出 现 的 所 有 位 置 ( 1 ) n ← l e n g t h ( T ) ( 2 ) m ← l e n g t h ( P ) ( 3 ) h ← d m m o d q ( 4 ) p ← 0 ( 5 ) t 1 ← 0 ( 6 ) F o r i ← 0 t o m − 1 d o ( 7 ) p ← d p + P [ i ] m o d q ; ( 8 ) t 1 ← d t 1 + T [ i ] m o d q ; ( 9 ) f o r k ← 0 t o n − m d o ( 10 ) I f p = t k T h e n ( 11 ) I f P [ 1 , … , m ] = T [ k , k + 1 , … , k + m − 1 ] T h e n p r i n t k ( 12 ) t k + 1 ← ( d t k − T [ k + 1 ] h + T [ k + m ] ) m o d q Input: 文本T,模式P , 基数d,素数q\\ Output: P在T中出现的所有位置\\ (1) n\leftarrow length(T)\\ (2) m\leftarrow length(P)\\ (3) h\leftarrow d^m mod q\\ (4) p\leftarrow0\\ (5) t_1\leftarrow0\\ (6) For\quad i\leftarrow0\quad to\quad m-1\quad do\\ (7) \quad\quad p\leftarrow dp+P[i] mod q;\\ (8) \quad\quad t1\leftarrow dt1+T[i] mod q;\\ (9) for\quad k\leftarrow0\quad to\quad n-m\quad do \\ (10)\quad\quad If\quad p=t_k\quad Then \\ (11)\quad\quad\quad\quad If\quad P[1,…,m] = T[k,k+1,…,k+m-1]\quad Then\quad print\quad k\\ (12)\quad\quad t_{k+1}\leftarrow(dt_k-T[k+1]h + T[k+m])mod q Input:文本T,模式P,基数d,素数qOutput:P在T中出现的所有位置(1)n←length(T)(2)m←length(P)(3)h←dmmodq(4)p←0(5)t1←0(6)Fori←0tom−1do(7)p←dp+P[i]modq;(8)t1←dt1+T[i]modq;(9)fork←0ton−mdo(10)Ifp=tkThen(11)IfP[1,…,m]=T[k,k+1,…,k+m−1]Thenprintk(12)tk+1←(dtk−T[k+1]h+T[k+m])modq
有穷自动机算法
F i n i t e − A u t o a t i o n − M a t c h e r ( T , δ , m ) I n p u t : 文 本 T , F A 的 状 态 转 移 函 数 , 模 式 长 度 m O u t p u t : P 在 T 中 出 现 的 所 有 位 置 ( 1 ) n ← l e n g t h ( T ) ( 2 ) q ← 0 ( 3 ) F o r k ← 0 t o n − 1 d o ( 4 ) q ← δ ( q , T [ k ] ) ( 5 ) I F q = m T H E N p r i n t k − m + 1 Finite-Autoation-Matcher(T,\delta,m)\\ Input: 文本T,FA的状态转移函数,模式长度m\\ Output: P在T中出现的所有位置\\ (1) n\leftarrow length(T)\\ (2) q\leftarrow0\\ (3) For\quad k\leftarrow0\quad to\quad n-1\quad do\\ (4) \quad\quad q\leftarrow\delta(q,T[k])\\ (5) \quad\quad IF\quad q=m\quad THEN\quad print\quad k-m+1 Finite−Autoation−Matcher(T,δ,m)Input:文本T,FA的状态转移函数,模式长度mOutput:P在T中出现的所有位置(1)n←length(T)(2)q←0(3)Fork←0ton−1do(4)q←δ(q,T[k])(5)IFq=mTHENprintk−m+1
I n p u t : 模 式 P , 字 符 表 Σ O u t p u t : P 对 应 有 穷 自 动 机 的 状 态 转 移 函 数 δ ( 1 ) m ← l e n g t h ( P ) ( 2 ) F o r q ← 0 t o m d o ( 3 ) F o r ∀ a ∈ Σ d o ( 4 ) k ← m i n { m + 1 , q + 2 } ( 5 ) r e p e a t k ← k − 1 u n t i l P k ► P q a ( 6 ) δ ( q , a ) ← k ( 7 ) r e t u r n δ ; Input: 模式P,字符表\Sigma\\ Output: P对应有穷自动机的状态转移函数\delta\\ (1) m\leftarrow length(P)\\ (2) For\quad q\leftarrow0\quad to\quad m\quad do\\ (3) \quad\quad For\quad\forall a\in\Sigma\quad do\\ (4) \quad\quad\quad\quad k\leftarrow min\{m+1, q+2\}\\ (5) \quad\quad\quad\quad repeat\quad k\leftarrow k-1\quad until\quad Pk ► Pqa\\ (6) \quad\quad\quad\quad\delta(q,a)\leftarrow k\\ (7) return \quad\delta; Input:模式P,字符表ΣOutput:P对应有穷自动机的状态转移函数δ(1)m←length(P)(2)Forq←0tomdo(3)For∀a∈Σdo(4)k←min{m+1,q+2}(5)repeatk←k−1untilPk►Pqa(6)δ(q,a)←k(7)returnδ;
KMP算法
C S & E C o m p u t e − P r e f i x − F u n c t i o n ( P ) I n p u t : 模 式 P O u t p u t : P 的 前 缀 函 数 π ( 1 ) m ← l e n g t h ( P ) ( 2 ) π [ 1 ] ← 0 ; k ← 0 ; ( 3 ) F o r q ← 2 t o m d o ( 4 ) W h i l e k > 0 & P [ k + 1 ] ≠ P [ q ] d o ( 5 ) k ← π [ k ] ; ( 6 ) I f P [ k + 1 ] = P [ q ] t h e n k ← k + 1 ; ( 7 ) π [ q ] ← k ; ( 8 ) r e t u r n π ; CS\&E Compute-Prefix-Function(P)\\ Input: 模式P\\ Output: P的前缀函数\pi\\ (1) m\leftarrow length(P)\\ (2) \pi[1]\leftarrow0; k\leftarrow0;\\ (3) For\quad q\leftarrow2\quad to\quad m\quad do\\ (4) \quad\quad While\quad k>0 \& P[k+1]\ne P[q]\quad do \\ (5) \quad\quad\quad\quad k\leftarrow\pi[k];\\ (6) \quad\quad If\quad P[k+1]=P[q]\quad then\quad k\leftarrow k+1;\\ (7) \quad\quad\pi[q]\leftarrow k ;\\ (8) return\quad\pi; CS&ECompute−Prefix−Function(P)Input:模式POutput:P的前缀函数π(1)m←length(P)(2)π[1]←0;k←0;(3)Forq←2tomdo(4)Whilek>0&P[k+1]=P[q]do(5)k←π[k];(6)IfP[k+1]=P[q]thenk←k+1;(7)π[q]←k;(8)returnπ;
K M P − M a t c h e r ( P , T ) I n p u t : 模 式 P , T O u t p u t : P 在 T 匹 配 的 所 有 起 始 位 置 ( 1 ) m ← l e n g t h ( P ) ; n ← l e n g t h ( T ) ( 2 ) π ← C o m p u t e _ P r e f e x _ F u n c t i o n ( P ) ; ( 3 ) q ← 0 ; ( 4 ) F o r i ← 2 t o n d o ( 5 ) W h i l e k > 0 & P [ q + 1 ] ≠ T [ i ] d o ( 6 ) q ← π [ q ] ; ( 7 ) I f P [ q + 1 ] = T [ i ] t h e n q ← q + 1 ; ( 8 ) I f q = m t h e n ( 9 ) p r i n t i − m + 1 ; ( 10 ) q ← π [ q ] ; KMP-Matcher(P,T)\\ Input: 模式P,T\\ Output: P在T匹配的所有起始位置\\ (1) m\leftarrow length(P); n\leftarrow length(T)\\ (2) \pi\leftarrow Compute\_Prefex\_Function(P);\\ (3) q\leftarrow 0;\\ (4) For\quad i\leftarrow 2\quad to\quad n\quad do\\ (5) \quad\quad While\quad k>0 \& P[q+1]\ne T[i]\quad do \\ (6) \quad\quad\quad\quad q\leftarrow \pi[q];\\ (7) \quad\quad If\quad P[q+1]=T[i]\quad then\quad q\leftarrow q+1;\\ (8) \quad\quad If\quad q=m\quad then \\ (9) \quad\quad\quad\quad print\quad i-m+1;\\ (10) \quad\quad\quad\quad q \leftarrow\pi [q]; KMP−Matcher(P,T)Input:模式P,TOutput:P在T匹配的所有起始位置(1)m←length(P);n←length(T)(2)π←Compute_Prefex_Function(P);(3)q←0;(4)Fori←2tondo(5)Whilek>0&P[q+1]=T[i]do(6)q←π[q];(7)IfP[q+1]=T[i]thenq←q+1;(8)Ifq=mthen(9)printi−m+1;(10)q←π[q];
Boyer-Moore-Horspool算法
关注发生失配的时候,对齐的最后一个字符x,x在P中没有出现,后移量=|P|;x在P中出现,后移量=|P|-1-x在P中最后出现的位置
后缀树
最简单的方法就是
n
2
n^2
n2时间和空间内遍历,然后建树。
线性时间内构造后缀树:叶柄变长、长新叶子、若无其事
引理1.在构建
T
1
,
…
,
T
m
T_1,…,T_m
T1,…,Tm的过程中,一旦一个叶子产生出来就不会消失,后续过程中该叶子可能的变化只能是叶柄变长
引理2.将构建
T
i
T_i
Ti的过程中最后一次长新叶子的操作时刻记为
j
i
j_i
ji,则
j
i
≤
j
i
+
1
j_i\le j_{i+1}
ji≤ji+1
引理3.在构建
T
i
T_i
Ti的过程中第一次若无其事发生后,以后的操作均是若无其事
结点
u
u
u的路径标记为
x
α
x\alpha
xα,则结点
u
u
u的suffix link指向结点
v
v
v, 其中
x
x
x是一个字符且从根结点到
v
v
v的路径标记为
α
\alpha
α
性质1:suffix link的出发点总是后缀树的内部节点
性质2:后缀树的每个内部节点均是某个suffix link的出发点
q-gram算法
将单词按照长度为q进行切分,然后找着的单词在所有切分项中间做匹配,最后选出出现频率比较大的单词的组合。
参考:哈工大算法设计与分析PPT