IDA*算法

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

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

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

/*
POJ 1077 Eight
C++
Memory 168K
Time 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;
}



IDA*算法

上一篇:Java 8即将正式发布


下一篇:物联网 毕业设计——方案选择