Data structure - solving maze problem with ring shortest path

Shortest path problem with loop

First, construct the map:

Firstly, a maze with multiple paths and rings is constructed.

The idea is the same as the previous method of finding the shortest path of multi-path. We need to traverse all the footholds first and save the shortest path in the minimum path stack. Different from that, the marking method has changed. This time, it can not be simply marked as 2, but should be marked as its path length (roughly). Then, when comparing, we can directly compare the value. If the current path goes The number of steps to this point is smaller than the previous value, so I can take this road and continue.
Auxiliary function: since some judgment conditions and previous problem judgment conditions have changed, it is necessary to create a judgment condition to consider.

int ExitWithCycle(Maze* m,Point pt,Point entry)//The judgment basis has not changed
{
    (void)m;
    //1 is the current point an entrance? If it is an entrance, it is not an exit
    if(pt.x==entry.x&&pt.y==entry.y)
    {
        return 0;
    }
    //2. If the current point is on the boundary, it is the exit
    if(pt.x==0||pt.y==0||pt.x== ROW-1||pt.y==COL-1)
    {
        return 1;
    }
    return 0;
}
//The way of marking has changed
void MarkWithCycle(Maze* m,Point cur,Point pre)
{
    //First, judge whether it is the entry point. It cannot be + 1. It should be directly assigned as 2;
    if(pre.x==-1&&pre.y==-1)
    {
        m->maze[cur.x][cur.y]=2;
        return;
    }
    //Get pre value
    //Let the value of this point = pre UU value + 1
    m->maze[cur.x][cur.y]=m->maze[pre.x][pre.y]+1;

}
//Judgment conditions have changed
int CanStayWithCycle(Maze* m,Point cur,Point pre)
{
    if(m==NULL)
    {
        return 0;
    }
    (void)m;
    //0. Outside the map
    if(cur.x<0||cur.x>=ROW||cur.y<0||cur.y>=COL)
    {
        return 0;
    }
    //1. If the current point is 1, it can be set directly
    if(m->maze[cur.x][cur.y]==1)
    {
        return 1;
    }
    //2. If the current point has passed, compare the size relationship between the value corresponding to cur and the value of pre
    //   a.cur_value 7,pre_value 5 should be shorter
    //   b.cur_value 6,pre_value 5 should not be the same, not necessary
    //   c.cur_value 5,pre_value 5 should not be longer
    if(m->maze[pre.x][pre.y]+1<m->maze[cur.x][cur.y])
    {
        return 1;
    }
    return 0;

}

Implementation function:

void _GetShortPathWithCycle(Maze* m,Point cur,Point pre,Point entry,SeqStack* cur_path,SeqStack* short_path)
{
    printf("(%d,%d)\n",cur.x,cur.y);
    //1. Determine whether the current point can be grounded (the determination rule has changed)
    if(!CanStayWithCycle(m,cur,pre))
    {
        return;
    }
    //2. Mark the current point, the marking rule changes, and insert the current point into cur? Path
    MarkWithCycle(m,cur,pre);
    SeqStackPush(cur_path,cur);
    pre=cur;
    //3. Determine whether the current point is an exit
    if(ExitWithCycle(m,cur,entry))
    {
        //  It is an exit. To pk (or short empty stack) cur path and short path, save the shorter path to short path (seqstackassign)
        //  Whether the current path is short or not, backtracking is required.
        printf("Found a path\n");
        if(cur_path->size<short_path->size||short_path->size==0)
        {
            SeqStackAssign(cur_path,short_path);
            printf("Found a shorter path\n");
        }
        SeqStackPop(cur_path);
        return;
    }
    //4. It's not an exit. It detects four directions. (clockwise)
    Point up=cur;
    up.x-=1;
    _GetShortPathWithCycle(m,up,pre,entry,cur_path,short_path);

    Point right=cur;
    right.y+=1;
    _GetShortPathWithCycle(m,right,pre,entry,cur_path,short_path);

    Point down=cur;
    down.x+=1;
    _GetShortPathWithCycle(m,down,pre,entry,cur_path,short_path);

    Point left=cur;
    left.y-=1;
    _GetShortPathWithCycle(m,left,pre,entry,cur_path,short_path);
    //5. If all four directions have been detected, the stack will be backtracked
    SeqStackPop(cur_path);
    return;
}
void GetShortPathWithCycle(Maze* maze,Point entry)
{
    SeqStack cur_path;
    SeqStack short_path;
    SeqStackInit(&cur_path);
    SeqStackInit(&short_path);
    Point pre={-1,-1};//Virtual an illegal point
    _GetShortPathWithCycle(maze,entry,pre,entry,&cur_path,&short_path);//5 parameters
    MazeSeqStackPrint(&short_path,"The shortest path is:");
}

The results are as follows:

Posted by phoenixx on Sun, 05 Apr 2020 20:06:03 -0700