演示程序
链接:http://pan.baidu.com/s/1hrMy7Qk 密码:3hhy
:: dfs By blackkitty
:: 算法描述:深搜
set xx_0=0 && set yy_0=-1
set xx_1=1 && set yy_1=0
set xx_2=0 && set yy_2=1
set xx_3=-1 && set yy_3=0
set x=%current_x% && set y=%current_y%
set flag=0
call:dfs %x% %y% 0
goto:eof
:dfs
:: <x> <y>
if "%1_%2" EQU "%end_x%_%end_y%" (set flag=1 && goto:eof)
set dic_%3=0
:dfs_loop1
set tmp=!dic_%3!
set/a dfs=%3+1
set/a nx=%1+!xx_%tmp%!
set/a ny=%2+!yy_%tmp%!
if !vis_%nx%_%ny%! EQU 0 (
if !%map%_%nx%_%ny%! EQU 1 (
call go %nx% %ny%
call:dfs %nx% %ny% %dfs%
)
)
if %flag% EQU 1 (goto:eof)
set/a dic_%3+=1
if !dic_%3! LSS 4 (goto dfs_loop1)
goto:eof
:: dbfs By blackkitty
:: 算法描述:逆向广搜
set xx_0=0&&set yy_0=-1
set xx_1=1&&set yy_1=0
set xx_2=0&&set yy_2=1
set xx_3=-1&&set yy_3=0
set l=0
set r=1
set x0=%end_x%
set y0=%end_y%
set nxt_%end_x%_%end_y%=0
:rbfs
set x=!x%l%!
set y=!y%l%!
:: 在地图上显示标记(x,y),演示搜索过程
:: call:mark %x% %y% .
set/a l+=1
if "%x%_%y%" EQU "%start_x%_%start_y%" (goto rush)
for /l %%i in (0,1,3) do (
set/a nx=x+!xx_%%i!
set/a ny=y+!yy_%%i!
set/a val=%map%_!nx!_!ny!
if "!val!" EQU "1" (
if not defined nxt_!nx!_!ny! (
set nxt_!nx!_!ny!=!x!_!y!
set x!r!=!nx!
set y!r!=!ny!
set/a r+=1
)
)
)
goto rbfs
:rush
set vv=!nxt_%start_x%_%start_y%!
:rush_loop
if "%vv%" EQU "0" (goto:eof)
call go %vv:_= %
set vv=!nxt_%vv%!
goto rush_loop
:mark
:: <x> <y> 在地图上显示标记(x,y),用来演示搜索过程
set/a _x=%1*2+%maze_x% && set/a _y=%2+%maze_y%
cc %_x% %_y% && echo.%~3
goto:eof
:: dbfs By blackkitty
:: 算法描述:双向广搜
set xx_0=0&&set yy_0=-1
set xx_1=1&&set yy_1=0
set xx_2=0&&set yy_2=1
set xx_3=-1&&set yy_3=0
set l=0
set r=2
set x0=%start_x%
set y0=%start_y%
set v%start_x%_%start_y%=pre
set pre_%start_x%_%start_y%=0
set x1=%end_x%
set y1=%end_y%
set v%end_x%_%end_y%=nxt
set nxt_%end_x%_%end_y%=0
:dbfs
set x=!x%l%!
set y=!y%l%!
:: 在地图上显示标记(x,y),演示搜索过程
:: call:mark %x% %y% .
set v=!v%x%_%y%!
set/a l+=1
set/a i=0
:loop
set/a nx=%x%+!xx_%i%!
set/a ny=%y%+!yy_%i%!
if "!%map%_%nx%_%ny%!" EQU "1" (
:: 若临块为路
if "!v%nx%_%ny%!" NEQ "%v%" (
:: 若临块的标记与本块不同
if defined v%nx%_%ny% (
::找到通路
if "%v%" EQU "pre" (
call:rush %x% %y% %nx% %ny%
) else (
call:rush %nx% %ny% %x% %y%
)
goto:eof
)
:: 若临块的标记与本块不同,且临块无标记
set %v%_%nx%_%ny%=%x%_%y%
set x%r%=%nx%&&set y%r%=%ny%&&set v%nx%_%ny%=%v%
set/a r+=1
)
)
set/a i+=1&&if "!i!" NEQ "4" (goto loop)
goto dbfs
:rush
set vv=%1_%2
:rvs_loop
if "!pre_%vv%!" EQU "0" (goto rvs_lopp_end)
set nxt_!pre_%vv%!=%vv%
set vv=!pre_%vv%!
goto rvs_loop
:rvs_lopp_end
set nxt_%1_%2=%3_%4
set vv=!nxt_%start_x%_%start_y%!
:rush_loop
if "%vv%" EQU "0" (goto:eof)
call go %vv:_= %
set vv=!nxt_%vv%!
goto rush_loop
:mark
:: <x> <y> 在地图上显示标记(x,y),用来演示搜索过程
set/a _x=%1*2+%maze_x% && set/a _y=%2+%maze_y%
cc %_x% %_y% && echo.%~3
goto:eof
:: astar By blackkitty
:: 算法描述:逆向启发式A*
set xx_0=0&&set yy_0=-1
set xx_1=1&&set yy_1=0
set xx_2=0&&set yy_2=1
set xx_3=-1&&set yy_3=0
set new=1
set x0=%end_x%
set y0=%end_y%
set nxt_%end_x%_%end_y%=0
set gn0=0
set fn0=0
set list=n0
set/a maxfn=!%map%_width!*!%map%_height!
:astar
set vv=_
set minfn=%maxfn%
:: 从列表选取fn最小的位置
for %%k in (%list%) do (
if !f%%k! LSS !minfn! (
set minfn=!f%%k!
set vv=%%k
)
)
:: 从列表中删除这个位置
set list=!list:%vv%=!
set vv=%vv:~1%
set x=!x%vv%!
set y=!y%vv%!
:: 在地图上显示标记(x,y),演示搜索过程
call:mark %x% %y% .
if "%x%_%y%" EQU "%start_x%_%start_y%" (goto rush)
for /l %%i in (0,1,3) do (
set/a nx=x+!xx_%%i!
set/a ny=y+!yy_%%i!
set/a val=%map%_!nx!_!ny!
if "!val!" EQU "1" (
if not defined nxt_!nx!_!ny! (
set nxt_!nx!_!ny!=!x!_!y!
:: 加入列表
set list=!list! n!new!
:: 计算gn
set/a gn!new!=!gn%vv%!+1
:: 计算fn保存至fn!new!
call:fn !nx! !ny! gn!new! fn!new!
set x!new!=!nx!
set y!new!=!ny!
set/a new+=1
)
)
)
goto astar
:rush
pause>nul
set vv=!nxt_%start_x%_%start_y%!
:rush_loop
if "%vv%" EQU "0" (goto:eof)
call go %vv:_= %
set vv=!nxt_%vv%!
goto rush_loop
:fn
:: <x> <y> [gn] [ret] 起点到x,y的估计代价(fn = gn + hn)
:: gn 终点到(x,y)的实际代价
:: hn 起点到(x,y)的估计代价,估值为起点到(x,y)的曼哈顿距离
set/a tmp=%1-%start_x%
if %tmp% LSS 0 (set/a tmp=-tmp)
set %4=%tmp%
set/a tmp=%2-%start_y%
if %tmp% LSS 0 (set/a tmp=-tmp)
set/a %4=!%4!+%tmp%+!%3!
goto:eof
:mark
:: <x> <y> 在地图上显示标记(x,y),用来演示搜索过程
set/a _x=%1*2+%maze_x% && set/a _y=%2+%maze_y%
cc %_x% %_y% && echo.%~3
goto:eof