1 00:00:00,000 --> 00:00:05,592 2 00:00:05,592 --> 00:00:06,800 KENDRA PUGH: Hi. 3 00:00:06,800 --> 00:00:08,370 Today, I'd like to talk to you about search. 4 00:00:08,370 --> 00:00:10,850 Previously, we've talked about ways to model uncertainty and 5 00:00:10,850 --> 00:00:13,370 also how to make estimations about a particular system when 6 00:00:13,370 --> 00:00:15,520 we're observing it from the outside or when we don't have 7 00:00:15,520 --> 00:00:17,130 perfect information. 8 00:00:17,130 --> 00:00:19,930 At this point, we've almost got enough components to 9 00:00:19,930 --> 00:00:22,670 attempt to make an autonomous system. 10 00:00:22,670 --> 00:00:25,860 But at this point, we also haven't enabled our autonomous 11 00:00:25,860 --> 00:00:29,340 systems to make complex decisions for itself. 12 00:00:29,340 --> 00:00:33,220 This is why we want to be able to encode search. 13 00:00:33,220 --> 00:00:37,620 Or we want to be able to enable a system to make an 14 00:00:37,620 --> 00:00:41,210 evaluation of a succession of decisions, or a succession of 15 00:00:41,210 --> 00:00:44,320 actions, when there are multiple choices and possibly 16 00:00:44,320 --> 00:00:46,020 multiple choices at every level. 17 00:00:46,020 --> 00:00:48,580 So as a consequence of being able to do search, our 18 00:00:48,580 --> 00:00:52,340 autonomous system should be able to complete a successive 19 00:00:52,340 --> 00:00:53,590 grouping of actions. 20 00:00:53,590 --> 00:00:57,810 21 00:00:57,810 --> 00:01:00,550 In 6.01, we're going to be searching state spaces. 22 00:01:00,550 --> 00:01:03,710 And searching state spaces borrows a lot of ideas from 23 00:01:03,710 --> 00:01:05,910 state transition diagrams, or what we already know about 24 00:01:05,910 --> 00:01:07,080 state machines. 25 00:01:07,080 --> 00:01:09,160 When we're searching a state space, we want to know what 26 00:01:09,160 --> 00:01:11,640 states we're searching, what the transitions between them 27 00:01:11,640 --> 00:01:14,650 are going to look like, or how the access to the transitions 28 00:01:14,650 --> 00:01:19,070 from a given state to all the states that are its neighbors. 29 00:01:19,070 --> 00:01:22,250 We're going to want the start state to be specified so we 30 00:01:22,250 --> 00:01:23,900 know where to begin. 31 00:01:23,900 --> 00:01:26,440 We want a goal test, which actually specifies what we're 32 00:01:26,440 --> 00:01:29,190 looking for as a consequence of the search. 33 00:01:29,190 --> 00:01:31,260 Or if we get to a state and we want to know whether or not 34 00:01:31,260 --> 00:01:33,350 we're done, we use our goal test. 35 00:01:33,350 --> 00:01:35,730 And it could look at the output of the state, or 36 00:01:35,730 --> 00:01:39,050 actually just the state name, that sort of thing. 37 00:01:39,050 --> 00:01:40,460 The other thing that we're going to have while we're 38 00:01:40,460 --> 00:01:42,220 searching is a legal action list. 39 00:01:42,220 --> 00:01:44,890 40 00:01:44,890 --> 00:01:47,220 The searches that we're going to do today, you and I are 41 00:01:47,220 --> 00:01:49,290 going to be able to see the entire state transition 42 00:01:49,290 --> 00:01:51,540 diagram at once. 43 00:01:51,540 --> 00:01:55,380 But if we're encoding how to search on our robot, our robot 44 00:01:55,380 --> 00:01:57,950 can't see the entire state transition diagram at once 45 00:01:57,950 --> 00:02:00,140 because if it could, then it wouldn't have to do search. 46 00:02:00,140 --> 00:02:03,660 It would know how to get there from here. 47 00:02:03,660 --> 00:02:07,310 Therefore, we give our system a legal action list, or all 48 00:02:07,310 --> 00:02:08,539 the actions that it should attempt to 49 00:02:08,539 --> 00:02:10,020 do at a given state. 50 00:02:10,020 --> 00:02:12,680 It's entirely possible that there aren't legal transitions 51 00:02:12,680 --> 00:02:15,070 at every state for every legal action. 52 00:02:15,070 --> 00:02:16,870 But it's good to have an exhaustive list of things to 53 00:02:16,870 --> 00:02:21,010 try and see if they succeed or fail and, as a consequence, 54 00:02:21,010 --> 00:02:24,390 what state you end up visiting every time you try 55 00:02:24,390 --> 00:02:25,640 to do one of these. 56 00:02:25,640 --> 00:02:29,930 57 00:02:29,930 --> 00:02:31,080 Being able to do search is great. 58 00:02:31,080 --> 00:02:33,980 But we also want to be able to keep track of where we 59 00:02:33,980 --> 00:02:37,520 searched and how so that once we're done searching, we can 60 00:02:37,520 --> 00:02:40,150 actually execute the best thing. 61 00:02:40,150 --> 00:02:43,530 We're going to use a search tree to keep track of where 62 00:02:43,530 --> 00:02:45,190 we've been and how we got there. 63 00:02:45,190 --> 00:02:47,700 Search tree is going to be comprised of nodes. 64 00:02:47,700 --> 00:02:49,010 It's otherwise going to look like a 65 00:02:49,010 --> 00:02:50,120 directed, acyclic graph. 66 00:02:50,120 --> 00:02:52,180 And it's going to have a lot of similarity to any 67 00:02:52,180 --> 00:02:54,320 particular state transition diagram 68 00:02:54,320 --> 00:02:56,220 that we end up searching. 69 00:02:56,220 --> 00:02:58,890 But it's going to have nodes instead of states. 70 00:02:58,890 --> 00:02:59,700 Nodes are different. 71 00:02:59,700 --> 00:03:08,420 Nodes represent both the state that you've visited as a 72 00:03:08,420 --> 00:03:14,190 consequence of expanding its parent node, the parent node, 73 00:03:14,190 --> 00:03:16,180 or the place that you came from as a consequence of 74 00:03:16,180 --> 00:03:19,110 getting to that node, and the transition that you made in 75 00:03:19,110 --> 00:03:21,550 order to get there, or the action that happened that got 76 00:03:21,550 --> 00:03:23,190 you from the parent node to the child. 77 00:03:23,190 --> 00:03:27,180 78 00:03:27,180 --> 00:03:30,660 Keeping track of a list of nodes is known as a path, or 79 00:03:30,660 --> 00:03:33,950 it specifies where you've been and how you got there. 80 00:03:33,950 --> 00:03:36,150 And if you're at a given node, you can actually use the 81 00:03:36,150 --> 00:03:39,720 reference to the parent node and the action to trace back 82 00:03:39,720 --> 00:03:43,410 from whatever node you're at currently to its parent node, 83 00:03:43,410 --> 00:03:46,300 to its parent node, to its parent node, and then finally 84 00:03:46,300 --> 00:03:47,670 get back to the start state. 85 00:03:47,670 --> 00:03:49,540 At that point, you'll know what path to take. 86 00:03:49,540 --> 00:03:52,040 87 00:03:52,040 --> 00:03:55,170 So the only thing left to do is, how do you figure out 88 00:03:55,170 --> 00:03:58,380 which paths to follow first? 89 00:03:58,380 --> 00:03:59,950 That's where the agenda comes in. 90 00:03:59,950 --> 00:04:02,370 The agenda is going to be the collection of all partial 91 00:04:02,370 --> 00:04:10,380 paths you've ever created as a consequence of expanding nodes 92 00:04:10,380 --> 00:04:15,210 and then putting its child nodes on a partial path meant 93 00:04:15,210 --> 00:04:19,990 for future expansion. 94 00:04:19,990 --> 00:04:23,050 The order in which you add and remove things to the agenda is 95 00:04:23,050 --> 00:04:27,270 going to determine what your search tree looks like. 96 00:04:27,270 --> 00:04:28,570 That's a lot of information. 97 00:04:28,570 --> 00:04:30,220 At this point, I'm going to go over an example. 98 00:04:30,220 --> 00:04:35,310 99 00:04:35,310 --> 00:04:38,400 We're going to search the state transition diagram. 100 00:04:38,400 --> 00:04:41,850 We're going to start at A. And our goal test would be whether 101 00:04:41,850 --> 00:04:46,060 or not our state was equal to E. 102 00:04:46,060 --> 00:04:47,370 Today, we're going to try two different 103 00:04:47,370 --> 00:04:48,770 kinds of basic search. 104 00:04:48,770 --> 00:04:51,480 One is referred to as breadth-first search, or BFS. 105 00:04:51,480 --> 00:04:55,610 And one is referred to as depth-first search, or DFS. 106 00:04:55,610 --> 00:04:58,780 Breadth-first search refers to the idea that as you build 107 00:04:58,780 --> 00:05:02,600 your search tree, you're going to exhaustively expand all the 108 00:05:02,600 --> 00:05:06,120 nodes at a given level before advancing to the next level, 109 00:05:06,120 --> 00:05:10,170 or all the given nodes at a given depth before expanding 110 00:05:10,170 --> 00:05:11,420 to the next depth. 111 00:05:11,420 --> 00:05:13,450 112 00:05:13,450 --> 00:05:15,300 This means you're being very thorough. 113 00:05:15,300 --> 00:05:18,300 It also means that you're guaranteed to find the 114 00:05:18,300 --> 00:05:22,805 shortest path from your start node to the goal if it exists. 115 00:05:22,805 --> 00:05:26,000 116 00:05:26,000 --> 00:05:29,850 Depth-first search is the opposite. 117 00:05:29,850 --> 00:05:31,890 As a consequence of depth-first search, you're 118 00:05:31,890 --> 00:05:36,160 going to expand all the nodes in a given branch as far down 119 00:05:36,160 --> 00:05:38,390 the tree as you possibly can before 120 00:05:38,390 --> 00:05:41,680 advancing to the next branch. 121 00:05:41,680 --> 00:05:44,450 It takes up a lot less space than the breadth-first search, 122 00:05:44,450 --> 00:05:47,400 but it's not guaranteed to find the optimal path. 123 00:05:47,400 --> 00:05:49,910 Another way to think about these two types of search is 124 00:05:49,910 --> 00:05:52,470 that if you're doing breadth-first search, then 125 00:05:52,470 --> 00:05:55,700 your agenda acts as a cue. 126 00:05:55,700 --> 00:05:57,870 First items in, or first partial paths that you 127 00:05:57,870 --> 00:06:00,880 discover, are the first items out or the first partial paths 128 00:06:00,880 --> 00:06:03,860 that you end up expanding. 129 00:06:03,860 --> 00:06:12,060 Depth-first search is when the agenda is used as a stack, or 130 00:06:12,060 --> 00:06:15,740 the first partial paths that you visit are the first 131 00:06:15,740 --> 00:06:16,760 partial paths-- 132 00:06:16,760 --> 00:06:20,640 or, the most recent partial paths that you visited are 133 00:06:20,640 --> 00:06:24,310 going to be the partial paths that you first extend. 134 00:06:24,310 --> 00:06:25,980 First in, last out. 135 00:06:25,980 --> 00:06:27,592 Or, last in, first out. 136 00:06:27,592 --> 00:06:30,250 137 00:06:30,250 --> 00:06:33,330 Let me walk through a couple iterations on this state 138 00:06:33,330 --> 00:06:34,670 transition diagram. 139 00:06:34,670 --> 00:06:38,930 And hopefully, it'll be clearer what's going on. 140 00:06:38,930 --> 00:06:41,740 The first thing that happens is that you end up visiting 141 00:06:41,740 --> 00:06:43,030 and expanding the start node. 142 00:06:43,030 --> 00:06:45,300 That's pretty straightforward. 143 00:06:45,300 --> 00:06:49,940 So the path A is going to be added to both agendas. 144 00:06:49,940 --> 00:06:55,750 And the node A is going to be visited first 145 00:06:55,750 --> 00:06:57,000 on both search trees. 146 00:06:57,000 --> 00:07:00,450 147 00:07:00,450 --> 00:07:04,360 If, in the general sense, I say that I'm going to make a 148 00:07:04,360 --> 00:07:08,320 transition to states in alphabetical order, and that's 149 00:07:08,320 --> 00:07:12,760 the order in which I'm going to add them to my agenda, 150 00:07:12,760 --> 00:07:15,180 that's going to be reflected in what I write up here. 151 00:07:15,180 --> 00:07:18,570 Let's say that I'm going to visit new nodes in 152 00:07:18,570 --> 00:07:20,450 alphabetical order. 153 00:07:20,450 --> 00:07:26,880 So nodes I would visit are B and C, and I'm going to add AB 154 00:07:26,880 --> 00:07:28,560 and AC to my agenda. 155 00:07:28,560 --> 00:07:57,260 156 00:07:57,260 --> 00:07:58,930 Here's where the difference between breadth-first search 157 00:07:58,930 --> 00:08:00,338 and depth-first search comes in. 158 00:08:00,338 --> 00:08:03,150 159 00:08:03,150 --> 00:08:06,420 In breadth-first search, because I'm following the 160 00:08:06,420 --> 00:08:11,800 convention first in, first out, if I place the partial 161 00:08:11,800 --> 00:08:18,250 path AB in my agenda first, then I'm going to expand B as 162 00:08:18,250 --> 00:08:22,780 a consequence of the partial path AB first. 163 00:08:22,780 --> 00:08:24,270 So when I go to B, I'm actually 164 00:08:24,270 --> 00:08:26,750 going to expand B now. 165 00:08:26,750 --> 00:08:29,600 I'm going to look at the nodes that I can visit as a 166 00:08:29,600 --> 00:08:35,120 consequence of expanding B. The ones that I can visit are 167 00:08:35,120 --> 00:08:44,730 C and D. And I'm going to add the partial paths ABC and ABD 168 00:08:44,730 --> 00:08:45,980 to my agenda. 169 00:08:45,980 --> 00:08:48,370 170 00:08:48,370 --> 00:08:51,080 So AC, I'm just going to move to the front of the queue, or 171 00:08:51,080 --> 00:08:57,190 the agenda, and I'm going to add ABC and ABD. 172 00:08:57,190 --> 00:09:07,630 173 00:09:07,630 --> 00:09:16,820 And I got there through B. So I'm going to add C and D here. 174 00:09:16,820 --> 00:09:21,050 175 00:09:21,050 --> 00:09:22,860 Depth-first search grabs from the 176 00:09:22,860 --> 00:09:25,500 opposite end of the agenda. 177 00:09:25,500 --> 00:09:29,210 So the first thing I'm going to look at is AC. 178 00:09:29,210 --> 00:09:35,850 I'm going to expand to C, look at the nodes that I can reach 179 00:09:35,850 --> 00:09:49,050 as a consequence of expanding C, and visit B and D. 180 00:09:49,050 --> 00:09:51,530 AB is still hanging out here. 181 00:09:51,530 --> 00:09:58,060 I popped off AC to use it in order to expand C's children. 182 00:09:58,060 --> 00:10:06,570 And I'm going to add ACB first and ACD second. 183 00:10:06,570 --> 00:10:19,270 184 00:10:19,270 --> 00:10:20,900 Note that our search trees already look different. 185 00:10:20,900 --> 00:10:25,290 186 00:10:25,290 --> 00:10:27,540 And we'll actually end up reaching the goal using one of 187 00:10:27,540 --> 00:10:31,500 these search strategies first than the other, or as opposed 188 00:10:31,500 --> 00:10:34,390 to the other. 189 00:10:34,390 --> 00:10:37,810 If I go back to breadth-first search, I'm going to pop the 190 00:10:37,810 --> 00:10:42,040 partial path AC off the front of my agenda. 191 00:10:42,040 --> 00:10:47,720 I'm going to expand C. Expanding C gets me B and D. 192 00:10:47,720 --> 00:10:50,910 I'm going to move over my existing partial paths. 193 00:10:50,910 --> 00:10:57,980 194 00:10:57,980 --> 00:11:00,860 And add ACB and ACD. 195 00:11:00,860 --> 00:11:15,350 196 00:11:15,350 --> 00:11:17,680 I've staggered these in order to indicate that they're a 197 00:11:17,680 --> 00:11:20,130 consequence of a third iteration of 198 00:11:20,130 --> 00:11:21,140 breadth-first search. 199 00:11:21,140 --> 00:11:23,020 But they're actually considered to be at the same 200 00:11:23,020 --> 00:11:25,770 depth, since their parents are considered to be at the same 201 00:11:25,770 --> 00:11:28,360 depth, since their parents are parents of the start node. 202 00:11:28,360 --> 00:11:31,070 203 00:11:31,070 --> 00:11:33,950 That's the defining feature of breadth-first research is the 204 00:11:33,950 --> 00:11:36,290 fact that we're going to exhaustively search a given 205 00:11:36,290 --> 00:11:41,280 depth in our search tree before advancing to the next 206 00:11:41,280 --> 00:11:42,530 depth level. 207 00:11:42,530 --> 00:11:46,820 208 00:11:46,820 --> 00:11:51,460 If I run one more iteration of depth-first search, again, I'm 209 00:11:51,460 --> 00:11:57,340 popping partial paths off this end of the agenda. 210 00:11:57,340 --> 00:12:00,860 I'm going to expand D. D one transition 211 00:12:00,860 --> 00:12:02,700 available to a node. 212 00:12:02,700 --> 00:12:04,680 And in plain old fashioned breadth-first search and 213 00:12:04,680 --> 00:12:08,620 depth-first search, I run my goal test when I visit a node. 214 00:12:08,620 --> 00:12:11,370 So at this point, I would test whether or not 215 00:12:11,370 --> 00:12:13,030 E was my goal test. 216 00:12:13,030 --> 00:12:15,620 I would discover it's my goal test. 217 00:12:15,620 --> 00:12:18,540 My search would return successfully and return the 218 00:12:18,540 --> 00:12:22,170 path found. 219 00:12:22,170 --> 00:12:31,390 So AB and ACB remain on the agenda. 220 00:12:31,390 --> 00:12:38,430 I popped off ACD in order to expand D. And 221 00:12:38,430 --> 00:12:39,680 I found this path. 222 00:12:39,680 --> 00:12:48,360 223 00:12:48,360 --> 00:12:50,190 At this point, I've concluded depth-first search. 224 00:12:50,190 --> 00:12:52,320 I'm going to do one more around of breadth-first search 225 00:12:52,320 --> 00:12:53,850 to demonstrate an important rule. 226 00:12:53,850 --> 00:12:56,380 227 00:12:56,380 --> 00:13:07,680 If I pop ABC off the agenda and move all these over, if 228 00:13:07,680 --> 00:13:13,270 I'm looking at ABC, and I look at the children of C, the two 229 00:13:13,270 --> 00:13:18,260 children of C are B and D. So the first partial path that I 230 00:13:18,260 --> 00:13:21,480 would end up adding to the agenda as a consequence of 231 00:13:21,480 --> 00:13:24,550 expanding C in this case would be ABCD. 232 00:13:24,550 --> 00:13:34,370 233 00:13:34,370 --> 00:13:37,900 And it would look like this. 234 00:13:37,900 --> 00:13:44,100 235 00:13:44,100 --> 00:13:46,740 You'll notice that we're going to create an infinite loop. 236 00:13:46,740 --> 00:13:51,320 And there are two basic rules of basic search that I need to 237 00:13:51,320 --> 00:13:54,370 emphasize now to prevent you from doing things like 238 00:13:54,370 --> 00:13:56,750 creating an infinite loop. 239 00:13:56,750 --> 00:13:58,900 If you look in the textbook, they're called "How to Not be 240 00:13:58,900 --> 00:14:03,410 Completely Stupid." 241 00:14:03,410 --> 00:14:06,330 If at any point you're visiting a node in your 242 00:14:06,330 --> 00:14:10,760 partial path that already exists in your partial path, 243 00:14:10,760 --> 00:14:13,560 don't add it to that partial path. 244 00:14:13,560 --> 00:14:15,880 You'll prevent yourself from creating a cycle. 245 00:14:15,880 --> 00:14:17,910 Because if you visit the same node more than once, you've 246 00:14:17,910 --> 00:14:21,060 actually done more work than you need to. 247 00:14:21,060 --> 00:14:22,230 The second rule-- 248 00:14:22,230 --> 00:14:24,160 and it's not demonstrated well on this 249 00:14:24,160 --> 00:14:25,580 state transition diagram. 250 00:14:25,580 --> 00:14:33,780 But, for instance, if I had two arrows from B to D, 251 00:14:33,780 --> 00:14:35,610 there's no particular reason to consider 252 00:14:35,610 --> 00:14:37,630 both of these actions. 253 00:14:37,630 --> 00:14:40,240 And if you have a state transition diagram that allows 254 00:14:40,240 --> 00:14:44,670 multiple transitions from one state to another based on 255 00:14:44,670 --> 00:14:46,720 different actions, then you need to come up with some sort 256 00:14:46,720 --> 00:14:48,865 of rule to decide between the two actions. 257 00:14:48,865 --> 00:14:52,240 258 00:14:52,240 --> 00:14:54,660 That's the second rule of how to not be completely stupid is 259 00:14:54,660 --> 00:14:57,420 -- if you have more than one transition from one state to 260 00:14:57,420 --> 00:15:01,190 another as a consequence of doing search, pick one and 261 00:15:01,190 --> 00:15:02,440 come up with a rule to pick one. 262 00:15:02,440 --> 00:15:06,070 263 00:15:06,070 --> 00:15:08,330 This covers basic search. 264 00:15:08,330 --> 00:15:10,660 Next week, I'm going to talk about dynamic programming, 265 00:15:10,660 --> 00:15:11,910 costs, and heuristics. 266 00:15:11,910 --> 00:15:13,620