Eight Digital Problem Enhanced Version: Fifteenth Digital Problem idA*Version

Links to the original text: https://www.cnblogs.com/fujudge/p/7398153.html

From: https://www.cnblogs.com/fujudge/p/7398153.html
Last time I introduced the dbfs version, this time I will introduce the idA* version.

First of all, we need to understand the idea of idA algorithm, which is the combination of iteration deepening and A. The evaluation function h(n) is used as the limit value of iteration to carry out dfs.

(A* and Iteration Deepening Introductions will be written when time is available)

Manhattan distance is calculated for all points except 0 (target state to initial state). h(n) is the sum of Manhattan distance for each point of the current node.

Look at the code:

#include<cstdio>
#include<algorithm>
#include<cstring>
#define abs(w) (w>=0?w:-(w))
int xx[20],yy[20],bound,flg;int u[4] = {0,0,1,-1};
int p[4] = {1,-1,0,0};
using namespace std;
struct node{
    int mat[20];
    int pos;
    int H()//Computing h(n)
    {
        register int ans(0);
        for(register int i = 0 ; i < 15 ; ++i)
            ans+=abs(xx[mat[i]]-(i>>2))+abs(yy[mat[i]]-(i&3));
        return ans;
    }
    bool check()//Judging the Existence of Solutions
    {
        register int tot(0),i,j;
        for( i = 0 ; i < 16 ; ++i)
        {
            if(!mat[i])continue;
            for(j = 0 ; j < i ; ++j)
                if(mat[j]<mat[i])++tot;
        }
        tot+=abs((pos>>2)-3)+abs((pos&3)-3);
        if(tot&1)return true;
        return false;
    }
}a;
inline bool ok(register int x,register int y)//Prevent going back from where you came.
{
    if(x>y)swap(x,y);
    if(x==0&y==1)return false;
    if(x==2&&y==3)return false;
    return true;
}
int dfs(register int step,register int h,register int las)
{if(step+h>bound)return step+h;//If g(n)+h(n)>f(n), update f(n)
    if(!h)//When the final state is reached, the output g(n) is sufficient.
    {
        printf("%d",step);
        flg=1;
        return step;
    }
    register int ret=127,pos=a.pos,x=pos>>2,y=pos&3;
    register int dx,dy,tar,ht,tmp,i;
    for(i = 0 ; i < 4 ; ++i)//Expanding in Four Directions
    {
         dx=x+u[i];
         dy=y+p[i];
        if(dx<0||dy<0||dx>3||dy>3||!ok(i,las))continue;
         tar=(dx<<2)|dy;//Computing one-dimensional coordinates of new nodes
        a.mat[pos]=a.mat[tar];
        a.mat[tar]=0;//These two lines are equivalent to swap operations (which are said to be faster)
        a.pos=tar;
         ht=h-(abs(xx[a.mat[pos]]-dx)+abs(yy[a.mat[pos]]-dy)) + abs(xx[a.mat[pos]]-x)+abs(yy[a.mat[pos]]-y) ;//Calculate the new h value
         tmp=dfs(step+1,ht,i);
        if(flg)return tmp;//Find the Path
        if(ret>tmp)ret=tmp;//Update bound
        a.mat[tar]=a.mat[pos];//To flash back
        a.mat[pos]=0;
        a.pos=pos;
    }
    return ret;
}
int main()
{
   // freopen("fifteen.in","r",stdin);
  //  freopen("fifteen.out","w",stdout);
    register int k,i;
    for( i = 0 ; i < 16 ; ++i)
    {
        scanf("%d",&k);
        if(!k)a.pos=i;//Location of record 0
        else 
        {
            a.mat[i]=k;
            xx[k]=i>>2;//Keep the two-dimensional coordinates of k
            yy[k]=i&3;//Equivalent to i%4
        }
    }if(!a.check())//Judging the Existence of Solutions
    {
        printf("No");
        return 0;
    }
    for( i = 0 ; i < 16 ; ++i)//Update from the target state to the initial state. Don't ask me why. Look at the code of all the big guys (it's said to be a little trick, you can do it faster).
        a.mat[i]=i+1;
    a.mat[15]=0;
    a.pos=15;
    for(bound=a.H();bound<=60;bound=dfs(0,a.H(),4))//idA* section
        if(flg)break;
    return 0;
}

Explain some minor details of the optimization in this code (the data seems to have card constants):

1. inline and register

Inline so-called inline functions are said to optimize time.

register optimizes time by storing space in CPU registers.

Using the example of netizens for reference, the effect is equivalent to having bread in your pocket, so you don't need to go to a shop 100 meters away to buy it. Natural time is fast.

2. I & 3 is equivalent to i%4

Because & 3 is equivalent to the last three binary bits, which implements the operation of% 4, but only applies to 2^n numbers such as% 2, 4, 8.

3. define for abs can be used to optimize the time by defining some small functions that appear repeatedly in the code.

Posted by WeddingLink on Tue, 30 Jul 2019 22:43:36 -0700