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:19,790 hundreds of MIT courses, visit MIT OpenCourseWare at 8 00:00:19,790 --> 00:00:21,040 ocw.mit.edu. 9 00:00:21,040 --> 00:00:25,664 10 00:00:25,664 --> 00:00:28,050 PROFESSOR: You guys have been talking about graphs in 11 00:00:28,050 --> 00:00:29,740 lecture, right? 12 00:00:29,740 --> 00:00:31,600 So what are graphs? 13 00:00:31,600 --> 00:00:41,280 14 00:00:41,280 --> 00:00:48,290 So graphs are a kind of formalism that have 15 00:00:48,290 --> 00:00:51,380 vertices and edges. 16 00:00:51,380 --> 00:00:53,730 A set of vertices is-- you can think of it-- it's 17 00:00:53,730 --> 00:00:54,980 like a set of things. 18 00:00:54,980 --> 00:00:58,080 19 00:00:58,080 --> 00:01:01,560 And then the edges are the relationships 20 00:01:01,560 --> 00:01:03,200 between those things. 21 00:01:03,200 --> 00:01:08,970 So the set of all your friendships and your friends' 22 00:01:08,970 --> 00:01:11,620 friendships could be considered a graph. 23 00:01:11,620 --> 00:01:19,560 So if this is me and this is all two of my friends, then an 24 00:01:19,560 --> 00:01:23,630 edge between us would indicate a relationship of friendship. 25 00:01:23,630 --> 00:01:26,430 But there's no edge here, so there's no friendship 26 00:01:26,430 --> 00:01:27,762 between these two. 27 00:01:27,762 --> 00:01:31,392 28 00:01:31,392 --> 00:01:32,630 AUDIENCE: [INAUDIBLE] 29 00:01:32,630 --> 00:01:33,900 PROFESSOR: Yes. 30 00:01:33,900 --> 00:01:42,290 So you have vertices, which are also called nodes, and 31 00:01:42,290 --> 00:01:48,390 then you have edges, and they could also be called arcs. 32 00:01:48,390 --> 00:01:54,430 So if you see any of these names, these two are the same, 33 00:01:54,430 --> 00:01:55,680 and these two are the same. 34 00:01:55,680 --> 00:01:58,200 35 00:01:58,200 --> 00:02:02,876 So what kinds of graphs do we have? 36 00:02:02,876 --> 00:02:05,136 AUDIENCE: [INAUDIBLE] 37 00:02:05,136 --> 00:02:08,150 PROFESSOR: So there's a directed graph, and there's an 38 00:02:08,150 --> 00:02:09,560 undirected graph. 39 00:02:09,560 --> 00:02:12,950 So up on the screen here, is a directed graph, right? 40 00:02:12,950 --> 00:02:14,200 And so-- 41 00:02:14,200 --> 00:02:16,750 42 00:02:16,750 --> 00:02:17,900 I'm not a sports fan. 43 00:02:17,900 --> 00:02:20,530 I think those are the Bruins, and I don't know what the 44 00:02:20,530 --> 00:02:21,670 other team is. 45 00:02:21,670 --> 00:02:23,594 Do you know? 46 00:02:23,594 --> 00:02:24,560 OK. 47 00:02:24,560 --> 00:02:29,540 Yes, I think it's a hockey team somewhere up in Montreal. 48 00:02:29,540 --> 00:02:34,990 So this is a representation or a graph representation of 49 00:02:34,990 --> 00:02:38,110 cities, which are the nodes and vertices and then the 50 00:02:38,110 --> 00:02:40,840 roads that connect the cities. 51 00:02:40,840 --> 00:02:45,720 And, obviously, it's not to scale or accurate, but it's an 52 00:02:45,720 --> 00:02:48,030 abstraction, so we're OK with that. 53 00:02:48,030 --> 00:02:52,380 And the question here is what's the path to get from 54 00:02:52,380 --> 00:02:55,080 Boston to Montreal. 55 00:02:55,080 --> 00:02:58,230 So in this case, it's a directed graph, so that means 56 00:02:58,230 --> 00:03:03,195 that we can only go this direction from node to node, 57 00:03:03,195 --> 00:03:05,240 in the direction of the arrow. 58 00:03:05,240 --> 00:03:07,210 So, really, there's only one way to go, right?-- 59 00:03:07,210 --> 00:03:10,170 60 00:03:10,170 --> 00:03:11,420 two hops. 61 00:03:11,420 --> 00:03:15,290 62 00:03:15,290 --> 00:03:17,520 So that's a directed graph, and then an undirected graph 63 00:03:17,520 --> 00:03:21,470 is basically the same thing, except we can go either 64 00:03:21,470 --> 00:03:24,080 direction on the edges, right? 65 00:03:24,080 --> 00:03:30,990 So on the directed graph in the previous slide, you could 66 00:03:30,990 --> 00:03:33,662 only go in this direction, so you had to make two hops in 67 00:03:33,662 --> 00:03:35,250 order to get to Montreal. 68 00:03:35,250 --> 00:03:40,255 In this undirected graph, you can just make one hop to get 69 00:03:40,255 --> 00:03:44,440 to Montreal-- so really conceptually very easy. 70 00:03:44,440 --> 00:03:48,344 AUDIENCE: Can you have a directed graph in a case where 71 00:03:48,344 --> 00:03:51,272 there's one going from Boston to New York and another one 72 00:03:51,272 --> 00:03:52,736 going from New York to Boston? 73 00:03:52,736 --> 00:03:53,680 PROFESSOR: Yes. 74 00:03:53,680 --> 00:03:54,690 So-- 75 00:03:54,690 --> 00:03:57,200 and actually we'll see that in the code. 76 00:03:57,200 --> 00:04:05,170 So the question was, can I have New York here and then 77 00:04:05,170 --> 00:04:06,720 Boston here? 78 00:04:06,720 --> 00:04:08,830 Can I have this sort of relationship? 79 00:04:08,830 --> 00:04:12,300 80 00:04:12,300 --> 00:04:15,110 And the answer is yes. 81 00:04:15,110 --> 00:04:17,323 This is actually just equivalent to 82 00:04:17,323 --> 00:04:18,799 an undirected graph. 83 00:04:18,799 --> 00:04:21,587 AUDIENCE: Probably you can have a directed graph in some 84 00:04:21,587 --> 00:04:22,735 cases like that. 85 00:04:22,735 --> 00:04:23,640 PROFESSOR: Yes. 86 00:04:23,640 --> 00:04:25,710 So you could have-- 87 00:04:25,710 --> 00:04:27,970 and we actually have-- actually, I think this might 88 00:04:27,970 --> 00:04:31,500 have an example of that, so, yes. 89 00:04:31,500 --> 00:04:35,850 So in this case, you have-- 90 00:04:35,850 --> 00:04:41,630 Hartford has a path to Albany and back in a path to New York 91 00:04:41,630 --> 00:04:45,355 City, but there's no path directly back to Hartford. 92 00:04:45,355 --> 00:04:47,247 That work for you? 93 00:04:47,247 --> 00:04:48,666 AUDIENCE: [INAUDIBLE] 94 00:04:48,666 --> 00:04:49,735 PROFESSOR: What's that? 95 00:04:49,735 --> 00:04:50,985 AUDIENCE: [INAUDIBLE] 96 00:04:50,985 --> 00:04:56,048 97 00:04:56,048 --> 00:04:58,200 PROFESSOR: Well, then I won't insult Hartford then. 98 00:04:58,200 --> 00:05:01,000 99 00:05:01,000 --> 00:05:03,370 I didn't do these graphs. 100 00:05:03,370 --> 00:05:07,120 101 00:05:07,120 --> 00:05:09,590 If I had done them, I certainly wouldn't have used 102 00:05:09,590 --> 00:05:14,000 sports teams because I know next to nothing about sports. 103 00:05:14,000 --> 00:05:16,410 So I don't know the rationale behind picking the names, 104 00:05:16,410 --> 00:05:21,150 other than I'm supposed to say that the reason why the Bruins 105 00:05:21,150 --> 00:05:23,480 want to go to Montreal is because they want to kick 106 00:05:23,480 --> 00:05:24,740 Canada's butt. 107 00:05:24,740 --> 00:05:25,620 AUDIENCE: They did. 108 00:05:25,620 --> 00:05:26,500 PROFESSOR: Did they? 109 00:05:26,500 --> 00:05:27,570 AUDIENCE: They already have. 110 00:05:27,570 --> 00:05:28,210 PROFESSOR: Oh. 111 00:05:28,210 --> 00:05:33,410 Well, then this is a very apropos slide then. 112 00:05:33,410 --> 00:05:37,480 So what we have up here is a weighted graph, right? 113 00:05:37,480 --> 00:05:42,760 So the undirected and directed graphs have been really easy 114 00:05:42,760 --> 00:05:47,450 so far because they're just defining the fact that there 115 00:05:47,450 --> 00:05:51,310 is a relationship that exists between two vertices, right? 116 00:05:51,310 --> 00:05:54,205 So what a weighted graph does, though, is it says that not 117 00:05:54,205 --> 00:05:57,390 only is there a relationship between these two entities-- 118 00:05:57,390 --> 00:05:58,480 these vertices-- 119 00:05:58,480 --> 00:06:01,950 but it also has maybe a cost associated with it. 120 00:06:01,950 --> 00:06:06,350 So if these represent the road networks, then these 121 00:06:06,350 --> 00:06:09,000 represent, kind of, the total costs-- 122 00:06:09,000 --> 00:06:10,850 the weights on these edges. 123 00:06:10,850 --> 00:06:13,110 So in saying that in order to get the Hartford, I need to 124 00:06:13,110 --> 00:06:16,020 pay $1.00; and then to get to Albany, I need to pay $3.00; 125 00:06:16,020 --> 00:06:18,920 and then to get to Montreal, to pay $6.00. 126 00:06:18,920 --> 00:06:22,000 So a common question-- 127 00:06:22,000 --> 00:06:24,970 on weighted graphs in general-- is what's the least 128 00:06:24,970 --> 00:06:28,740 cost path from here to here. 129 00:06:28,740 --> 00:06:31,570 So can anyone tell me? 130 00:06:31,570 --> 00:06:35,827 131 00:06:35,827 --> 00:06:38,665 AUDIENCE: From Boston to Montreal? 132 00:06:38,665 --> 00:06:39,710 PROFESSOR: Yes-- 133 00:06:39,710 --> 00:06:42,208 what the least cost is from Boston to Montreal. 134 00:06:42,208 --> 00:06:43,630 AUDIENCE: It's-- 135 00:06:43,630 --> 00:06:45,526 Hartford is your only choice. 136 00:06:45,526 --> 00:06:46,474 PROFESSOR: Right. 137 00:06:46,474 --> 00:06:48,850 AUDIENCE: Then New York and then Hartford. 138 00:06:48,850 --> 00:06:50,340 PROFESSOR: Right. 139 00:06:50,340 --> 00:06:53,005 So-- and the cost for that is $9.00, right?-- because you 140 00:06:53,005 --> 00:06:56,730 got $1.00, $7.00, $1.00-- sum $9.00. 141 00:06:56,730 --> 00:06:58,325 There are actually two paths to get 142 00:06:58,325 --> 00:06:59,470 from Boston to Montreal. 143 00:06:59,470 --> 00:07:02,890 The other path is from Boston, Hartford, Albany, Montreal, 144 00:07:02,890 --> 00:07:05,100 but the cost of that path is $10.00. 145 00:07:05,100 --> 00:07:12,760 So the question is how do you figure out which path is 146 00:07:12,760 --> 00:07:14,310 shortest, right? 147 00:07:14,310 --> 00:07:18,210 So did he talk about breadth-first search and 148 00:07:18,210 --> 00:07:18,920 depth-first search at all? 149 00:07:18,920 --> 00:07:20,382 AUDIENCE: He only talked about depth-first. 150 00:07:20,382 --> 00:07:22,100 PROFESSOR: He only talked about depth-first. 151 00:07:22,100 --> 00:07:22,500 OK. 152 00:07:22,500 --> 00:07:25,370 So we need to do breadth-first. 153 00:07:25,370 --> 00:07:32,710 So before we do breadth-first, can someone define depth-first 154 00:07:32,710 --> 00:07:36,980 for me and maybe walk me through it a little bit? 155 00:07:36,980 --> 00:07:44,110 So let's take this off the screen, and let's assume that 156 00:07:44,110 --> 00:07:45,805 I have a very simple graph. 157 00:07:45,805 --> 00:07:49,640 158 00:07:49,640 --> 00:07:52,450 I'm going to start here. 159 00:07:52,450 --> 00:07:54,205 I want to end here. 160 00:07:54,205 --> 00:07:55,455 And I have-- 161 00:07:55,455 --> 00:08:14,670 162 00:08:14,670 --> 00:08:18,800 So I'm starting at v0, and I want to get to v8. 163 00:08:18,800 --> 00:08:21,310 164 00:08:21,310 --> 00:08:24,860 Let's call this a directed graph, so you 165 00:08:24,860 --> 00:08:26,700 can only go one direction. 166 00:08:26,700 --> 00:08:29,450 It also doesn't have any cycles, so that makes it a 167 00:08:29,450 --> 00:08:30,550 little easier. 168 00:08:30,550 --> 00:08:35,030 So if I'm starting here in depth-first 169 00:08:35,030 --> 00:08:37,572 search, what do I do? 170 00:08:37,572 --> 00:08:39,476 AUDIENCE: Pick a daughter-- 171 00:08:39,476 --> 00:08:40,428 Pick a daughter? 172 00:08:40,428 --> 00:08:42,770 PROFESSOR: So you pick one of your children, so you're going 173 00:08:42,770 --> 00:08:45,820 to pick v1 or v4. 174 00:08:45,820 --> 00:08:47,840 Now, you go to this node. 175 00:08:47,840 --> 00:08:49,115 What do you do now? 176 00:08:49,115 --> 00:08:50,025 AUDIENCE: Pick a daughter. 177 00:08:50,025 --> 00:08:50,970 PROFESSOR: Same thing again. 178 00:08:50,970 --> 00:08:53,685 So you pick another daughter and because this is a really 179 00:08:53,685 --> 00:08:57,670 trivial example, we just walk down the line until you find 180 00:08:57,670 --> 00:08:58,820 the node that you're looking for. 181 00:08:58,820 --> 00:09:01,890 Or if you don't find it, and you have no more-- 182 00:09:01,890 --> 00:09:06,580 there are no more children to look at, then there's no path 183 00:09:06,580 --> 00:09:07,230 that exists. 184 00:09:07,230 --> 00:09:10,260 But we can get to our goal node here, right? 185 00:09:10,260 --> 00:09:14,180 So what do we do once we find this node? 186 00:09:14,180 --> 00:09:15,430 AUDIENCE: [INAUDIBLE] 187 00:09:15,430 --> 00:09:18,020 188 00:09:18,020 --> 00:09:19,950 PROFESSOR: We save it off somewhere. 189 00:09:19,950 --> 00:09:25,040 It becomes a path with just itself, and then we return 190 00:09:25,040 --> 00:09:26,620 that to who-- 191 00:09:26,620 --> 00:09:29,542 And then we say, OK, well, where did I come from? 192 00:09:29,542 --> 00:09:31,670 Well, I came from v7. 193 00:09:31,670 --> 00:09:38,110 So, now, I know that my shortest path from v7 to v8 is 194 00:09:38,110 --> 00:09:39,710 going to be v7-v8. 195 00:09:39,710 --> 00:09:43,740 And then I'm back here, I'm going to add 196 00:09:43,740 --> 00:09:46,600 wherever I came from here. 197 00:09:46,600 --> 00:09:55,380 So the idea is that I grow my shortest paths backwards. 198 00:09:55,380 --> 00:09:56,630 Right? 199 00:09:56,630 --> 00:09:58,360 200 00:09:58,360 --> 00:10:02,756 And, actually, the shortest path is the top one here, so-- 201 00:10:02,756 --> 00:10:06,044 AUDIENCE: If you hit a branch in v7, can you go back to v7 202 00:10:06,044 --> 00:10:07,496 would you jump to the next branch? 203 00:10:07,496 --> 00:10:08,790 PROFESSOR: So, yes. 204 00:10:08,790 --> 00:10:14,850 So if I had something like this, and the 205 00:10:14,850 --> 00:10:16,100 answer would be-- 206 00:10:16,100 --> 00:10:18,460 207 00:10:18,460 --> 00:10:21,670 let's say that it loops around-- 208 00:10:21,670 --> 00:10:22,870 so now we have a cycle. 209 00:10:22,870 --> 00:10:24,350 So it becomes interesting. 210 00:10:24,350 --> 00:10:30,390 So let's say that I've reached my goal here, and I know that 211 00:10:30,390 --> 00:10:32,420 if I'm at my goal, then my shortest path is 212 00:10:32,420 --> 00:10:33,630 just my goal, right? 213 00:10:33,630 --> 00:10:36,930 So now I return here and I say, well, what would be my 214 00:10:36,930 --> 00:10:38,460 shortest path in this case? 215 00:10:38,460 --> 00:10:42,410 216 00:10:42,410 --> 00:10:44,890 Does this child have the shortest path? 217 00:10:44,890 --> 00:10:52,440 218 00:10:52,440 --> 00:10:55,840 When I get here first to v7, I asked the question, what's the 219 00:10:55,840 --> 00:11:00,150 shortest path to v8 from either of my two children. 220 00:11:00,150 --> 00:11:04,740 So I'm going to look at all the children of v7, and I'm 221 00:11:04,740 --> 00:11:07,770 going to find what's the shortest path from v8-- 222 00:11:07,770 --> 00:11:10,310 or from this node to the end node-- 223 00:11:10,310 --> 00:11:12,630 and then from this node to the end node. 224 00:11:12,630 --> 00:11:14,330 And, obviously, this one's the shortest because 225 00:11:14,330 --> 00:11:15,690 it is the end node. 226 00:11:15,690 --> 00:11:18,200 So now, I know that my shortest path 227 00:11:18,200 --> 00:11:24,120 is this plus myself. 228 00:11:24,120 --> 00:11:28,380 And so that means that the shortest path from v6 to the 229 00:11:28,380 --> 00:11:33,546 end node is going to be this path, plus this. 230 00:11:33,546 --> 00:11:38,210 And I don't know if that's getting any clearer. 231 00:11:38,210 --> 00:11:45,520 So, really, if we start out at the beginning here, we're 232 00:11:45,520 --> 00:11:47,560 looking at this first node-- 233 00:11:47,560 --> 00:11:51,730 we ask the question, what's the shortest path from v1 to 234 00:11:51,730 --> 00:11:54,040 the end, and what's the shortest path 235 00:11:54,040 --> 00:11:56,020 from v4 to the end? 236 00:11:56,020 --> 00:11:59,380 And we choose the shortest of those two paths as our answer, 237 00:11:59,380 --> 00:12:02,600 then we just add ourselves to the beginning. 238 00:12:02,600 --> 00:12:04,810 And that's all we do for each of these nodes. 239 00:12:04,810 --> 00:12:08,770 We ask, of the children at each of these nodes, what's 240 00:12:08,770 --> 00:12:12,300 the shortest path, and then we add ourselves to the beginning 241 00:12:12,300 --> 00:12:16,140 of that path and return that as our answer. 242 00:12:16,140 --> 00:12:18,380 So if we are to look at that in code-- 243 00:12:18,380 --> 00:12:22,850 244 00:12:22,850 --> 00:12:30,295 so you guys have all seen the graph object in class with the 245 00:12:30,295 --> 00:12:32,050 node and edges? 246 00:12:32,050 --> 00:12:33,150 Yes or no? 247 00:12:33,150 --> 00:12:40,540 OK So here is shortest path depth-first. 248 00:12:40,540 --> 00:12:44,240 249 00:12:44,240 --> 00:12:47,760 So there's a lot of debugging code here, but-- 250 00:12:47,760 --> 00:12:49,840 and some administrative stuff-- so all this is doing 251 00:12:49,840 --> 00:12:51,680 is just making sure that the nodes we're looking 252 00:12:51,680 --> 00:12:54,911 for are in the graph. 253 00:12:54,911 --> 00:12:56,650 And, actually, let me backtrack. 254 00:12:56,650 --> 00:12:59,220 So when we first call shortest path, we're going to call it 255 00:12:59,220 --> 00:13:01,310 with a graph object. 256 00:13:01,310 --> 00:13:05,600 We're going to start in an end node. 257 00:13:05,600 --> 00:13:08,120 And we're also going to have this parameter visited, which 258 00:13:08,120 --> 00:13:11,450 keeps track of the nodes that we've already seen. 259 00:13:11,450 --> 00:13:14,740 And we'll get to that in a second. 260 00:13:14,740 --> 00:13:19,080 So one of the first things that we do that's of any 261 00:13:19,080 --> 00:13:21,210 importance is, we check to make sure that the start and 262 00:13:21,210 --> 00:13:25,710 end nodes are actually in the graph, because you can't get 263 00:13:25,710 --> 00:13:27,090 from one to the other if they don't exist. 264 00:13:27,090 --> 00:13:30,150 265 00:13:30,150 --> 00:13:33,560 And now we're going to construct a path or a list 266 00:13:33,560 --> 00:13:38,710 that just contains the start node as its element. 267 00:13:38,710 --> 00:13:41,970 And then we're going to check to see if 268 00:13:41,970 --> 00:13:43,670 start is equal to end. 269 00:13:43,670 --> 00:13:47,260 So if we're already at our goal, then the shortest path 270 00:13:47,260 --> 00:13:49,300 is just us, right? 271 00:13:49,300 --> 00:13:51,260 We don't have to go anywhere. 272 00:13:51,260 --> 00:13:52,510 AUDIENCE: [INAUDIBLE] 273 00:13:52,510 --> 00:13:56,516 274 00:13:56,516 --> 00:13:59,190 PROFESSOR: For comparison purposes. 275 00:13:59,190 --> 00:14:04,870 I mean, if you look at the definition of node, it's 276 00:14:04,870 --> 00:14:06,540 pretty sparse-- 277 00:14:06,540 --> 00:14:08,860 pretty spartan. 278 00:14:08,860 --> 00:14:12,190 If we wanted to make it so that we just added the node 279 00:14:12,190 --> 00:14:17,380 object itself, would have to add an underbar equal method-- 280 00:14:17,380 --> 00:14:21,120 stuff like that-- and in this case, we don't want to bother 281 00:14:21,120 --> 00:14:24,940 with kind of complicating it like that. 282 00:14:24,940 --> 00:14:31,340 So if we're not at the end, though, now, we need to figure 283 00:14:31,340 --> 00:14:34,810 out what the shortest path is from each of our children to 284 00:14:34,810 --> 00:14:36,320 the goal node, right? 285 00:14:36,320 --> 00:14:40,670 So we have a variable that we call shortest, and that's 286 00:14:40,670 --> 00:14:42,890 going to keep track of what our shortest path so far is, 287 00:14:42,890 --> 00:14:44,540 and then we're going to iterate through all the 288 00:14:44,540 --> 00:14:48,160 children in this node. 289 00:14:48,160 --> 00:14:53,590 And if the node is not in visited-- 290 00:14:53,590 --> 00:14:57,880 and that's where this parameter comes in-- 291 00:14:57,880 --> 00:15:02,450 we're going to say, OK, well, let's take a look at it. 292 00:15:02,450 --> 00:15:04,020 And then we're going to say-- we're going to add it to 293 00:15:04,020 --> 00:15:07,495 visited so we know that we visited this node. 294 00:15:07,495 --> 00:15:11,370 It sounds kind of cyclic, which is funny because we have 295 00:15:11,370 --> 00:15:12,650 visited so that we avoid cycles. 296 00:15:12,650 --> 00:15:15,530 297 00:15:15,530 --> 00:15:20,510 Because if we've already visited a node and we figured 298 00:15:20,510 --> 00:15:23,810 out what its shortest path is, why would we 299 00:15:23,810 --> 00:15:25,060 want to visit it again? 300 00:15:25,060 --> 00:15:29,550 301 00:15:29,550 --> 00:15:35,460 If we're on a path, and we're saying-- 302 00:15:35,460 --> 00:15:37,850 let's say I have-- 303 00:15:37,850 --> 00:15:48,610 I'm trying to figure out the shortest path from v1 to v4-- 304 00:15:48,610 --> 00:15:50,480 and I'm using depth-first-- 305 00:15:50,480 --> 00:15:54,940 and so I decide depth-first first goes to v2, then to v3. 306 00:15:54,940 --> 00:15:57,950 Now, it's got two choices on which nodes to get the 307 00:15:57,950 --> 00:16:00,660 shortest path for. 308 00:16:00,660 --> 00:16:04,570 Let's say, for some reason, when it gets the list of 309 00:16:04,570 --> 00:16:07,180 children, it's going to get v1 and v4, and if it's looking at 310 00:16:07,180 --> 00:16:10,680 v1 before it looks at v4, then, if we didn't have that 311 00:16:10,680 --> 00:16:11,870 check in there, just to make sure 312 00:16:11,870 --> 00:16:13,880 that we are not visiting-- 313 00:16:13,880 --> 00:16:16,670 or looking at other nodes that we've already visited-- 314 00:16:16,670 --> 00:16:19,370 then the algorithm would just go here, and it would repeat 315 00:16:19,370 --> 00:16:22,390 itself in a cycle, like that. 316 00:16:22,390 --> 00:16:24,790 So that's what that visited parameter is doing, is it's 317 00:16:24,790 --> 00:16:26,485 preventing that cyclic check. 318 00:16:26,485 --> 00:16:30,960 319 00:16:30,960 --> 00:16:37,030 So now we ask the question-- 320 00:16:37,030 --> 00:16:40,590 or we make a recursive call to shortest path, right? 321 00:16:40,590 --> 00:16:46,800 And the only parameter that changes is the start node. 322 00:16:46,800 --> 00:16:50,490 And we're going to ask it, what's the shortest path from 323 00:16:50,490 --> 00:16:53,750 this node to the end. 324 00:16:53,750 --> 00:16:59,420 And it's going to call itself again and return an answer. 325 00:16:59,420 --> 00:17:01,780 And if it doesn't return anything, then we're just 326 00:17:01,780 --> 00:17:04,640 going to ignore it and continue. 327 00:17:04,640 --> 00:17:09,640 But if it returns something, and either we haven't found 328 00:17:09,640 --> 00:17:13,845 shortest path yet, or the length of this new path that 329 00:17:13,845 --> 00:17:15,819 it's found is shorter than the shortest path that we've 330 00:17:15,819 --> 00:17:19,420 already found, then we're going to record it, and say 331 00:17:19,420 --> 00:17:23,260 that this is our new shortest path here. 332 00:17:23,260 --> 00:17:26,300 And then we're just going to keep iterating through all the 333 00:17:26,300 --> 00:17:30,540 children of the node until we've exhausted all 334 00:17:30,540 --> 00:17:32,300 possibilities. 335 00:17:32,300 --> 00:17:35,650 And then once we finish going through all the children, 336 00:17:35,650 --> 00:17:37,820 we're going to say-- 337 00:17:37,820 --> 00:17:39,910 if we found the shortest path-- 338 00:17:39,910 --> 00:17:43,340 that means that there exists a path from one of its children 339 00:17:43,340 --> 00:17:46,180 to the goal node-- 340 00:17:46,180 --> 00:17:50,830 then we're going to add it to our existing path, which is 341 00:17:50,830 --> 00:17:52,270 just ourself. 342 00:17:52,270 --> 00:17:54,360 So we're adding ourselves to the beginning of the shortest 343 00:17:54,360 --> 00:17:57,350 path that it found. 344 00:17:57,350 --> 00:17:59,540 And then we will return it. 345 00:17:59,540 --> 00:18:08,310 So it's kind of growing the shortest path from the back to 346 00:18:08,310 --> 00:18:10,570 the front, right? 347 00:18:10,570 --> 00:18:13,280 Breadth-first search works in the opposite direction. 348 00:18:13,280 --> 00:18:15,026 So the way that-- 349 00:18:15,026 --> 00:18:17,460 well, first, is anyone confused 350 00:18:17,460 --> 00:18:20,398 by depth-first search? 351 00:18:20,398 --> 00:18:21,648 AUDIENCE: [INAUDIBLE] 352 00:18:21,648 --> 00:18:26,794 353 00:18:26,794 --> 00:18:31,850 PROFESSOR: So this line here-- 354 00:18:31,850 --> 00:18:33,290 this is-- 355 00:18:33,290 --> 00:18:35,380 well, this if statement first is checking to 356 00:18:35,380 --> 00:18:37,150 see that we've got-- 357 00:18:37,150 --> 00:18:40,640 that one of our children has a shortest path. 358 00:18:40,640 --> 00:18:45,540 It's possible that none of our possible children leads to the 359 00:18:45,540 --> 00:18:52,850 goal node, so let's say that I have another kind 360 00:18:52,850 --> 00:18:54,100 of subgraph on here. 361 00:18:54,100 --> 00:19:02,180 362 00:19:02,180 --> 00:19:04,430 When v2 is my start node, I'm still going to 363 00:19:04,430 --> 00:19:08,640 check these two children. 364 00:19:08,640 --> 00:19:13,130 And let's say that my goal node is to get to v8, right? 365 00:19:13,130 --> 00:19:16,260 Well, I'm still going to check to see what the shortest path 366 00:19:16,260 --> 00:19:18,270 is for both of these children. 367 00:19:18,270 --> 00:19:21,490 Well, once I use this is my start node, there's obviously 368 00:19:21,490 --> 00:19:27,580 no path to the actual goal node, so the depth-first 369 00:19:27,580 --> 00:19:30,500 search call, or the call to the shortest path, is going to 370 00:19:30,500 --> 00:19:32,772 return none in this case. 371 00:19:32,772 --> 00:19:39,390 And we need to check that, so that's what that bit of code 372 00:19:39,390 --> 00:19:42,170 is doing there. 373 00:19:42,170 --> 00:19:47,850 It's saying if there is a shortest path, then we're 374 00:19:47,850 --> 00:19:50,380 going to just add ourselves to the front of that shortest 375 00:19:50,380 --> 00:19:53,080 path, and return that as our answer. 376 00:19:53,080 --> 00:19:54,540 But if there is no shortest path 377 00:19:54,540 --> 00:19:59,260 from one of our children-- 378 00:19:59,260 --> 00:20:02,080 from any of the children on the start node-- 379 00:20:02,080 --> 00:20:05,200 to the goal node, then we're just going to return none as 380 00:20:05,200 --> 00:20:08,800 our answer because we can't get to the goal node from 381 00:20:08,800 --> 00:20:10,050 where we are. 382 00:20:10,050 --> 00:20:13,150 383 00:20:13,150 --> 00:20:14,400 Did that work for you? 384 00:20:14,400 --> 00:20:19,720 385 00:20:19,720 --> 00:20:23,520 So why don't we take a look at how this is working. 386 00:20:23,520 --> 00:20:38,810 387 00:20:38,810 --> 00:20:41,775 So we're going to try DFS on undirected graph. 388 00:20:41,775 --> 00:20:44,970 389 00:20:44,970 --> 00:20:52,950 And the code that does this is called Test 2 here, and all it 390 00:20:52,950 --> 00:20:55,500 does is, it creates a graph with 10 nodes. 391 00:20:55,500 --> 00:20:58,390 392 00:20:58,390 --> 00:21:03,170 And, in this case, it's going to be an undirected graph. 393 00:21:03,170 --> 00:21:06,330 And we're going to create a bunch of edges. 394 00:21:06,330 --> 00:21:07,580 So-- 395 00:21:07,580 --> 00:21:09,390 396 00:21:09,390 --> 00:21:14,930 is that diagram you sent out, is that the 397 00:21:14,930 --> 00:21:15,550 representation of it? 398 00:21:15,550 --> 00:21:17,530 AUDIENCE: This is the code from lecture, Professor 399 00:21:17,530 --> 00:21:18,520 [INAUDIBLE] code. 400 00:21:18,520 --> 00:21:20,995 So it only uses 5 nodes. 401 00:21:20,995 --> 00:21:25,500 PROFESSOR: So we have this graph, and what we're going to 402 00:21:25,500 --> 00:21:29,360 do is use depth-first search to compute the shortest path 403 00:21:29,360 --> 00:21:32,420 from here to here. 404 00:21:32,420 --> 00:21:40,810 405 00:21:40,810 --> 00:21:45,000 So this is showing the depth of the recursion, right? 406 00:21:45,000 --> 00:21:47,550 407 00:21:47,550 --> 00:21:54,480 So we start off on node 0, and then it starts looking for the 408 00:21:54,480 --> 00:21:57,540 shortest path from 1 to 4. 409 00:21:57,540 --> 00:22:01,690 410 00:22:01,690 --> 00:22:08,680 And at the same depth, it's going to try and find the 411 00:22:08,680 --> 00:22:11,940 shortest path from 2 to 4. 412 00:22:11,940 --> 00:22:17,600 So it starts out here, and then it asks what's the 413 00:22:17,600 --> 00:22:20,970 shortest path from 1 to 4, and then what's the shortest path 414 00:22:20,970 --> 00:22:22,220 from 2 to 4. 415 00:22:22,220 --> 00:22:25,340 416 00:22:25,340 --> 00:22:28,970 And so when it's looking at 1, now it's going to ask what's 417 00:22:28,970 --> 00:22:33,320 the shortest path from-- 418 00:22:33,320 --> 00:22:34,570 I want it to do that-- 419 00:22:34,570 --> 00:22:47,072 420 00:22:47,072 --> 00:22:48,520 Hey, Sarri? 421 00:22:48,520 --> 00:22:49,998 Is there a bug in your code? 422 00:22:49,998 --> 00:22:51,950 AUDIENCE: Is there? 423 00:22:51,950 --> 00:22:56,710 PROFESSOR: So is this the lecture code? 424 00:22:56,710 --> 00:22:58,210 AUDIENCE: None of this is mine. 425 00:22:58,210 --> 00:23:00,210 I did the breadth-first search. 426 00:23:00,210 --> 00:23:01,710 This is the depth-first? 427 00:23:01,710 --> 00:23:03,680 PROFESSOR: Yes, because it seems like it's 428 00:23:03,680 --> 00:23:05,050 checking node 0 twice. 429 00:23:05,050 --> 00:23:07,640 430 00:23:07,640 --> 00:23:11,192 AUDIENCE: It didn't do that on mine. 431 00:23:11,192 --> 00:23:12,170 PROFESSOR: So it's going from-- 432 00:23:12,170 --> 00:23:14,230 AUDIENCE: Oh, no-- because there's a directed-- is from 1 433 00:23:14,230 --> 00:23:17,528 to 0, right? 434 00:23:17,528 --> 00:23:18,020 Yes. 435 00:23:18,020 --> 00:23:22,750 So what it's doing-- what the code does is, it says-- 436 00:23:22,750 --> 00:23:27,630 it does a depth-first, so first, it looks at node 0, and 437 00:23:27,630 --> 00:23:30,090 then it goes for child in-- 438 00:23:30,090 --> 00:23:31,270 for all the children nodes. 439 00:23:31,270 --> 00:23:32,540 What's the first child of node 0? 440 00:23:32,540 --> 00:23:33,250 It's node 1. 441 00:23:33,250 --> 00:23:34,880 PROFESSOR: Oh, because 0 hasn't been added to the 442 00:23:34,880 --> 00:23:35,860 visited list. 443 00:23:35,860 --> 00:23:36,680 AUDIENCE: Right. 444 00:23:36,680 --> 00:23:37,826 And then-- 445 00:23:37,826 --> 00:23:40,220 PROFESSOR: And then it asks, what are all the children of-- 446 00:23:40,220 --> 00:23:41,100 AUDIENCE: Well, no. 447 00:23:41,100 --> 00:23:45,070 The print statement comes before it discovers that 448 00:23:45,070 --> 00:23:48,021 checking node 0 is an invalid path. 449 00:23:48,021 --> 00:23:50,009 I forgot to add another print statement. 450 00:23:50,009 --> 00:23:51,003 If you go to the code-- 451 00:23:51,003 --> 00:23:52,253 PROFESSOR: OK. 452 00:23:52,253 --> 00:23:59,950 453 00:23:59,950 --> 00:24:03,506 So where are we at? 454 00:24:03,506 --> 00:24:04,410 AUDIENCE: Yes. 455 00:24:04,410 --> 00:24:06,330 So see how I have the very first at 456 00:24:06,330 --> 00:24:07,240 the top of the function? 457 00:24:07,240 --> 00:24:10,210 See how there's the if to print? 458 00:24:10,210 --> 00:24:13,040 I say that, but then there's this check here 459 00:24:13,040 --> 00:24:14,680 if it's not in visited. 460 00:24:14,680 --> 00:24:17,400 If it is in visited, there's no print statement that says-- 461 00:24:17,400 --> 00:24:19,040 PROFESSOR: --that says that-- you know-- it's-- 462 00:24:19,040 --> 00:24:20,050 AUDIENCE: That-- yes. 463 00:24:20,050 --> 00:24:22,650 So, basically, what's happened is, when we do that second 464 00:24:22,650 --> 00:24:26,660 check where we end up finding the second path from 0 to 4, 465 00:24:26,660 --> 00:24:30,540 it ends up hitting that test that says, we've already 466 00:24:30,540 --> 00:24:32,520 visited node 0, so we don't continue that. 467 00:24:32,520 --> 00:24:33,030 PROFESSOR: I got it. 468 00:24:33,030 --> 00:24:33,750 I got it. 469 00:24:33,750 --> 00:24:34,660 That was just a little-- 470 00:24:34,660 --> 00:24:37,050 AUDIENCE: There was no print statements in the code before, 471 00:24:37,050 --> 00:24:39,280 and I was having a really hard time figuring it out, and I 472 00:24:39,280 --> 00:24:41,352 did this, and this made it a lot more clear-- 473 00:24:41,352 --> 00:24:43,515 I thought-- to try and figure out how the depth-first search 474 00:24:43,515 --> 00:24:44,385 was working. 475 00:24:44,385 --> 00:24:45,260 PROFESSOR: No, I think so, too. 476 00:24:45,260 --> 00:24:48,430 It's just maybe we should add a couple extra-- 477 00:24:48,430 --> 00:24:49,680 AUDIENCE: Yeah, I agree. 478 00:24:49,680 --> 00:24:52,750 479 00:24:52,750 --> 00:24:54,390 PROFESSOR: Sorry. 480 00:24:54,390 --> 00:24:58,360 I was perplexed-- because I'm like, uh-oh. 481 00:24:58,360 --> 00:25:00,770 So it's working correctly. 482 00:25:00,770 --> 00:25:02,970 Is there any confusion on depth-first 483 00:25:02,970 --> 00:25:05,252 search, in spite of that? 484 00:25:05,252 --> 00:25:06,740 OK. 485 00:25:06,740 --> 00:25:09,120 So let's start our breadth-first search. 486 00:25:09,120 --> 00:25:12,340 487 00:25:12,340 --> 00:25:17,720 So you guys covered depth-first search in lecture, 488 00:25:17,720 --> 00:25:19,184 so we need to do breadth-first search. 489 00:25:19,184 --> 00:25:20,540 OK. 490 00:25:20,540 --> 00:25:24,570 So the idea behind breadth-first search is that 491 00:25:24,570 --> 00:25:28,450 instead of asking the question, what's the shortest 492 00:25:28,450 --> 00:25:31,660 path from v1 to v4 and adding ourselves to the front of 493 00:25:31,660 --> 00:25:36,100 that, to get the shortest path, we're going to build the 494 00:25:36,100 --> 00:25:39,270 paths from the start outward-- 495 00:25:39,270 --> 00:25:41,140 or from the start forward-- 496 00:25:41,140 --> 00:25:44,100 so, in this case, we're building the paths from the 497 00:25:44,100 --> 00:25:45,810 goal backward. 498 00:25:45,810 --> 00:25:54,560 In this case, we're going to say, I'm at v0, so my current 499 00:25:54,560 --> 00:25:56,085 partial path is v0. 500 00:25:56,085 --> 00:25:59,200 501 00:25:59,200 --> 00:26:03,900 Then I'm going to look at v1 and v4. 502 00:26:03,900 --> 00:26:06,130 And so I'm going to have-- 503 00:26:06,130 --> 00:26:18,380 504 00:26:18,380 --> 00:26:21,260 I'm going to say, now, this is my list of partial 505 00:26:21,260 --> 00:26:23,470 paths to the goal. 506 00:26:23,470 --> 00:26:27,570 And then, for v1, I'm going to say-- 507 00:26:27,570 --> 00:26:31,555 I'm going to ask what its neighbors are, and we have v2. 508 00:26:31,555 --> 00:26:34,880 509 00:26:34,880 --> 00:26:37,930 And then, for v4, we're going to ask the same question. 510 00:26:37,930 --> 00:26:42,431 So now we're building our partial paths. 511 00:26:42,431 --> 00:26:45,520 512 00:26:45,520 --> 00:26:49,060 So, conceptually, what we're doing is, we're just 513 00:26:49,060 --> 00:26:53,000 maintaining a list of all the paths that we-- 514 00:26:53,000 --> 00:26:55,380 or all-- the history of nodes-- 515 00:26:55,380 --> 00:26:58,310 or paths that we've been looking at and just kind of 516 00:26:58,310 --> 00:27:01,120 going out one by one by one. 517 00:27:01,120 --> 00:27:09,500 So if we look at this in code, shortest path-- 518 00:27:09,500 --> 00:27:10,580 BFS-- 519 00:27:10,580 --> 00:27:16,330 has a slightly different call signature than the DFS method. 520 00:27:16,330 --> 00:27:19,010 So we still get a graph, and then we get this variable 521 00:27:19,010 --> 00:27:19,950 called paths. 522 00:27:19,950 --> 00:27:23,960 And what paths contains is the partial path, or list of the 523 00:27:23,960 --> 00:27:26,470 partial paths of tuples. 524 00:27:26,470 --> 00:27:33,710 So the format of this is, each element has a list of the 525 00:27:33,710 --> 00:27:37,600 nodes in the path and then the length of 526 00:27:37,600 --> 00:27:43,930 that particular path. 527 00:27:43,930 --> 00:27:49,580 So we also have the goal node. 528 00:27:49,580 --> 00:27:52,800 And what we do-- 529 00:27:52,800 --> 00:27:56,110 the first thing that happens is, this pass gets shorted-- 530 00:27:56,110 --> 00:27:57,900 or sorted. 531 00:27:57,900 --> 00:28:02,390 So it's sorted by the length of the path. 532 00:28:02,390 --> 00:28:06,690 So is anyone puzzled by this lambda here? 533 00:28:06,690 --> 00:28:07,626 AUDIENCE: Yes. 534 00:28:07,626 --> 00:28:09,030 PROFESSOR: OK. 535 00:28:09,030 --> 00:28:10,980 So when you call the sorted function, you 536 00:28:10,980 --> 00:28:12,250 can pass it a list. 537 00:28:12,250 --> 00:28:14,672 You can also pass it this key parameter. 538 00:28:14,672 --> 00:28:23,940 And this key parameter is a function that takes an object, 539 00:28:23,940 --> 00:28:28,000 and it'll return, kind of, the value 540 00:28:28,000 --> 00:28:29,230 associated with that object. 541 00:28:29,230 --> 00:28:34,210 So, in this case, each of these paths contain-- 542 00:28:34,210 --> 00:28:37,270 each of the elements and paths contains a tuple. 543 00:28:37,270 --> 00:28:41,160 And what this key function does is, it says, each element 544 00:28:41,160 --> 00:28:46,145 in this path has got a value that is equal to the 545 00:28:46,145 --> 00:28:47,810 length of that path. 546 00:28:47,810 --> 00:28:52,100 And this length parameter-- that's just the second element 547 00:28:52,100 --> 00:28:54,510 in the tuple, right? 548 00:28:54,510 --> 00:28:58,040 So when sorted does its work, it's going to call this key 549 00:28:58,040 --> 00:29:01,640 function on each element in path. 550 00:29:01,640 --> 00:29:07,780 And what this function has to do is return the value 551 00:29:07,780 --> 00:29:11,205 associated with that particular element. 552 00:29:11,205 --> 00:29:15,790 AUDIENCE: Is lambda just a key word that generates an effect? 553 00:29:15,790 --> 00:29:18,800 PROFESSOR: Lambda is what's known as 554 00:29:18,800 --> 00:29:20,050 an anonymous function. 555 00:29:20,050 --> 00:29:22,990 556 00:29:22,990 --> 00:29:27,220 And he covered that in a lecture at one point. 557 00:29:27,220 --> 00:29:29,080 AUDIENCE: [INAUDIBLE]? 558 00:29:29,080 --> 00:29:30,490 PROFESSOR: Did he just use lambda? 559 00:29:30,490 --> 00:29:32,380 AUDIENCE: He blew past it, so-- 560 00:29:32,380 --> 00:29:34,360 this is something called lambda. 561 00:29:34,360 --> 00:29:37,030 Ask your TAs. 562 00:29:37,030 --> 00:29:40,350 PROFESSOR: Well, since I'm your TA and I'm here-- 563 00:29:40,350 --> 00:29:42,555 so real briefly-- 564 00:29:42,555 --> 00:29:47,180 565 00:29:47,180 --> 00:29:51,090 lambda is a way of, kind of, doing really simple-- 566 00:29:51,090 --> 00:29:55,250 not really simple functions-- but it's a way of creating 567 00:29:55,250 --> 00:29:56,200 anonymous function. 568 00:29:56,200 --> 00:29:59,010 So let's say that I want to create a function 569 00:29:59,010 --> 00:30:00,260 that squares a number. 570 00:30:00,260 --> 00:30:03,220 571 00:30:03,220 --> 00:30:07,570 This is exactly-- 572 00:30:07,570 --> 00:30:09,615 well, not exactly-- but, it's equivalent to this. 573 00:30:09,615 --> 00:30:12,320 574 00:30:12,320 --> 00:30:17,490 I can use g as a function just as easily as I can use h. 575 00:30:17,490 --> 00:30:29,510 576 00:30:29,510 --> 00:30:31,220 That's all. 577 00:30:31,220 --> 00:30:40,260 And it's useful for situations where you have elements that 578 00:30:40,260 --> 00:30:42,470 don't have an order to find. 579 00:30:42,470 --> 00:30:46,490 So like, sorted needs to know a value of an element in order 580 00:30:46,490 --> 00:30:49,210 to put it in order-- in order to do the sorting, right? 581 00:30:49,210 --> 00:30:52,460 So that's what this function does, is it gives each element 582 00:30:52,460 --> 00:30:57,710 in that list a value so that the sorting can do its job. 583 00:30:57,710 --> 00:31:04,625 So the key that we want to sort on, or the item that we 584 00:31:04,625 --> 00:31:07,990 want to sort on, is the length the path. 585 00:31:07,990 --> 00:31:13,020 And the reason why we want to do that is, we're going to 586 00:31:13,020 --> 00:31:20,570 take the first partial path that exists in our paths, and 587 00:31:20,570 --> 00:31:26,074 for every node in the shortest-- 588 00:31:26,074 --> 00:31:28,700 or for every node in the-- 589 00:31:28,700 --> 00:31:33,650 590 00:31:33,650 --> 00:31:39,060 for every child of the last node in this path, we want to 591 00:31:39,060 --> 00:31:44,630 check to see if it's the goal, and if it's not, then we're 592 00:31:44,630 --> 00:31:51,950 going to append a new partial path, which is the path that 593 00:31:51,950 --> 00:31:57,200 we're looking at, plus one of the children nodes. 594 00:31:57,200 --> 00:32:01,670 And then the length of the path to this 595 00:32:01,670 --> 00:32:04,870 value called new paths. 596 00:32:04,870 --> 00:32:09,920 So it's saying-- 597 00:32:09,920 --> 00:32:11,260 this node that I'm looking at-- 598 00:32:11,260 --> 00:32:17,080 599 00:32:17,080 --> 00:32:19,236 let's say that this is my partial path. 600 00:32:19,236 --> 00:32:22,710 601 00:32:22,710 --> 00:32:25,590 What it's doing is, it's looking at this last node in 602 00:32:25,590 --> 00:32:27,020 this path, and it's saying what are all the 603 00:32:27,020 --> 00:32:29,160 children of this node? 604 00:32:29,160 --> 00:32:34,830 And if none of the children are the goal node, then it's 605 00:32:34,830 --> 00:32:45,880 going to create a new set of paths that are composed of 606 00:32:45,880 --> 00:32:49,148 this path, plus all the children. 607 00:32:49,148 --> 00:32:59,047 AUDIENCE: So if v2 also went to v10, would the new path be 608 00:32:59,047 --> 00:33:02,344 easier [INAUDIBLE]? 609 00:33:02,344 --> 00:33:03,594 PROFESSOR: No. 610 00:33:03,594 --> 00:33:07,287 611 00:33:07,287 --> 00:33:11,530 So we should probably get rid of this. 612 00:33:11,530 --> 00:33:14,440 The reason why breadth-first search has its name, is that 613 00:33:14,440 --> 00:33:21,800 it doesn't try to go towards the end immediately. 614 00:33:21,800 --> 00:33:23,260 It grows gradually. 615 00:33:23,260 --> 00:33:28,105 So if you can kind of envision a graph like this. 616 00:33:28,105 --> 00:33:41,020 617 00:33:41,020 --> 00:33:45,480 Depth-first works by going-- 618 00:33:45,480 --> 00:33:50,880 by proceeding down until it finds the goal node for each 619 00:33:50,880 --> 00:33:53,020 of the possible paths. 620 00:33:53,020 --> 00:33:54,360 Right? 621 00:33:54,360 --> 00:33:58,320 What breadth-first search does is, it starts at a node, and 622 00:33:58,320 --> 00:34:04,910 then it builds all the paths from that node. 623 00:34:04,910 --> 00:34:11,420 And then for each of these, it builds the paths. 624 00:34:11,420 --> 00:34:15,204 So that's what I'm saying when I say partial paths. 625 00:34:15,204 --> 00:34:16,454 AUDIENCE: [INAUDIBLE] 626 00:34:16,454 --> 00:34:20,520 627 00:34:20,520 --> 00:34:21,190 PROFESSOR: Yes. 628 00:34:21,190 --> 00:34:22,630 It's a new partial path, so-- 629 00:34:22,630 --> 00:34:28,560 AUDIENCE: So it would be v0, v1, v2, v4-- the next one. 630 00:34:28,560 --> 00:34:33,525 And v0, v2, v [INAUDIBLE]. 631 00:34:33,525 --> 00:34:36,351 632 00:34:36,351 --> 00:34:42,935 PROFESSOR: So let's say this is v0, v1, v2. 633 00:34:42,935 --> 00:34:55,110 634 00:34:55,110 --> 00:34:59,290 Let's say that I have this partial path already. 635 00:34:59,290 --> 00:35:02,120 All right? 636 00:35:02,120 --> 00:35:08,280 When I build a new partial-- 637 00:35:08,280 --> 00:35:12,040 when I'm looking at this path, which is what I'm doing when I 638 00:35:12,040 --> 00:35:14,050 pop it off the front of the list of paths 639 00:35:14,050 --> 00:35:15,230 that I already have-- 640 00:35:15,230 --> 00:35:16,840 I'm going to look at all its children. 641 00:35:16,840 --> 00:35:22,780 So I'm going to look at these two nodes right here. 642 00:35:22,780 --> 00:35:26,970 And then I'm going to say-- let's say that my goal node is 643 00:35:26,970 --> 00:35:33,570 here, and then I'm going to say that these 644 00:35:33,570 --> 00:35:34,970 aren't my goal nodes. 645 00:35:34,970 --> 00:35:38,080 So I'm going to create new partial paths, and one of them 646 00:35:38,080 --> 00:35:41,830 is going to be v0, v1, v2, and v4. 647 00:35:41,830 --> 00:35:43,430 So I already have that. 648 00:35:43,430 --> 00:35:45,000 And the other partial path is going to be 649 00:35:45,000 --> 00:35:46,730 v0, v1, v2, and v5. 650 00:35:46,730 --> 00:35:49,652 651 00:35:49,652 --> 00:35:53,061 AUDIENCE: You just find every single possible path to get 652 00:35:53,061 --> 00:35:54,311 the tuples [INAUDIBLE]. 653 00:35:54,311 --> 00:35:56,555 654 00:35:56,555 --> 00:35:57,240 PROFESSOR: What's that? 655 00:35:57,240 --> 00:35:58,490 AUDIENCE: [INAUDIBLE] 656 00:35:58,490 --> 00:36:01,208 657 00:36:01,208 --> 00:36:03,250 PROFESSOR: Until you reach the goal node. 658 00:36:03,250 --> 00:36:05,680 So with depth-first search, you do have to-- 659 00:36:05,680 --> 00:36:09,080 660 00:36:09,080 --> 00:36:10,860 well, no, not even with depth-first search. 661 00:36:10,860 --> 00:36:13,410 662 00:36:13,410 --> 00:36:15,400 There's some interesting properties about the different 663 00:36:15,400 --> 00:36:19,090 searches, but we just want you to be familiar with how they 664 00:36:19,090 --> 00:36:20,590 go about doing their task. 665 00:36:20,590 --> 00:36:25,970 So the idea is that we start off with a partial path-- 666 00:36:25,970 --> 00:36:27,040 just this guy-- 667 00:36:27,040 --> 00:36:29,250 and then we find all the other partial paths. 668 00:36:29,250 --> 00:36:32,650 So it'll start off with just this guy 669 00:36:32,650 --> 00:36:34,820 as its list of paths-- 670 00:36:34,820 --> 00:36:36,970 so one element-- 671 00:36:36,970 --> 00:36:40,600 and then it's going to pop this off the front. 672 00:36:40,600 --> 00:36:42,860 It's going to say, OK, I'm looking at this partial path. 673 00:36:42,860 --> 00:36:45,960 What are the additional paths that I can build off of this? 674 00:36:45,960 --> 00:36:50,390 And I can build four additional paths off of this. 675 00:36:50,390 --> 00:36:54,800 So now I have a set of four paths that I want to look at. 676 00:36:54,800 --> 00:37:00,490 And then it takes a look at, say, this partial path of v0, 677 00:37:00,490 --> 00:37:03,410 v1, and it says, what are the paths that I can build off of 678 00:37:03,410 --> 00:37:06,630 this, and then adds it to the end. 679 00:37:06,630 --> 00:37:08,470 And then it says, what are the paths that I can 680 00:37:08,470 --> 00:37:09,820 build off of this guy-- 681 00:37:09,820 --> 00:37:13,110 adds those to the end-- what are the paths that I get from 682 00:37:13,110 --> 00:37:15,650 this guy-- adds those to the end, and so on and so forth. 683 00:37:15,650 --> 00:37:20,490 AUDIENCE: So you keep track of all the paths that you 684 00:37:20,490 --> 00:37:20,980 [INAUDIBLE]? 685 00:37:20,980 --> 00:37:22,080 PROFESSOR: Right. 686 00:37:22,080 --> 00:37:22,690 Oh, OK. 687 00:37:22,690 --> 00:37:23,490 Is that what you meant? 688 00:37:23,490 --> 00:37:26,940 AUDIENCE: You hit a node-- and there's another possible 689 00:37:26,940 --> 00:37:29,395 thing-- but if you don't hit a node-- if there's some paths 690 00:37:29,395 --> 00:37:31,720 somewhere else in the graph, then it doesn't 691 00:37:31,720 --> 00:37:35,000 ever reach into that. 692 00:37:35,000 --> 00:37:36,335 It just doesn't account for it. 693 00:37:36,335 --> 00:37:41,470 PROFESSOR: Well, I mean, it is possible for breadth-first 694 00:37:41,470 --> 00:37:47,330 search to go find nodes that don't reach the goal, but 695 00:37:47,330 --> 00:37:49,370 what's going to happen in those cases is, 696 00:37:49,370 --> 00:37:51,065 they're going to-- 697 00:37:51,065 --> 00:37:56,600 698 00:37:56,600 --> 00:37:59,460 so let's say that there's such a path at the front of this 699 00:37:59,460 --> 00:38:06,600 paths list, and it doesn't have any children. 700 00:38:06,600 --> 00:38:13,030 So you can't go anywhere after you've gotten to this node. 701 00:38:13,030 --> 00:38:16,090 Then what's going to happen is this for loop's not going to 702 00:38:16,090 --> 00:38:20,970 execute, right?-- because it has no children. 703 00:38:20,970 --> 00:38:26,670 And so it's just going to be discarded as a possibility. 704 00:38:26,670 --> 00:38:34,910 So I mean, the key thing is that you're generating these 705 00:38:34,910 --> 00:38:38,430 new partial paths for every node that you're looking at. 706 00:38:38,430 --> 00:38:41,920 And you're adding those to a list or a queue of partial 707 00:38:41,920 --> 00:38:45,780 paths that you need to examine in the future if you don't 708 00:38:45,780 --> 00:38:48,350 find your goal. 709 00:38:48,350 --> 00:38:52,600 If you do find a partial path that has a child that is the 710 00:38:52,600 --> 00:38:56,140 goal, then you can just immediately return that path 711 00:38:56,140 --> 00:38:58,090 because you know it's going to be the shortest 712 00:38:58,090 --> 00:39:00,460 path, in this case. 713 00:39:00,460 --> 00:39:02,330 So-- 714 00:39:02,330 --> 00:39:03,580 I don't know. 715 00:39:03,580 --> 00:39:05,760 716 00:39:05,760 --> 00:39:08,210 AUDIENCE: So what happens when you find two partial paths 717 00:39:08,210 --> 00:39:10,660 that both reach? 718 00:39:10,660 --> 00:39:13,750 PROFESSOR: Well, then it depends on which one appears 719 00:39:13,750 --> 00:39:15,830 first in your list. 720 00:39:15,830 --> 00:39:17,520 So you're asking-- 721 00:39:17,520 --> 00:39:23,180 722 00:39:23,180 --> 00:39:26,610 let's do something really simple-- 723 00:39:26,610 --> 00:39:27,630 if I have-- 724 00:39:27,630 --> 00:39:29,032 AUDIENCE: Oh, OK. 725 00:39:29,032 --> 00:39:32,364 So that makes sense. 726 00:39:32,364 --> 00:39:34,670 PROFESSOR: So at some point, you're going to have a partial 727 00:39:34,670 --> 00:39:40,190 path right here, or a list of partial paths that consist of 728 00:39:40,190 --> 00:39:47,030 v0, v1, and then v0 and v2. 729 00:39:47,030 --> 00:39:51,450 Whichever path you ultimately wind up returning is going to 730 00:39:51,450 --> 00:39:55,410 be dependent on whether or not this one comes first in your 731 00:39:55,410 --> 00:39:58,280 list of partial paths to check, or this one comes first 732 00:39:58,280 --> 00:40:01,720 in your list of partial paths to check. 733 00:40:01,720 --> 00:40:03,205 Did that kind of answer it? 734 00:40:03,205 --> 00:40:06,950 735 00:40:06,950 --> 00:40:11,550 So is everyone good on breadth-first search, 736 00:40:11,550 --> 00:40:12,810 conceptually? 737 00:40:12,810 --> 00:40:16,440 Is the code flummoxing anyone? 738 00:40:16,440 --> 00:40:22,392 739 00:40:22,392 --> 00:40:25,368 AUDIENCE: How do you find which one is the shortest? 740 00:40:25,368 --> 00:40:31,170 741 00:40:31,170 --> 00:40:33,635 PROFESSOR: If you're building your partial path-- 742 00:40:33,635 --> 00:40:36,930 743 00:40:36,930 --> 00:40:39,850 so you've popped off this path that you're examining-- 744 00:40:39,850 --> 00:40:41,290 and you look at all its children, and one of the 745 00:40:41,290 --> 00:40:44,440 children is a goal node, then you know that you've found the 746 00:40:44,440 --> 00:40:46,100 shortest path, right?-- 747 00:40:46,100 --> 00:40:50,760 because you've been building this incrementally, 748 00:40:50,760 --> 00:40:52,280 one by one by one. 749 00:40:52,280 --> 00:40:57,206 And then if you've found the goal node, then you know to-- 750 00:40:57,206 --> 00:41:00,710 you know, you already built up the shortest path possible. 751 00:41:00,710 --> 00:41:05,390 Because if the goal node had been on a shorter path before, 752 00:41:05,390 --> 00:41:06,836 you would have found it already. 753 00:41:06,836 --> 00:41:09,104 AUDIENCE: That would be a different scenario if that 754 00:41:09,104 --> 00:41:11,700 path were weighted. 755 00:41:11,700 --> 00:41:13,970 PROFESSOR: Well, if the paths are weighted, then it's a 756 00:41:13,970 --> 00:41:16,660 little different because here, we're just 757 00:41:16,660 --> 00:41:18,270 doing shortest path. 758 00:41:18,270 --> 00:41:21,330 What you're talking about is doing a least cost path, in 759 00:41:21,330 --> 00:41:28,440 which case the main difference would be how it sorts its list 760 00:41:28,440 --> 00:41:31,021 of candidate paths, right? 761 00:41:31,021 --> 00:41:32,482 AUDIENCE: [INAUDIBLE] 762 00:41:32,482 --> 00:41:35,891 PROFESSOR: Hmm? 763 00:41:35,891 --> 00:41:38,813 AUDIENCE: When it does sort it, it would say, keep this 764 00:41:38,813 --> 00:41:40,274 [UNINTELLIGIBLE] path [UNINTELLIGIBLE PHRASE]? 765 00:41:40,274 --> 00:41:44,215 766 00:41:44,215 --> 00:41:45,010 PROFESSOR: Yes. 767 00:41:45,010 --> 00:41:49,020 So in this case, our lambda function is saying that we're 768 00:41:49,020 --> 00:41:51,480 going to sort these lists based on their length. 769 00:41:51,480 --> 00:41:54,470 But if I wanted to say, sort them based on the sum of their 770 00:41:54,470 --> 00:41:58,210 weights, then I would have a function that sums up the 771 00:41:58,210 --> 00:42:03,030 weights on that path and uses that in the sorting in order 772 00:42:03,030 --> 00:42:06,385 to select the next partial path to search. 773 00:42:06,385 --> 00:42:08,570 AUDIENCE: Although, in that case, you'd actually have to 774 00:42:08,570 --> 00:42:11,181 ennumerate every single possible path, to show you 775 00:42:11,181 --> 00:42:12,924 found the lowest cost path. 776 00:42:12,924 --> 00:42:16,410 777 00:42:16,410 --> 00:42:18,402 PROFESSOR: No. 778 00:42:18,402 --> 00:42:19,896 AUDIENCE: Because doesn't-- 779 00:42:19,896 --> 00:42:24,550 I might understand this-- is that you find all the paths of 780 00:42:24,550 --> 00:42:25,990 length one through a certain point and all the 781 00:42:25,990 --> 00:42:27,190 paths of length 2. 782 00:42:27,190 --> 00:42:27,810 PROFESSOR: Right. 783 00:42:27,810 --> 00:42:30,050 AUDIENCE: And so if you're worried about cost, it's 784 00:42:30,050 --> 00:42:33,390 possible-- in principal-- that your longest path is your 785 00:42:33,390 --> 00:42:34,330 lowest cost path. 786 00:42:34,330 --> 00:42:34,956 AUDIENCE: Wait. 787 00:42:34,956 --> 00:42:36,680 You're not sorting it by length then. 788 00:42:36,680 --> 00:42:39,690 PROFESSOR: Right. 789 00:42:39,690 --> 00:42:39,950 [INTERPOSING VOICES] 790 00:42:39,950 --> 00:42:41,980 PROFESSOR: But what he's saying is that because you're 791 00:42:41,980 --> 00:42:45,910 growing it by one each time, then it's possible that-- 792 00:42:45,910 --> 00:42:53,890 let's say that I have partial paths of length 2, but my 793 00:42:53,890 --> 00:42:58,650 least cost path is actually of length 5, then even if one of 794 00:42:58,650 --> 00:43:00,160 these nodes reaches-- 795 00:43:00,160 --> 00:43:05,440 like, say that v2 reaches the goal before the actual least 796 00:43:05,440 --> 00:43:09,710 cost path, then you can't stop. 797 00:43:09,710 --> 00:43:11,590 You do have to integrate through all of them. 798 00:43:11,590 --> 00:43:13,000 AUDIENCE: Well, you just sort it by cost. 799 00:43:13,000 --> 00:43:15,662 I think that it's a better example to say that if you 800 00:43:15,662 --> 00:43:16,970 have one partial path that has cost 7 ... 801 00:43:16,970 --> 00:43:18,410 PROFESSOR: Well, actually, wait. 802 00:43:18,410 --> 00:43:18,670 No. 803 00:43:18,670 --> 00:43:19,380 You're actually right. 804 00:43:19,380 --> 00:43:22,830 Because if you sort it by cost, then your least cost 805 00:43:22,830 --> 00:43:24,750 path is going to be in front of your queue all the time. 806 00:43:24,750 --> 00:43:26,214 AUDIENCE: No, I don't think that's true. 807 00:43:26,214 --> 00:43:28,654 Because imagine this-- 808 00:43:28,654 --> 00:43:31,338 imagine you had a graph that was like-- this 809 00:43:31,338 --> 00:43:32,558 is your start node. 810 00:43:32,558 --> 00:43:35,910 This is your end node, and you go like 811 00:43:35,910 --> 00:43:40,230 this, this, this, this. 812 00:43:40,230 --> 00:43:42,250 And so you make a breadth-first, where you go to 813 00:43:42,250 --> 00:43:45,210 this node and this node, and the cost of this is 1 and the 814 00:43:45,210 --> 00:43:46,760 cost of this is 8. 815 00:43:46,760 --> 00:43:50,710 The cost of this is 20 and the cost of this is 1. 816 00:43:50,710 --> 00:43:54,664 This is your shortest path, or this is your cheapest path, 817 00:43:54,664 --> 00:43:57,760 but when you add them-- they're both of length 1-- 818 00:43:57,760 --> 00:44:02,075 so you explore this one first because it's the cheapest at a 819 00:44:02,075 --> 00:44:04,602 cost of 1, but the total cost is 21 to 820 00:44:04,602 --> 00:44:05,786 continue from this node. 821 00:44:05,786 --> 00:44:09,090 But the total cost is [UNINTELLIGIBLE] that node. 822 00:44:09,090 --> 00:44:10,485 So I think that he's right. 823 00:44:10,485 --> 00:44:11,200 Right? 824 00:44:11,200 --> 00:44:13,490 I thought you had to expand all nodes when you're doing 825 00:44:13,490 --> 00:44:14,000 breadth-first. 826 00:44:14,000 --> 00:44:15,250 That's why you do, like, [UNINTELLIGIBLE]. 827 00:44:15,250 --> 00:44:19,000 828 00:44:19,000 --> 00:44:19,820 But, yes. 829 00:44:19,820 --> 00:44:24,058 For weights you have to expand all of them. 830 00:44:24,058 --> 00:44:24,850 PROFESSOR: So-- 831 00:44:24,850 --> 00:44:26,078 AUDIENCE: [INAUDIBLE] 832 00:44:26,078 --> 00:44:26,996 PROFESSOR: Yes? 833 00:44:26,996 --> 00:44:27,914 AUDIENCE: [INAUDIBLE] 834 00:44:27,914 --> 00:44:30,450 PROFESSOR: Possibly, yes. 835 00:44:30,450 --> 00:44:32,608 I'm blanking on the answer. 836 00:44:32,608 --> 00:44:37,570 837 00:44:37,570 --> 00:44:41,411 But in this case, we don't have to enumerate all paths. 838 00:44:41,411 --> 00:44:44,226 AUDIENCE: We're just looking for the shortest path-- we can 839 00:44:44,226 --> 00:44:45,387 just find the shortest path. 840 00:44:45,387 --> 00:44:46,381 PROFESSOR: Right. 841 00:44:46,381 --> 00:44:50,360 But if you're incorporating costs, then you would use a 842 00:44:50,360 --> 00:44:52,460 different algorithm, so it'd be, like, actual shortest path 843 00:44:52,460 --> 00:44:55,720 algorithm or something like that. 844 00:44:55,720 --> 00:44:58,439 So why don't we just run this. 845 00:44:58,439 --> 00:45:02,303 AUDIENCE: So is one better than the other, when you 846 00:45:02,303 --> 00:45:03,553 [INAUDIBLE]? 847 00:45:03,553 --> 00:45:05,684 848 00:45:05,684 --> 00:45:07,910 PROFESSOR: They have different running characteristics. 849 00:45:07,910 --> 00:45:09,550 It really depends on your application. 850 00:45:09,550 --> 00:45:12,700 851 00:45:12,700 --> 00:45:18,020 The nice thing about depth-first search is that 852 00:45:18,020 --> 00:45:21,190 it's fairly memory efficient because with breadth-first 853 00:45:21,190 --> 00:45:23,710 search, you're storing all the possible paths-- 854 00:45:23,710 --> 00:45:27,600 all the possible partial paths. 855 00:45:27,600 --> 00:45:30,370 With depth-first search, you only have one path and memory 856 00:45:30,370 --> 00:45:33,860 at a given point, right? 857 00:45:33,860 --> 00:45:37,890 You have the path that you've already found from one of your 858 00:45:37,890 --> 00:45:40,830 children to the end node, plus 1. 859 00:45:40,830 --> 00:45:43,450 But with the breadth-first search, you're going to have a 860 00:45:43,450 --> 00:45:44,990 list of all the partial paths that you 861 00:45:44,990 --> 00:45:46,240 have to search through. 862 00:45:46,240 --> 00:45:50,170 863 00:45:50,170 --> 00:45:51,420 So let's see. 864 00:45:51,420 --> 00:46:13,075 865 00:46:13,075 --> 00:46:14,554 This doesn't make sense. 866 00:46:14,554 --> 00:46:17,512 AUDIENCE: I don't think it matches the picture. 867 00:46:17,512 --> 00:46:20,963 AUDIENCE: [0, 4] is a path, isn't it? 868 00:46:20,963 --> 00:46:22,935 From the graph? 869 00:46:22,935 --> 00:46:24,760 PROFESSOR: Right. 870 00:46:24,760 --> 00:46:25,100 Yes. 871 00:46:25,100 --> 00:46:26,200 No, it's not matching the picture. 872 00:46:26,200 --> 00:46:26,730 AUDIENCE: [INAUDIBLE] 873 00:46:26,730 --> 00:46:27,613 PROFESSOR: What's that? 874 00:46:27,613 --> 00:46:30,860 AUDIENCE: [INAUDIBLE] 875 00:46:30,860 --> 00:46:31,400 PROFESSOR: Is what? 876 00:46:31,400 --> 00:46:32,672 AUDIENCE: It was undirected. 877 00:46:32,672 --> 00:46:36,730 PROFESSOR: Yes, it was an undirected graph-- that's why. 878 00:46:36,730 --> 00:46:41,755 So if we run it directed, let's see what happens. 879 00:46:41,755 --> 00:46:51,040 880 00:46:51,040 --> 00:46:53,540 AUDIENCE: 0 to 4 is still in the graph. 881 00:46:53,540 --> 00:46:54,790 PROFESSOR: Yes. 882 00:46:54,790 --> 00:46:57,910 883 00:46:57,910 --> 00:47:00,906 You are absolutely right. 884 00:47:00,906 --> 00:47:02,770 Oh, you know what's going on-- it's running both. 885 00:47:02,770 --> 00:47:03,910 It's running the depth-first search. 886 00:47:03,910 --> 00:47:06,453 AUDIENCE: No, it's running both the directed and the 887 00:47:06,453 --> 00:47:06,806 undirected. 888 00:47:06,806 --> 00:47:08,430 PROFESSOR: Well, it's also running the 889 00:47:08,430 --> 00:47:10,730 depth-first search as well. 890 00:47:10,730 --> 00:47:13,880 That was my question, because I was looking at this, and I 891 00:47:13,880 --> 00:47:16,650 was, like, that's not breadth-first search, that's 892 00:47:16,650 --> 00:47:18,610 depth-first search. 893 00:47:18,610 --> 00:47:22,530 This, on the other hand, is breadth-first search. 894 00:47:22,530 --> 00:47:28,390 So there we go. 895 00:47:28,390 --> 00:47:31,670 So if we have a graph-- and let's see-- 896 00:47:31,670 --> 00:47:37,240 so it starts off with node 0, and then it builds a new list 897 00:47:37,240 --> 00:47:44,490 of partial paths with [0, 1], [0, 2], so it's got, in this 898 00:47:44,490 --> 00:47:50,500 case, this partial path and then this partial path. 899 00:47:50,500 --> 00:47:53,910 And then it expands one of them. 900 00:47:53,910 --> 00:47:56,630 So, in this case, I guess [0, 1] 901 00:47:56,630 --> 00:47:59,540 was the path that was first on the list, right? 902 00:47:59,540 --> 00:48:06,050 So it's going to expand the children of 1, which is just 2 903 00:48:06,050 --> 00:48:06,800 and itself. 904 00:48:06,800 --> 00:48:08,300 But it's going to avoid cycles. 905 00:48:08,300 --> 00:48:09,641 AUDIENCE: [INAUDIBLE] 906 00:48:09,641 --> 00:48:10,400 PROFESSOR: What's that? 907 00:48:10,400 --> 00:48:11,610 AUDIENCE: [INAUDIBLE] 908 00:48:11,610 --> 00:48:12,180 PROFESSOR: Oh, yes. 909 00:48:12,180 --> 00:48:17,975 And then it's going to expand this partial path-- the [0, 2] 910 00:48:17,975 --> 00:48:18,390 -- 911 00:48:18,390 --> 00:48:21,970 because it's the shortest one, and it's going to add that new 912 00:48:21,970 --> 00:48:24,350 partial path to the end. 913 00:48:24,350 --> 00:48:29,770 And then it's going to expand this guy, and add the 914 00:48:29,770 --> 00:48:33,230 expansion here, and then it's going to expand this guy. 915 00:48:33,230 --> 00:48:41,260 And it turns out that one of the children of 3 is 4. 916 00:48:41,260 --> 00:48:45,180 So it's found the shortest path from 0 to 4. 917 00:48:45,180 --> 00:48:48,500 918 00:48:48,500 --> 00:48:49,493 Make sense? 919 00:48:49,493 --> 00:48:53,150 AUDIENCE: So, can you go back to [INAUDIBLE]? 920 00:48:53,150 --> 00:48:57,972 Then why does it say [0, 2, 3] then? 921 00:48:57,972 --> 00:49:00,680 PROFESSOR: That's the representation in the pass 922 00:49:00,680 --> 00:49:08,400 list, so each element in the path's list is 923 00:49:08,400 --> 00:49:10,140 represented as a tuple. 924 00:49:10,140 --> 00:49:14,240 The first element is the list of nodes on that path, and 925 00:49:14,240 --> 00:49:18,640 then the second element is the length of that path. 926 00:49:18,640 --> 00:49:21,400 And that's why we had that lambda function in the first 927 00:49:21,400 --> 00:49:24,430 place, right? 928 00:49:24,430 --> 00:49:28,330 So if you read the specification here, you have 929 00:49:28,330 --> 00:49:30,980 path length, and then you have the nodes 930 00:49:30,980 --> 00:49:32,230 that are on that path. 931 00:49:32,230 --> 00:49:34,820 932 00:49:34,820 --> 00:49:40,360 And when we sort the path list-- because we need to make 933 00:49:40,360 --> 00:49:44,300 sure that we're looking at the shortest path-- 934 00:49:44,300 --> 00:49:51,030 then we use this lambda function in order to get that 935 00:49:51,030 --> 00:49:52,750 length for each tuple. 936 00:49:52,750 --> 00:49:57,398