00:00:17.160
all right so my name is jamus Buck and I'm here to talk to you about algorithms the joy of algorithms you are going to
00:00:23.279
be riveted you're are going to be so excited coming out of here we going to pound more code after this session than has ever been pounded at rubycon
00:00:31.320
now what I want to talk to you about is getting better at something whether it's running or walking or crawling or
00:00:38.680
dancing or singing or drawing cooking or programming no matter what it is the
00:00:43.920
process of going from where you are to where you want to be involves hard work
00:00:50.079
okay that's the secret sauce it's hard yeah
00:00:56.680
interlude and I don't dance so it would be hard work for you to watch me dance
00:01:02.320
okay that that's the secret sauce That's the Silver Bullet there's there's not an easy way to get good at something you
00:01:08.840
just have to work hard at it now the thing about hard work is it's hard work
00:01:13.920
right it's sometimes we don't want it to be hard work we we we sit down we get frustrated when we want to learn
00:01:20.680
something and it's not easy but we need to accept that it's hard and go forward with it we need to work the parts that
00:01:26.200
are hard for us because that's what will make us better when we work the parts that are easy for us that's play okay
00:01:33.159
and there's a place for that because it keeps us fresh it keeps us able to do the things we do regularly but
00:01:40.240
play is not exercise play is not hard work and it's the hard work I want to
00:01:45.399
focus on now one of the key things about hard work seriously the hard the thing
00:01:52.159
about hard work is you need to keep you need to work at it regularly you know consistent
00:01:59.439
regular exercise and you know a schedule is what will will help you improve when you
00:02:05.600
don't stick to a schedule things kind of fall apart I mean it can still help it's better to do it once in a while than not
00:02:11.319
at all like if you're trying to learn to program it's better to sit down in front of the computer and try something once in a while but it's even better if you
00:02:17.680
sit down in front of that computer on a regular basis and for force yourself to do something new something that's not in
00:02:24.400
your comfort zone now you don't want to sit down and like solve an NP hard
00:02:30.480
problem right you you you need to focus on something that's within your range that you can reach but still stretch
00:02:36.080
yourself go a little bit outside your comfort zone now the thing about this the regular consistent schedule is
00:02:42.480
that's all uh time management and I don't want to talk about that time management does not interest me at all
00:02:47.959
what interests me is the plan the steps you will take to get better okay and
00:02:54.720
along those lines I want to talk to you about algorithms because algorithms I think are one of the perfect tools you can use as a programmer to get better at
00:03:01.319
your craft I mean what is an algorithm an algorithm is a stepbystep description of
00:03:06.640
what you need to do right it takes you through the process of accomplishing some task and that's why they're great
00:03:12.879
but the cool thing about algorithms is that they're everywhere okay in computers you seriously can't turn
00:03:18.040
around without bumping into an algorithm um no matter what you do day-to-day as a
00:03:23.120
software developer you are using algorithms and algorithms there's there's easy algorithms there's hard
00:03:28.840
algorithms there's algorithms that you use all the time and algorithms that you've never heard of before and everything in between there's a huge
00:03:35.840
range of possibilities for you to investigate which is another thing that's awesome about him and for me I
00:03:42.080
really enjoy maze generation algorithms how many of you followed my blog a year ago when I was writing about that good
00:03:48.480
so a lot of this will be new to people the rest of you it's review no um a maze really is just you know it's
00:03:55.879
the puzzle where you start at some point and you go through the maze the other end of the point and as long as you don't cross any lines you win but the
00:04:02.760
cool thing about it is it's also packed with graph Theory and graph theory is
00:04:08.000
fascinating and it has so many applications in computer science now my personal interest in mazes are the class
00:04:14.920
of Mazes called perfect mazes and these are mazes that um have one unique
00:04:21.199
solution there is no Cycles in the Maze you you just find your way through it okay and it's what most of us think of
00:04:27.600
when we think of mazes now a maze is a spanning tree a
00:04:33.000
perfect maze is a spanning tree and spanning trees are a very well researched and very well documented data
00:04:38.280
structure for which there is a huge body of algorithms available and now you're sitting there glaring at me saying wait
00:04:44.759
a minute I didn't sign up for a computer science lecture and I'm saying surprise you totally signed up for a computer
00:04:50.400
science lecture um but that's not a bad thing if you want to get good at chinups right you're
00:04:56.800
going to do a lot of chin-ups but if you want to get in shape you're going to do chinups and sit-ups and push-ups and
00:05:03.479
running and a lot of other things it's not just about the chinups the same as with um computer
00:05:10.199
science or with programming or anything you want to do if you can cover a wide base you're going to make yourself more
00:05:16.199
able to learn more by learning these new Concepts you add these little hooks in
00:05:21.600
your brain that you can hang stuff on and then when you encounter another idea those hooks are already there for you
00:05:28.280
you can say wait that's just like this other thing I learned about okay if you look at graphs and you're like yeah there's this little dot thingy and then
00:05:34.440
a line it's really hard to talk to other computer scientists about it because a DOT thingy in a line can mean a lot of
00:05:40.960
different things but if you're talking with the same vocabulary things get a lot easier so we're going to start with a basic
00:05:47.120
vocabulary lesson we're going to look at this okay in graph terms this is called a Vertex
00:05:53.240
or a node all sometimes call it a cell and it's represented as a dot but it can but it can really be anything it can be
00:05:59.479
a a car it can be a person like in data modeling it might be um the people that
00:06:04.600
are friends and so forth okay this is an edge and it's usually represented as a line between two nodes and it represents
00:06:11.680
a relationship between those two nodes in a maze that's going to be a passage between two locations but in a database
00:06:19.319
it might be you know is a friend of this person it represents some relationship between two entities now when you get a
00:06:25.479
bunch of nodes and edges Al together that's a graph and in this case so if you have if every node is reachable by
00:06:32.520
every other node in the graph by following one or more edges then you've got a connected graph which is what this
00:06:38.599
is and this is also a graph with a cycle in it which means it's got a loop okay you go around and round and round if we
00:06:45.960
cross out one of those edges and break the cycle we now have what is called an acyclic graph this happens to be a
00:06:52.160
connected acyclic graph which is the same thing as a tree and trees we deal
00:06:57.479
with all the time in computer science now any given graph can contain multiple
00:07:02.879
trees at the same time a tree doesn't have to span the entire graph but if it does we have what is called a spanning
00:07:10.400
tree because it spans the graph obviously um and spanning trees
00:07:17.879
are cool because they are those perfect mazes that I was talking
00:07:23.120
about now fortunately for Maze lovers any given graph contains multiple
00:07:30.400
possible spanning trees okay and that group of spanning trees is called the spanning
00:07:36.039
forest and so what the what the act of maze generation is it's simply going
00:07:42.720
into that spanning forest and plucking one of those spanning trees out and saying here's my maze or this one and
00:07:48.560
ideally if you can do that uniformly like with no bias no Prejudice just
00:07:53.759
randomly and evenly distributed distributedly evenly pulling those things out
00:08:00.159
the result is called a uniform spanning tree and there's nothing that you can look at and say this is a uniform
00:08:05.759
spanning tree it's a statistical entity but this kind of the Holy Grail of maze generation is a uniform spanning tree be
00:08:12.360
able to pull it out and have have no bias and be perfectly random the question is how do
00:08:18.319
you get these mythical beasts okay these uniform spanning trees and that's where things start getting interesting Aldis
00:08:25.360
and broer were two researchers who were studying this problem and they came up with a solution an algorithm yes what
00:08:34.080
they said is well if you start anywhere in this graph that's your starting point and then you do a drunkard's walk okay
00:08:39.599
you just start going node to node through this graph visiting as you go by
00:08:45.560
the time you visited all the nodes you'll have um a uniform spanning tree
00:08:51.080
specifically if as you go when you move from one node to another if that other node has not been visited yet you
00:08:56.920
connect them draw a passage between them in maze terminology but if you go from
00:09:02.040
one node to another and that one's already been visited then you don't do anything as long as you obey those Rules by the time you've visited all the nodes
00:09:08.320
you'll have a maze in my terminology so let's take a
00:09:13.360
look at it let's run one here quick it finally gets around to
00:09:19.079
finishing it up let's do that one more time just so you can be totally bored see how it just kind of goes and does
00:09:24.800
its own little thing that's because it's not intelligent right it's just following the rules of blindly walking
00:09:30.640
that graph which the downside is that it's theoretically possible for this
00:09:36.279
algorithm to never complete right it could if it's purely random then there is a chance that it could go back and
00:09:43.120
forth forever between two nodes and never actually visit the entire Maze and that's bad if you actually want to
00:09:48.399
generate a maze you'd like some guarantee that it will eventually complete so this one is slow it is
00:09:55.680
guaranteed that if it completes it will give you a uniform sping tree but we'd like a little more of a guarantee than
00:10:01.839
that so Wilson went along and he said well maybe there's a way to speed this up a little bit and his approach was
00:10:06.920
that we're going to start somewhere and we're going to put out feelers okay we're GNA we're going to add one node to
00:10:12.240
the to the spanning tree and then we're going to choose another place and we're just going to try and feel our way to that one okay and when we find it we're
00:10:20.040
going to do our drunkard's walk as we attempt to do it and when we get there when we find a connection between those
00:10:25.519
two we'll draw the path We'll add that path to our spanning tree then we'll do it again we'll pick some other node that
00:10:31.040
has that isn't part of the tree and we'll just do our random walk until we encounter a node that is in the tree and we do that over and over and over until
00:10:37.440
everything's been visited now this works um a little faster than Aldis broer because after that first walk
00:10:44.959
where it has to go from one place to find the needle in the hay stack that's already in the tree after that you've
00:10:50.880
added a bunch more nodes to the tree and so the next walk has a much greater chance of finding one of them and a walk
00:10:56.519
after that a much greater chance and so forth and so at snowballs and gets much faster let's take a look
00:11:01.760
here see at first and there there it just picks right up and goes like crazy let's do it one more time you can see it
00:11:07.560
walks for a while until it finds what it's looking for and then it gets there so that's Wilson's algorithm but because
00:11:14.279
it's doing that random walk that can go anywhere It suffers from that same problem of Alis broer that there's a
00:11:20.600
chance that it may never complete and that's that's not cool so this one is slow as well but if we don't mind
00:11:28.600
farming from a particular corner of that spanning Forest right if we don't mind
00:11:33.720
that there might be a bias involved we might get mazes that are all long and twisty passages or the that have a lot
00:11:39.480
of dead ends or or things like that if we don't mind those kind of biases then there are ways to do this faster the
00:11:45.920
binary tree algorithm is one of those algorithms it's very fast and very
00:11:52.800
biased the reason it's fast is because it can do the entire graph in order end time it only has to look at each node
00:11:59.000
once and it makes one decision for each node it says do I connect the passage North
00:12:05.320
or do I connect The Passage West once it makes that decision it moves to the next node so you can just fly through this
00:12:13.440
this um algorithm there's an example now you can
00:12:19.800
see there's kind of a strong lean to the maze right it tends to have this River
00:12:25.680
heading towards the diagonals there's also a solid Corridor on the North and a solid Corridor on the west and those are
00:12:31.560
all side effects of the algorithm okay we we farmed this particular maze from a
00:12:37.160
particular corner of our spanning forest right and in this and in this corner all of the mazes have a solid Corridor
00:12:43.600
across the top and a solid Corridor on the west um we can we can switch things up a
00:12:49.000
little bit for instance we can say what if we choose south and east instead when we run it if we choose south and east
00:12:55.760
then it just changes where that bias is located but the maze still has that very strong bias the nice thing about this is
00:13:02.320
if you're in that corner and you're trying to get to the other it's trivial because there's there's only there's no
00:13:08.399
dead ends if you're going from one diagonal to the other but if you're going the other way then it gets harder because there's more dead ends so there
00:13:16.600
there's some bias in that one so let's take a look at the Sidewinder this one has the potential to get rid of some of
00:13:22.120
that bias the way it works I mean you looked at the binary tree algorithm right it
00:13:27.240
looks at each node in isolation it says okay okay what are you going to do buddy and you are going to go north or you are
00:13:33.120
going to go west and and and that's the way it is Sidewinder goes row by row just like the binary tree algorithm did
00:13:39.519
but this time it groups adjacent nodes into clusters okay into random groups
00:13:44.760
and they'll say okay this guy's by himself and these next two are together and these next three are together and this guy's by himself and so forth and
00:13:50.839
then it looks at those groups and says from each of those groups I'm going to choose one member to carve
00:13:58.040
North when we do that see there's no longer that strong
00:14:04.399
lean anymore but there's still a solid passage across the top because you can
00:14:09.680
never carve up from a cell that's already at the top so you just group them all and just try it with your eyes
00:14:16.320
here pick any cell on the bottom and try and find your way to the top it's trivial like again there are no dead
00:14:22.800
ends when you move bottom to top there are dead ends when you move top to bottom though so in situations where
00:14:28.399
that's the direction you need to go this may be a very appropriate algorithm for you okay so that one has some bias too
00:14:35.800
so what what can we do well we can look at ales groer and Wilson's algorithms and say well what were they doing that
00:14:42.160
these other algorithms weren't and one of them is well they were doing that drunkard's walk right say well maybe there's something to that what if we try
00:14:49.399
that oh I got ahead of myself sorry there's one more we're going to do that goes rowwise this one's actually really tricky this
00:14:56.040
one took me a long time to wrap my mind around um even though it looks like visually like it should be simple um it
00:15:03.720
works a lot like the side Winder in that it groups horizontal clusters of cells but this time it groups them into sets
00:15:09.600
where they may not be adjacent cells like you may have this one in set one and this one in set two and this one in set one
00:15:15.199
again um in this case we've got two adjacent cells that are in different sets and we're trying to decide if we want to merge them we'll say we do we
00:15:21.759
merge them the next step is you say okay we're going to create at least one downward passage for each group of cells
00:15:29.759
each set not group of cell each set on this row and in this case we create one and we merge that one then into the same
00:15:36.720
set then we increment the row so then we go down to the next row we do the same thing but this time some of the sets are
00:15:42.160
already done for us they're part of that the previous row or the previous rows and that's where things get tricky you
00:15:47.920
have to keep track of which set each cell is in and but the
00:15:53.560
result as it goes down it's a lot less bias like you look at this you don't immediately see the biases that you saw
00:15:59.959
in the binary tree and The Sidewinder it does have a tendency to create a long passage on the bottom that
00:16:05.399
is probably its weakness because it has to combine all the sets into one by the time it finishes and it usually tends to
00:16:11.199
do that last minute gets to the bottom and says oh crap and it combines everything all at the last minute you
00:16:16.360
got this one long passage um but other than that The Mazes it generates are are pretty pretty great
00:16:22.680
okay but so now now we're to the the drunkard's walk one what happens when we go with drunkard's walk hunt and kill is
00:16:29.000
one such algorithm that's based on the drunkard's walk and it works in two phases the first is the kill phase where it tries
00:16:35.199
to swat as many um cells as it can doing a drunkard's walk just Teeters along follows uh
00:16:43.680
follows that drunkard's walk into any cell it wants with one condition this time it adds a constraint so that we
00:16:48.720
make sure that we can eventually terminate the problem with eldis broer and Wilson is that they have a chance of
00:16:54.000
never terminating because they can go back and forth this time we say you can do a drunkard anywhere you want as long
00:17:00.040
as you only visit cells that haven't been visited yet and so that way it can never go back to where it was it only
00:17:05.520
has just snakes on and on but because we've added that constraint it can now walk itself into a corner right it can
00:17:11.600
go around on itself and and dead end so what you do in that case the hunt and kill algorithm in that case enters hunt
00:17:18.199
mode okay that's where it says oh we're done killing now we need to look for more to kill and so it goes up to the
00:17:23.799
top row and it starts scanning row by Row for any cell that hasn't been visited that is immediately adjacent to
00:17:30.039
a cell that has been visited okay once it finds that particular configuration it goes back into kill mode well it
00:17:36.360
connects those two goes back into kill mode and starts doing the random walk again from that unvisited
00:17:42.200
note and with that addition you're guaranteed that it will complete because
00:17:47.600
when you finished when you do a final scan and you hunt and you don't find anything that's unvisited then you know
00:17:53.039
you're done so let's take a look at that one so it snakes around you can see it
00:17:59.720
doing a quick scan there and then does a final scan and it's done one more
00:18:07.000
time and there it's done so that's cool that's possibly an improvement it's
00:18:12.760
still biased the bias on this one is it's got long windy passages with few dead ends okay because we're sacrificing
00:18:20.280
dead ends for longer passages we're just winding as far as we can before we dead in and then we go as far as we can
00:18:25.840
before we dead in I kind of like that bias personally I like the look of this kind of maze but it does tend to create
00:18:31.880
mazes with simpler Solutions because there are fewer dead ends there's fewer chances of going
00:18:37.360
wrong um this one's also slow right not
00:18:42.559
as slow as Alis broer or Wilson's but scanning the entire graph over and over and over again is not a cheap operation
00:18:48.840
you're looking I mean that right there makes it in order N squared right um the
00:18:54.720
bigo notation so what can we do well let's let's try another tag what if we
00:19:01.480
do our random walk but we keep track of where we've been we keep a stack and every time we
00:19:07.240
visit a node we throw it on a stack we visit one we just keep throwing it on there then when we dead in we start
00:19:12.520
popping those babies off until we get to a node that has an unvisited neighbor at which point we can start our random walk
00:19:18.520
again and throw some nodes on there again so throw the nodes on pop them off and when we've popped all the way back
00:19:24.840
to the very beginning and our stack is empty that's when we're done because we we know that we've tried every possible
00:19:30.480
node and none of them have any unvisited neighbors therefore we're finished so this one is one of my favorite to
00:19:39.559
watch just snakes around until everything's
00:19:44.679
done still it has the same bias as hunt and kill right because you're still doing the long passages um and
00:19:51.039
sacrificing the short deadend corridors now since we're talking about
00:19:56.320
recursion here's another really cool algorithm that's actually very different from any other maze algorithm I've seen
00:20:02.480
whereas most maze algorithms I've talked about and researched work by carving through something you can think of like
00:20:08.440
you're in a mountain you're this little you give a dwarf a pickaxe and off he goes chipping his way through carving passages right recurs of division
00:20:15.480
algorithm actually says well no we're going to be calm and we're going to have a nice big peaceful field and we're going to build walls all through it so
00:20:22.320
it's a different way of thinking about the problem what it does is the first it gives you that empty plane and then it
00:20:27.640
chops the field in half okay and then it creates a passage between the two sub the two halves and
00:20:32.799
then chops those halves in half and then creates passages there and then chops in half and chops in half and you just keep chopping in half until you get down to
00:20:39.200
the resolution of your passageways and then you're
00:20:44.480
done like this it's a lot of fun this is actually
00:20:51.200
a fun one to step through let's go step at a time so you start with your full field and you cut it in half and then you add a passageway connecting the two
00:20:58.280
you choose choose one of the sub fields and you cut it in half choose me you create a passage connecting the two and then you choose one of those sub fields
00:21:04.360
and you just keep doing it recursively the same process one two three one two 3 one two three and when you get down to
00:21:10.919
the resolution you want then you pop over to some other subfield that hasn't been divided far enough yet and you let it
00:21:16.279
go so that's the recursive division algorithm and one nice thing about this one is you can actually control how far
00:21:22.720
down you go you don't have to go all the way down to the resolution of the passages every time if you stop early you wind up with room
00:21:29.480
okay larger areas that are than connected to other parts of the the I want to say dungeon because that's what
00:21:34.960
comes to mind other areas of your maze but it it's biased okay it's biased
00:21:41.520
too because if you look if you're trying to go from the top to the bottom we we cut the entire field in half and created
00:21:47.520
one passage right so you know that if you're going north to south you have to go through that bottleneck somewhere
00:21:53.039
there's lots of bottlenecks in this kind of maze which means you wind up with mazes that are fairly straightforward to solve it's never going to do these big
00:21:59.240
up and down and back and forth yeah oh
00:22:05.039
yeah you don't chop the graph in half what you do is you build walls in other words you start with a fully connected
00:22:10.840
graph and you pull edges out and then you connect them again where your passage is and then you pull edges out
00:22:17.360
and anyway yeah now actually under the covers I mean that's how you would think of it as a graph but if actually under
00:22:23.440
the covers implementing it it might be easier to implement it some other way like with an array right with a two dimensional array
00:22:30.080
um but yeah it's still graph Theory okay so now we've explored a few
00:22:38.080
different options what if we say well obviously spanning trees are a very well researched well documented area um
00:22:45.279
surely others have have solved these problems before of taking a graph and finding a spanning tree for it and of
00:22:50.840
course people have if you have a graph with weighted edges in other words
00:22:55.880
there's a number on each Edge that tells how expensive it is is to cross that edge then you can take an algorithm like
00:23:02.240
crustal which finds a minimum spanning tree and run it on that and what it does is it tries to find the spanning tree
00:23:08.279
with the lowest cost okay by finding the edges with the lowest numbers that still make a spanning tree but now if you
00:23:16.039
instead of weighted edges what if you just throw random numbers on all of them and then run prestal well what you get
00:23:22.039
is a random spanning tree okay still with some bias but it works and conceptually the
00:23:28.640
way I think of it is like a field of Play-Doh balls right and as you go through this field you start
00:23:34.760
connecting adjacent pieces of PlayDoh with the constraint that you can never connect two adjacent pieces of
00:23:41.400
Play-Doh if they are already connected somehow so that piece in the upper left corner there we couldn't connect the
00:23:46.559
bottom two because they're already there's already a path between them but we could connect the the two in the
00:23:51.640
middle on the right okay you just keep doing that until all you've got left is one big piece of Play-Doh strung all
00:23:57.559
over the field and when you've done that you've got your spanning
00:24:02.960
tree crusts itself doesn't do a whole lot for me I mean it's kind of fun to watch how it appears out of nothing like
00:24:08.440
just little pieces here and there all kind of coming together but what I love about crcll is this if you start with a configuration like this where you've
00:24:14.520
stretched the Play-Doh across the middle across three nodes and then you've taken another piece of Play-Doh and stretched
00:24:19.679
it underneath that one okay it's all still disjoint sets but what happens
00:24:25.320
when you run crust BS on that configuration well what you get is a weave maze where the passages go over
00:24:30.720
and under and you get some really interesting configurations that way if you start by just putting up your
00:24:36.799
Crossings and you make sure that the sets are all valid and that's kind of tricky and out itself sometimes once you've got that then you just run
00:24:46.039
crusts and don't get tangled um and there You' got your weave
00:24:51.159
maze but the cool thing is by changing the density of that initial um configuration of Crossings you can
00:24:57.480
change how thick your maze is like how how many Crossings it has those weave
00:25:02.760
mazes I just love it's such a such a great visual representation it's great
00:25:08.200
to look at okay so prims is another one that solves the same problem as pral it
00:25:13.919
creates a weighted spanning a minimum spanning tree from a weighted graph yes
00:25:27.320
sir sure where where would you like it to enter pick
00:25:32.799
one and then pick one that anyone you want to be the
00:25:39.279
exit okay yeah I I I
00:25:44.799
def sure and it can but that's the thing with a perfect maze because this is a perfect maze which means between any two
00:25:53.000
nodes in the graph there is exactly one path which means I could choose the top
00:25:58.640
left and the bottom right and I am guaranteed that there is a path between them I could pick any two nodes inside
00:26:04.399
the maze on the edges anywhere I want and I'm guaranteed a path that's why that's why perfect mazes interest me
00:26:11.080
because the actual entrance and exit is boring it can be anywhere you want you just pick them okay does that make
00:26:19.480
sense it is true I these These are deceptive to look at
00:26:26.200
right you look at that and you think there's no way that's all connected but I defy you to find a path that does not
00:26:31.799
connect to any other node in that okay we're not going to stand here while you try and defy me
00:26:37.880
but feel free to shoot me an email if you find an exception but it is it is all connected and watch let's let's do
00:26:45.200
this these Crossings are not all connected right I think we can agree on that because I've thrown them in there
00:26:51.399
at random some of them are like long windy passages through there others aren't okay but they don't all connect
00:26:59.279
but what crus does is it takes disjoint sets Okay does everyone know what I mean when I say disjoint sets sets for which
00:27:06.440
there is no overlap for which there's no there are no elements in common it takes these disjoint sets and makes of them a
00:27:13.360
single set okay that is what cuscal does and so when I run it it just starts
00:27:20.240
taking all of those sets including the crossings that I made and bringing them all together into one set so that when
00:27:25.399
I'm done I'm guaranteed to have a single single set okay from which that
00:27:31.320
everything there is a part of hope that makes sense Prim like I said does the same
00:27:38.159
sort of thing but it approaches it differently whereas cuscal kind of does something here and then something here and something here and just magically
00:27:44.039
everything comes together prims actually chooses a starting point kind of a seed
00:27:49.320
adds it to the spanning tree and then takes all of its neighbors and marks them as Frontier okay they're the Wild
00:27:56.960
Frontier the the next pass and subsequent passes look at that Frontier set grabbing one at random from the
00:28:03.320
frontier connecting it to the adjacent node the visited node that it's adjacent to and then marking its unvisited
00:28:10.360
neighbors as Frontier CES and it does that over and over and over until there are no more Frontier cells okay and the
00:28:17.600
way this one works reminds me of like you know setting a piece of paper on fire because it starts at one place and
00:28:24.000
it kind of grows outward kind of growing it organically it's a fun effect especially on a large maze where the
00:28:30.279
animation runs quickly it kind of just blows up um let's watch it one more time
00:28:35.440
just because it's fun just because I can so that's
00:28:41.799
primms um and you can do over and under weave mazes with a lot of these different algorithms I should state but
00:28:48.200
crustal is by far the most well suited to that okay the growing tree is probably
00:28:54.399
my favorite algorithm because it can be customized to act like other algorithms it's like the mocking bird of maze
00:29:00.440
generation algorithms okay the way it works it's not there's
00:29:06.960
nothing remarkable about the way the algorithm actually proceeds what you do is you take any node as your starting point and you put it in a set we're
00:29:13.200
going to call it the active set then at subsequent passes through the through the algorithm you look at
00:29:20.360
any node in that active set and you find its adjacent neighbor you look at its adjacent neighbors and you pick one at
00:29:26.640
random and you connect them and then you take that neighbor and you throw it in the active
00:29:32.440
set now if that node had no unvisited neighbors then you would remove it from
00:29:37.960
the active set okay so that's how the algorithm terminates it goes until there are no more nodes in the active set but
00:29:43.559
as long as there are nodes in the active set you pick one out you look to see unvisited adjacent neighbors you connect
00:29:49.360
to one of them and you throw that neighbor into the active set and you just keep doing that over and over there's nothing really exciting about
00:29:55.679
how that works but what interests me is this like how do you choose something out of that active set changing how that
00:30:02.360
works changes the whole behavior of the algorithm for instance if you you always grab the the N the the node that was
00:30:10.440
most recently added to the active set so you put one in and you immediately take it out again and look for adjacent neighbors to that one you get the exact
00:30:17.360
behavior of the recursive backtracker okay because it's a stack you put it in you pull it out you put one in take it
00:30:23.360
out you just keep building on top of that on the other hand if you grab at random so you put one in and then you
00:30:28.919
Shuffle the bag and you take one out you have something very similar though not identical to prim's algorithm where it
00:30:34.480
starts at a seed and it just starts growing out so let's take a look here's the growing tree done as um taking
00:30:41.399
newest from the active set and you'll see it acts exactly like the recursive
00:30:46.760
backtracker there's no way looking at just an animation of the algorithm to say whether it was growing tree newest
00:30:52.600
first or a recursive backtracker on the other hand we take prims
00:30:58.480
not prims but choosing randomly we get something that's very much like prims where it grows
00:31:04.080
outward until the whole maze is done but the cool thing now is what happens if half the time we choose the newest from
00:31:11.039
that active set and the other half of the time we choose it random okay if we go 5050 we get kind of
00:31:17.799
a fusion of the two algorithms where it tries to go you know
00:31:23.720
a random walk and then it jumps over here and does a little random walk here and jumps over here until the whole maze is flushed out and that gives you it
00:31:30.159
kind of tries to mitigate the long winding passage bias that you get in recursive backtracker right because now
00:31:35.799
it it goes but then it jumps somewhere else like it'll abort that random walk and go try to do it somewhere
00:31:41.159
else and you can do like uh 25 75 split if you want so we're we're favoring the
00:31:48.240
random on this one now what happens if we always choose the oldest node in that
00:31:56.840
pack pretty exciting it's interesting not the most
00:32:03.080
exciting maze in the world but what's interesting now is what if we take that and combine it with one so we take
00:32:08.559
oldest newest 50/50 split okay and you get this interesting fracture pattern where it looks like
00:32:14.519
youve shot a bullet at at a piece of glass and the passages just kind of all go out from there um you can do the same
00:32:21.000
thing with the random so oldest and random split but you can combine these in all kinds of ways like you could have
00:32:27.559
uh 1/3 1/3 1/3 split with newest oldest and random okay or you could weight random a little heavier in other words
00:32:33.960
you can tweak this to get almost exactly the effect you want okay it's really really quite
00:32:39.639
fun now just for grins I want to talk about one more algorithm okay those 11 I just talked
00:32:46.000
about are the ones I mentioned on my blog and which um I think will do you a world of good to actually try
00:32:51.440
implementing this last one is called the growing binary tree algorithm and I stumbled on this one I won't say
00:32:57.960
discovered it because that is way too um that's overstating it by a lot what I
00:33:03.039
did basically is as I was playing with the growing tree algorithm I thought you know what instead of choosing one adjacent neighbor and putting it in the
00:33:09.159
active set what if I choose two and put it in the active set okay and instead of
00:33:14.399
keeping the that node in the active set when I look at it what if I take it out and remove it and then add the two
00:33:20.720
neighbors and when I do that it's still growing tree algorithm so I can still choose to take newest first or random or
00:33:27.440
whatever uh using newest first I get this kind of effect where you get the long windy
00:33:33.679
passage but it's kind of hairy okay it's got all these short little passages branching off of it all the way
00:33:39.240
around and interestingly if I do random first you don't get that hairy effect
00:33:44.320
okay it it's basically just like primms but moving twice as fast because you're you're throwing more nodes out there um
00:33:50.679
and of course you know you can do any of these others just like you can u a growing tree but the point that I want
00:33:57.200
to make is not so much that U how cool is this algorithm it's look what happens
00:34:02.720
when you take things that you know and combine them that way you start playing
00:34:08.280
with these algorithms as you've learned them okay you start pushing that envelope back a little bit and you say oh that's a cool effect and this is a
00:34:14.679
neat idea and it's stuff that may not be documented anywhere because there's so much that you can learn and discover
00:34:20.399
that not everything has been documented yet it's all about hard work that is the
00:34:26.040
real Point here is it wasn't easy for me to learn all of these algorithms but I'm
00:34:31.280
so glad I did because they've been a blast I've had so much fun with these and I've gotten so much mileage out of
00:34:36.800
them and it's it's a great tool once you are familiar with the algorithms
00:34:43.000
themselves are you done no just because the algorithms themselves are no longer
00:34:48.320
a challenge doesn't mean they can no longer offer a challenge try try implementing them in a framework or a
00:34:54.079
language you're not familiar with like how many of you are would say you are comfortable in functional Lang in a functional
00:35:00.240
language few of you very brave of you I am not I am not from comfortable in
00:35:06.440
functional languages but I'm trying to be and I tell you I can Implement these algorithms almost in my sleep in Ruby
00:35:13.680
okay it is extremely different implementing them in a functional language because you have to think about
00:35:19.240
them in an entirely different way it's the same algorithm but completely different way of approaching them so
00:35:25.480
just because you've mastered something in one field doesn't mean it can no longer offer any challenge the goal
00:35:30.800
ultimately is to look for the resistance okay look for the pieces that are going to offer the most resistance because
00:35:36.200
those are what you need to push against in order to make yourself better if you want to be a better programmer you must
00:35:41.520
work at it it's not going to just happen and your day jobs are very often I Won't Say Never your day jobs are very often
00:35:47.400
not enough resistance okay what you do every day is stuff that you do every day and once in a while there will be some
00:35:53.599
new problem that you have to solve but I would strongly recommend you think about finding time to do homework to exercise