IDA*搜索又成为迭代加深搜索,感觉迭代加深这个称谓就基本概括了这种搜索算没的核心。首先所以讨论一下什么迭代加深搜索,深度优先搜索一个局面可以搜索很多很多层,这种情况很可能时间啊复杂度很大;怎么办呢?聪明的人们想到了限制限制了搜索深度,正是所谓的迭代加深搜索,就是在深度无上限的情况下,先预估一个深度(尽量小)进行搜索,如果没有找到解,再逐步放大深度搜索。这种方法虽然会导致重复的遍历 某些结点,但是由于搜索的复杂度是呈指数级别增加的,所以对于下一层搜索,前面的工作可以忽略不计;
总的来说,迭代加深搜索是在速度上接近广度优先搜索,空间上和深度优先搜索相当的搜索方式。由于在使用过程中引入了深度优先搜索,所以也可以当作深度优先搜索的优化方案。
迭代加深搜索适用于当搜索深度没有明确上限的情况。
又从别的大佬那里看到一张图,可以看出IDA*搜索和广搜的搜索形式相同,但是只要搜索到答案的深度就可以了,不像广搜会跑完整张图。
题意:一个个井字形的棋盘上有8个1,8个2,8个3,有8个操作(标号为A~H),表示把某一行或某一列进行挪动,头位数字放到尾部,其他依次挪一格,求出字典序最小的操作序列。
#include<iostream>
using namespace std;
int step[10][10]={//代表A-H八种操作在读入的数字种的位置
{ 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 index[9]={6,7,8,11,12,15,16,17};//中心位置的方块用于检查
int map[30];
char ans[100];
int check(){//检查中心的八个方块,是否数字相同
for(int i=0;i<8;i++){
if(map[index[0]]!=map[index[i]])
return 0;
}
return 1;
}
int move(int loc){//头位数字放到尾部,其他依次挪一格
int head=map[step[loc][0]];
for(int i=0;i<6;i++){
map[step[loc][i]]=map[step[loc][i+1]];
}
map[step[loc][6]]=head;
return 0;
}
int pre(){//估价函数
int most=100;
for(int i=1;i<=3;i++){
int k=0;
for(int j=0;j<8;j++)
if(map[index[j]]!=i)
k++;
most=min(most,k);
}
return most;
}
int dfs(int d,int dm ){
if(d==dm)
return check();
if(d+pre()>dm)
return 0;
for(int i=0;i<8;i++){
ans[d]=i+'A';
move(i);
if(dfs(d+1,dm)){
return 1;
}
if(i%2==0){//撤销刚才的操作
move((i+5)%8);
}
else
move((i+3)%8);
}
return 0;
}
int main(){
while(cin>>map[0]&&map[0]!=0){
for(int i=1;i<24;i++){
cin>>map[i];
}
// for(int i=0;i<24;i++){
// cout<<map[i];
// }
// cout<<endl;
if(check()){
cout<<"No moves needed"<<endl;
}
else{
int i=1;
while(!dfs(0,i)){
i++;
}
ans[i]='\0';
cout<<ans<<endl;
}
cout<<map[index[0]]<<endl;
}
return 0;
}