广度优先算法(Breadth-First Search)
同广度优先搜索,又称作宽度优先搜索,或横向优先搜索,简称BFS,是一种图形搜索演算法。简单的说,BFS是从根节点开始,沿着树的宽度遍历树的节点,如果发现目标,则演算终止。广度优先搜索的实现一般采用open-closed表。
做法
BFS是一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止。BFS并不使用经验法则算法。
从算法的观点,所有因为展开节点而得到的子节点都会被加进一个先进先出的伫列中。一般的实作里,其邻居节点尚未被检验过的节点会被放置在一个被称为open的容器中(例如伫列或是链表),而被检验过的节点则被放置在被称为closed的容器中。(open-closed表)
实作方法
- 将根节点放入伫列中。列表内容
- 检验伫列是否为空。
若伫列为空,表示整张图都检查过了——亦即图中没有欲搜寻的目标。结束搜寻并回传“找不到目标”。
若伫列不为空,从伫列中取出第一个节点,并检验它是否为目标。如果找到目标,则结束搜寻并回传结果。否则将它所有尚未检验过的直接子节点加入伫列中。 - 重复步骤2。
列子
代码如下
class Program
{
static note[] que = new note[2500];
static int[,] aa = new int[51, 51];
static int[,] book = new int[51, 51];
static void Main(string[] args)
{
dfs();
Console.ReadKey();
}
public static void dfs()
{
//初始化:一个数组4*3并将数组赋值;亦可以直接输入(需要手动添加,此功能未写)
aa[1, 1] = 0;
aa[1, 2] = 0;
aa[1, 3] = 1;
aa[1, 4] = 0;
aa[2, 1] = 0;
aa[2, 2] = 0;
aa[2, 3] = 0;
aa[2, 4] = 0;
aa[3, 1] = 0;
aa[3, 2] = 0;
aa[3, 3] = 1;
aa[3, 4] = 0;
aa[4, 1] = 0;
aa[4, 2] = 1;
aa[4, 3] = 0;
aa[4, 4] = 0;
aa[5, 1] = 0;
aa[5, 2] = 0;
aa[5, 3] = 0;
aa[5, 4] = 1;
//打印构建的AA数组
for (int i = 1; i <= 5; i++)
{
for (int j = 1; j <= 4; j++)
{
Console.Write(aa[i, j]);
}
Console.WriteLine();
}
//定义一个走的方向数组:右,下,左,上
int[,] next = new int[4, 2]{
{0,1},
{1,0},
{0,-1},
{-1,0}};
int head, tail;
//n为行,m为列的个数;;;在前面的话,数组自定义
int k, n = 5, m = 4, startx = 1, starty = 1, p=4, q=3, tx, ty, flag;
//队列初始化
head = 1;
tail = 1;
//往队列插入迷宫入口坐标
que[tail].x = startx;//开始人的横坐标
que[tail].y = starty;//开始人的纵坐标
que[tail].s = 0;//第一次初始化走的次数
tail++;
book[startx, starty] = 1;
flag = 0;//用来标记是否到达目标点,0表示暂时还没有到达,1表示到达
//当列队不为空的时候循环
while (head < tail)
{
//尝试4个方法
for (k = 0; k <= 3; k++)
{
//计算下一个坐标
tx = que[head].x + next[k, 0];
ty = que[head].y + next[k, 1];
//判断是否越界
if (tx < 1 || ty < 1 || tx > n || ty > m)
{
continue;
}
//判断是否是障碍或者已经在路上
if (aa[tx, ty] == 0 && book[tx, ty] == 0)
{
//把这个点标记为已经走过
//注意每个点只能入队一次,不用把之前的数组还原
book[tx, ty] = 1;
//插入新的点到队列中
que[tail].x = tx;
que[tail].y = ty;
//步数是父亲的步数加+1
que[tail].s = que[head].s + 1;
tail++;//往后移一位
}
//如果已经到达目标点,停止扩展,任务结束,退出循环
if (tx == p && ty == q)
{
flag = 1;
break;
}
}
if (flag == 1)
{
break;
}
head++;
}
//注意tail是指向队列队尾的下一个位置,所以这需要-1
Console.WriteLine(que[tail-1].s);
}
}
struct note
{
public int x;
public int y;
public int s;
}
}