1.搜索算法的定义
搜索算法是利用计算机的高性能来有目的地穷举一个问题的部分或所有的可能情况,从而求出问题的解的一种方法.相比于单纯的枚举算法有了一定的方向性和目标性.算法是在解的空间里,从一个状态转移(按照要求拓展)到其他状态,这样进行下去,将解的空间中的状态遍历,找到答案(目标的状态).
2.搜索的分类
(1.)广度优先搜索(BFS)
从初始状态S 开始,利用规则,生成所有可能的状态.构成的下一层节点,检查是否出现目标状态G,若未出现,就对该层所有状态节点,分别顺序利用规则.生成再下一层的所有状态节点,对这一层的所有状态节点检查是否出现G,若未出现,继续按上面思想生成再下一层的所有状态节点,这样一层一层往下展开。直到出现目标状态为止
(2.)深度优先搜索(DFS)
从初始状态,利用规则生成搜索树下一层任一个结点,检查是否出现目标状态,若未出现,以此状态利用规则生成再下一层任一个结点,再检查,重复过程一直到叶节点(即不能再生成新状态节点),当它仍不是目标状态时,回溯到上一层结果,取另一可能扩展搜索的分支。采用相同办法一直进行下去,直到找到目标状态为止。
3.搜索的框架
(1.)广度优先搜索(BFS)
While Not Queue.Empty ()
Begin
可加结束条件
Tmp = Queue.Top ()
从Tmp循环拓展下一个状态Next
If 状态Next合法 Then
Begin
生成新状态Next
Next.Step = Tmp.Step + 1
Queue.Pushback (Next)
End
Queue.Pop ()
End
(2.)深度优先搜索(DFS)【DFS分为递归和非递归两种】
递归
Function Dfs (Int Step, 当前状态)
Begin
可加结束条件
从当前状态循环拓展下一个状态Next
If 状态Next合法 Then
Dfs (Step + 1, Next ))
End
非递归
While Not Stack.Empty ()
Begin
Tmp = Stack.top()
从Tmp拓展下一个未拓展的状态Next
If 没有未拓展状态(到达叶节点) Then
Stack.pop()
Else If 状态Next合法 Then
Stack.push(Next)
End
4.例题
(1.)广度优先搜索(BFS)【一个代码比较简单的,能简单看出来的】
HDU2717-Catch That Cow(POJ3278)
题意描述:一个人站在n点,只能向左走一步,或者向右走一步,或者直接走n的2倍步,要求走最少的步数抓住站在k点的牛。
题意分析:一看就是广搜的经典题目。一般要求最少步数用广搜。
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
#define MAX 200005
int v[MAX];
int cnt;
void BFS( int n, int k ){
queue<int>Q;
Q.push( n );
Q.push( cnt );
v[n] = 1;
while( !Q.empty() ){
n = Q.front();
Q.pop();
cnt = Q.front();
Q.pop();
if( n == k ){
return ;
}
if( n-1>=0 && !v[n-1] ){
Q.push( n-1 );
Q.push( cnt+1 );
v[n-1] = 1;
}
if( n+1<MAX && !v[n+1] ){
Q.push( n+1 );
Q.push( cnt+1 );
v[n+1] = 1;
}
if( 2*n<MAX && !v[2*n] ){
Q.push( 2*n );
Q.push( cnt+1 );
v[2*n] = 1;
}
}
}
int main(){
int n,k;
while( scanf( "%d%d", &n,&k ) != EOF ){
if( n >= k ){
printf( "%d\n",n-k );
continue;
}
cnt = 0;
memset( v, 0, sizeof(v) );
BFS( n, k );
printf( "%d\n", cnt );
}
return 0;
}
(2.)深度优先搜索(DFS)poj 1154 : letters 给出一个roe*col的大写字母矩阵,一开始的位置为左上角,你可以向上下左右四个方向移动,并且不能移向曾经经过的字母。问最多可以经过几个字母。
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string.h>
using namespace std;
int visit[30];
int n,m;
int step[8] = {1,0,-1,0,0,1,0,-1};
int num[100][100],cou = 1,mmax = 0;;
void DFS(int i, int j)
{
for( int k=0; k<8; k+=2)
{
int a = i+step[k];
int b = j+step[k+1];
if( a>=1 && a<=n && b>=1 && b<=m && !visit[num[a][b]] )
{
visit[num[a][b]] = 1;
cou++;
DFS(a,b);
if( cou > mmax )
mmax = cou;
cou--;
visit[num[a][b]] = 0;
}
}
}
int main()
{
char str[100];
while( cin >> n >> m )
{
getchar();
memset(visit,0,sizeof(visit));
cou = 1; mmax = 1;
for(int i=1; i<=n; i++)
{
gets(str);
for(int k=0; k<m; k++)
num[i][k+1] = str[k] -'A' + 1;
}
visit[num[1][1]] = 1;
DFS(1,1);
cout << mmax << endl;
}
return 0;
}
5.感想
搜索是学程序设计以来所接触的最难得东西啦,这一部分我感觉变式特别多,也就是题目百变多样,容易糊涂,懵圈,但我看见咱们班做的题目统计(杭电上的),感觉咱们班大神太多了,拜服!!总而言之,这一部分太难了,难怪老师说要拿出四倍的课上时间来看啊,真是醉醉的啦,总之接下来加油啦!!!
动态规划啊!!!