Set List Generator: Automatic Constrained Generation of Set Lists

For three years, I played guitar in an ‘80s cover band (, and early on we struggled a bit with getting transition time down between songs. The essence of the problem was that the keys, bass, and guitar all had to make adjustments between songs to cover the breadth of tones we were trying to cover: I switched guitars a lot, the keys (one keyboardist, two keyboards) switched patches basically every song, and the bass player switches between standard and drop-D quite a bit.

This largely comes down to set list design: if we could make sure that I only needed to change guitars, for example, after songs where I don’t play in the last 10 seconds or before songs that start with just drums, etc., we would never wait for me to change guitars. If I play three songs on one guitar and they end up back to back, that’s two transitions where you we need to wait for a guitar change. There are lots of other constraints, though, that go into set list ordering: we had three vocalists and wanted to avoid using a vocalist twice in a row, especially for tough songs. We had certain songs we often like to close with, and certain songs that are best played late in a night. Etc., etc.

With all that said, it’s not like we could just come up with “the” set list and stick with it forever. Aside from the fact that the band is better when every show is a little different, we were always adding new material, clients had specific requests for openers or for new songs, shows were anywhere from 40 minutes to 4 hours, etc.


I took it upon myself to solve this problem the way any engineer would: with code. I took all the songs in our repertoire and put them in a spreadsheet (we had this anyway), then annotated them with information about who plays and who doesn’t at the very beginning and end of each song, which singers sings each song, etc. And I created columns where I could assign values (bonuses or penalties) to each song for parameters like “appears in the first set” or “appears at the end of some set”, etc. Most of these parameters are empty (i.e. this is a very sparse matrix), but it’s quick to add values that matter. For example, if a client says “I want this song as an opener”, I just edit that cell to have a big value.

Then I wrote a little .cs program that does an optimization over all those parameters: first a simple greedy optimization to set up an initial ordering (this results in a horrible third set), then (the real procedure) a few million iterations over the set list looking for “swaps” in the order that improve the “score” of the set (with penalties wherever we would have to wait for anything between two songs and thus not be able to roll right from one song into the next). Actually, the probability of making a good swap is not quite 1.0, and the probability of making a bad swap is not quite 0.0; in fact the process is more akin to simulated annealing where those probabilities change over the course of the iteration.

When it’s all done, it writes a pretty html file.

Right before our last practice before a show, I edit whatever parameters are specific to this show (how many sets, how many songs, client requests, etc.), and I run the script. It takes about 30 seconds, so if I don’t like something, I just run it again. After 2 or 3 runs I get a set list that fits all the constraints, makes for quick swaps (and marks any places where there won’t be immediate swaps, so the drummer knows not to cruise along and the singers know to fill time at the mics), but is still new and interesting every show, so the set doesn’t get stale.

It has a lot of stuff specific to our band, but if anyone else wants to play with it:

How’s that for gratuitous use of Visual Studio?


Back to Dan’s projects page...