常用的搜索算法

//状态空间盲目搜索
//对具体问题可以加入限制和设置边界条件,对搜索状态空间剪枝

//广度优先搜索:总是先搜索一个深度上的所有结点,之后再搜索下一个深度的结点
bfs()
1 初始化列表N
2 如果N为空,返回并给出失败信号
3 n为N的第一个结点, 并在N中删除结点n,放入已经访问的列表中
4 如果n为目标结点,则返回并给出成功信号
5 否则,扩展n,将n的子节点加入到N的末尾,转到2

//深度优先搜索:总是扩展深度大的结点,直到找到目标结点
//回溯其实就是一个深度优先搜索

dfs()
1 初始化列表N
2 如果N为空,返回并给出失败信号
3 n为N的第一个结点, 并在N中删除结点n,放入已经访问的列表中
4 如果n为目标结点,则返回并给出成功信号
5 否则,将n的子节点作为列表N的表头(第一个结点),扩展到N中,转到2

//迭代加深搜索:在固定的深度上, 进行深度优先搜索;如果没有找到目标结点,则增加深度,重复深度优先搜索,直到找到目标结点

idfs()
1 初始化列表N, 给定搜索深度max
2 如果N为空,返回并给出失败信号
3 n为N的第一个结点, 并在N中删除结点n,放入已经访问的列表中
4 如果n为目标结点,则返回并给出成功信号
5 如果n的深度 = max, 则返回2
6 否则,将n的子节点作为列表N的表头(第一个结点),扩展到N中,转到2

 

//回溯基本框架
//搜索子集树
void backtrack(int d)
{
 if(d > n) output(x);
 else
 {
  for(i = 0; i <= 1; ++i)
  {
   x[d] = i;
   if(constraint(d) && bound(d)) backtrack(d + 1);
  }  
 }
}

//搜索排列树
void backtrack(int d)
{
 if(d > n) output(x);
 else
 {
  for(i = d; i <= n; ++i)
  {
   swap(x[d], x[i]);
   if(constraint(d) && bound(d)) backtrack(d + 1);
   swap(x[d], x[i]);
  }  
 }
}

 

//启发式搜索1:最佳优先搜索:将结点按照距目标的估计距离进行排序,再以结点的估计距离为标准选择待扩展结点

bestFisrtSearch()
1 用N表示已经排序的初始结点表
2 如果N为空集,则退出并给出失败信号
3 n为N的第一个结点,并在N中删除结点n,放入已经访问的列表中
4 如果n为目标结点,则返回并给出成功信号
5 否则, 将n的后继结点加到N中, 记作N', 对N'中的结点按距目标的估计距离排序,转到2


//启发式搜索2:启发式图搜索算法(A算法):搜索空间不一定是树形的,也可能是更一般的图
//数据结构:open存放已经生成而尚未进行扩展的结点, closed存放已经生成且处理过的结点
//这两张表除了结点的状态描述,还包括结点的代价估计值f和g, 后继元素, 主链表=的前驱指针

A()
1 建立一个只由初始结点S组成的搜索图G, open = S, closed = 空
2 if open = 空, then 退出并给出失败信号
3 n = first(open), remove(n, open), add(n, closed);
4 if n是目标结点, then 退出并给出成功信号
5 else 扩展结点n, 生成集合M = { m | m不是n的祖先的后继结点}, 把每一个m作为n的后继结点加入图G中
6 if m没有在open和closed表中出现,then add(m, open);
7 if m在open中出现重复结点k,且g(m) < g(k), then remove(k, open), add(m, open);
8 if m在closed中有重复结点k,且g(m) < g(k), then 将closed中的结点k改为结点m,同时按后继元素,修改k在open和closed中的后继元素f,g的值
9 按f值从小到大对open中的结点重新排序,转到2

//双向搜索

//前面的算法都是从初始状态出发,一步步向后搜索到目标状态,如果同时从目标状态向前搜索,这就是双向搜索

//局部搜索

LSA()
1 选择初始解X0, 令当前解X=X0
2 while 未满足停止准则
3 X' = gen(X) //选择X的领域N(X)的一个状态X'
4 if f(X') < f(X) then X=X'
5 return X

//模拟退火搜索,也是一种启发式搜索
//SA实际上改变LSA的接受准则,采用了更多的启发式信息。LSA不接受差的解,从而很容易陷入局部最优无法自拔,而SA搜索以一定的概率接受较差解,从而扩大了搜索领域,从而具备一定的跳出局部最优而发现全局最优解的能力

SA()
1 随机选择一个初始解X0
2 给定初始温度T0, 马尔科夫链长L0, 并令当前解X=X0, 当前温度T=T0
3 while 未满足停止准则
4 for i = 1 to Lt
5  X' = gen(X) //在X的领域随机选择一个元素X'
6  Δf = f(X') - f(X)
7  if Δf < 0 then X = X'
8  else 按照概率exp(-Δf/T) 选定X = X'
9  T = g(T) //降温
10  Lt = h(Lt) //调整马尔科夫链长,当然也可以设定马尔科夫的链长为一个定值
11 return X


//遗传算法搜索
GA()
1 当前代t = 0
2 初始化种群规模为N,种群Pop(0) = {a1(0), a2(0),...,an(0)},
3 while 未满足停止准则
4 for i = 1 to N do 计算当前代每个个体的适应度f(ai(t))
5 for i = 1 to N do
6  NewPopi(t+1) = 按轮盘赌概率pj从Pop(t)中选择
7 CrossPop(t + 1) = 按概率pc对新种群NewPop(t + 1)杂交
8 MutPop(t + 1) = 按概率pm对种群CrossPop(t + 1)变异
9 Pop(t+1) = MutPop(t+1)
10 t = t + 1

//禁忌搜索

TS()
1 选择初始解X0, 令当前解X = X0
2 令最优解X* = X
3 while 未满足停止准则
4  N*(X) = {X1 |X1 ∈N(X) : 从X到X1没有出现在禁忌表中,或者X1满足吸引准则}
5 选择N*(X)的最优解X'∈N*(X)
6 X = X' //even if f(X') > f(X)
7 if f(X) < f(X*) then X* = X
8 return X*

//禁忌搜索可以和其他搜索算法结合形成更加强大的搜索

Edited by sheng__
2010-6-28

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值