当前位置: 首页 > 工具软件 > queue-fun > 使用案例 >

erl_stack_queue-队列求迷宫最短路径

茹正祥
2023-12-01

求迷宫的最短路径:
现要求设计一个算法找一条从迷宫入口到出口的最短路径。本算法要求找一条迷宫的最短路径,算法的基本思想为:从迷宫入口点(2,2)出发,向四周搜索,记下所有一步能到达的坐标点;然后依次再从这些点出发,再记下所有一步能到达的坐标点,…,依此类推,直到到达迷宫的出口点(9,7)为止,然后从出口点沿搜索路径回溯直至入口。这样就找到了一条迷宫的最短路径,否则迷宫无路径。
Map = [
[1,1,1,1,1,1,1,1,1,1],
[1,0,1,1,1,0,1,1,1,1],
[1,1,0,1,0,1,1,1,1,1],
[1,0,1,0,0,0,0,0,1,1],
[1,0,1,1,1,0,1,1,1,1],
[1,1,0,0,1,1,0,0,0,1],
[1,0,1,1,0,0,1,1,0,1],
[1,1,1,1,1,1,1,1,1,1]
],
有关迷宫的数据结构、试探方向、如何防止重复到达某点以避免发生死循环的问题与例3.2 处理相同,不同的是:如何存储搜索路径。在搜索过程中必须记下每一个可到达的坐标点,以便从这些点出发继续向四周搜索。由于先到达的点先向下搜索,故引进一个“先进先出”数据结构——队列来保存已到达的坐标点。
方向list
Dir = [{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,1},{-1,0},{-1,1}],
队列
Path_Queue : 【{X,Y,Dir}。。】
判断是否可走
lists:member({X+DX,Y+DY},FindList)

代码如下:


find_path_queue()->
    Map = [
        [1,1,1,1,1,1,1,1,1,1],
        [1,0,1,1,1,0,1,1,1,1],
        [1,1,0,1,0,1,1,1,1,1],
        [1,0,1,0,0,0,0,0,1,1],
        [1,0,1,1,1,0,1,1,1,1],
        [1,1,0,0,1,1,0,0,0,1],
        [1,0,1,1,0,0,1,1,0,1],
        [1,1,1,1,1,1,1,1,1,1]
    ],
    Dir = [{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,1},{-1,0},{-1,1}],
    Path_Queue = queue_init(),

%%从点2,2  开始八方向找点
    spawn(fun()->
        find_path_queue1({2,2},Dir,Path_Queue,Map,{9,7},[]),
        case get_queue_path() of
            []->
                nil;
            List->
                TT =
                    lists:foldl(fun(Queue,Tq)->
                        case queue:len(Queue) < Tq of
                            true->
                                Queue;
                            _->
                                Tq
                        end
                    end,{[],[]},List),
                io:format("find_path_queue 111111------------~p-----",[TT])
        end
    end).




get_queue_path()->
    case get(findpath) of
        undefined->
            [];
        L->
            L
    end.
set_queue_path(Data)->
    TP = get_queue_path(),
    put(findpath,[Data|TP]).

find_path_queue1({X,Y},DirL,Path_Queue,Map,{FX,FY},FindPos)->
    FindPos1 = [{X,Y}|FindPos],
    lists:foldl(fun({DirX,DirY},C)->
        case get_right_pos_dir([{DirX,DirY}],FindPos1,{X,Y},Map,C) of
            {DX,DY,Dir}->
                NewPath_Queue = queue_insert(Path_Queue,{X,Y,Dir}),
                case {FX,FY} == {DX,DY} of  %%每次找出可走点与最终点对应
                    true->
                        set_queue_path(NewPath_Queue);
                    _ ->
                        find_path_queue1({DX,DY},DirL,NewPath_Queue,Map,{FX,FY},FindPos1)
                end,
                C+1;
            false->
                C+1
        end
    end,1,DirL).

%%get_right_pos_dir(DirL,findPos,SPos,Map,1)
get_right_pos_dir1([],_,_,_,_)->
    false;
get_right_pos_dir1([{DX,DY}|DirL],FindList,{X,Y},Map,Count)->
    case lists:nth(X+DX,lists:nth(Y+DY,Map) )  of
        1->
            get_right_pos_dir1(DirL,FindList,{X,Y},Map,Count+1);
        _->
            case lists:member({X+DX,Y+DY},FindList) of
                false->
                    {X+DX,Y+DY,Count};
                _ ->
                    get_right_pos_dir1(DirL,FindList,{X,Y},Map,Count+1)
            end
    end.
 类似资料: