當前位置:首頁 » 操作系統 » 廣度搜索優先演算法

廣度搜索優先演算法

發布時間: 2022-05-01 04:32:03

⑴ 深度優先搜索和廣度優先搜索、A星演算法三種演算法的區別和聯系

在說它之前先提提狀態空間搜索。狀態空間搜索,如果按專業點的說法就是將問題求解過程表現為從初始狀態到目標狀態尋找這個路徑的過程。通俗點說,就是 在解一個問題時,找到一條解題的過程可以從求解的開始到問題的結果(好象並不通俗哦)。由於求解問題的過程中分枝有很多,主要是求解過程中求解條件的不確 定性,不完備性造成的,使得求解的路徑很多這就構成了一個圖,我們說這個圖就是狀態空間。問題的求解實際上就是在這個圖中找到一條路徑可以從開始到結果。 這個尋找的過程就是狀態空間搜索。 常用的狀態空間搜索有深度優先和廣度優先。廣度優先是從初始狀態一層一層向下找,直到找到目標為止。深度優先是按照一定的順序前查找完一個分支,再查找另一個分支,以至找到目標為止。這兩種演算法在數據結構書中都有描述,可以參看這些書得到更詳細的解釋。 前面說的廣度和深度優先搜索有一個很大的缺陷就是他們都是在一個給定的狀態空間中窮舉。這在狀態空間不大的情況下是很合適的演算法,可是當狀態空間十分大,且不預測的情況下就不可取了。他的效率實在太低,甚至不可完成。在這里就要用到啟發式搜索了。 啟發中的估價是用估價函數表示的,如: f(n) = g(n) + h(n) 其中f(n) 是節點n的估價函數,g(n)實在狀態空間中從初始節點到n節點的實際代價,h(n)是從n到目標節點最佳路徑的估計代價。在這里主要是h(n)體現了搜 索的啟發信息,因為g(n)是已知的。如果說詳細點,g(n)代表了搜索的廣度的優先趨勢。但是當h(n) >> g(n)時,可以省略g(n),而提高效率。這些就深了,不懂也不影響啦!我們繼續看看何謂A*演算法。 2、初識A*演算法 啟發式搜索其實有很多的演算法,比如:局部擇優搜索法、最好優先搜索法等等。當然A*也是。這些演算法都使用了啟發函數,但在具體的選取最佳搜索節點時的 策略不同。象局部擇優搜索法,就是在搜索的過程中選取「最佳節點」後舍棄其他的兄弟節點,父親節點,而一直得搜索下去。這種搜索的結果很明顯,由於舍棄了 其他的節點,可能也把最好的節點都舍棄了,因為求解的最佳節點只是在該階段的最佳並不一定是全局的最佳。最好優先就聰明多了,他在搜索時,便沒有舍棄節點 (除非該節點是死節點),在每一步的估價中都把當前的節點和以前的節點的估價值比較得到一個「最佳的節點」。這樣可以有效的防止「最佳節點」的丟失。那麼 A*演算法又是一種什麼樣的演算法呢?其實A*演算法也是一種最好優先的演算法。只不過要加上一些約束條件罷了。由於在一些問題求解時,我們希望能夠求解出狀態空 間搜索的最短路徑,也就是用最快的方法求解問題,A*就是干這種事情的!我們先下個定義,如果一個估價函數可以找出最短的路徑,我們稱之為可採納性。A* 演算法是一個可採納的最好優先演算法。A*演算法的估價函數可表示為: f'(n) = g'(n) + h'(n) 這里,f'(n)是估價函數,g'(n)是起點到終點的最短路徑值,h'(n)是n到目標的最斷路經的啟發值。由於這個f'(n)其實是無法預先知道 的,所以我們用前面的估價函數f(n)做近似。g(n)代替g'(n),但 g(n)>=g'(n)才可(大多數情況下都是滿足的,可以不用考慮),h(n)代替h'(n),但h(n)<=h'(n)才可(這一點特別 的重要)。可以證明應用這樣的估價函數是可以找到最短路徑的,也就是可採納的。我們說應用這種估價函數的最好優先演算法就是A*演算法。哈。你懂了嗎?肯定沒 懂。接著看。 舉一個例子,其實廣度優先演算法就是A*演算法的特例。其中g(n)是節點所在的層數,h(n)=0,這種h(n)肯定小於h'(n),所以由前述可知廣度優先演算法是一種可採納的。實際也是。當然它是一種最臭的A*演算法。 再說一個問題,就是有關h(n)啟發函數的信息性。h(n)的信息性通俗點說其實就是在估計一個節點的值時的約束條件,如果信息越多或約束條件越多則排除 的節點就越多,估價函數越好或說這個演算法越好。這就是為什麼廣度優先演算法的那麼臭的原因了,誰叫它的h(n)=0,一點啟發信息都沒有。但在游戲開發中由 於實時性的問題,h(n)的信息越多,它的計算量就越大,耗費的時間就越多。就應該適當的減小h(n)的信息,即減小約束條件。但演算法的准確性就差了,這 里就有一個平衡的問題。可難了,這就看你的了! 好了我的話也說得差不多了,我想你肯定是一頭的霧水了,其實這是寫給懂A*演算法的同志看的。哈哈。你還是找一本人工智慧的書仔細看看吧!我這幾百字是不足以將A*演算法講清楚的。只是起到拋磚引玉的作用希望大家熱情參與嗎。

⑵ 深度優先和廣度優先 的區別 ,用法。

1、主體區別

深度優先搜索是一種在開發爬蟲早期使用較多的方法。它的目的是要達到被搜索結構的葉結點(即那些不包含任何超鏈的HTML文件)。

寬度優先搜索演算法(又稱廣度優先搜索)是最簡便的圖的搜索演算法之一,這一演算法也是很多重要的圖的演算法的原型。

2、演算法區別

深度優先搜索是每次從棧中彈出一個元素,搜索所有在它下一級的元素,把這些元素壓入棧中。並把這個元素記為它下一級元素的前驅,找到所要找的元素時結束程序。

廣度優先搜索是每次從隊列的頭部取出一個元素,查看這個元素所有的下一級元素,把它們放到隊列的末尾。並把這個元素記為它下一級元素的前驅,找到所要找的元素時結束程序。

3、用法

廣度優先屬於一種盲目搜尋法,目的是系統地展開並檢查圖中的所有節點,以找尋結果。換句話說,它並不考慮結果的可能位置,徹底地搜索整張圖,直到找到結果為止。

深度優先即在搜索其餘的超鏈結果之前必須先完整地搜索單獨的一條鏈。深度優先搜索沿著HTML文件上的超鏈走到不能再深入為止,然後返回到某一個HTML文件,再繼續選擇該HTML文件中的其他超鏈。

(2)廣度搜索優先演算法擴展閱讀:

實際應用

BFS在求解最短路徑或者最短步數上有很多的應用,應用最多的是在走迷宮上,單獨寫代碼有點泛化,取來自九度1335闖迷宮一例說明,並給出C++/Java的具體實現。

在一個n*n的矩陣里走,從原點(0,0)開始走到終點(n-1,n-1),只能上下左右4個方向走,只能在給定的矩陣里走,求最短步數。n*n是01矩陣,0代表該格子沒有障礙,為1表示有障礙物。

int mazeArr[maxn][maxn]; //表示的是01矩陣int stepArr = {{-1,0},{1,0},{0,-1},{0,1}}; //表示上下左右4個方向,int visit[maxn][maxn]; //表示該點是否被訪問過,防止回溯,回溯很耗時。核心代碼。基本上所有的BFS問題都可以使用類似的代碼來解決。

⑶ 廣度優先搜索是什麼

寬度優先搜索演算法(又稱廣度優先搜索)是最簡便的圖的搜索演算法之一,這一演算法也是很多重要的圖的
演算法的原型。Dijkstra單源最短路徑演算法和Prim最小生成樹演算法都採用了和寬度優先搜索類似的思想。其別名又叫BFS,屬於一種盲目搜尋法,目的是系統地展開並檢查圖中的所有節點,以找尋結果。換句話說,它並不考慮結果的可能位址,徹底地搜索整張圖,直到找到結果為止。BFS並不使用經驗法則演算法。從演算法的觀點,所有因為展開節點而得到的子節點都會被加進一個先進先出的佇列中。一般的實作里,其鄰居節點尚未被檢驗過的節點會被放置在一個被稱為 open 的容器中(例如佇列或是鏈表),而被檢驗過的節點則被放置在被稱為 closed 的容器中。(open-closed表)

⑷ 關於廣度優先搜索演算法

廣度優先搜索演算法,是按層遍歷各個結點,以求出最短或最優的解,
常用於計算路徑的最短距離,和最佳通路。
例如:迷宮的最短路徑計算,推箱子的移動最小步數等小游戲,都是按廣度搜索來進行的。

這個演算法是教程中很經典的,有很多例子和代碼。你可以好好研究!

如下是一段迷宮的最佳路徑求解演算法。
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;

const int dx[4]={-1,0,1,0};
const int dy[4]={0,1,0,-1};
int maze[5][5],prev[5][5];
int que[32];
int qn;

void print(int x,int y)
{
if(prev[x][y]!=-2)
{
print(prev[x][y]>>3,prev[x][y]&7);
}
printf("(%d, %d)\n",x,y);
}

int main()
{
int i,j,cx,cy,nx,ny;
for(i=0;i<5;i++)
{
for(j=0;j<5;j++)
{
scanf("%d",&maze[i][j]);
}
}
memset(prev,-1,sizeof(prev));
prev[0][0]=-2;
que[0]=0;
qn=1;
for(i=0;i<qn;i++)
{
cx=que[i]>>3;
cy=que[i]&7;
for(j=0;j<4;j++)
{
nx=cx+dx[j];
ny=cy+dy[j];
if((nx>=0)&&(nx<5)&&(ny>=0)&&(ny<5)&&(maze[nx][ny]==0)&&(prev[nx][ny]==-1))
{
prev[nx][ny]=(cx<<3)|cy;
que[qn++]=(nx<<3)|ny;
if((nx==4)&&(ny==4))
{
print(nx,ny);
return 0;
}
}
}
}
return 0;
}

⑸ 什麼是廣度優先搜索

寬度優先,搜索演算法是最簡便的圖的搜索演算法之一,這一演算法也是很多重要的圖的演算法的原型,在說單元最短路徑演算法和論文最小生成數算用了和寬度優先搜索類似的思想,他並不考慮結果的可能位置,徹底的搜索整張圖,直到找到結果為止

⑹ 常見的搜索演算法有哪幾種

  • 廣度優先搜索(BFS)

  • 深度優先搜索(DFS)

  • 爬山法(Hill Climbing)

  • 最佳優先演算法(Best-first search strategy)

  • 回溯法 (Backtracking)

  • 分支限界演算法(Branch-and-bound Search Algorithm)

⑺ 廣度優先搜索C語言演算法

它沒有固定的寫法, 但是大框都差不多, 一定要使用隊列, 因為隊列的存在可以維護程序按照廣度優先的方式進行搜索。即層次遍歷

可以給你一份我作過的一個題的代碼,大體上就是這個樣子

/****************************************************\
*
* Title : Rescue
* From : HDU 1242
* AC Time : 2012.01.12
* Type : 廣度優先搜索求最短步數
* Method :從目標結點向回搜索,初始結點有多個
*
\****************************************************/

#include <stdio.h>
#include <string.h>
#define DATASIZE 201
#define QUEUESIZE 65536

typedef struct
{
int x,y;
}CPOINT;

int bfs(char map[][DATASIZE], int n, int m, CPOINT cpa);
int direction[][2] = {{1,0},{-1,0},{0,1},{0,-1}};

int main(void)
{
int m,n,i,j,res;
CPOINT cpa;
char map[DATASIZE][DATASIZE];
freopen("c:\\in.data","r",stdin);
while(scanf("%d%d%*c",&n,&m) != EOF) {
for(i = 0 ; i < n ; i++) {
gets(map[i]);
for(j = 0 ; j < m ; j++) {
if(map[i][j] == 'a') {
cpa.x = i;
cpa.y = j;
}
}
}
res = bfs(map, n, m, cpa);
if(res) {
printf("%d\n",res);
} else {
printf("Poor ANGEL has to stay in the prison all his life.\n");
}
}
return 0;
}

int bfs(char map[][DATASIZE], int n, int m, CPOINT cpa)
{
CPOINT q[QUEUESIZE],u,np;
int vis[DATASIZE][DATASIZE],step[DATASIZE][DATASIZE],i,front,rear,res;
memset(q, 0, sizeof(q));
memset(vis, 0, sizeof(vis));
memset(step, 0, sizeof(step));
front = rear = res = 0;
q[rear++] = cpa;
vis[cpa.x][cpa.y] = 1;
step[cpa.x][cpa.y] = 0;
while(front <= rear) {
u = q[front++];
if(map[u.x][u.y] == 'r') {
res = step[u.x][u.y];
break;
}
for(i = 0 ; i < 4; i++) {
np.x = u.x + direction[i][0];
np.y = u.y + direction[i][1];
if(np.x >= 0 && np.x < n && np.y >= 0 && np.y < m && !vis[np.x][np.y] && map[np.x][np.y] != '#' ) {
vis[np.x][np.y] = 1;
q[rear++] = np;
step[np.x][np.y] = step[u.x][u.y] + 1;
if(map[np.x][np.y] == 'x') {
++step[np.x][np.y];
}
}
}
}
return res;
}

⑻ 詳細介紹廣度優先搜索的實現,原理,c++程序

寬度優先搜索演算法(又稱廣度優先搜索)是最簡便的圖的搜索演算法之一,這一演算法也是很多重要的圖的演算法的原型。Dijkstra單源最短路徑演算法和Prim最小生成樹演算法都採用了和寬度優先搜索類似的思想。其別名又叫BFS,屬於一種盲目搜尋法,目的是系統地展開並檢查圖中的所有節點,以找尋結果。換句話說,它並不考慮結果的可能位址,徹底地搜索整張圖,直到找到結果為止。

已知圖G=(V,E)和一個源頂點s,寬度優先搜索以一種系統的方式探尋G的邊,從而「發現」s所能到達的所有頂點,並計算s到所有這些頂點的距離(最少邊數),該演算法同時能生成一棵根為s且包括所有可達頂點的寬度優先樹。對從s可達的任意頂點v,寬度優先樹中從s到v的路徑對應於圖G中從s到v的最短路徑,即包含最小邊數的路徑。該演算法對有向圖和無向圖同樣適用。
之所以稱之為寬度優先演算法,是因為演算法自始至終一直通過已找到和未找到頂點之間的邊界向外擴展,就是說,演算法首先搜索和s距離為k的所有頂點,然後再去搜索和S距離為k+l的其他頂點。
為了保持搜索的軌跡,寬度優先搜索為每個頂點著色:白色、灰色或黑色。演算法開始前所有頂點都是白色,隨著搜索的進行,各頂點會逐漸變成灰色,然後成為黑色。在搜索中第一次碰到一頂點時,我們說該頂點被發現,此時該頂點變為非白色頂點。因此,灰色和黑色頂點都已被發現,但是,寬度優先搜索演算法對它們加以區分以保證搜索以寬度優先的方式執行。若(u,v)∈E且頂點u為黑色,那麼頂點v要麼是灰色,要麼是黑色,就是說,所有和黑色頂點鄰接的頂點都已被發現。灰色頂點可以與一些白色頂點相鄰接,它們代表著已找到和未找到頂點之間的邊界。
在寬度優先搜索過程中建立了一棵寬度優先樹,起始時只包含根節點,即源頂點s.在掃描已發現頂點u的鄰接表的過程中每發現一個白色頂點v,該頂點v及邊(u,v)就被添加到樹中。在寬度優先樹中,我們稱結點u 是結點v的先輩或父母結點。因為一個結點至多隻能被發現一次,因此它最多隻能有--個父母結點。相對根結點來說祖先和後裔關系的定義和通常一樣:如果u處於樹中從根s到結點v的路徑中,那麼u稱為v的祖先,v是u的後裔。

⑼ 深度優先搜索和廣度優先搜索的區別。 請講的詳細點,最好能用例子,謝謝啦

深度優先搜索所遵循的搜索策略是盡可能「深」地搜索圖。在深度優先搜索中,對於最新發現的結點,如果它還有以此為起點而未搜過的邊,就沿著邊繼續搜索下去。當結點v的所有邊都已被探尋過,搜索將回溯到發現結點v有那條邊的始結點。這一過程一直進行到已發現從源結點可達的所有結點為止。如果還存在未被發現的結點,則選擇其中一個作為源結點並重復以上過程,整個過程反復進行直到所有結點都被發現為止。

深度優先搜索基本演算法如下{遞歸演算法}:
PROCEDURE dfs_try(i);
FOR i:=1 to maxr DO
BEGIN
IF 子結點 mr 符合條件 THEN
BEGIN
產生的子結點mr入棧;
IF 子結點mr是目標結點
THEN 輸出
ELSE dfs_try(i+1);
棧頂元素出棧;
END;
END; 寬度優先搜索演算法(又稱廣度優先搜索演算法)是最簡單的圖的搜索演算法之一,這一演算法也是很多重要的圖的演算法的原型。Dijksta單源最短路徑演算法和Prim最小生成樹演算法都採用了與寬度優先搜索類似的思想。
寬度優先搜索的核心思想是:從初始結點開始,應用算符生成第一層結點,檢查目標結點是否在這些後繼結點中,若沒有,再用產生式規則將所有第一層的結點逐一擴展,得到第二層結點,並逐一檢查第二層結點中是否包含目標結點。若沒有,再用算符逐一擴展第二層所有結點……,如此依次擴展,直到發現目標結點為止。

寬度優先搜索基本演算法如下:
list[1]:=source; {加入初始結點,list為待擴展結點的表}
head:=0; {隊首指針}
foot:=1; {隊尾指針}
REPEAT
head:=head+1;
FOR x:=1 to 規則數 DO
BEGIN
根據規則產生新結點nw;
IF not_appear(nw,list) THEN {若新結點隊列中不存在,則加到隊尾}
BEGIN
foot:=foot+1;
list[foot]:=nw;
list[foot].father:=head;
IF list[foot]=目標結點 THEN 輸出;
END;
END;
UNTIL head>foot; {隊列為空表明再無結點可擴展}
望採納

⑽ 廣度優先法(BFS)演算法

#include<stdio.h>#define MAX 10 int front=-1,rear=-1; struct node { int value; struct node *next; }; typedef struct node node; typedef node *link; struct graph_link { link first; //隊頭指針 link last; //隊尾指針 }; int run[9]={0}; int queue[MAX]; struct graph_link head[9]; void print(struct graph_link temp) { link current=temp.first; while (current!=NULL) { printf("[%d] ",current->value); current=current->next; } putchar('\n'); } void insert(struct graph_link *temp, int x) //鄰接表法存儲頂點 { link new_node; new_node=new node; new_node->value=x; new_node->next=NULL; if (temp->first==NULL) { temp->first=new_node; //新隊頭 temp->last=new_node; //當前尾指向頭 } else { temp->last->next=new_node; //原隊尾的結點接上新結點 temp->last=new_node; //將隊尾結點指向新結點 } } void enqueue(int value) //入隊 { if (rear>=MAX) return; queue[rear++]=value; } int dequeue() //出隊 { if (front==rear) return -1; front++; return queue[front]; } void bfs(int current) //廣度優先 { link tempnode; enqueue(current); //入隊 run[current]=1; printf("[%d] ",current); while (front!=rear) //判斷是否為空隊列 { current=dequeue(); //出隊 tempnode=head[current].first; //與i個頂點的鏈表頭指針 while (tempnode!=NULL) { if (run[tempnode->value]==0) //判斷以i個頂點連接的頂點是否被訪問過 { enqueue(tempnode->value); //入隊 run[tempnode->value]=1; //標記已訪問過 printf("[%d] ",tempnode->value); } tempnode=tempnode->next; } } } void main() { int data[20][2]={{1,2},{2,1},{1,3},{3,1},{2,4},{4,2}, {2,5},{5,2},{3,6},{6,3},{3,7},{7,3}, {4,5},{5,4},{6,7},{7,6},{5,8},{8,5}, {6,8},{8,6}}; int data_num,i,j; for (i=1; i<9; i++) { head[i].first=NULL; head[i].last=NULL; for (j=0; j<20; j++) { if (data[j][0]==i) { data_num=data[j][1]; insert(&head[i],data_num); } } } printf("Imgae Data:\n"); for (i=1; i<9; i++) { printf("peak[%d]=> ",i); link ptr=head[i].first; while (ptr!=NULL) { printf("[%d] ",ptr->value); ptr=ptr->next; } putchar('\n'); } putchar('\n'); bfs(1); putchar('\n'); }

熱點內容
C事件編程 發布:2024-10-05 15:15:43 瀏覽:638
一台伺服器出現兩IP 發布:2024-10-05 15:10:05 瀏覽:924
md5加密演算法c 發布:2024-10-05 15:05:40 瀏覽:760
如何重設控制器密碼 發布:2024-10-05 14:19:13 瀏覽:439
安卓如何遠程簽到 發布:2024-10-05 14:11:11 瀏覽:301
阿里雲伺服器控制面板 發布:2024-10-05 13:57:48 瀏覽:819
涉法涉訴信訪問題意見 發布:2024-10-05 13:56:23 瀏覽:895
華為路由器配置導出的方法有哪些 發布:2024-10-05 13:55:36 瀏覽:163
我的世界好玩伺服器拍視頻 發布:2024-10-05 13:23:19 瀏覽:556
穿越火線掛機腳本 發布:2024-10-05 13:05:44 瀏覽:39