1 00:00:00,000 --> 00:00:00,530 2 00:00:00,530 --> 00:00:02,960 The following content is provided under a Creative 3 00:00:02,960 --> 00:00:04,370 Commons license. 4 00:00:04,370 --> 00:00:07,410 Your support will help MIT OpenCourseWare continue to 5 00:00:07,410 --> 00:00:11,060 offer high-quality educational resources for free. 6 00:00:11,060 --> 00:00:13,960 To make a donation or view additional materials from 7 00:00:13,960 --> 00:00:18,590 hundreds of MIT courses, visit MIT OpenCourseWare at 8 00:00:18,590 --> 00:00:19,840 ocw.mit.edu. 9 00:00:19,840 --> 00:00:25,400 10 00:00:25,400 --> 00:00:25,740 PROFESSOR: Hello. 11 00:00:25,740 --> 00:00:26,990 Welcome. 12 00:00:26,990 --> 00:00:29,190 13 00:00:29,190 --> 00:00:33,440 Today we're going to talk about one last new topic which 14 00:00:33,440 --> 00:00:35,682 has to do with search. 15 00:00:35,682 --> 00:00:38,820 So as you remember, we're working on our last topic. 16 00:00:38,820 --> 00:00:43,490 The last topic was probability and planning. 17 00:00:43,490 --> 00:00:45,130 Last lecture we talked about probability. 18 00:00:45,130 --> 00:00:49,260 19 00:00:49,260 --> 00:00:53,000 Mostly we focused on Bayes' theorem, Bayes' rule. 20 00:00:53,000 --> 00:00:56,400 That was a way of updating our belief about some situation 21 00:00:56,400 --> 00:00:59,350 based on new information. 22 00:00:59,350 --> 00:01:02,580 And this week in Design Lab 12, you'll get a chance to use 23 00:01:02,580 --> 00:01:06,110 that in a robot application. 24 00:01:06,110 --> 00:01:09,300 The idea to Design Lab 12 is going to be that a robot is 25 00:01:09,300 --> 00:01:12,770 pedaling along a corridor with some 26 00:01:12,770 --> 00:01:15,750 obstacles off to its left. 27 00:01:15,750 --> 00:01:20,260 And the idea will be, you don't know where the robot is, 28 00:01:20,260 --> 00:01:24,620 but the robot will be able to estimate where it is by the 29 00:01:24,620 --> 00:01:29,480 signals that it receives from its left-facing sonars. 30 00:01:29,480 --> 00:01:31,450 So this is a very realistic type of 31 00:01:31,450 --> 00:01:33,030 state-estimation problem. 32 00:01:33,030 --> 00:01:37,110 The idea is going to be that at any given time, t, you have 33 00:01:37,110 --> 00:01:41,460 access to your previous belief at time t minus 1. 34 00:01:41,460 --> 00:01:44,940 And you have access to a new observation, which is the 35 00:01:44,940 --> 00:01:46,890 sonar to your left. 36 00:01:46,890 --> 00:01:49,840 And based on those two bits of information, you will update 37 00:01:49,840 --> 00:01:50,430 your belief. 38 00:01:50,430 --> 00:01:53,110 Which means that when you start out you'll have no idea 39 00:01:53,110 --> 00:01:55,200 where you are, but that situation should 40 00:01:55,200 --> 00:01:58,010 improve with time. 41 00:01:58,010 --> 00:01:58,075 Ok. 42 00:01:58,075 --> 00:02:01,900 So that's what we're going to do in Design Lab 12. 43 00:02:01,900 --> 00:02:04,380 Today we're going to blast ahead and think about the 44 00:02:04,380 --> 00:02:08,410 other important topic, which is search. 45 00:02:08,410 --> 00:02:10,370 So we're going to think about planning. 46 00:02:10,370 --> 00:02:11,430 We're going to be planning ahead. 47 00:02:11,430 --> 00:02:13,520 We're not going to just react to the situation 48 00:02:13,520 --> 00:02:14,260 that's given to us. 49 00:02:14,260 --> 00:02:16,840 We're going to try to figure out what's the right thing to 50 00:02:16,840 --> 00:02:17,890 do in the future. 51 00:02:17,890 --> 00:02:20,550 And to do that, we're going to think about all the things we 52 00:02:20,550 --> 00:02:24,540 could possibly do, search through that space, and figure 53 00:02:24,540 --> 00:02:27,790 out the one that's, quote, "best." And we'll have to 54 00:02:27,790 --> 00:02:30,490 define "best" somehow. 55 00:02:30,490 --> 00:02:34,420 Just to get going, I want to show you a very simple kind of 56 00:02:34,420 --> 00:02:37,290 a search problem. 57 00:02:37,290 --> 00:02:40,930 This is called the eight puzzle. 58 00:02:40,930 --> 00:02:45,110 The idea is to make a plan to go from this configuration, 59 00:02:45,110 --> 00:02:48,430 which we'll call the state, to this configuration, which 60 00:02:48,430 --> 00:02:51,790 we'll call the goal state. 61 00:02:51,790 --> 00:02:57,180 And on each move, you get to move one of the tiles into the 62 00:02:57,180 --> 00:02:57,890 free space. 63 00:02:57,890 --> 00:03:00,660 So I could move the 8 to the right or the 6 down. 64 00:03:00,660 --> 00:03:04,070 Those are the only two things I could do in the start state. 65 00:03:04,070 --> 00:03:05,760 So I have to make up my mind which of those I 66 00:03:05,760 --> 00:03:07,340 would like to do. 67 00:03:07,340 --> 00:03:09,750 And I would like to believe that ultimately, after a 68 00:03:09,750 --> 00:03:12,780 series of moves, I'm going to be able to control this state 69 00:03:12,780 --> 00:03:15,680 into that state. 70 00:03:15,680 --> 00:03:18,240 And you can imagine guessing. 71 00:03:18,240 --> 00:03:22,150 And we'll estimate in a moment how big is the guess space. 72 00:03:22,150 --> 00:03:24,360 I mean, if the guess space only had like four elements in 73 00:03:24,360 --> 00:03:27,250 it, guessing's a fine strategy. 74 00:03:27,250 --> 00:03:31,510 If the guess space has a lot more elements than that, 75 00:03:31,510 --> 00:03:34,860 guessing's probably not a good idea. 76 00:03:34,860 --> 00:03:38,720 So I previously ran our search algorithms, the ones that 77 00:03:38,720 --> 00:03:41,320 we'll develop during lecture, on this problem. 78 00:03:41,320 --> 00:03:43,070 And here's the solution that our search 79 00:03:43,070 --> 00:03:44,320 algorithm came up with. 80 00:03:44,320 --> 00:03:51,300 81 00:03:51,300 --> 00:03:55,520 It's not exactly what you might do the first time you 82 00:03:55,520 --> 00:03:56,770 touched it. 83 00:03:56,770 --> 00:03:59,740 84 00:03:59,740 --> 00:04:02,150 OK, I made it. 85 00:04:02,150 --> 00:04:05,430 If you were counting, I made 22 moves. 86 00:04:05,430 --> 00:04:08,200 87 00:04:08,200 --> 00:04:12,180 The question is, how difficult was that problem and how good 88 00:04:12,180 --> 00:04:14,190 was that solution? 89 00:04:14,190 --> 00:04:16,130 Was that a good solution or a bad solution? 90 00:04:16,130 --> 00:04:18,320 Is there a better solution? 91 00:04:18,320 --> 00:04:20,519 How much work did I have to do in order to 92 00:04:20,519 --> 00:04:22,420 calculate that solution? 93 00:04:22,420 --> 00:04:23,850 To get a handle on that, let's start by 94 00:04:23,850 --> 00:04:25,450 asking a simple question. 95 00:04:25,450 --> 00:04:28,610 How many configurations are there? 96 00:04:28,610 --> 00:04:30,190 I got there in 22. 97 00:04:30,190 --> 00:04:33,190 What was the space of things I had to look through? 98 00:04:33,190 --> 00:04:37,470 How many different board configurations exist? 99 00:04:37,470 --> 00:04:38,880 So think about that for 20 seconds. 100 00:04:38,880 --> 00:04:39,720 Talk to your neighbor. 101 00:04:39,720 --> 00:04:43,640 And figure out whether it is 8-squared, 9-squared, 102 00:04:43,640 --> 00:04:46,390 8-factorial, 9-factorial, or none of those. 103 00:04:46,390 --> 00:05:46,270 104 00:05:46,270 --> 00:05:49,530 So how many bar configurations do you see? 105 00:05:49,530 --> 00:05:51,730 Raise your hand, show me a number of fingers, so I can 106 00:05:51,730 --> 00:05:55,410 figure out roughly how people were-- that's excellent. 107 00:05:55,410 --> 00:05:58,560 Very good participation, and nearly 100% correct. 108 00:05:58,560 --> 00:06:00,980 The answer is number (4). 109 00:06:00,980 --> 00:06:01,960 You can think about this. 110 00:06:01,960 --> 00:06:03,880 What if you took all the tiles out and threw them on the 111 00:06:03,880 --> 00:06:07,470 floor, and then put them in one at a time? 112 00:06:07,470 --> 00:06:09,710 Well, you would have 9 possibilities for where you 113 00:06:09,710 --> 00:06:11,390 wanted to put the first one. 114 00:06:11,390 --> 00:06:13,460 Then you would have 8 possibilities for where you 115 00:06:13,460 --> 00:06:15,110 wanted to put the second one. 116 00:06:15,110 --> 00:06:17,300 Then you'd have 7 possibilities for where you 117 00:06:17,300 --> 00:06:19,830 put the third one, et cetera, et cetera. 118 00:06:19,830 --> 00:06:22,450 Even though the space doesn't have a number on it, it still 119 00:06:22,450 --> 00:06:25,390 sort of counts. 120 00:06:25,390 --> 00:06:27,550 And so you end up with 9-factorial. 121 00:06:27,550 --> 00:06:32,130 And the point is, 9-factorial is a big number. 122 00:06:32,130 --> 00:06:37,050 9-factorial is 362880. 123 00:06:37,050 --> 00:06:41,550 So if you thought about simply guessing, that's probably not 124 00:06:41,550 --> 00:06:44,580 going to work all that well, right? 125 00:06:44,580 --> 00:06:48,390 Even if you guessed, you have on each-- 126 00:06:48,390 --> 00:06:53,830 there's a third of a million different configurations that 127 00:06:53,830 --> 00:06:56,260 you have to look at. 128 00:06:56,260 --> 00:06:59,370 And that's if you didn't lose track of things. 129 00:06:59,370 --> 00:07:00,280 If you lost track of-- 130 00:07:00,280 --> 00:07:00,780 Oh, my. 131 00:07:00,780 --> 00:07:02,080 It's coming up-- 132 00:07:02,080 --> 00:07:03,460 almost, anyway. 133 00:07:03,460 --> 00:07:07,040 It looks like it's chopped off at the top. 134 00:07:07,040 --> 00:07:09,130 So ignore that for now. 135 00:07:09,130 --> 00:07:12,100 Look over here. 136 00:07:12,100 --> 00:07:20,270 So even if you didn't confuse yourself, there's a space of a 137 00:07:20,270 --> 00:07:22,760 third of a million things to look at. 138 00:07:22,760 --> 00:07:25,720 And if you confused yourself, there's even more. 139 00:07:25,720 --> 00:07:29,930 So it's not a huge problem by computer science standards. 140 00:07:29,930 --> 00:07:31,690 But it's certainly not a trivial problem. 141 00:07:31,690 --> 00:07:36,190 It's not something that you can just guess and get right. 142 00:07:36,190 --> 00:07:41,790 So what we want to do today is figure out an algorithm for 143 00:07:41,790 --> 00:07:43,920 conducting a search like that. 144 00:07:43,920 --> 00:07:47,520 We'd like to figure out the algorithm, analyze how well it 145 00:07:47,520 --> 00:07:52,530 works, optimize it, and try to find out a way to find the 146 00:07:52,530 --> 00:07:55,900 best solution, where "best" for this particular problem 147 00:07:55,900 --> 00:07:59,090 would mean minimum path length. 148 00:07:59,090 --> 00:08:01,720 So figure out the best solution by considering as few 149 00:08:01,720 --> 00:08:02,810 cases as possible. 150 00:08:02,810 --> 00:08:04,850 Obviously, if you enumerate all the 151 00:08:04,850 --> 00:08:08,120 cases, that should work. 152 00:08:08,120 --> 00:08:10,190 The problem is, it will be interesting to solve problems 153 00:08:10,190 --> 00:08:12,110 where that enumeration is quite large. 154 00:08:12,110 --> 00:08:15,690 Even here, the enumeration is quite large. 155 00:08:15,690 --> 00:08:17,670 So let's think about the algorithm. 156 00:08:17,670 --> 00:08:19,690 And I'll think about the algorithm by way of an even 157 00:08:19,690 --> 00:08:21,790 simpler, more finite problem. 158 00:08:21,790 --> 00:08:25,480 What if I thought about a grid of possible locations 159 00:08:25,480 --> 00:08:27,650 where I could be. 160 00:08:27,650 --> 00:08:28,800 Maybe this is the intersections 161 00:08:28,800 --> 00:08:31,640 of streets in Manhattan. 162 00:08:31,640 --> 00:08:35,130 I want to go from point A to point I. What's the 163 00:08:35,130 --> 00:08:36,260 minimum-distance path? 164 00:08:36,260 --> 00:08:40,100 I hope you probably can all figure that out. 165 00:08:40,100 --> 00:08:41,640 What I want to do is write an algorithm that 166 00:08:41,640 --> 00:08:42,919 can figure that out. 167 00:08:42,919 --> 00:08:45,070 And then if we write the algorithm well, we'll be able 168 00:08:45,070 --> 00:08:47,120 to use it for the tile problem, which is not quite so 169 00:08:47,120 --> 00:08:49,130 easy to do. 170 00:08:49,130 --> 00:08:52,430 The way we're going to think about doing that is to 171 00:08:52,430 --> 00:08:55,270 organize all of our possible paths through 172 00:08:55,270 --> 00:09:00,140 that maze, in a tree. 173 00:09:00,140 --> 00:09:03,640 So if I started at A, I have a decision to make. 174 00:09:03,640 --> 00:09:07,780 I could either go to B or D. 175 00:09:07,780 --> 00:09:16,140 Then if I went to, say, B, I could either then go to A or C 176 00:09:16,140 --> 00:09:18,810 or E. I've organized them alphabetically for no 177 00:09:18,810 --> 00:09:20,310 particularly good reason. 178 00:09:20,310 --> 00:09:20,640 Just-- 179 00:09:20,640 --> 00:09:24,010 I needed some order. 180 00:09:24,010 --> 00:09:34,260 Then if I went from A to B to A, say, then I could either go 181 00:09:34,260 --> 00:09:37,710 from A to B or D. That's illustrated here. 182 00:09:37,710 --> 00:09:40,260 So the idea then-- ah, it works. 183 00:09:40,260 --> 00:09:42,700 So now it looks like they're all three working. 184 00:09:42,700 --> 00:09:46,140 So the idea is, think about the original problem. 185 00:09:46,140 --> 00:09:49,440 The original problem is find the shortest path 186 00:09:49,440 --> 00:09:51,950 through some grid. 187 00:09:51,950 --> 00:09:55,360 I want to go from A to I. And I'll think about all the 188 00:09:55,360 --> 00:09:58,650 possible paths on a tree. 189 00:09:58,650 --> 00:10:03,020 Then the problem is that for the kinds of problems we're 190 00:10:03,020 --> 00:10:08,350 going to look at, that tree could be infinite in length. 191 00:10:08,350 --> 00:10:09,530 Oh, that's a bummer. 192 00:10:09,530 --> 00:10:12,440 That means that the strategy of building the tree and then 193 00:10:12,440 --> 00:10:14,910 searching it is probably not a good strategy. 194 00:10:14,910 --> 00:10:17,890 So what we'll do instead is, we'll try to write the 195 00:10:17,890 --> 00:10:22,650 algorithm in such a way that we construct the tree and 196 00:10:22,650 --> 00:10:26,760 search for the best solution all in one pass. 197 00:10:26,760 --> 00:10:29,650 Then hopefully, if we find a solution in some finite number 198 00:10:29,650 --> 00:10:33,560 of steps, we'll only have built part of the tree. 199 00:10:33,560 --> 00:10:37,650 But we'll have built the part that has the answer. 200 00:10:37,650 --> 00:10:41,200 The idea, then, is going to be, think about what is the 201 00:10:41,200 --> 00:10:44,130 path we want to take, by thinking about the tree of all 202 00:10:44,130 --> 00:10:46,100 possible paths. 203 00:10:46,100 --> 00:10:51,270 But what we want to do is write code that will construct 204 00:10:51,270 --> 00:10:57,150 the tree on the fly, while it's considering how good were 205 00:10:57,150 --> 00:11:00,400 all the different nodes. 206 00:11:00,400 --> 00:11:00,460 Ok. 207 00:11:00,460 --> 00:11:02,820 So how are we going to do that? 208 00:11:02,820 --> 00:11:05,070 We'll be working in Python, not surprisingly. 209 00:11:05,070 --> 00:11:07,510 We'll represent all the possible locations. 210 00:11:07,510 --> 00:11:10,420 We'll call those states. 211 00:11:10,420 --> 00:11:14,160 So the problem will have states A, B, C, D, and we'll 212 00:11:14,160 --> 00:11:17,240 just represent those by strings. 213 00:11:17,240 --> 00:11:19,090 That makes it flexible. 214 00:11:19,090 --> 00:11:21,480 That makes it arbitrary. 215 00:11:21,480 --> 00:11:24,440 Then we'll think about transitions, not by 216 00:11:24,440 --> 00:11:25,570 enumerating them. 217 00:11:25,570 --> 00:11:27,830 Remember, we don't want to enumerate them, because there 218 00:11:27,830 --> 00:11:29,050 could be infinitely many of them. 219 00:11:29,050 --> 00:11:31,050 So how's the other way we could do it? 220 00:11:31,050 --> 00:11:33,730 Well, we'll embody that information in a program. 221 00:11:33,730 --> 00:11:38,780 We'll write a procedure called "successor" that will, given 222 00:11:38,780 --> 00:11:45,730 the current state and action, figure out the next state. 223 00:11:45,730 --> 00:11:48,870 So that's a way that we can incrementally build the tree. 224 00:11:48,870 --> 00:11:58,383 So imagine here, if I started in A and I executed action 0 225 00:11:58,383 --> 00:12:02,420 or 1, I would end up in B or D, respectively. 226 00:12:02,420 --> 00:12:06,630 So I tell you the current state and the current action, 227 00:12:06,630 --> 00:12:09,410 and the successor program then will return 228 00:12:09,410 --> 00:12:12,420 to you the new state. 229 00:12:12,420 --> 00:12:17,730 That's all we need to construct the tree on the fly. 230 00:12:17,730 --> 00:12:20,710 Then, to specify the particular problem with 231 00:12:20,710 --> 00:12:23,400 interest, I have to tell you where you start. 232 00:12:23,400 --> 00:12:27,530 So I have to define initial state. 233 00:12:27,530 --> 00:12:30,250 And I have to tell you where to end. 234 00:12:30,250 --> 00:12:33,000 I could just tell you the final state. 235 00:12:33,000 --> 00:12:35,310 But in some of the problems of the type that we will want to 236 00:12:35,310 --> 00:12:40,250 do, there could be multiple acceptable answers. 237 00:12:40,250 --> 00:12:42,630 So I don't want to just give you the final state. 238 00:12:42,630 --> 00:12:44,750 I'll give you a test. 239 00:12:44,750 --> 00:12:48,550 I'll give you another procedure, called "goalTest." 240 00:12:48,550 --> 00:12:51,070 And that goal test, when passed an input which is a 241 00:12:51,070 --> 00:12:54,410 state, will tell you whether or not you reached the goal. 242 00:12:54,410 --> 00:12:57,400 That way, for example, all the even-numbered squares could 243 00:12:57,400 --> 00:13:00,000 satisfy the goal, if that were the problem of interest. 244 00:13:00,000 --> 00:13:04,560 Or all the states on the right could satisfy the goal. 245 00:13:04,560 --> 00:13:06,520 It's just a little bit more flexible. 246 00:13:06,520 --> 00:13:12,620 The idea, then, is that in order to represent that tree, 247 00:13:12,620 --> 00:13:18,050 we'll do it by specifying a procedure called successor and 248 00:13:18,050 --> 00:13:22,940 specifying the start state and the goal test. 249 00:13:22,940 --> 00:13:27,670 So here's how I might set that up for the simple Manhattan 250 00:13:27,670 --> 00:13:30,720 problem that I showed-- that I started with. 251 00:13:30,720 --> 00:13:34,550 So I want ultimately to have something called successor 252 00:13:34,550 --> 00:13:36,530 that eats a state and an action. 253 00:13:36,530 --> 00:13:39,560 254 00:13:39,560 --> 00:13:46,370 I've built the structure of Manhattan into a dictionary. 255 00:13:46,370 --> 00:13:50,690 The dictionary lists for every state-- 256 00:13:50,690 --> 00:13:55,940 A, B, C, D, E, F, G, H, I-- 257 00:13:55,940 --> 00:14:00,840 for every state, it associates that state with a list of 258 00:14:00,840 --> 00:14:02,490 possible next states. 259 00:14:02,490 --> 00:14:06,780 So if I'm in A, I could next be in B or D. I could next be 260 00:14:06,780 --> 00:14:10,330 in B or D. 261 00:14:10,330 --> 00:14:13,220 I've organized these arbitrarily in alphabetical 262 00:14:13,220 --> 00:14:15,220 order so I can remember what's going on. 263 00:14:15,220 --> 00:14:17,970 So the next states are all in alphabetical order. 264 00:14:17,970 --> 00:14:21,760 The number of next states depends on the state. 265 00:14:21,760 --> 00:14:23,530 I'm not going to worry about that too much. 266 00:14:23,530 --> 00:14:28,170 I'm just going to specify the action as an integer-- 267 00:14:28,170 --> 00:14:29,290 0,1,2,3 -- 268 00:14:29,290 --> 00:14:31,590 however many I need. 269 00:14:31,590 --> 00:14:35,000 So the possible actions are taken from that list. 270 00:14:35,000 --> 00:14:38,290 The possible action might be do action 0, do action 271 00:14:38,290 --> 00:14:39,840 1, do action 2. 272 00:14:39,840 --> 00:14:47,500 So if I did action 2 starting on state E, I would go to-- 273 00:14:47,500 --> 00:14:48,750 so action started at 0 -- 274 00:14:48,750 --> 00:14:50,940 so 0, 1, 2 -- 275 00:14:50,940 --> 00:14:54,330 I would go to state F. OK? 276 00:14:54,330 --> 00:14:56,800 Is that all clear? 277 00:14:56,800 --> 00:15:00,520 The initial state is A, and the goal state is, return S 278 00:15:00,520 --> 00:15:04,130 equal to I. So if S is equal to I, it returns True. 279 00:15:04,130 --> 00:15:06,140 If S is not equal to I, it returns False. 280 00:15:06,140 --> 00:15:10,010 281 00:15:10,010 --> 00:15:11,430 I'm not quite done. 282 00:15:11,430 --> 00:15:13,850 That's enough to completely specify the tree, but now I 283 00:15:13,850 --> 00:15:15,280 have to build the tree in Python. 284 00:15:15,280 --> 00:15:18,050 285 00:15:18,050 --> 00:15:23,020 Not surprisingly, from our object-oriented past, we will 286 00:15:23,020 --> 00:15:29,000 use an object-oriented representation for that tree. 287 00:15:29,000 --> 00:15:33,480 So we'll specify every node in the tree as an instance of the 288 00:15:33,480 --> 00:15:36,230 class SearchNode. 289 00:15:36,230 --> 00:15:37,870 SearchNode is trivial. 290 00:15:37,870 --> 00:15:40,670 SearchNode simply knows, what was the 291 00:15:40,670 --> 00:15:42,140 action that got me here? 292 00:15:42,140 --> 00:15:43,220 Who's my parent? 293 00:15:43,220 --> 00:15:45,420 And what's my current state? 294 00:15:45,420 --> 00:15:49,090 So when you make a new node, you have to tell the 295 00:15:49,090 --> 00:15:52,550 constructor those three things. 296 00:15:52,550 --> 00:15:54,290 What was the action that got me here? 297 00:15:54,290 --> 00:15:55,230 What's my current state? 298 00:15:55,230 --> 00:15:56,480 And who is my parent? 299 00:15:56,480 --> 00:15:58,930 300 00:15:58,930 --> 00:16:03,280 Knowing the node, you're supposed to know the entire 301 00:16:03,280 --> 00:16:05,140 path that got you here. 302 00:16:05,140 --> 00:16:10,420 So we'll also add a method which reports the path. 303 00:16:10,420 --> 00:16:15,750 So if I happen to be in node E, my path ought to be I 304 00:16:15,750 --> 00:16:20,500 started in A, I took action 0 and got to B, and then I took 305 00:16:20,500 --> 00:16:25,360 action 2 and got to E. This subroutine is 306 00:16:25,360 --> 00:16:28,130 intended to do that. 307 00:16:28,130 --> 00:16:31,230 If my parent is "none," which will happen for the initial 308 00:16:31,230 --> 00:16:41,060 state, simply report that the path to me is none, A. 309 00:16:41,060 --> 00:16:47,460 However, if I'm anybody other than the initial node, if I'm 310 00:16:47,460 --> 00:16:52,340 other than the initial node, then figure out the 311 00:16:52,340 --> 00:16:58,280 description of the path to my parent, and add the action 312 00:16:58,280 --> 00:17:01,980 that got me here, and my state. 313 00:17:01,980 --> 00:17:04,790 So that's what this is. 314 00:17:04,790 --> 00:17:06,190 OK, so what are we doing? 315 00:17:06,190 --> 00:17:09,849 We specify a problem by telling you the successor 316 00:17:09,849 --> 00:17:14,180 function, the start state, and the goal test. 317 00:17:14,180 --> 00:17:20,020 Then we provide a class by which you can build nodes to 318 00:17:20,020 --> 00:17:26,010 construct, on the fly, the search tree. 319 00:17:26,010 --> 00:17:27,900 Now we're ready to write the algorithm. 320 00:17:27,900 --> 00:17:30,530 Here's the pseudocode for the algorithm. 321 00:17:30,530 --> 00:17:31,150 What do we do? 322 00:17:31,150 --> 00:17:32,870 We initialize-- 323 00:17:32,870 --> 00:17:34,930 so we're going to be doing a s-- oh, 324 00:17:34,930 --> 00:17:36,270 this is very confusing. 325 00:17:36,270 --> 00:17:37,740 I'm trying to solve a search problem. 326 00:17:37,740 --> 00:17:40,500 327 00:17:40,500 --> 00:17:42,210 To solve the search problem, I'm going to 328 00:17:42,210 --> 00:17:45,610 search through the tree. 329 00:17:45,610 --> 00:17:48,560 So I'm going to think about the state of my search through 330 00:17:48,560 --> 00:17:53,870 the tree by way of something we'll call the agenda. 331 00:17:53,870 --> 00:17:55,330 Very jargon-y word. 332 00:17:55,330 --> 00:17:56,700 I completely apologize for it. 333 00:17:56,700 --> 00:17:58,050 I didn't invent it. 334 00:17:58,050 --> 00:17:59,630 It's what everybody calls it. 335 00:17:59,630 --> 00:18:00,880 Sorry. 336 00:18:00,880 --> 00:18:05,870 337 00:18:05,870 --> 00:18:10,700 The agenda is the set of nodes that I'm 338 00:18:10,700 --> 00:18:12,920 currently thinking about. 339 00:18:12,920 --> 00:18:16,140 So I'll initialize that to contain the starting node. 340 00:18:16,140 --> 00:18:18,990 341 00:18:18,990 --> 00:18:23,640 Then I'll just systematically keep repeating the same thing 342 00:18:23,640 --> 00:18:24,740 over and over again. 343 00:18:24,740 --> 00:18:28,450 Take one of the nodes out of the agenda, think about it, 344 00:18:28,450 --> 00:18:32,960 replace that node by its children. 345 00:18:32,960 --> 00:18:36,740 While I'm doing that, two things are supposed to happen. 346 00:18:36,740 --> 00:18:40,180 I'm supposed to construct the search tree. 347 00:18:40,180 --> 00:18:42,810 But I'm also going to be looking over my shoulder to 348 00:18:42,810 --> 00:18:49,970 see if I just constructed a child who is the answer. 349 00:18:49,970 --> 00:18:51,950 Because if I just constructed the answer, I'm done. 350 00:18:51,950 --> 00:18:54,420 Ok. 351 00:18:54,420 --> 00:18:57,150 So initialize the agenda to contain just 352 00:18:57,150 --> 00:18:58,160 the starting node. 353 00:18:58,160 --> 00:18:59,670 Then repeat the following steps. 354 00:18:59,670 --> 00:19:01,680 Remove one node from the agenda. 355 00:19:01,680 --> 00:19:03,830 Add that node's children to the agenda. 356 00:19:03,830 --> 00:19:07,010 And keep going until one of two things happens. 357 00:19:07,010 --> 00:19:08,510 Either you found it-- 358 00:19:08,510 --> 00:19:13,210 goal test returned True-- 359 00:19:13,210 --> 00:19:16,310 or the agenda got empty, in which case there 360 00:19:16,310 --> 00:19:19,310 must not be a solution. 361 00:19:19,310 --> 00:19:21,480 If I've removed all of my options and still haven't 362 00:19:21,480 --> 00:19:23,170 found anything, then there's no solution. 363 00:19:23,170 --> 00:19:25,800 364 00:19:25,800 --> 00:19:25,900 Ok. 365 00:19:25,900 --> 00:19:27,330 So what's the program look like? 366 00:19:27,330 --> 00:19:30,150 It's actually remarkably simple, especially when you 367 00:19:30,150 --> 00:19:31,780 think about just how hard the problem is. 368 00:19:31,780 --> 00:19:37,450 Imagine if you wanted to do that tiles problem with a very 369 00:19:37,450 --> 00:19:41,290 simple-minded "if this then this, if this then this." 370 00:19:41,290 --> 00:19:44,420 We're talking about a third of a million ifs, right? 371 00:19:44,420 --> 00:19:47,540 That's probably not the right way to do it. 372 00:19:47,540 --> 00:19:49,640 This program is going to end up being about this long. 373 00:19:49,640 --> 00:19:51,460 It'll fit on this page. 374 00:19:51,460 --> 00:19:53,600 And it's going to be able to handle that case, or even 375 00:19:53,600 --> 00:19:56,580 harder cases. 376 00:19:56,580 --> 00:19:57,800 Define the search procedure. 377 00:19:57,800 --> 00:19:59,670 The search procedure is something that's going to take 378 00:19:59,670 --> 00:20:02,870 the initial state, the goal test, the possible actions, 379 00:20:02,870 --> 00:20:06,320 and the successor sub routine, the successor procedure. 380 00:20:06,320 --> 00:20:09,700 That's everything you need to specify the problem. 381 00:20:09,700 --> 00:20:12,818 And it's going to return to me the optimal path. 382 00:20:12,818 --> 00:20:15,520 383 00:20:15,520 --> 00:20:17,310 First, step (1). 384 00:20:17,310 --> 00:20:21,320 Initialize the agenda to contain the start node. 385 00:20:21,320 --> 00:20:22,440 I want to put the start node in. 386 00:20:22,440 --> 00:20:24,420 Well, there's a chance-- 387 00:20:24,420 --> 00:20:26,350 I want this procedure to be general purpose-- 388 00:20:26,350 --> 00:20:30,900 there's a chance that that start node is the answer. 389 00:20:30,900 --> 00:20:32,150 So take care of that first. 390 00:20:32,150 --> 00:20:34,630 391 00:20:34,630 --> 00:20:38,460 If you're already there, return the answer. 392 00:20:38,460 --> 00:20:41,450 The path to the answer is me. 393 00:20:41,450 --> 00:20:44,080 394 00:20:44,080 --> 00:20:46,340 I'm trying to create the agenda. 395 00:20:46,340 --> 00:20:48,330 I'm trying to put the first node into the agenda. 396 00:20:48,330 --> 00:20:51,040 There's a chance that first node is the answer. 397 00:20:51,040 --> 00:20:53,760 If that first node's the answer, return the path to me. 398 00:20:53,760 --> 00:20:55,710 Which is, take no action. 399 00:20:55,710 --> 00:20:56,960 You're here. 400 00:20:56,960 --> 00:20:59,010 401 00:20:59,010 --> 00:21:00,560 But that's not likely to be the case for the kinds of 402 00:21:00,560 --> 00:21:04,430 questions we ask, in which case we will create a list 403 00:21:04,430 --> 00:21:07,560 that contains one node, which is the node that represents 404 00:21:07,560 --> 00:21:08,810 the start node. 405 00:21:08,810 --> 00:21:12,780 406 00:21:12,780 --> 00:21:16,060 Then, repeat 'remove a node' -- which 407 00:21:16,060 --> 00:21:17,890 we'll call the parent-- 408 00:21:17,890 --> 00:21:19,900 from the agenda. 409 00:21:19,900 --> 00:21:21,670 And substitute -- 410 00:21:21,670 --> 00:21:26,590 replace that node that we pulled out of the agenda -- 411 00:21:26,590 --> 00:21:29,920 replace that with the children. 412 00:21:29,920 --> 00:21:32,180 While not empty of agenda-- 413 00:21:32,180 --> 00:21:33,940 empty is some kind of a pseudo-routine that I'm going 414 00:21:33,940 --> 00:21:35,690 to fill in, in a minute-- 415 00:21:35,690 --> 00:21:40,600 while the agenda is not empty, get an element out of the 416 00:21:40,600 --> 00:21:42,110 agenda, which we'll call the parent. 417 00:21:42,110 --> 00:21:45,320 418 00:21:45,320 --> 00:21:48,890 Then I want to think about all the children. 419 00:21:48,890 --> 00:21:51,190 Well, there's a list of possible actions. 420 00:21:51,190 --> 00:21:54,620 So for a in actions, do the following things. 421 00:21:54,620 --> 00:21:57,370 Each parent can have multiple children, one for every 422 00:21:57,370 --> 00:21:58,720 possible action. 423 00:21:58,720 --> 00:22:03,840 So for a in action, figure out what would be the new state. 424 00:22:03,840 --> 00:22:10,370 The new state is just the successor of the parent state. 425 00:22:10,370 --> 00:22:14,240 Remember, the parent is a node, right? 426 00:22:14,240 --> 00:22:15,330 The parent is a node. 427 00:22:15,330 --> 00:22:17,890 We're constructing nodes in the search tree. 428 00:22:17,890 --> 00:22:21,080 But nodes know their state. 429 00:22:21,080 --> 00:22:24,790 So figure out the new state, which is the successor of my 430 00:22:24,790 --> 00:22:27,720 parent, the guy that I pulled out of the agenda. 431 00:22:27,720 --> 00:22:30,290 432 00:22:30,290 --> 00:22:36,300 Make a new node, which corresponds to this child. 433 00:22:36,300 --> 00:22:40,070 Then ask the question, did the new state 434 00:22:40,070 --> 00:22:42,500 satisfy the goal test? 435 00:22:42,500 --> 00:22:45,760 If it did, the answer is the path to the new node. 436 00:22:45,760 --> 00:22:49,410 437 00:22:49,410 --> 00:22:49,585 Ok. 438 00:22:49,585 --> 00:22:53,270 So create a new state, which is the successor of the parent 439 00:22:53,270 --> 00:22:57,070 under the given action A. Create a new node. 440 00:22:57,070 --> 00:22:58,320 See if it's the end. 441 00:22:58,320 --> 00:23:01,410 If it is, just return, I'm done. 442 00:23:01,410 --> 00:23:04,100 Return from search. 443 00:23:04,100 --> 00:23:08,230 Otherwise, add it-- again, one of these pseudo-procedures. 444 00:23:08,230 --> 00:23:10,890 445 00:23:10,890 --> 00:23:12,560 We'll fill that in, in a minute-- 446 00:23:12,560 --> 00:23:14,360 add the new node into the agenda. 447 00:23:14,360 --> 00:23:17,670 448 00:23:17,670 --> 00:23:19,210 There's several things that could happen 449 00:23:19,210 --> 00:23:21,690 when I run this loop. 450 00:23:21,690 --> 00:23:26,800 If the node has no children, I will take out the parent and 451 00:23:26,800 --> 00:23:30,100 not put anything back in. 452 00:23:30,100 --> 00:23:35,700 If the node has multiple children, I could take out one 453 00:23:35,700 --> 00:23:40,010 node and put in more nodes than I took out, so the agenda 454 00:23:40,010 --> 00:23:41,260 could get longer. 455 00:23:41,260 --> 00:23:46,990 456 00:23:46,990 --> 00:23:50,580 So the agenda could either increase in length or decrease 457 00:23:50,580 --> 00:23:53,320 in length as a result of spinning around this loop. 458 00:23:53,320 --> 00:23:56,020 459 00:23:56,020 --> 00:23:59,740 Also, we could either identify a goal or fail 460 00:23:59,740 --> 00:24:01,160 to identify a goal. 461 00:24:01,160 --> 00:24:05,500 So as it's increasing and decreasing, we either will or 462 00:24:05,500 --> 00:24:07,090 won't find an answer. 463 00:24:07,090 --> 00:24:10,100 464 00:24:10,100 --> 00:24:10,195 Ok. 465 00:24:10,195 --> 00:24:11,450 Now the trick-- 466 00:24:11,450 --> 00:24:14,030 the only thing that makes this complicated-- 467 00:24:14,030 --> 00:24:16,346 is that order matters. 468 00:24:16,346 --> 00:24:19,600 469 00:24:19,600 --> 00:24:24,980 So those pseudo-operations, whatever they were-- 470 00:24:24,980 --> 00:24:28,710 get element and add-- 471 00:24:28,710 --> 00:24:32,110 exactly how I get element and exactly how I add it to the 472 00:24:32,110 --> 00:24:36,235 agenda affects the way I conduct the search. 473 00:24:36,235 --> 00:24:38,820 474 00:24:38,820 --> 00:24:40,380 Let's think of something very simple. 475 00:24:40,380 --> 00:24:48,550 Let's always remove the first node from the agenda and 476 00:24:48,550 --> 00:24:52,710 replace it by its children. 477 00:24:52,710 --> 00:24:54,310 So pull out the first node. 478 00:24:54,310 --> 00:24:57,050 And put back into the beginning of the agenda the 479 00:24:57,050 --> 00:24:58,980 children of the first node. 480 00:24:58,980 --> 00:24:59,500 How? 481 00:24:59,500 --> 00:25:01,830 I would start out in step (0). 482 00:25:01,830 --> 00:25:06,070 I would put the start node into the agenda. 483 00:25:06,070 --> 00:25:09,030 So now there's one element in the agenda, the start node. 484 00:25:09,030 --> 00:25:11,840 Then, on the first pass through the loop, I 485 00:25:11,840 --> 00:25:14,350 would pull out that. 486 00:25:14,350 --> 00:25:16,930 That's the first node in the agenda. 487 00:25:16,930 --> 00:25:18,280 There's only one node in the agenda. 488 00:25:18,280 --> 00:25:20,630 That is the first one. 489 00:25:20,630 --> 00:25:23,620 Pull out the first one and replace it by its children. 490 00:25:23,620 --> 00:25:27,900 Its children are AB and AD. 491 00:25:27,900 --> 00:25:33,510 I'm representing the nodes in this notation by the path, 492 00:25:33,510 --> 00:25:37,400 because the same state can appear multiple 493 00:25:37,400 --> 00:25:40,150 times in the tree. 494 00:25:40,150 --> 00:25:44,580 Notice that I could walk ABAB -- 495 00:25:44,580 --> 00:25:46,970 which would correspond to the same state being 496 00:25:46,970 --> 00:25:49,090 repeated in the tree. 497 00:25:49,090 --> 00:25:53,130 So I can't, when I'm writing it down here, represent the 498 00:25:53,130 --> 00:25:55,950 node by a state. 499 00:25:55,950 --> 00:26:00,230 But I can represent a node by a path. 500 00:26:00,230 --> 00:26:04,940 So on the first pass through the loop, pull out the first 501 00:26:04,940 --> 00:26:08,390 item in the agenda, which is A, and push 502 00:26:08,390 --> 00:26:10,900 back that A's children. 503 00:26:10,900 --> 00:26:16,150 Well A's children are AB and AD. 504 00:26:16,150 --> 00:26:16,230 Ok. 505 00:26:16,230 --> 00:26:20,850 So now on the second pass, the rule is pull out the first guy 506 00:26:20,850 --> 00:26:23,420 and replace it by the children. 507 00:26:23,420 --> 00:26:26,450 Now the first guy is AB. 508 00:26:26,450 --> 00:26:28,010 So I'm here. 509 00:26:28,010 --> 00:26:32,310 So pull that guy out and replace him by his children. 510 00:26:32,310 --> 00:26:37,940 His children are ABA, ABC, and ABE. 511 00:26:37,940 --> 00:26:41,030 AD is left over. 512 00:26:41,030 --> 00:26:43,610 The number of elements in the agenda got bigger. 513 00:26:43,610 --> 00:26:46,430 514 00:26:46,430 --> 00:26:51,120 Next step, pull out the first item in the agenda, replace it 515 00:26:51,120 --> 00:26:52,170 by its children. 516 00:26:52,170 --> 00:26:54,020 The first item in the agenda is ABA. 517 00:26:54,020 --> 00:26:57,340 518 00:26:57,340 --> 00:27:02,498 The children of ABA are ABAB and ABAD. 519 00:27:02,498 --> 00:27:06,320 520 00:27:06,320 --> 00:27:06,560 Ok. 521 00:27:06,560 --> 00:27:09,490 Notice the structure of what's going on. 522 00:27:09,490 --> 00:27:11,520 Ignore the stuff on the bottom, and just watch the 523 00:27:11,520 --> 00:27:12,510 picture on the top. 524 00:27:12,510 --> 00:27:16,200 So I start by putting A in the agenda, then its children, 525 00:27:16,200 --> 00:27:19,840 then its children, then its children. 526 00:27:19,840 --> 00:27:21,500 So when I implemented the algorithm-- 527 00:27:21,500 --> 00:27:24,730 take out the first and replace it by its children-- 528 00:27:24,730 --> 00:27:28,080 I'm searching along the depth first. 529 00:27:28,080 --> 00:27:32,820 I'm going deeper and deeper into the tree without fully 530 00:27:32,820 --> 00:27:36,620 exploring all the horizontal spaces. 531 00:27:36,620 --> 00:27:40,970 So I'm tracing a line down that way. 532 00:27:40,970 --> 00:27:42,970 If you imagine this tree-- 533 00:27:42,970 --> 00:27:45,530 I've only represented the first three layers of nodes 534 00:27:45,530 --> 00:27:48,770 here-- this tree goes on forever. 535 00:27:48,770 --> 00:27:52,150 It's an infinite tree, because you can walk around in that 536 00:27:52,150 --> 00:27:54,140 Manhattan grid forever. 537 00:27:54,140 --> 00:27:58,390 There's no limit to how long you can walk around. 538 00:27:58,390 --> 00:28:02,280 So although I'm only listing the first three, the tree, in 539 00:28:02,280 --> 00:28:04,900 principle, goes on forever. 540 00:28:04,900 --> 00:28:08,930 And this algorithm will have the feature that it walks 541 00:28:08,930 --> 00:28:11,740 along the left edge. 542 00:28:11,740 --> 00:28:17,350 We call that depth-first search because we're exploring 543 00:28:17,350 --> 00:28:20,650 depth first, as opposed to breadth. 544 00:28:20,650 --> 00:28:23,500 545 00:28:23,500 --> 00:28:25,630 That results because of our rule. 546 00:28:25,630 --> 00:28:28,040 The rule was, replace the first node by its children. 547 00:28:28,040 --> 00:28:30,260 Let's think about a different rule. 548 00:28:30,260 --> 00:28:32,430 Let's replace the last node by its children. 549 00:28:32,430 --> 00:28:38,320 550 00:28:38,320 --> 00:28:42,440 We start by initializing the agenda to the node that 551 00:28:42,440 --> 00:28:45,320 represents the start state. 552 00:28:45,320 --> 00:28:50,830 So that's the path A. Then pull out the 553 00:28:50,830 --> 00:28:54,040 last node in the agenda-- 554 00:28:54,040 --> 00:28:55,080 that's A-- 555 00:28:55,080 --> 00:28:57,480 and replace it by its children. 556 00:28:57,480 --> 00:28:59,915 Its children are still AB and AD, just like before. 557 00:28:59,915 --> 00:29:02,460 558 00:29:02,460 --> 00:29:04,770 Now the answer differs from the previous answer. 559 00:29:04,770 --> 00:29:08,680 Because when I pull out the last node, I'm pulling out AD 560 00:29:08,680 --> 00:29:09,930 now, instead. 561 00:29:09,930 --> 00:29:12,710 562 00:29:12,710 --> 00:29:16,160 And now I replace AD by its children, which 563 00:29:16,160 --> 00:29:19,350 are ADA, ADE, ADG. 564 00:29:19,350 --> 00:29:22,900 565 00:29:22,900 --> 00:29:28,480 Repeat, and what I've got is a different, but still 566 00:29:28,480 --> 00:29:31,060 depth-first search. 567 00:29:31,060 --> 00:29:33,680 So I've looked at two different orderings-- 568 00:29:33,680 --> 00:29:36,410 pull out the first node from the agenda and replace it by 569 00:29:36,410 --> 00:29:39,190 children, pull out the last node and 570 00:29:39,190 --> 00:29:40,540 replace it by its children. 571 00:29:40,540 --> 00:29:47,320 Both of those algorithms give an exploration of the decision 572 00:29:47,320 --> 00:29:51,580 tree searching out depth first. 573 00:29:51,580 --> 00:29:54,060 So it's going to try to exhaustively go through the 574 00:29:54,060 --> 00:29:57,480 entire depth before it tries to explore the width. 575 00:29:57,480 --> 00:30:01,510 576 00:30:01,510 --> 00:30:04,080 As an alternative, think about a slightly 577 00:30:04,080 --> 00:30:05,770 more complicated rule. 578 00:30:05,770 --> 00:30:08,290 Remove the first element from the agenda and add its 579 00:30:08,290 --> 00:30:09,880 children to the end of the agenda. 580 00:30:09,880 --> 00:30:13,350 581 00:30:13,350 --> 00:30:19,330 So initialize it with the start state, A. Pull out the 582 00:30:19,330 --> 00:30:21,670 first element from the agenda-- that's A-- 583 00:30:21,670 --> 00:30:26,500 and replace it by its children, which is AB, AD. 584 00:30:26,500 --> 00:30:28,360 Now pull out the first guy-- 585 00:30:28,360 --> 00:30:31,470 the first guy is AB-- 586 00:30:31,470 --> 00:30:35,600 and put its children at the end. 587 00:30:35,600 --> 00:30:39,580 It's children are ABA, ABC, ABE-- 588 00:30:39,580 --> 00:30:41,480 ABA, ABC, ABE-- 589 00:30:41,480 --> 00:30:43,380 and they are now put at the end. 590 00:30:43,380 --> 00:30:48,650 So that on the next step, I'll pick up AD-- the guy at the 591 00:30:48,650 --> 00:30:49,900 beginning-- 592 00:30:49,900 --> 00:30:51,780 593 00:30:51,780 --> 00:30:54,940 and put AD's children at the end. 594 00:30:54,940 --> 00:30:57,710 et cetera, et cetera, et cetera, et cetera, 595 00:30:57,710 --> 00:30:59,390 et cetera, et cetera. 596 00:30:59,390 --> 00:31:02,240 The idea being-- and now, pay no attention to the bottom for 597 00:31:02,240 --> 00:31:04,350 a moment and just think about the pattern that 598 00:31:04,350 --> 00:31:06,520 you see at the top. 599 00:31:06,520 --> 00:31:11,640 In this order, where we remove the first node and put its 600 00:31:11,640 --> 00:31:15,770 children at the end of the agenda, has the effect of 601 00:31:15,770 --> 00:31:17,210 exploring breadth first. 602 00:31:17,210 --> 00:31:22,260 603 00:31:22,260 --> 00:31:23,760 So we call that a breadth-first. 604 00:31:23,760 --> 00:31:29,880 so the idea is, we got this generic set of tools that let 605 00:31:29,880 --> 00:31:32,180 us construct search trees. 606 00:31:32,180 --> 00:31:35,630 But the order by which we manipulate the agenda plays a 607 00:31:35,630 --> 00:31:41,210 critical role in how the search is conducted. 608 00:31:41,210 --> 00:31:47,100 And the two that epitomize the two extreme cases are, what 609 00:31:47,100 --> 00:31:50,850 would happen if I replace the last node by its children? 610 00:31:50,850 --> 00:31:54,460 Or what would happen if I remove the first node and put 611 00:31:54,460 --> 00:31:56,000 its children's at the end? 612 00:31:56,000 --> 00:31:58,870 Those two structures have names because 613 00:31:58,870 --> 00:32:00,110 they happen so often. 614 00:32:00,110 --> 00:32:01,780 We'll call the first one a stack and the 615 00:32:01,780 --> 00:32:04,580 second one a queue. 616 00:32:04,580 --> 00:32:07,970 The stack-based is going to give us depth first. 617 00:32:07,970 --> 00:32:11,080 The queue-based is going to give us breadth first. 618 00:32:11,080 --> 00:32:12,720 So, stack. 619 00:32:12,720 --> 00:32:15,270 How do you think about a stack? 620 00:32:15,270 --> 00:32:19,190 You think about a stack by saying, OK, I've got a stack. 621 00:32:19,190 --> 00:32:21,080 A stack is like a stack of dishes. 622 00:32:21,080 --> 00:32:25,620 So here's my table, and I'm going to rack my dishes up. 623 00:32:25,620 --> 00:32:26,870 I'm going to put them on a stack. 624 00:32:26,870 --> 00:32:29,380 625 00:32:29,380 --> 00:32:30,370 So I make a stack. 626 00:32:30,370 --> 00:32:31,660 OK, I made the stack-- 627 00:32:31,660 --> 00:32:33,590 push a 1, push a 9, push a 3. 628 00:32:33,590 --> 00:32:37,720 Push a 1, push a 9, push a 3. 629 00:32:37,720 --> 00:32:39,370 That's how I do a stack. 630 00:32:39,370 --> 00:32:41,530 Then pop. 631 00:32:41,530 --> 00:32:45,920 When I pop, the 3 comes out. 632 00:32:45,920 --> 00:32:50,840 Then pop, then the 9 comes out. 633 00:32:50,840 --> 00:32:53,060 Then push a minus 2. 634 00:32:53,060 --> 00:32:55,600 635 00:32:55,600 --> 00:32:57,290 Then pop. 636 00:32:57,290 --> 00:33:00,850 Now the minus 2 comes out. 637 00:33:00,850 --> 00:33:01,440 OK? 638 00:33:01,440 --> 00:33:03,460 It's stack-based. 639 00:33:03,460 --> 00:33:10,030 So the last in becomes the first out. 640 00:33:10,030 --> 00:33:14,220 That was the rule that we wanted to have for the 641 00:33:14,220 --> 00:33:17,460 depth-first search. 642 00:33:17,460 --> 00:33:18,960 It's very easy to implement this. 643 00:33:18,960 --> 00:33:22,440 We can implement it as a list. 644 00:33:22,440 --> 00:33:26,230 All we need to do is be careful about how we implement 645 00:33:26,230 --> 00:33:29,820 the push and pop operators. 646 00:33:29,820 --> 00:33:34,120 So if we set up the push operator to simply append to 647 00:33:34,120 --> 00:33:39,700 the end, and then pop ordinarily pops from the end, 648 00:33:39,700 --> 00:33:42,320 we'll get the behavior of a stack. 649 00:33:42,320 --> 00:33:45,180 That gives me, then, the rules that I would want to use for 650 00:33:45,180 --> 00:33:50,140 those procedures, the get element an add. 651 00:33:50,140 --> 00:33:55,040 I will use these stack-based operators. 652 00:33:55,040 --> 00:33:58,270 The other alternative is a queue. 653 00:33:58,270 --> 00:33:59,230 A queue is different. 654 00:33:59,230 --> 00:34:01,390 A queue is like when you're waiting in line 655 00:34:01,390 --> 00:34:03,980 at the Stop & Shop. 656 00:34:03,980 --> 00:34:08,500 The queue is, I've got this queue here and I've got the 657 00:34:08,500 --> 00:34:09,750 server over here. 658 00:34:09,750 --> 00:34:12,880 659 00:34:12,880 --> 00:34:14,850 The first person who comes into the queue-- 660 00:34:14,850 --> 00:34:16,620 so say I push one. 661 00:34:16,620 --> 00:34:19,429 So now 1 goes into the queue. 662 00:34:19,429 --> 00:34:22,010 Then another person walks up while he's-- 663 00:34:22,010 --> 00:34:26,889 the second person lines up behind the first person. 664 00:34:26,889 --> 00:34:30,170 Then I push a 3. 665 00:34:30,170 --> 00:34:32,980 But the way the queue works is that when I pop the next 666 00:34:32,980 --> 00:34:38,389 person off the queue, I take the head of the line. 667 00:34:38,389 --> 00:34:39,639 So the 1 comes out. 668 00:34:39,639 --> 00:34:42,830 669 00:34:42,830 --> 00:34:44,880 If I pop again, the 9 comes out. 670 00:34:44,880 --> 00:34:48,889 671 00:34:48,889 --> 00:34:57,410 If I then push a minus 2 and pop, then the next person in 672 00:34:57,410 --> 00:34:58,720 the queue comes out. 673 00:34:58,720 --> 00:35:01,200 And it's like that. 674 00:35:01,200 --> 00:35:04,000 It's queue based versus stack based. 675 00:35:04,000 --> 00:35:06,857 And the queue based is the one that we want to do for a 676 00:35:06,857 --> 00:35:09,873 breadth-first organization. 677 00:35:09,873 --> 00:35:12,570 678 00:35:12,570 --> 00:35:16,300 And the implementation of a queue is very trivially 679 00:35:16,300 --> 00:35:19,170 different from the implementation for a stack. 680 00:35:19,170 --> 00:35:22,690 The only difference is that I'll manipulate the list by 681 00:35:22,690 --> 00:35:26,060 popping off from the head of the queue. 682 00:35:26,060 --> 00:35:29,950 So pop takes an optional argument, which when 683 00:35:29,950 --> 00:35:32,020 0, tells you the-- 684 00:35:32,020 --> 00:35:34,340 the argument tells you which element to pop. 685 00:35:34,340 --> 00:35:36,530 So when you specify the zero-th one, it takes it from 686 00:35:36,530 --> 00:35:39,480 the head of the queue. 687 00:35:39,480 --> 00:35:45,460 That makes it very easy now to replace the pseudo-procedures 688 00:35:45,460 --> 00:35:47,180 with real procedures. 689 00:35:47,180 --> 00:35:52,670 If I wanted to implement a depth-first search, I would 690 00:35:52,670 --> 00:35:57,830 replace the "create a list that contains the agenda" with 691 00:35:57,830 --> 00:36:04,400 "create a stack that will contain the agenda." So create 692 00:36:04,400 --> 00:36:07,850 a new stack, the agenda is a stack. 693 00:36:07,850 --> 00:36:11,900 And then rather than simply sticking the node-- 694 00:36:11,900 --> 00:36:13,340 the start node-- 695 00:36:13,340 --> 00:36:19,020 into a list, I will push it into the stack. 696 00:36:19,020 --> 00:36:21,510 So agenda is a stack. 697 00:36:21,510 --> 00:36:25,560 Agenda.push, the initial node. 698 00:36:25,560 --> 00:36:28,610 And then every time I want to get a new element out, I'll 699 00:36:28,610 --> 00:36:31,080 agenda.pop it. 700 00:36:31,080 --> 00:36:33,500 And every time I want to put something into it, I'll 701 00:36:33,500 --> 00:36:36,050 agenda.push it. 702 00:36:36,050 --> 00:36:40,150 Other than that, it looks just the same as the pseudocode 703 00:36:40,150 --> 00:36:42,800 that I showed earlier. 704 00:36:42,800 --> 00:36:45,982 So there is an implementation, then, for 705 00:36:45,982 --> 00:36:50,400 a depth-first search. 706 00:36:50,400 --> 00:36:53,990 If I wanted instead to do breadth, it's trivial. 707 00:36:53,990 --> 00:36:59,640 Change the word "stack" to the word "queue." Now create an 708 00:36:59,640 --> 00:37:05,060 agenda that is a queue, but queues have the same 709 00:37:05,060 --> 00:37:06,450 operations-- 710 00:37:06,450 --> 00:37:09,660 push and pop and empty-- 711 00:37:09,660 --> 00:37:10,840 that stacks have. 712 00:37:10,840 --> 00:37:12,790 So nothing else in the program changed. 713 00:37:12,790 --> 00:37:16,470 All I needed to do is change the structure of the thing 714 00:37:16,470 --> 00:37:18,580 that's holding the agenda. 715 00:37:18,580 --> 00:37:19,830 Everything else just follows. 716 00:37:19,830 --> 00:37:27,700 717 00:37:27,700 --> 00:37:27,775 Ok. 718 00:37:27,775 --> 00:37:29,770 So that's everything we need, right? 719 00:37:29,770 --> 00:37:31,930 Now what I want to do is think through examples and think 720 00:37:31,930 --> 00:37:33,830 about the advantages and disadvantages of different 721 00:37:33,830 --> 00:37:35,840 kinds of searches. 722 00:37:35,840 --> 00:37:38,680 And I want to go on to the second step that I raised in 723 00:37:38,680 --> 00:37:40,730 the first slide. 724 00:37:40,730 --> 00:37:43,260 I want to think about, how do I optimize the search? 725 00:37:43,260 --> 00:37:46,290 As I said, even that simple little tile problem, even the 726 00:37:46,290 --> 00:37:47,340 eight puzzle-- 727 00:37:47,340 --> 00:37:49,500 eight sounds easy, right? 728 00:37:49,500 --> 00:37:52,990 Even the eight puzzle had a third of a 729 00:37:52,990 --> 00:37:54,540 million different states. 730 00:37:54,540 --> 00:37:56,740 I don't necessarily want to look through all of them. 731 00:37:56,740 --> 00:37:59,100 I want to think now about these different search 732 00:37:59,100 --> 00:38:03,000 strategies, and how optimal are they relative to each 733 00:38:03,000 --> 00:38:05,320 other, and are there ways to improve that? 734 00:38:05,320 --> 00:38:10,910 Now some of you may have noticed that all of these 735 00:38:10,910 --> 00:38:15,070 paths don't seem equally good. 736 00:38:15,070 --> 00:38:16,220 So take a minute. 737 00:38:16,220 --> 00:38:18,500 Think about it. 738 00:38:18,500 --> 00:38:19,590 Remember the problem. 739 00:38:19,590 --> 00:38:22,540 The problem was this walk around Manhattan problem. 740 00:38:22,540 --> 00:38:26,940 I wanted to go from A to I. This was the tree of all 741 00:38:26,940 --> 00:38:30,640 possible paths from A to I. What I'd like you to do is 742 00:38:30,640 --> 00:38:35,780 think about whether all of those paths are important. 743 00:38:35,780 --> 00:38:37,250 Could we get rid of some of them? 744 00:38:37,250 --> 00:40:52,820 745 00:40:52,820 --> 00:40:54,810 So the question is, can I throw away some of the 746 00:40:54,810 --> 00:40:55,700 terminal nodes? 747 00:40:55,700 --> 00:40:57,680 Notice that I'm using the word "terminal" kind of funny here. 748 00:40:57,680 --> 00:41:00,550 The tree keeps going. 749 00:41:00,550 --> 00:41:03,890 The tree is actually infinite in length. 750 00:41:03,890 --> 00:41:06,180 So by "terminal," I just mean this row three. 751 00:41:06,180 --> 00:41:09,840 So could I throw away some of the nodes in row three? 752 00:41:09,840 --> 00:41:12,410 And in particular, how many of them could I throw away? 753 00:41:12,410 --> 00:41:15,190 0, 2, 4, 6, or 8? 754 00:41:15,190 --> 00:41:19,540 or Raise your hand with the funny coding. 755 00:41:19,540 --> 00:41:22,530 And the answer is-- 756 00:41:22,530 --> 00:41:23,080 come on, come on. 757 00:41:23,080 --> 00:41:24,340 Raise your hands, raise your hands. 758 00:41:24,340 --> 00:41:25,690 Blame it on your neighbor. 759 00:41:25,690 --> 00:41:27,840 That's the whole point. 760 00:41:27,840 --> 00:41:35,870 OK, it's 2/3 (5) and 1/3 (4) 761 00:41:35,870 --> 00:41:37,120 How'd you get (5) and (4)? 762 00:41:37,120 --> 00:41:39,856 763 00:41:39,856 --> 00:41:42,286 Yes? 764 00:41:42,286 --> 00:41:45,688 AUDIENCE: When you have that [INAUDIBLE] nodes, you may 765 00:41:45,688 --> 00:41:47,146 know that there's [? a procedure ?] 766 00:41:47,146 --> 00:41:48,130 [INAUDIBLE] before. 767 00:41:48,130 --> 00:41:48,920 PROFESSOR: Good. 768 00:41:48,920 --> 00:41:52,930 If you're walking around Manhattan, and you're trying 769 00:41:52,930 --> 00:41:57,590 to go from A to I, and if you spun around in this loop and 770 00:41:57,590 --> 00:42:03,000 came back to A, that would probably be a bad path, right? 771 00:42:03,000 --> 00:42:09,070 So revisiting a place you've been before is probably a bad 772 00:42:09,070 --> 00:42:13,350 idea, if what your goal was, was to get from A to I in the 773 00:42:13,350 --> 00:42:17,030 shortest possible distance. 774 00:42:17,030 --> 00:42:18,510 So that's exactly right. 775 00:42:18,510 --> 00:42:23,360 So I would like to identify instances where I go back to 776 00:42:23,360 --> 00:42:24,090 where I started. 777 00:42:24,090 --> 00:42:27,730 So for example, that A. That A is bad. 778 00:42:27,730 --> 00:42:30,200 That means I went back to the start place. 779 00:42:30,200 --> 00:42:32,860 I'm just starting over. 780 00:42:32,860 --> 00:42:37,430 So if I think about those, I can identify by red all the 781 00:42:37,430 --> 00:42:38,610 places where I'm repeating. 782 00:42:38,610 --> 00:42:44,380 So ABA, don't really care what happens after that. 783 00:42:44,380 --> 00:42:47,180 ABCB, well, that's B again. 784 00:42:47,180 --> 00:42:49,900 So that's just brain dead, right? 785 00:42:49,900 --> 00:42:55,440 So I can actually remove a fair amount of the tree by 786 00:42:55,440 --> 00:42:59,300 simply getting rid of silliness. 787 00:42:59,300 --> 00:43:05,540 Don't start the path over again, where "over" means if 788 00:43:05,540 --> 00:43:08,200 you come to a place you've been before, 789 00:43:08,200 --> 00:43:09,550 stop looking there. 790 00:43:09,550 --> 00:43:12,320 That's not the right answer. 791 00:43:12,320 --> 00:43:15,850 And so you can see there that I actually 792 00:43:15,850 --> 00:43:18,740 deleted half of the tree. 793 00:43:18,740 --> 00:43:21,370 The number of nodes on the third line was 16. 794 00:43:21,370 --> 00:43:24,870 And 8 of them had the property that they repeated. 795 00:43:24,870 --> 00:43:26,290 Yes? 796 00:43:26,290 --> 00:43:27,778 AUDIENCE: [INAUDIBLE] 797 00:43:27,778 --> 00:43:28,770 [? after D. ?] 798 00:43:28,770 --> 00:43:29,762 Are you [INAUDIBLE]? 799 00:43:29,762 --> 00:43:33,234 PROFESSOR: This B and D. So there's no reason to consider 800 00:43:33,234 --> 00:43:37,698 this D, even though the D didn't repeat. 801 00:43:37,698 --> 00:43:40,674 AUDIENCE: That would be [? AD? ?] 802 00:43:40,674 --> 00:43:42,658 PROFESSOR: ABC, 803 00:43:42,658 --> 00:43:44,146 AUDIENCE: [? That would be E? ?] 804 00:43:44,146 --> 00:43:46,130 PROFESSOR: ABED. 805 00:43:46,130 --> 00:43:48,610 AUDIENCE: [INAUDIBLE] 806 00:43:48,610 --> 00:43:54,066 PROFESSOR: So I didn't, in this path, ever hit D before. 807 00:43:54,066 --> 00:43:58,034 AUDIENCE: When it did lead to the path there, you'll get the 808 00:43:58,034 --> 00:44:01,506 same one, AD [INAUDIBLE] 809 00:44:01,506 --> 00:44:03,490 PROFESSOR: I guess I don't understand. 810 00:44:03,490 --> 00:44:06,466 AUDIENCE: What I'm saying is that without getting the path 811 00:44:06,466 --> 00:44:08,450 AD, I still get (2)? 812 00:44:08,450 --> 00:44:09,442 PROFESSOR: Yes. 813 00:44:09,442 --> 00:44:13,910 So this D seems clearly inferior to that D. Yes, 814 00:44:13,910 --> 00:44:17,530 that's absolutely true. 815 00:44:17,530 --> 00:44:20,960 So this is a very simple rule for removing things. 816 00:44:20,960 --> 00:44:23,380 You're thinking of a more advanced rule. 817 00:44:23,380 --> 00:44:25,100 So if you saw-- 818 00:44:25,100 --> 00:44:27,950 if there's a shorter path to a particular place, don't look 819 00:44:27,950 --> 00:44:28,800 at the longer path. 820 00:44:28,800 --> 00:44:30,100 You're absolutely right. 821 00:44:30,100 --> 00:44:36,500 So in fact, there might be more severe pruning 822 00:44:36,500 --> 00:44:38,290 that you could do. 823 00:44:38,290 --> 00:44:39,670 There might have been an answer that was 824 00:44:39,670 --> 00:44:41,590 bigger than 8 -- 825 00:44:41,590 --> 00:44:41,990 right? 826 00:44:41,990 --> 00:44:43,240 And so you're absolutely right. 827 00:44:43,240 --> 00:44:47,900 828 00:44:47,900 --> 00:44:48,015 Ok. 829 00:44:48,015 --> 00:44:50,100 Let me ignore that for the moment and come back to it in 830 00:44:50,100 --> 00:44:51,580 about four slides. 831 00:44:51,580 --> 00:44:54,490 You're absolutely right. 832 00:44:54,490 --> 00:44:58,850 So what we want to do now is take that idea of throwing 833 00:44:58,850 --> 00:45:03,690 away silly paths and formalize it so that we can put it into 834 00:45:03,690 --> 00:45:05,760 the algorithm. 835 00:45:05,760 --> 00:45:08,870 And we'll think about that as pruning rules. 836 00:45:08,870 --> 00:45:10,730 So the first pruning rule is the easy one. 837 00:45:10,730 --> 00:45:15,460 Don't consider any path that visits the same state twice. 838 00:45:15,460 --> 00:45:19,560 That doesn't pick up your case, but it does pick up 8 839 00:45:19,560 --> 00:45:22,360 cases here. 840 00:45:22,360 --> 00:45:27,630 So that's easy to implement. 841 00:45:27,630 --> 00:45:29,990 All we need to do is-- 842 00:45:29,990 --> 00:45:32,970 down here where we're thinking about whether this is a good 843 00:45:32,970 --> 00:45:35,870 state to add or not-- 844 00:45:35,870 --> 00:45:39,920 we just ask, is it in the path? 845 00:45:39,920 --> 00:45:43,870 So if the state that I'm about to put in the path is already 846 00:45:43,870 --> 00:45:47,750 in the path, don't put it there. 847 00:45:47,750 --> 00:45:49,210 If you don't shove it back into the 848 00:45:49,210 --> 00:45:52,640 agenda, it'll get forgotten. 849 00:45:52,640 --> 00:45:55,570 So before you shove it into the agenda, ask yourself the 850 00:45:55,570 --> 00:45:57,960 question, is it already in the path? 851 00:45:57,960 --> 00:46:00,090 And so I do that here. 852 00:46:00,090 --> 00:46:08,050 Keep in mind, I popped out an element called the parent. 853 00:46:08,050 --> 00:46:10,660 I'm looking at the children. 854 00:46:10,660 --> 00:46:14,640 The children's state is called "new state." So I ask, is new 855 00:46:14,640 --> 00:46:19,400 state in the parent's path? 856 00:46:19,400 --> 00:46:23,000 So parent.inpath of new state. 857 00:46:23,000 --> 00:46:25,280 So that means I have to write inpath. 858 00:46:25,280 --> 00:46:27,630 Inpath is easy. 859 00:46:27,630 --> 00:46:30,960 It's especially easy if we use recursion. 860 00:46:30,960 --> 00:46:40,200 So inpath says, if my state is state, then return True. 861 00:46:40,200 --> 00:46:42,760 I'm in the path. 862 00:46:42,760 --> 00:46:48,530 If that's not true, and I don't have a parent, then that 863 00:46:48,530 --> 00:46:50,850 means I'm the start state. 864 00:46:50,850 --> 00:46:53,590 That means it wasn't in the path. 865 00:46:53,590 --> 00:46:55,990 And if neither of those is true, ask the same 866 00:46:55,990 --> 00:46:59,210 question of my parent. 867 00:46:59,210 --> 00:47:01,830 So that makes it recursive. 868 00:47:01,830 --> 00:47:04,860 So consider two cases that could either 869 00:47:04,860 --> 00:47:06,390 make it true or false. 870 00:47:06,390 --> 00:47:09,680 It would be True if I'm currently sitting on a node 871 00:47:09,680 --> 00:47:11,310 that happens to be the same state. 872 00:47:11,310 --> 00:47:14,980 It would be False if I recursed the whole way back to 873 00:47:14,980 --> 00:47:19,060 the start state and hadn't found it yet. 874 00:47:19,060 --> 00:47:21,680 So there are two termination states-- 875 00:47:21,680 --> 00:47:26,240 I landed on a state in the path that was the same as new 876 00:47:26,240 --> 00:47:29,830 state, or I ran the whole way back to the start state and 877 00:47:29,830 --> 00:47:30,860 didn't find it. 878 00:47:30,860 --> 00:47:34,000 Those two terminate by doing returns -- 879 00:47:34,000 --> 00:47:36,890 return True or return False. 880 00:47:36,890 --> 00:47:39,800 The other option is that I don't know the 881 00:47:39,800 --> 00:47:41,295 answer, ask my parent. 882 00:47:41,295 --> 00:47:44,040 883 00:47:44,040 --> 00:47:48,170 So just recurse on inpath, and ask my parent 884 00:47:48,170 --> 00:47:51,400 to do the same thing. 885 00:47:51,400 --> 00:47:53,380 So that's the way I can figure out-- 886 00:47:53,380 --> 00:47:57,360 I can implement pruning rule (1). 887 00:47:57,360 --> 00:47:59,510 Now pruning rule (2) -- 888 00:47:59,510 --> 00:48:02,200 if multiple actions lead to the same state, only think 889 00:48:02,200 --> 00:48:03,320 about one of them. 890 00:48:03,320 --> 00:48:05,580 That actually doesn't happen on the Manhattan grid problem. 891 00:48:05,580 --> 00:48:09,110 Because you can imagine search cases where there are three 892 00:48:09,110 --> 00:48:10,380 different things that you could do. 893 00:48:10,380 --> 00:48:12,790 In fact, you saw some of those when you were coding 894 00:48:12,790 --> 00:48:15,270 the robot last week. 895 00:48:15,270 --> 00:48:18,160 There were multiple ways you could end up at the state at 896 00:48:18,160 --> 00:48:20,430 the end of the hall. 897 00:48:20,430 --> 00:48:23,840 You could get there by being there and moving left, which 898 00:48:23,840 --> 00:48:24,800 you hit the wall. 899 00:48:24,800 --> 00:48:27,510 Or you could get there by being here and moving left. 900 00:48:27,510 --> 00:48:30,400 Both of them left you in the same place. 901 00:48:30,400 --> 00:48:32,840 So if you're planning a search, you don't need to 902 00:48:32,840 --> 00:48:35,200 distinguish among those, because they take the same 903 00:48:35,200 --> 00:48:37,400 amount of steps. 904 00:48:37,400 --> 00:48:39,810 So since they take the same amount of steps, we don't need 905 00:48:39,810 --> 00:48:40,500 to search further. 906 00:48:40,500 --> 00:48:41,650 So we can collapse them. 907 00:48:41,650 --> 00:48:44,390 That's called pruning rule (2). 908 00:48:44,390 --> 00:48:46,120 That's also easy to implement. 909 00:48:46,120 --> 00:48:49,890 What we do is, we keep track of, for every parent, what are 910 00:48:49,890 --> 00:48:52,830 all of its children. 911 00:48:52,830 --> 00:48:59,250 If the parent already has a child at that place, throw 912 00:48:59,250 --> 00:49:02,210 away the excess children. 913 00:49:02,210 --> 00:49:03,460 That doesn't sound good. 914 00:49:03,460 --> 00:49:07,220 915 00:49:07,220 --> 00:49:10,490 So keep track of how many child states I have. 916 00:49:10,490 --> 00:49:12,480 Make a list. 917 00:49:12,480 --> 00:49:18,180 And if the new state didn't satisfy the goal, ask if it's 918 00:49:18,180 --> 00:49:21,500 already in the list of children. 919 00:49:21,500 --> 00:49:23,360 If it's already there, pass. 920 00:49:23,360 --> 00:49:24,610 Don't do anything. 921 00:49:24,610 --> 00:49:27,430 922 00:49:27,430 --> 00:49:29,360 Otherwise, do pruning rule (1). 923 00:49:29,360 --> 00:49:32,850 And then, before you push it into the agenda, also push it 924 00:49:32,850 --> 00:49:35,150 into the list of new children. 925 00:49:35,150 --> 00:49:38,010 926 00:49:38,010 --> 00:49:41,100 That's a way of making sure that if there's multiple ways 927 00:49:41,100 --> 00:49:43,700 to get the same state, you only keep track of one. 928 00:49:43,700 --> 00:49:47,420 So that's an additional pruning rule. 929 00:49:47,420 --> 00:49:52,050 So now let's think about how we would implement these. 930 00:49:52,050 --> 00:49:55,560 Let's think about the solution to a problem where we want to 931 00:49:55,560 --> 00:50:02,490 apply a depth-first search on this Manhattan problem, to get 932 00:50:02,490 --> 00:50:04,250 from A to I. So let's think about-- 933 00:50:04,250 --> 00:50:09,800 934 00:50:09,800 --> 00:50:11,050 let's go up-- 935 00:50:11,050 --> 00:50:14,740 936 00:50:14,740 --> 00:50:19,780 so I want to think about, how do I apply depth-first search 937 00:50:19,780 --> 00:50:21,260 to that problem? 938 00:50:21,260 --> 00:50:23,040 So think about the agenda. 939 00:50:23,040 --> 00:50:25,870 So the agenda, I initialized it with the node that 940 00:50:25,870 --> 00:50:32,370 corresponds to the start state, so that's A. I'm doing 941 00:50:32,370 --> 00:50:33,050 depth first. 942 00:50:33,050 --> 00:50:35,120 What's the rule for depth first? 943 00:50:35,120 --> 00:50:39,290 Pop the last guy, replace it by his children. 944 00:50:39,290 --> 00:50:41,360 OK, so pop the last guy. 945 00:50:41,360 --> 00:50:42,550 What's the last guy? 946 00:50:42,550 --> 00:50:45,220 The last guy is A. Replace it by his children. 947 00:50:45,220 --> 00:50:47,420 What's his children of A? 948 00:50:47,420 --> 00:50:49,225 Well, there's two of them, AB and AD. 949 00:50:49,225 --> 00:50:56,050 950 00:50:56,050 --> 00:50:56,125 Ok. 951 00:50:56,125 --> 00:51:00,330 So I'm done with the loop for the first level. 952 00:51:00,330 --> 00:51:06,230 So pop the last guy, that's AD. 953 00:51:06,230 --> 00:51:07,420 Replace it by his children. 954 00:51:07,420 --> 00:51:10,780 What are the children of AD? 955 00:51:10,780 --> 00:51:11,830 Well, what could D do? 956 00:51:11,830 --> 00:51:17,040 D could go to A or E or G. A's brain dead, so I 957 00:51:17,040 --> 00:51:18,620 don't want that one. 958 00:51:18,620 --> 00:51:21,970 So I'll think about E and G. 959 00:51:21,970 --> 00:51:26,120 So ADE, ADG. 960 00:51:26,120 --> 00:51:30,810 961 00:51:30,810 --> 00:51:32,900 By the way, stop me if I make a mistake. 962 00:51:32,900 --> 00:51:35,360 It's really embarrassing. 963 00:51:35,360 --> 00:51:39,200 OK, pop the end, ADG. 964 00:51:39,200 --> 00:51:43,740 Who's the possible children of ADG? 965 00:51:43,740 --> 00:51:44,390 ADG? 966 00:51:44,390 --> 00:51:46,130 Well, it could go back to D, but that's stupid. 967 00:51:46,130 --> 00:51:48,940 So ADGH seems to be the only good one. 968 00:51:48,940 --> 00:51:54,600 969 00:51:54,600 --> 00:51:58,260 Pop the last one, ADGH. 970 00:51:58,260 --> 00:52:02,400 And who's his children, ADGH? 971 00:52:02,400 --> 00:52:11,460 ADGH has children E, G, and I. But I don't want G, because 972 00:52:11,460 --> 00:52:12,770 that's brain dead. 973 00:52:12,770 --> 00:52:24,700 So ADGH, E or I. And that one won, right? 974 00:52:24,700 --> 00:52:27,750 Because I got to A. 975 00:52:27,750 --> 00:52:28,960 Everyone see what I did? 976 00:52:28,960 --> 00:52:33,380 I tried to work out the algorithm manually. 977 00:52:33,380 --> 00:52:35,230 So the idea, then, was that-- 978 00:52:35,230 --> 00:52:38,630 979 00:52:38,630 --> 00:52:40,400 so how much work I do? 980 00:52:40,400 --> 00:52:43,570 I visited 1, 2, 3, 4, 5, 6, 7. 981 00:52:43,570 --> 00:52:44,720 And then I found it. 982 00:52:44,720 --> 00:52:45,970 So I did 7 visits. 983 00:52:45,970 --> 00:52:48,580 984 00:52:48,580 --> 00:52:49,830 And I got the right answer. 985 00:52:49,830 --> 00:52:52,450 986 00:52:52,450 --> 00:52:53,740 So both of those are good-- 987 00:52:53,740 --> 00:52:56,220 7 is a small number, and getting the right answer. 988 00:52:56,220 --> 00:52:59,330 Both of those are good things. 989 00:52:59,330 --> 00:53:02,570 And in general, if you think about the way a depth-first 990 00:53:02,570 --> 00:53:03,850 search works-- 991 00:53:03,850 --> 00:53:07,330 here's a transcript of what I just did. 992 00:53:07,330 --> 00:53:09,550 This will be posted on the online version. 993 00:53:09,550 --> 00:53:11,600 So you can see it, even though it's not 994 00:53:11,600 --> 00:53:14,150 handed out to you now. 995 00:53:14,150 --> 00:53:17,410 So you can look this up on the web. 996 00:53:17,410 --> 00:53:21,940 So in general, depth-first search won't 997 00:53:21,940 --> 00:53:23,190 work for every problem. 998 00:53:23,190 --> 00:53:25,840 999 00:53:25,840 --> 00:53:27,790 It happened to work for this problem. 1000 00:53:27,790 --> 00:53:29,820 In fact, it happened to be very good for this problem. 1001 00:53:29,820 --> 00:53:31,420 But it won't work for every problem because 1002 00:53:31,420 --> 00:53:33,570 it could get stuck. 1003 00:53:33,570 --> 00:53:36,480 It could run forever in a problem with infinite domain. 1004 00:53:36,480 --> 00:53:37,890 This problem has infinite domain. 1005 00:53:37,890 --> 00:53:41,030 So if I were to choose my start and end state 1006 00:53:41,030 --> 00:53:44,380 judiciously, I could get it stuck in an infinite loop. 1007 00:53:44,380 --> 00:53:49,530 That's a property of depth-first search. 1008 00:53:49,530 --> 00:53:53,420 Even when it finds a path, it doesn't necessarily find the 1009 00:53:53,420 --> 00:53:55,110 shortest path. 1010 00:53:55,110 --> 00:53:58,710 Well, that's a bummer. 1011 00:53:58,710 --> 00:54:04,040 But it's very efficient in its use of memory. 1012 00:54:04,040 --> 00:54:08,580 So it's not a completely brain-dead search strategy, 1013 00:54:08,580 --> 00:54:10,720 but it's usually brain dead. 1014 00:54:10,720 --> 00:54:16,230 So let's think about breadth-first search as an 1015 00:54:16,230 --> 00:54:17,360 alternative. 1016 00:54:17,360 --> 00:54:21,060 Again, all we need do is switch the idea of thinking 1017 00:54:21,060 --> 00:54:26,020 about stacks versus queues. 1018 00:54:26,020 --> 00:54:28,300 Take off the beginning, add to the end. 1019 00:54:28,300 --> 00:54:30,180 That's the way queues work. 1020 00:54:30,180 --> 00:54:32,650 So now let's do the same problem with a 1021 00:54:32,650 --> 00:54:34,640 breadth-first search. 1022 00:54:34,640 --> 00:54:36,190 So I start with the agenda. 1023 00:54:36,190 --> 00:54:43,260 I put in A. I pop off the head of the queue and stuff the 1024 00:54:43,260 --> 00:54:45,320 children at the end. 1025 00:54:45,320 --> 00:54:49,280 I pop off the beginning and stuff the children AB, AD. 1026 00:54:49,280 --> 00:54:52,200 1027 00:54:52,200 --> 00:54:54,520 That looks right. 1028 00:54:54,520 --> 00:54:57,940 That's the end of path one. 1029 00:54:57,940 --> 00:55:02,020 Now I pop off the beginning and stick in the children. 1030 00:55:02,020 --> 00:55:04,160 What are the children of AB? 1031 00:55:04,160 --> 00:55:06,840 Well, AB could go to ACE. 1032 00:55:06,840 --> 00:55:08,955 A is brain dead, so ABC-- 1033 00:55:08,955 --> 00:55:12,070 1034 00:55:12,070 --> 00:55:13,320 ABC or ABE. 1035 00:55:13,320 --> 00:55:16,670 1036 00:55:16,670 --> 00:55:20,340 ABC or ABE, that looks right. 1037 00:55:20,340 --> 00:55:26,130 Now pop off this guy, AD, and put his children at the end. 1038 00:55:26,130 --> 00:55:27,863 That's ADE and ADG. 1039 00:55:27,863 --> 00:55:35,690 1040 00:55:35,690 --> 00:55:37,870 I don't think I made a mistake yet. 1041 00:55:37,870 --> 00:55:40,430 Pop off the first guy, ABC. 1042 00:55:40,430 --> 00:55:44,350 Stick in his children ABC-- 1043 00:55:44,350 --> 00:55:49,930 ABC, it could go to B or F. Looks like F is the only one 1044 00:55:49,930 --> 00:55:52,630 that makes any sense. 1045 00:55:52,630 --> 00:55:54,850 ABC, that looks right. 1046 00:55:54,850 --> 00:56:01,750 ABE, put his children ABE-- 1047 00:56:01,750 --> 00:56:04,340 E could go to B-- that's brain dead-- 1048 00:56:04,340 --> 00:56:11,450 D, F, or H. D, F-- wait. 1049 00:56:11,450 --> 00:56:15,019 1050 00:56:15,019 --> 00:56:15,920 AUDIENCE: AB. 1051 00:56:15,920 --> 00:56:17,170 PROFESSOR: AB, thank you. 1052 00:56:17,170 --> 00:56:21,770 1053 00:56:21,770 --> 00:56:26,010 I'm supposed to be doing ABE followed by something, ABE 1054 00:56:26,010 --> 00:56:27,150 followed by something. 1055 00:56:27,150 --> 00:56:32,290 I don't want B. D is fine, F is fine, and H is fine. 1056 00:56:32,290 --> 00:56:44,320 D, F, and H. OK so far? 1057 00:56:44,320 --> 00:56:45,410 AUDIENCE: [INAUDIBLE] 1058 00:56:45,410 --> 00:56:47,000 PROFESSOR: Oh no, it's not right? 1059 00:56:47,000 --> 00:56:48,349 OK, what did I do wrong? 1060 00:56:48,349 --> 00:56:51,283 AUDIENCE: Just AB. 1061 00:56:51,283 --> 00:56:53,239 It's the fourth-- 1062 00:56:53,239 --> 00:56:54,217 PROFESSOR: Oh, here. 1063 00:56:54,217 --> 00:56:55,195 That's up here. 1064 00:56:55,195 --> 00:56:56,662 Is that [INAUDIBLE]. 1065 00:56:56,662 --> 00:56:57,640 AUDIENCE: Yeah. 1066 00:56:57,640 --> 00:56:58,618 PROFESSOR: Thank you. 1067 00:56:58,618 --> 00:57:00,090 That would be embarrassing. 1068 00:57:00,090 --> 00:57:03,010 OK, next pop off AD-- 1069 00:57:03,010 --> 00:57:04,940 This is why we have computers, right? 1070 00:57:04,940 --> 00:57:08,420 We don't normally do this by hand. 1071 00:57:08,420 --> 00:57:10,410 OK, so ADE-- 1072 00:57:10,410 --> 00:57:15,850 1073 00:57:15,850 --> 00:57:19,880 if I had ADE, I could do B-- 1074 00:57:19,880 --> 00:57:23,370 that seems OK, D seems bad-- 1075 00:57:23,370 --> 00:57:25,790 F, or H. So it would look like 1076 00:57:25,790 --> 00:57:37,490 B, F, H. OK, ADG. 1077 00:57:37,490 --> 00:57:43,160 1078 00:57:43,160 --> 00:57:48,013 A, D, G. It looks like H is my only option. 1079 00:57:48,013 --> 00:57:52,690 1080 00:57:52,690 --> 00:57:53,940 ABCF. 1081 00:57:53,940 --> 00:57:56,378 1082 00:57:56,378 --> 00:58:11,300 A, B, C, F. Looks like I could do E or I. Finally. 1083 00:58:11,300 --> 00:58:12,650 Now the only question is whether I got the 1084 00:58:12,650 --> 00:58:14,380 right number of states. 1085 00:58:14,380 --> 00:58:15,780 Let's assume I did. 1086 00:58:15,780 --> 00:58:17,030 So 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 -- 1087 00:58:17,030 --> 00:58:26,740 1088 00:58:26,740 --> 00:58:28,010 which happens to be the right answer. 1089 00:58:28,010 --> 00:58:29,820 At least it happens to be the answer I got this morning when 1090 00:58:29,820 --> 00:58:32,380 I was at breakfast. 1091 00:58:32,380 --> 00:58:34,220 So what did I just do? 1092 00:58:34,220 --> 00:58:37,450 I just did a breadth-first search. 1093 00:58:37,450 --> 00:58:40,030 1094 00:58:40,030 --> 00:58:41,660 Here's a transcript. 1095 00:58:41,660 --> 00:58:42,910 16 matches, good. 1096 00:58:42,910 --> 00:58:45,860 1097 00:58:45,860 --> 00:58:48,870 Breadth-first search has a different set of properties. 1098 00:58:48,870 --> 00:58:51,680 Notice that it took me longer. 1099 00:58:51,680 --> 00:58:55,490 But because it's breadth first, and because each row 1100 00:58:55,490 --> 00:58:58,020 corresponds to an increasing path length, it's always 1101 00:58:58,020 --> 00:59:00,190 guaranteed to give you the shortest answer. 1102 00:59:00,190 --> 00:59:02,070 That's good. 1103 00:59:02,070 --> 00:59:04,280 So it always gives you the shortest answer. 1104 00:59:04,280 --> 00:59:07,410 1105 00:59:07,410 --> 00:59:09,210 It requires more space. 1106 00:59:09,210 --> 00:59:10,930 I mean, you can see that just on the chalkboard. 1107 00:59:10,930 --> 00:59:13,960 1108 00:59:13,960 --> 00:59:17,140 And also it still didn't take care of your problem. 1109 00:59:17,140 --> 00:59:20,480 So this still seems like there's too much work. 1110 00:59:20,480 --> 00:59:24,690 1111 00:59:24,690 --> 00:59:28,360 I looked at 16 different places. 1112 00:59:28,360 --> 00:59:32,140 I did 16 visits. 1113 00:59:32,140 --> 00:59:34,800 There's just something completely wrong about that, 1114 00:59:34,800 --> 00:59:36,375 because there's only 9 states. 1115 00:59:36,375 --> 00:59:39,080 1116 00:59:39,080 --> 00:59:44,750 How could it take more visits than there are states? 1117 00:59:44,750 --> 00:59:46,930 So that just doesn't sound right. 1118 00:59:46,930 --> 00:59:48,830 And it's for exactly your point. 1119 00:59:48,830 --> 00:59:51,570 And so there's another idea that we can use, which is 1120 00:59:51,570 --> 00:59:56,170 called "dynamic programming." The idea in dynamic 1121 00:59:56,170 --> 01:00:00,370 programming, the principal is, if you think about a path that 1122 01:00:00,370 --> 01:00:08,000 goes from x is z through y, the best path from x to z 1123 01:00:08,000 --> 01:00:11,820 through y is the sum of two paths-- 1124 01:00:11,820 --> 01:00:15,608 the best path from x to y and the best path from y to z. 1125 01:00:15,608 --> 01:00:18,750 1126 01:00:18,750 --> 01:00:20,520 If you think about that, that has to be the case. 1127 01:00:20,520 --> 01:00:23,040 1128 01:00:23,040 --> 01:00:27,690 And if we further assume that we're going to do breadth 1129 01:00:27,690 --> 01:00:33,720 first, then the first time that we see a state is the 1130 01:00:33,720 --> 01:00:35,420 best way to get there. 1131 01:00:35,420 --> 01:00:38,100 1132 01:00:38,100 --> 01:00:40,840 So what we can do then, in order to take care of your 1133 01:00:40,840 --> 01:00:45,530 case, is keep track of the states we've already visited. 1134 01:00:45,530 --> 01:00:49,760 If we've already visited a state, it appears earlier in 1135 01:00:49,760 --> 01:00:54,480 the tree, there's no point in thinking about it further. 1136 01:00:54,480 --> 01:00:57,440 That's the idea of dynamic programming. 1137 01:00:57,440 --> 01:00:59,980 And that's also easy to implement. 1138 01:00:59,980 --> 01:01:02,370 All we need to do is keep track of all those places 1139 01:01:02,370 --> 01:01:04,940 we've already visited. 1140 01:01:04,940 --> 01:01:13,440 So we make a dictionary called "visited." So I initialize 1141 01:01:13,440 --> 01:01:15,510 before I start looking at the children. 1142 01:01:15,510 --> 01:01:18,910 I initialize right after I set up the initial 1143 01:01:18,910 --> 01:01:20,900 contents of the agenda. 1144 01:01:20,900 --> 01:01:23,640 I create this dictionary called visited. 1145 01:01:23,640 --> 01:01:30,010 And every time I visit a new state, I put that state in the 1146 01:01:30,010 --> 01:01:32,430 visit list. 1147 01:01:32,430 --> 01:01:41,520 Then before I add the child to the agenda I ask, is the child 1148 01:01:41,520 --> 01:01:45,510 already in the visit list? 1149 01:01:45,510 --> 01:01:47,950 If the child's already there, well forget it. 1150 01:01:47,950 --> 01:01:51,030 I don't need him. 1151 01:01:51,030 --> 01:01:57,560 Otherwise, just before you push the new state, remember 1152 01:01:57,560 --> 01:02:02,180 now that that's an element that's been visited. 1153 01:02:02,180 --> 01:02:05,420 So the idea, then, is that by keeping track of who you've 1154 01:02:05,420 --> 01:02:08,890 already looked at, you can avoid looking-- 1155 01:02:08,890 --> 01:02:15,840 so if there's a depth-3 way to get to D, and a depth-2, then 1156 01:02:15,840 --> 01:02:19,620 I don't need to worry about the previous ones, because 1157 01:02:19,620 --> 01:02:20,560 it's already in the visit list. 1158 01:02:20,560 --> 01:02:21,535 Yes? 1159 01:02:21,535 --> 01:02:25,495 AUDIENCE: Why do we still need the new child states up there? 1160 01:02:25,495 --> 01:02:28,465 PROFESSOR: Why do we still have the new child states? 1161 01:02:28,465 --> 01:02:30,940 AUDIENCE: The placement was based [? on-- ?] the 1162 01:02:30,940 --> 01:02:32,425 [INAUDIBLE] state. 1163 01:02:32,425 --> 01:02:35,395 PROFESSOR: I think you're right. 1164 01:02:35,395 --> 01:02:36,880 I should think about that. 1165 01:02:36,880 --> 01:02:37,870 I think you're right. 1166 01:02:37,870 --> 01:02:41,630 I think when I was modifying the code for the different 1167 01:02:41,630 --> 01:02:43,960 places I slipped and could have removed that line. 1168 01:02:43,960 --> 01:02:45,540 I think you're right. 1169 01:02:45,540 --> 01:02:47,360 I'll have to think about it, but I think you're right. 1170 01:02:47,360 --> 01:02:50,370 So if that line magically disappears from the online 1171 01:02:50,370 --> 01:02:51,620 version, he's right. 1172 01:02:51,620 --> 01:02:55,020 1173 01:02:55,020 --> 01:02:58,300 OK, so now one last problem. 1174 01:02:58,300 --> 01:03:04,840 I want to see if I can figure out what would happen with 1175 01:03:04,840 --> 01:03:07,930 dynamic programming. 1176 01:03:07,930 --> 01:03:10,500 So I want to do breadth first. 1177 01:03:10,500 --> 01:03:14,500 And just as a warning, I'm hypoglycemic at this point. 1178 01:03:14,500 --> 01:03:17,440 So there may be more errors than usual. 1179 01:03:17,440 --> 01:03:19,860 So I need to keep track of two things. 1180 01:03:19,860 --> 01:03:22,580 I need to keep track of the visit list. 1181 01:03:22,580 --> 01:03:26,460 And I need to keep track of the agenda. 1182 01:03:26,460 --> 01:03:29,650 So there's two lists I have to keep track of. 1183 01:03:29,650 --> 01:03:30,320 OK. 1184 01:03:30,320 --> 01:03:33,000 Let's start out by saying that the agenda 1185 01:03:33,000 --> 01:03:34,970 contains the start element. 1186 01:03:34,970 --> 01:03:44,100 That's A. That means we visited A. It's breadth first, 1187 01:03:44,100 --> 01:03:47,550 so I want to take the first guy out of the queue and add 1188 01:03:47,550 --> 01:03:49,810 his children to the end of the queue. 1189 01:03:49,810 --> 01:03:51,730 So take the first guy out of the queue. 1190 01:03:51,730 --> 01:03:52,790 Add his children. 1191 01:03:52,790 --> 01:03:59,510 A's children are B and D, which means that I've now 1192 01:03:59,510 --> 01:04:06,620 visited B and D. 1193 01:04:06,620 --> 01:04:10,460 Now I want to take out the first guy from the queue, AB, 1194 01:04:10,460 --> 01:04:14,583 and I want to put his children at the end of the queue. 1195 01:04:14,583 --> 01:04:17,060 AB's children are A-- 1196 01:04:17,060 --> 01:04:19,200 that's been visited, C-- 1197 01:04:19,200 --> 01:04:21,040 not visited, and E-- 1198 01:04:21,040 --> 01:04:22,740 not visited. 1199 01:04:22,740 --> 01:04:24,162 So ABCE. 1200 01:04:24,162 --> 01:04:28,580 1201 01:04:28,580 --> 01:04:35,810 But that visits C and E. 1202 01:04:35,810 --> 01:04:42,580 Now I want to take out AD and put its children at the end. 1203 01:04:42,580 --> 01:04:46,060 AD is AEG. 1204 01:04:46,060 --> 01:04:52,245 A is visited, E is visited, which leaves just G, so ADG . 1205 01:04:52,245 --> 01:04:54,800 1206 01:04:54,800 --> 01:04:59,700 And that visits G. 1207 01:04:59,700 --> 01:05:04,940 Then I want to take out ABC and put in its children, A, B, 1208 01:05:04,940 --> 01:05:09,180 C. ABC, oh dear. 1209 01:05:09,180 --> 01:05:09,850 AB-- 1210 01:05:09,850 --> 01:05:11,920 I'm looking up there. 1211 01:05:11,920 --> 01:05:14,360 I said I'm hypoglycemic. 1212 01:05:14,360 --> 01:05:15,710 ABC-- 1213 01:05:15,710 --> 01:05:20,030 ABC -- could be B or F. Well, B's no good. 1214 01:05:20,030 --> 01:05:27,290 Which leaves F, but that visits F. 1215 01:05:27,290 --> 01:05:28,540 So now, ABE. 1216 01:05:28,540 --> 01:05:32,740 1217 01:05:32,740 --> 01:05:38,570 ABE, so that could be B, D, F, H. B-- 1218 01:05:38,570 --> 01:05:40,270 visited, D-- 1219 01:05:40,270 --> 01:05:41,820 visited, F-- 1220 01:05:41,820 --> 01:05:43,562 visited, H-- 1221 01:05:43,562 --> 01:05:44,812 OK. 1222 01:05:44,812 --> 01:05:47,530 1223 01:05:47,530 --> 01:05:50,760 That visits H. 1224 01:05:50,760 --> 01:05:52,010 Now take out ADG. 1225 01:05:52,010 --> 01:05:55,560 1226 01:05:55,560 --> 01:05:58,100 Children of ADG-- 1227 01:05:58,100 --> 01:06:03,760 ADG, two children, D and H. D and H, they're both there. 1228 01:06:03,760 --> 01:06:05,380 That didn't work. 1229 01:06:05,380 --> 01:06:09,567 There are no children of ADG. 1230 01:06:09,567 --> 01:06:10,817 ABCF-- 1231 01:06:10,817 --> 01:06:13,810 1232 01:06:13,810 --> 01:06:17,210 ABCF, three children-- 1233 01:06:17,210 --> 01:06:20,590 C, E, I. C-- 1234 01:06:20,590 --> 01:06:21,710 visited, E-- 1235 01:06:21,710 --> 01:06:22,970 visited, I-- 1236 01:06:22,970 --> 01:06:25,240 done. 1237 01:06:25,240 --> 01:06:26,070 Found the right answer. 1238 01:06:26,070 --> 01:06:27,320 1, 2, 3, 4, 5, 6, 7, 8 -- 1239 01:06:27,320 --> 01:06:29,410 1240 01:06:29,410 --> 01:06:32,050 8 visits. 1241 01:06:32,050 --> 01:06:40,910 So I've got the same answer, and it's optimal, and I did 1242 01:06:40,910 --> 01:06:42,560 fewer than 9 visits. 1243 01:06:42,560 --> 01:06:44,800 9 was the number of states. 1244 01:06:44,800 --> 01:06:48,790 So this algorithm will always have those properties. 1245 01:06:48,790 --> 01:06:52,380 So the dynamic programming-- 1246 01:06:52,380 --> 01:06:53,630 oh, I forgot a slide. 1247 01:06:53,630 --> 01:06:56,270 1248 01:06:56,270 --> 01:06:59,360 The dynamic programming with breadth-first search will 1249 01:06:59,360 --> 01:07:01,410 always find the best. 1250 01:07:01,410 --> 01:07:04,600 It will never take longer than the number of states. 1251 01:07:04,600 --> 01:07:07,400 So in this problem that had a finite number of states, even 1252 01:07:07,400 --> 01:07:10,360 though I had an infinite number of paths-- 1253 01:07:10,360 --> 01:07:13,290 because you can go around in circles-- 1254 01:07:13,290 --> 01:07:16,910 it'll still never take more than the number of states. 1255 01:07:16,910 --> 01:07:21,390 And all that it requires to implement is to maintain two 1256 01:07:21,390 --> 01:07:24,040 lists instead of one. 1257 01:07:24,040 --> 01:07:27,670 So the point, then, is that today we looked at a variety-- 1258 01:07:27,670 --> 01:07:29,980 we looked at two real different kinds of search 1259 01:07:29,980 --> 01:07:32,240 algorithms, depth-first search and breadth-first search. 1260 01:07:32,240 --> 01:07:34,600 And we looked at a number of different pruning rules. 1261 01:07:34,600 --> 01:07:36,610 Pruning rule (1) -- don't go to some place that you've 1262 01:07:36,610 --> 01:07:37,880 already visited. 1263 01:07:37,880 --> 01:07:39,570 Pruning rule (2) -- if you have two children that go to 1264 01:07:39,570 --> 01:07:42,200 the same place, only think about one of them. 1265 01:07:42,200 --> 01:07:44,510 You can consider dynamic programming to be a third 1266 01:07:44,510 --> 01:07:49,030 pruning rule, because that's the effect of it. 1267 01:07:49,030 --> 01:07:54,850 And the final announcement, don't forget about Wednesday. 1268 01:07:54,850 --> 01:07:56,100 Have a good week. 1269 01:07:56,100 --> 01:08:05,503