前言
穷竭搜索是将所有的可能性罗列出来,在其中寻找答案的方法
深度优先搜索
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
int maze[5][5] = {
0, 1, 0, 0, 0,
0, 1, 0, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
};
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
int d[5][5];
bool flag[5][5];
void dfs(int x, int y) {
for(int i=0; i < 4; i++) {
int _x = x+dx[i];
int _y = y+dy[i];
if(_x>=0 && _x<5 && _y>=0 && _y<5 && maze[_x][_y]==0 && !flag[_x][_y]) {
flag[_x][_y] = true;
d[_x][_y] = min(d[x][y]+1, d[_x][_y]);
dfs(_x,_y);
flag[_x][_y] = false;
}
}
}
int main() {
memset(d, 0x3f, sizeof(d));
d[0][0] = 0;
dfs(0,0);
cout << d[4][4] << endl;
return 0;
}
广度优先搜索
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> Pair;
const int INF = 0x3f3f3f3f;
int maze[5][5] = {
0, 1, 0, 0, 0,
0, 1, 0, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
};
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
int d[5][5];
void bfs() {
memset(d, 0x3f, sizeof(d));
queue<Pair> que;
que.push(Pair(0,0)); // 将起点入队
d[0][0] = 0; //把起点设置为0
while(que.size()) {
Pair p = que.front();
que.pop();
if(p.first == 5 && p.second == 5) break;
for(int i=0; i < 4; i++) {
int x = p.first + dx[i];
int y = p.second + dy[i];
if(x>=0 && x<5 && y>=0 && y<5 && maze[x][y]==0 && d[x][y]==INF) {
que.push(Pair(x,y));
d[x][y] = d[p.first][p.second] + 1;
}
}
}
}
int main() {
bfs();
cout << d[4][4] << endl;
return 0;
}
双向广搜
void TBFS() {
bool found=false;
memset(visited,0,sizeof(visited)); // 判重数组
while(!Q1.empty()) Q1.pop(); // 正向队列
while(!Q2.empty()) Q2.pop(); // 反向队列
// 正向扩展的状态标记为1,反向扩展标记为2
visited[s1.state]=1; // 初始状态标记为1
visited[s2.state]=2; // 结束状态标记为2
Q1.push(s1); // 初始状态入正向队列
Q2.push(s2); // 结束状态入反向队列
while(!Q1.empty() || !Q2.empty()) {
if(!Q1.empty())
BFS_expand(Q1,true); // 在正向队列中搜索
if(found) // 搜索结束
return ;
if(!Q2.empty())
BFS_expand(Q2,false); // 在反向队列中搜索
if(found) // 搜索结束
return ;
}
}
void BFS_expand(queue<Status> &Q,bool flag) {
s=Q.front(); // 从队列中得到头结点s
Q.pop()
for( 每个s 的子节点 t ) {
t.state=Gethash(t.temp) // 获取子节点的状态
if(flag) { // 在正向队列中判断
if (visited[t.state]!=1) { // 没在正向队列出现过
if(visited[t.state]==2) { // 该状态在反向队列中出现过
各种操作;
found = true;
return;
}
visited[t.state]=1; // 标记为在在正向队列中
Q.push(t); // 入队
}
}else { // 在正向队列中判断
if (visited[t.state]!=2){ // 没在反向队列出现过
if(visited[t.state]==1) { // 该状态在正向向队列中出现过
各种操作;
found = true;
return;
}
visited[t.state]=2; // 标记为在反向队列中
Q.push(t); // 入队
}
}
}
}
A*启发式搜索
void addAdjacentNode(curNode){
nodeList = getAdjacentNode(curNode);
for(node belong nodeList){
calculate of update F of node;
openList.add(node);
}
}
void main(){
openList.add(startNode)
while(!openList.isEmpty()){
node = openList.getMinFNode();
closeList.add(node);
if(node==endNode){
isFind = true;
break;
}
addAdjacentNode(node);
}
getTrace();
}
迭代加深搜索 IDA*
#include<bits/stdc++.h>
using namespace std;
bool flag=false;
char finop[20];
int reverseop[9] = {5,4,7,6,1,0,3,2,-1};
int mp[24];
int pos[8][7] = {
{ 0,2,6,11,15,20,22 }, //A
{ 1,3,8,12,17,21,23 }, //B
{ 10,9,8,7,6,5,4 }, //C
{ 19,18,17,16,15,14,13 }, //D
{ 23,21,17,12,8,3,1 }, //E
{ 22,20,15,11,6,2,0 }, //F
{ 13,14,15,16,17,18,19}, //G
{ 4,5,6,7,8,9,10 } //H
};
int center[8]={6,7,8,11,12,15,16,17};
void option(int op) {
int temp=mp[pos[op][0]];
for (int i=0;i<6;i++) {
mp[pos[op][i]]=mp[pos[op][i + 1]];
}
mp[pos[op][6]]=temp;
}
bool cmp(int a,int b) {
return a>b;
}
int get_h() {
int cnt[3]={0,0,0};
for (int i = 0; i < 8; i++) {
cnt[mp[center[i]] - 1]++;
}
sort(cnt,cnt+3,cmp);
return 8-cnt[0];
}
void dfs(int depth,int lastop,int maxdepth) {
if(flag)
return;
if(depth>maxdepth||depth+get_h()>maxdepth)
return;
if(get_h()==0) {
flag=true;
finop[depth]='\0';
cout<<finop<<endl;
cout<<mp[center[0]]<<endl;
return;
}
for(int nextop=0;nextop<8;nextop++) {
if(nextop!=reverseop[lastop]) {
option(nextop);
finop[depth]=nextop+'A';
dfs(depth+1,nextop,maxdepth);
option(reverseop[nextop]);
}
}
}
int main() {
for(int maxdepth=1; !flag; maxdepth++)
dfs(0,8,maxdepth);
return 0;
}
代码多源于网络,更多模板