假設有如下的迷宮:迷宮0
1000
0001
0010
1011
1000
1001
0100
0 其中0表示可走,1表示牆壁,只能按上下左右的方向走,請問從左上角走到右下角哪條路最短?
這裡就以廣度優先搜尋演算法來探索走法。過程如下:
下面給出php和go的示例**:
define
('maze_file'
,__dir__
.directory_separator
.'maze.list');
define
('maze_dire',[
[-1,
0],// 往上[0
,-1]
,// 往左[1
,0],
// 往下[0
,1],
// 往右])
;/**
* 讀取迷宮
* @return array
*/function
readmaze()
:array
fclose($f
);return
$maze;}
/** * 迷宮按當前點的上左下右順時針方向走
* @param array $maze
* @param array $start
* @param array $end
* @return array
*/function
walkmaze
(array
$maze
,array
$start
,array
$end):
array
}$queue=[
$start];
// 把可以走的點放入該佇列中
while
($cur
=array_shift
($queue))
// 按逆時針方向探索
foreach
(maze_dire
as$dir
)list
($val
,$ok)=
pointmap
($next
,$maze);
if(!$ok
||$val==1
)list
($val
,$ok)=
pointmap
($next
,$steps);
if(!$ok
||$val
>0)
// 把能走的下個點的值改為當前點的值+1
$steps
[$next[0
]][$next[1
]]=pointmap
($cur
,$steps)[
0]+1
;array_push
($queue
,$next);
// 儲存可以走的座標點}}
return
$steps;}
/** * 返回座標點對應的值
* @param array $point
* @param array $grid
* @return array
*/function
pointmap
(array
$point
,array
$grid):
arrayif(
$point[1
]<0||
$point[1
]>=
count
($grid
[$point[0
]]))
return
[$grid
[$point[0
]][$point[1
]],true];
}/**
* 座標點相加
* @param array $p1
* @param array $p2
* @return array
*/function
addpoint
(array
$p1,
array
$p2)
:array
$maze
=readmaze()
;$steps
=walkmaze
($maze,[
0,0]
,[count
($maze)-
1,count
($maze[0
])-1
]);foreach
($steps
as$item
)printf
("\n");
}
// 廣度優先搜尋演算法
func
readmaze
(filename string)[
][]int
defer file.
close()
var row, col int
// 按行讀取檔案 碰到換行符會自動結束本次讀取
fmt.
fscanf
(file,
"%d %d"
,&row,
&col)
maze :=
make([
][]int
, row)
// maze裡只有6個元素 而每個元素又是乙個陣列
for i :=
range maze
}return maze
}// i表示第幾行 j表示第幾列
type point struct
// 表示上左下右四個方向
var directions =[4
]point ,,
,}func
(p point)
add(dirs point) point
}/**
* 可以把迷宮或者走過的路線圖放進去
*/func
(p point)
pointat
(grid [
]int)(
int,
bool
)if p.j <
0|| p.j >=
len(grid[p.i]
)return grid[p.i]
[p.j]
,true
}func
walk
(maze [
]int
, start, end point)
int/**
* 迷宮初始化:
* 把能走的點放入佇列 起初只有起點在佇列
* * 迷宮走法:
* 1. 按上左下右的逆時針方向走
* 2. 判斷走的點是否撞牆了、出界了、已經走過了或者走回了原點(由於原點合法並且可能不是牆壁
* 但我們就是從原點走的所以要迴避掉)
* 3. 把能走的點放入佇列
*/q :=
point
forlen
(q)>
0// 往四個方向走
for_
, dir :=
range directions
val, ok = next.
pointat
(steps)
if!ok || val !=
0// 原點不能走
if next == start
// 可走的點放入佇列中
q =(q, next)
cursteps,
_:= cur.
pointat
(steps)
steps[next.i]
[next.j]
= cursteps +1}
}return steps
}func
main()
, point
)for
_, row :=
range steps
fmt.
println()
}}
乙個強型別語言,乙個弱型別語言,是不是有很強的衝擊感。。 廣度優先搜尋演算法
廣度優先搜尋 bfs 這個是第乙個研究的課題,廣度優先搜尋也叫寬度優先搜尋,英文為breadth first searth,開始看的時候一頭霧水,基本也能懂大致意思,但是還不是真正的理解,今天又仔細看看,大致理解上又更深了一層吧。下面來總結下,自己的一些體會,以及對它的獨到的理解。大的方面來說它是一...
廣度優先搜尋演算法
在深度優先搜尋中,深度越大的結點越先得到擴充套件。如果把它改為深度越小的結點越先得到擴充套件,就是廣度優先搜尋法。廣度優先搜尋演算法的基本思想 1 建立乙個空的狀態佇列ss 2 建立乙個空的狀態庫sb 3 把初始狀態s 0 存入佇列ss中 4 若佇列狀態是目標狀態,則搜尋成功,演算法執行中止。如該狀...
廣度優先搜尋演算法
看了下廣度優先搜尋演算法得定義為從乙個頂點開始,找到最短路勁,歸結為一種連通圖得遍歷策略 如果我們要求v0到v6的一條最短路 假設走乙個節點按一步來算 注意 此處你可以選擇不看這段文字直接看圖3 1 我們明顯看出這條路徑就是v0 v2 v6,而不是v0 v3 v5 v6。先想想你自己剛剛是怎麼找到這...