《广度优先搜索》PPT课件.ppt_第1页
《广度优先搜索》PPT课件.ppt_第2页
《广度优先搜索》PPT课件.ppt_第3页
《广度优先搜索》PPT课件.ppt_第4页
《广度优先搜索》PPT课件.ppt_第5页
已阅读5页,还剩41页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第九讲,搜索专题 广度优先(BFS),ACM算法与程序设计,广度优先搜索算法(Breadth -First-Search),也被作宽度优先搜索,或横向优先搜索,简称BFS。BFS是从根节点开始,沿着树的宽度遍历树的节点。如果所有节点均被访问,则算法中止。 广度优先搜索的实现一般采用队列。所有因为展开节点而得到的子节点都会被加进一个先进先出的队列中。 因为所有节点都必须被储存,因此BFS的空间复杂度为 O(|V| + |E|),其中 |V| 是节点的数目,而 |E| 是图中边的数目。 另一种说法称BFS的空间复杂度为 O(BM),其中 B 是最大分支系数,而 M 是树的最长路径长度。由于对空间的大量需求,因此BFS并不适合解非常大的问题。 最差情形下,BFS必须寻找所有到可能节点的所有路径,因此其时间复杂度为 O(|V| + |E|),其中 |V| 是节点的数目,而 |E| 是图中边的数目。,还是以迷宫作为引入。可怜的小老鼠被困在了迷宫里面想要逃出去,但是它不知道到底该怎么走,无论如何还是先选定一个方向走一下再说。 我们对各个方向设定一个优先级,比如我们设定先向上走,再向右走,然后是向下,向左。这个顺序是顺时针排的。不难相当,通过设定一个优先级,我们可以保证在行进过程不会因为随机选择而出现重复情况。 深度优先搜索的思路是找到一条可能的路就一直那么走下去只到走不通为止。这个走不通可能的情况很多,也许是遇到了自然的障碍物,也就是到了死胡同走不下去了,这个时侯只有倒退回去。 但是现实总是充满了陷阱。或许就存在这么一种路,当你辛辛苦苦走了几十步甚至上百步之后才发现那是一个没有未来的选择。我们可以在迷宫中给老鼠设定,上帝也可以在人生里为我们设定。,我们发现固执的小老鼠就是那样子走下去了没有回头。该怎么办才能防止这种情况的发生呢? 对,我们可以叫住他!“喂,那条路不能走了,快回来!”实现起来其实很简单,就是在程序里面加一个深度判断,如果深度达到了一个上界,我们就不继续往下走了,也就是跳出返回。其实这里面要涉及的还有很多,比如迭代加深搜索,A*等。 其实我们可以让那只老鼠变得聪明一点的。假如我们的主角不是一只小老鼠,而是一大群,如果你是老鼠王,你会怎么安排让你的子民们尽快逃生? Thinking。,很简单,让老鼠们分头行动。我们给每一只老鼠都配一个对讲机。从出发点开始分成四个小队,四个小队分别分别负责四个方向,一起出发。每次只能选择没有去过的地方走,没有去过既包括自己没有去过也要包括别的老鼠没有去过,这个我们可以用一个布尔数组在去过的地方标记一下,对于小老鼠来说标记的方式可能会比较特殊。每次到一个位置都可能会有几种不同的走法,那好,我们把当前的这个小队再次划分,每个能走的方向都派一个小小队去。如果没有路可走了,就呆在那儿了。当有一队老鼠或者是一只找到了出口,这位英雄就在对讲机里大吼一声,“哈哈,我找到出口啦,大家到这里来”。,相信大家听问题的时候都注意到了关键词“尽快”。毋庸置疑,老鼠们的做法是肯定能在最快时间内找到出口。接下来我们分析一下其中原因。我们给老鼠能到的每个方块一个距离。初始位置的距离为0,由这个位置出发能到的距离为1,再有这些点能到的不重复的点的距离为2。如此下去,我们就可以给每一个可以到达的位置一个距离值。我们每次所做的都是把一个位置能够拓展的所有位置都拓展出来了,而且也没有走重复的路。可以保证在到达某一个位置的时候我们所走的距离肯定是最短的。 这就是宽度优先搜索。 恭喜老鼠们成功获救!可是现在的问题我们如何在程序里面实现?,BFS的关键:队列,我们要模拟出小老鼠找路的过程就必须把每一个时刻每一队小老鼠所到的位置记录下来。对于我们来说,只有在知道当前老鼠的位置的前提下,我们才能产生下一时间的决策。而为了达到上面所说的拓展最短,我们就必须根据各个位置被到达的先后顺序来拓展。这就要用到队列。 我们把每一个到的位置叫做一个状态。象这样子来构造一个队列。最初队列里只有一个元素,那就是最初的状态。机器开始运行了。第一次我们从队列里面取出第一个元素。然后对它进行拓展,找到所有由它为基础能到的状态,然后我们把这些状态加入到队列里面。这样的操作不断重复,直到我们找到了我们想要的为止。当然操作不止这么简单。我们还必须对过去已经到过的进行标记。,另外,我们可以通过在状态之中添加一些信息而实现更多的东西,比如路径保存,方向记录等。 这样我们就可以实现BFS了。参考结构见下(伪代码),Q0,QNum = 1;/初始队列元素设定,QNum用于存储队列元素个数 I = 0;/指针指向队列首位 While (I QNum) /拓展QI;QNum可能会变化 I+;/指针后移 ,以德国城市为范例的地图, 城市间有数条道路相连接。,从法兰克福开始执行广度优先搜索算法,所产生的广度优先搜索算法树。,1、首先将根节点放入队列中。 2、从队列中取出第一个节点,并检验它是否为目标。 如果找到目标,则结束搜寻并回传结果。 否则将它所有尚未检验过的直接子节点加入队列中。 3、若队列为空,表示整张图都检查过了亦即图中没有欲搜寻的目标。结束搜寻并回传“找不到目标”。 4、重复步骤2。,算法:,void BFS(VLink G, int v) int w; VISIT(v); /*访问顶点v*/ visitedv = 1; /*顶点v对应的访问标记置为1*/ ADDQ(Q,v); while(!QMPTYQ(Q) v = DELQ(Q); /*退出队头元素v*/ w = FIRSTADJ(G,v); /*求v的第1个邻接点。无邻接点则返回-1*/ while(w != -1) if(visitedw = 0) VISIT(w); /*访问顶点v*/ ADDQ(Q,w); /*当前被访问的顶点w进队*/ visitedw = 1; /*顶点w对应的访问标记置为1*/ W = NEXTADJ(G,v); /*求v的下一个邻接点。若无邻接点则返回-1*/ ,总结BFS的思路就是第N步就把N步所能达到的所有状态都找出来。当然这样子是有代价的,那就是可能需要比DFS多很多的空间。不过BFS的优势在于它能够很快的找到最优解。BFS和DFS一样都是很暴力的算法,因为它们都属于盲目搜索算法。,Find The Multiple /JudgeOnline/problem?id=1426,Description Given a positive integer n, write a program to find out a nonzero multiple m of n whose decimal representation contains only the digits 0 and 1. You may assume that n is not greater than 200 and there is a corresponding m containing no more than 100 decimal digits.,Input The input file may contain multiple test cases. Each line contains a value of n (1 = n = 200). A line containing a zero terminates the input. Output For each value of n in the input print a line containing the corresponding value of m. The decimal representation of m must not contain more than 100 digits. If there are multiple solutions for a given value of n, any one of them is acceptable.,Sample Input 2 6 19 0 Sample Output 10 100100100100100100 111111111111111111,这等同于构造一颗二叉树,然后按层次去遍历这颗树;,1,10,11,100,101,110,111,#include using namespace std; int n; long long q9999999; int main() while(scanf(“%d“, ,void BFS() int front,rear; front=rear=0; qrear=1; rear+; long long top; while(rearfront) top = qfront; if( top%n=0 ) break; top *= 10; qrear+=top; qrear+=top+1; front+; printf(“%lldn“,top); ,Prime Path /JudgeOnline/problem?id=3126,Description The ministers of the cabinet were quite upset by the message from the Chief of Security stating that they would all have to change the four-digit room numbers on their offices. It is a matter of security to change such things every now and then, to keep the enemy in the dark. But look, I have chosen my number 1033 for good reasons. I am the Prime minister, you know! I know, so therefore your new number 8179 is also a prime. You will just have to paste four new digits over the four old ones on your office door. No, its not that simple. Suppose that I change the first digit to an 8, then the number will read 8033 which is not a prime! I see, being the prime minister you cannot stand having a non-prime number on your door even for a few seconds. Correct! So I must invent a scheme for going from 1033 to 8179 by a path of prime numbers where only one digit is changed from one prime to the next prime,Now, the minister of finance, who had been eavesdropping, intervened. No unnecessary expenditure, please! I happen to know that the price of a digit is one pound. Hmm, in that case I need a computer program to minimize the cost. You dont know some very cheap software gurus, do you? In fact, I do. You see, there is this programming contest going on. Help the prime minister to find the cheapest prime path between any two given four-digit primes! The first digit must be nonzero, of course. Here is a solution in the case above. 1033 1733 3733 3739 3779 8779 8179,The cost of this solution is 6 pounds. Note that the digit 1 which got pasted over in step 2 can not be reused in the last step a new 1 must be purchased.,Input One line with a positive number: the number of test cases (at most 100). Then for each test case, one line with two numbers separated by a blank. Both numbers are four-digit primes (without leading zeros). Output One line for each case, either with a number stating the minimal cost or containing the word Impossible.,Sample Input 3 1033 8179 1373 8017 1033 1033 Sample Output 6 7 0,首先区分the prime minister 和prime number中的prime的不同意思。 从起始素数开始进行广搜,每轮将所有可行的改变(个位至千位,每个位置进行一次改变)放入搜寻队列一次进行素数判断。 用数组来记载转变路径,每个结点指向其父结点。达到纲标之后向上寻找到先人,即可求出转变了多少次 。,STL:queue,#include 定义一个queue的变量 queue M 查看是否为空队列 M.empty() 是的话返回1,不是返回0; 从已有元素后面增加元素 M.push() 输出现有元素的个数 M.size() 显示第一个元素 M.front() 显示最后一个元素 M.back() 清除第一个元素 M.pop(),#include #include #include using namespace std; int a, b; int p9999 = 0 ; int visited9999 = 0 ; bool isprime(int x) for (int i = 2; i = sqrt(double) x); +i) if (x % i = 0) return false; return true; ,int BFS(int s, int r) queue q; q.push(s); ps = 0; visiteds = 1; while (!q.empty() int temp = q.front(); q.pop(); for (int i = 0; i = 9; i+) int y1 = (temp / 10) * 10 + i; if (isprime(y1) ,int y3 = temp % 100 + (temp / 1000) * 1000 + 100 * i; if (isprime(y3) ,int main() int n; scanf (“%d“, ,Erdos Number /ShowProblem.aspx?ProblemID=1154,Description Paul Erdos(1913-1996) is a legendary mathematician of the 20th century. Famous for his eccentric living style, Erdos was one of the most prolific publishers of papers in mathematical history, having written around 1500 mathematical articles, mostly with co-authors. Erdos spent most of his lifetime traveling between scientific conferences and visiting homes of colleagues all over the world, with most of his belongings in a suitcase. He would typically show up at a colleagues doorstep and announce “my brain is open“, staying long enough to collaborate on a few papers before moving on a few days later. In many cases, he would ask the current collaborator whom he should visit next. Because of his prolific output, friends created the Erdos number as a humorous tribute, which has been a part of the folklore of mathematicians throughout the world for many years. Erdos himself is assigned the Erdos number of 0.,Those who have co-written a paper with Erdos have an Erdos number of 1. In turn, authors who have collaborated with those whose Erdos number is 1(but not with Erdos himself) have an Erdos number of 2. In general, if the lowest Erdos number of the cowriters of an author is S, then his Erdos number is S + 1. A person with no such coauthorship chain connecting to Erdos has an infinite Erdos number.,For example, in the picture above, the lady collaborates with Erdos on one paper, and then with the man on the right on another, so this man is given an Erdos number of 2(assuming he has never collaborated with Erdos himself).,The interesting thing with Erdos number is that about 90% of the worlds active mathematicians have an Erdos number smaller than 8, and many mathematicians have an Erdos number surprisingly smaller than they expect. For example, Andrew Wiles, who have proved the Fermats Last Theorem and whose research area is very different from that of Erdos, has an Erdos number of only 3. All Fields prize winners have an Erdos number at most 5 and all Wolf prize winners Erdos numbers do not exceed 6. In addition, a very large number of non-mathematicians also have finite Erdos numbers. For example, Albert Einstein has an Erdos number of 2 and Bill Gates has an Erdos number of 4.,Your task is, given a list of co-writing activities of authors, to answer a series of queries according to the list, which have the form: “What is the Erdos number of author A?“,Input The first line of the input file is an integer N, number of co-authoring activities. The next N lines each contain two names, separated with spaces, meaning these two authors have co-written a paper. On the next line is an integer M, number of queries. The next M lines each contain the name of an author. Constraints N 50000, M 50000,Notes Names contain letters(A-Z, a-z) and . only and dont contain white spaces. Each name has at most 20 characters. Names are case-sensitive, e.g. Erdos is not the same person as erdos. Authors with the same name should be considered the same person. Paul Erdos himself is represented with exactly the name “Erdos“. The same co-authoring activity is listed at most once. No author will be co-authoring with himself.,Output For each query, output the corresponding authors Erdos number on a line. If the author doesnt have a finite Erdos number, output “infinity“ instead(quotes for clarity only).,Sample Input 7 Erdos Andrew.Odlyzko Andrew.Odlyzko Chris.M.Skinner Chris.M.Skinner Andrew.Wiles Erdos Pavol.Hell Pavol.Hell Xiao.Tie.Deng Xiao.Tie.Deng Chris.Papadimitriou Chris.Papadimitriou Bill.Gates 3 Andrew.Wiles Bill.Gates Albert.Einstein Sample Output 3 4 infinity,以Erdos为起始点直接BFS扩展一棵宽度优先树,两个节点有边当且仅当这两个作者合作。 每个节点在树中到Erdos的距离就是它的Erdos数。 陷阱:输入的合作关系里边可能没有Erdos这个人,但是查询中可能会有Erdos,这时应当输出0而不是infinity。,为了迅速的找到Erdos,可构造经典的字符串Hash函数实现。,unsigned ELFhash(const char *ke

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论