关闭

HDOJ-1667/TJU4106 The Rotation Game(IDA*搜索)

标签: acmhdoj搜索算法IDA
296人阅读 评论(0) 收藏 举报
分类:

今天下午学习了一下IDA*算法,收获还是不小的。

关于IDA*算法的和此题的题解见下面博客:

http://blog.csdn.net/urecvbnkuhbh_54245df/article/details/5856756

讲得非常详细,我的代码也算参考上面那篇博客的。

ID即迭代加深(Iterative Deepening),不断加深允许的最大DFS深度,避免了DFS一条到走到死的情况。虽然出现了某些状态重复搜索的弊端,但是从空间上讲,没有像BFS那样耗费大量内存。

A*算法使用估价函数进行剪枝。

同A*一样,难点是找到合适的估价函数。此题的估价函数剪枝为:如果8-中间最多的数的个数>限定的迭代深度-当前DFS深度则退出搜索。


/*************************************************************************
 > File Name: 4106.cpp
 > Author:wangxin 
 > Mail: 
 > Created Time: 2015年07月10日 星期五 16时25分53秒
 ************************************************************************/

#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;

int DEPTH,ansnum;   //迭代深度,中间的数
int map[25];			 //井字格
int midblocks[8]={7,8,9,12,13,16,17,18};  //位于井字中间位置的编号
char ansPath[100];   //存储搜索路径


//判断是否完成搜索
bool Judge(const int* state)
{
   int i;
   for(i=1;i<=7;i++) 
       if(state[midblocks[i]]!=state[midblocks[i-1]])
           return false;
   return true;

}


//进行状态转换
void ChangeState(int *state,int a1,int a2,int a3,int a4,int a5,int a6,int a7)
{
    int temp;
    temp=state[a1];       state[a1]=state[a2]; state[a2]=state[a3];
    state[a3]=state[a4];  state[a4]=state[a5]; state[a5]=state[a6];
    state[a6]=state[a7];  state[a7]=temp;

}

//计算中间出现最多的数字的个数
int CountMaxSameNum(const int* state)
{
    int i,j,cntarr[4];
    memset(cntarr,0,sizeof(cntarr));
    for(i=0;i<8;i++) cntarr[state[midblocks[i]]]++;
    j=0;
    for(i=1;i<=3;i++)
        if(cntarr[i]>cntarr[j]) j=i;
    return cntarr[j];
}


//DFS函数,返回值表示是否搜索到  curDepth表示当前的搜索深度,preDir表示上一步的变换方向
bool DFS(int *state, int curDepth, int preDir)
{
    int i,j;
    int temp[25]; 

//IDA*估价函数剪枝,如果剩下的搜索深度不可能完成任务,不进行进一步搜索
    if(DEPTH-curDepth < 8-CountMaxSameNum(state))
        return false;
//限定迭代深度
    if(curDepth>DEPTH)
        return false;
//枚举变换的方向
    for(i=1;i<=8;i++)
    {
    //剪枝:连续的方向相反的变换是没有意义的
        if((i==1 && preDir==6)||(i==6 && preDir==1)) continue;
        if((i==2 && preDir==5)||(i==5 && preDir==2)) continue;
        if((i==3 && preDir==8)||(i==8 && preDir==3)) continue;
        if((i==4 && preDir==7)||(i==7 && preDir==4)) continue;

        for(j=1;j<=24;j++) temp[j]=state[j];

        switch(i)
        {
            case 1:ansPath[curDepth]='A'; ChangeState(temp, 1, 3, 7,12,16,21,23);break;
            case 2:ansPath[curDepth]='B'; ChangeState(temp, 2, 4, 9,13,18,22,24);break;
            case 3:ansPath[curDepth]='C'; ChangeState(temp,11,10, 9, 8, 7, 6, 5);break;
            case 4:ansPath[curDepth]='D'; ChangeState(temp,20,19,18,17,16,15,14);break;
            case 5:ansPath[curDepth]='E'; ChangeState(temp,24,22,18,13, 9, 4, 2);break;
            case 6:ansPath[curDepth]='F'; ChangeState(temp,23,21,16,12, 7, 3, 1);break;
            case 7:ansPath[curDepth]='G'; ChangeState(temp,14,15,16,17,18,19,20);break;
            case 8:ansPath[curDepth]='H'; ChangeState(temp, 5, 6, 7, 8, 9,10,11);break;
            default: printf("There is something wrong!");
        }
        
        //如果检测到搜索成功,返回true
        if (Judge(temp))
        {
            ansnum=temp[7];
            ansPath[curDepth+1]='\0';
            return true;
        }

        if (DFS(temp,curDepth+1,i)) return true;
    }
    return false; 
}


void work()
{
    int i,j,k,t,m,n;
    
    for(i=2;i<=24;i++) scanf("%d",&map[i]);

    if(Judge(map))
    {
        printf("No moves needed\n");
        printf("%d\n",map[7]);
    }
    else
    {
    //限定初始的迭代深度
        DEPTH=1;
        while(1)
        {
            if(DFS(map,0,-1)) break;
            DEPTH++;
            //如果在当前迭代深度下没有搜出答案,加大搜索深度
        }
        printf("%s\n",ansPath);
        printf("%d\n",ansnum);
    }

}

int main()
{
    while(scanf("%d",&map[1]),map[1])
    {
        work();
    }
    return 0;
}



0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

5.IDA-文本搜索、二进制搜索(16进制字节序列)、替换16进制

1.文本搜索 IDA文本搜索相当于对反汇编列表窗口进行子字符串搜索。通过Search▶Text(热键:ALT+T)命令启动文本搜索 选择Find all occurences(...
  • qq_22642239
  • qq_22642239
  • 2017-08-03 20:19
  • 204

【启发式搜索】A*与IDA*学习笔记

搞了这么久发现自己到现在还不会启发式搜索ヾ(。`Д´。)所以今天正好趁着搜索练习题的风去搞了启发式搜索 A*搜索算法,俗称A星算法。这是一种在图形平面上,有多个节点的路径,求出最低通过成本的算法...
  • CreationAugust
  • CreationAugust
  • 2014-12-14 21:48
  • 1421

CMPSCI 683 AI 第三讲 启发式搜索-IDA*算法

IDA*算法是A*算法和迭代加深ID算法的结合,先搜录相关资料如下[1] 搜索算法:IDA*算法,这是对IDA*算法的一个解释和学习笔记http://blog.csdn.net/urecvbnkuhB...
  • yangliuy
  • yangliuy
  • 2014-10-29 13:10
  • 2381

IDA反汇编/反编译静态分析iOS模拟器程序(三)函数表示与搜索函数

打开IDA一般都是去搜索函数,可以说函数是IDA工程的基本单位吧,数据结构什么的都是为函数服务而已。函数列表在界面左侧的Functions Window: 可以看到,UIKit有27789个函数呢...
  • hursing
  • hursing
  • 2013-05-14 18:40
  • 10061

搜索算法:IDA*算法

搜索算法:IDA*算法 分类: 算法与数据结构2010-09-01 22:30 2922人阅读 评论(2) 收藏 举报 算法扩展structc游戏up 今天学习了IDA*算法...
  • pi9nc
  • pi9nc
  • 2013-09-23 20:16
  • 3275

使用IDA定位基于MFC的CrackMe的按钮函数-----理论篇

MFC程序不同于普通的windows程序,由于使用了框架代码,我们很难
  • SilverMagic
  • SilverMagic
  • 2014-10-30 18:01
  • 1443

13.IDA-显示正确的函数名称(去掉c++后缀命名)

随便看一段IDA的反汇编: C++编译器用于区分重载函数的机制。为了给重载函数生成唯一的名称,编译器用其他字符来修饰函数名称 图左就是C++的后缀命名法,图右是正常的函数名字 为了显示正常的...
  • hgy413
  • hgy413
  • 2016-01-26 21:34
  • 2187

AVL二叉搜索树的Rotation

Rotations in AVL TreesLL(left-left) rotation 当x位于A的左子树的左子树时,执行LL。首先定义left为A的左子节点。将A的左指针指向left的右子节点...
  • AdmireLinux
  • AdmireLinux
  • 2017-03-17 15:27
  • 206

IDA下MD5算法F5特征

从IDA里抠出来的: int __usercall MD5_COMPUT(char *a1, int a2) { int v2; // edx@1 int v3; // ebx@1 ...
  • chence19871
  • chence19871
  • 2014-05-20 18:11
  • 3820

【DayDayUp】【算法_搜索_A* 和 IDA*】

【坚持不能偷懒】 【A*——A Star算法(启发式搜索)】 记起点为 Start 终点为 End f(n) = g(n) + h(n) f(n)—— 经由状态 n 到 E 的【预计代价】 g(n)—...
  • under_sky_dxj
  • under_sky_dxj
  • 2017-03-14 22:42
  • 122
    个人资料
    • 访问:28494次
    • 积分:1086
    • 等级:
    • 排名:千里之外
    • 原创:82篇
    • 转载:3篇
    • 译文:0篇
    • 评论:3条
    文章分类
    最新评论