IDA*算法

来源:互联网 发布:谷歌地图高程数据 编辑:程序博客网 时间:2024/05/02 12:19

该文主要介绍用IDA*算法实现八数码问题

IDA*算法即迭代加深的A*算法,实现代码是最简练的,无须状态判重,无需估价排序

IDA*大部分时候比A*还要快,可以说是A*的一个优化版本!

/*POJ 1077 EightC++Memory 168KTime 32MS*/#include <iostream>#include <string>using namespace std;const unsigned int M = 1001;int dir[4][2] = {    1, 0, // Down      -1, 0, // Up      0,-1, // Left      0, 1 // Right  };typedef struct STATUS{    int data[3][3];    int r,c;//0所在的位置}STATUS;char dirCode[] = {"dulr"};char rDirCode[] = {"udrl"};char path[M]; // 最优解STATUS start, goal = { 1,2,3,4,5,6,7,8,0,2,2 }; // 起始和终止状态int maxDepth = 0; // 深度边界//计算h值,作为IDAstar算法的评估函数int dist(STATUS suc, STATUS goal, int k) {//计算方格的错位距离  int si,sj,gi,gj;  //si,sj表示suc中k所处位置,gi,gj表示goal中k所处的位置for(int i=0;i<3;i++)for(int j=0;j<3;j++){if(suc.data[i][j]==k){si=i;sj=j;}if(goal.data[i][j]==k){gi=i;gj=j;}}return abs(si-gi) + abs(sj-gj); }int H(STATUS suc, STATUS goal) {//计算 h 值    int h = 0;  for(int i = 1; i <= 8; i++)   h = h + dist(suc, goal, i);  return h;                                        } //计算h值结束//IDAstar算法开始bool dfs(STATUS cur,int depth,int h,char preDir){//IDA*估值函数剪枝//当前局面的估价函数值+当前的搜索深度 > 预定义的最大搜索深度时剪枝if(depth+h>maxDepth)return false; if(memcmp(&cur, &goal, sizeof(STATUS)) == 0 )      {        path[depth] = '\0';          return true;      }  STATUS next;for(int i=0;i<4;++i){if(dirCode[i]==preDir)continue;//不能回到上一状态next=cur;next.r = cur.r + dir[i][0];          next.c = cur.c + dir[i][1];          if( !( next.r >= 0 && next.r < 3 && next.c >= 0 && next.c < 3 ) )              continue;  swap(next.data[cur.r][cur.c], next.data[next.r][next.c]); //置换变成新的状态int nexth=H(next,goal);//重新计算h值path[depth] = dirCode[i];          if(dfs(next, depth + 1, nexth, rDirCode[i]))              return true;  }return false;}int IDAstar(){int h = H(start,goal);      maxDepth = h;      while (!dfs(start,0, h, '\0'))         maxDepth++;      return maxDepth;  }//IDAstar算法结束//是否可解bool IsSolvable(const STATUS &cur){    int i, j, k=0, s = 0;    int a[9];    for(i=0; i < 3; i++){        for(j=0; j < 3; j++){            if(cur.data[i][j]==0) continue;            a[k++] = cur.data[i][j];        }    }    for(i=0; i < 8; i++){        for(j=i+1; j < 8; j++){            if(a[j] < a[i])                s++;        }    }    return (s%2 == 0);}//初始状态赋值void input(){char c;for(int i=0;i<3;i++){for(int j=0;j<3;j++){cin>>c;if(c=='x'){start.data[i][j]=0;start.r=i;start.c=j;}else start.data[i][j]=c-'0';}}}int main(){freopen("C:\\in.txt","r",stdin);input();if(IsSolvable(start)){IDAstar();          cout<<path<<endl;      }      else          cout<<"unsolvable"<<endl; return 0;}



0 0