By Pavel Panchekha

29 January 2016

Share under CC-BY-SA.

Any opinions, findings, and conclusions or recommendations expressed in this material are those of the author and do not necessarily reflect the views of the National Science Foundation.

Designing the PLSE logo

The Programming Languages and Software Engineering group at the University of Washington has a slick purple pulse logo, as of a little more than two years ago. The logo was designed not just by our group—I also recruited hundreds of people from all over the world to contribute through Mechanical Turn by building a genetic algorithm for designing logos. You, too, can contribute, both to the logo and to code.

Logo space

From some initial discussions, we'd concluded that our logo should be a purple (for reasons I cannot recall, we do not use UW purple) square with a white line going across it, reminding one of an electric pulse—“pulse” being how you pronounce PLSE. What we didn't really know is how big the pulse should be, whether it should be centered or asymmetrical, straight or angled, and so on.

To best explore this design space, I decided to represent the space of possible logos by a sequence of coordinates defining a broken white line through a purple square. For example, the initial logo was the points `(-1, 0) (-½, 0) (0, 0) (½, 0) (1, 0)`, representing a straight horizontal line (made up of five points) across the middle of the square.

Genetic mutations

To make a genetic algorithm, there has to be a way of randomly changing and crossing logos to create potentially better logos. I settled on three possible mutations:

• A point could be randomly moved. The move was chosen from a normal distribution, so that most moves were pretty small.
• A random point could be deleted.
• The edge between any two points could be split in two. A location was chosen along the edge, made into a new point, and then moved.

To keep the logos from getting too crazy, 10% of mutations were splits and another 10% were deletions.

Most mutations just moved a point. Sometimes these mutations made a logo with very short edges, which generally looked unseemly, and sometimes points were moved outside the purple square, which didn't match what sort of logo we wanted. Mutations that made bad logos were redone.

Logos could also be crossed, which could combine a lot of beneficial mutations at once. This was complicated, because I wanted to ensure that common points were kept, but also wanted to keep in mind that common points could have been moved, and points could have been added or deleted.

To cross points well, each point was assigned a unique identifier, which was preserved by mutations that moved points. Then two logos could be split on point identifiers they had in common. For each common identifier, the new logo would have a point somewhere between the identified points in each parent logo. Between common identifiers, different logos would have a different sequence of new points, and one of those sequences would be chosen at random.

This crossing function tended to produce reasonable-looking logos when given two reasonable-looking logos as inputs. I settled on creating new logos by applying one mutation 50% of the time, applying 20 mutations 10% of the time (to introduce something truly new and unexpected into the pool), and otherwise crossing two random logos.

Fitness

With logos being mutated and generated, I needed to add some sort of fitness function. I wanted to employ Mechanical Turk users to rate the logos, and it seemed like two-up heads-to-heads comparison would be best for that. I set up a web server that would track a pool of 20 logos, pick two at random to display, and allow users to choose one that they liked more.

To this end, I wrote a short snipped of code that would write a sequence of points to an SVG file, which would render as a logo proper. Each logo tracked the number of votes for and against it, and when a logo went below 60% votes in favor (with at least 3 votes against), it would be removed from the pool. Then a new logo would be created (by mutation or crossing) and added to the pool.

You can look at the pool to see who's doing better or worse. The percentages shown there are not quite win/loss percentages; they're adjusted for the number of voters (using Wilson's lower bound).

Each logo, even the ones that don't do well, are saved to the file system, so they could be looked over after they left the pool.

Results

Several striking logos were generated by the joint powers of randomness and the internet. One had a striking asymmetry; another angled the pulse in a very attractive way; a third made the pulse look like a W, subtly referring to our school.

The logos appearing on this page were all made by the genetic algorithm (and then touched up in Inkscape).

We also had our pool polluted when one of the PLSE students absent-mindedly clicked clicked the left arrow key while listening to a lecture. This injection of randomness quickly confused the genetic algorithm, killed several very good logos, and replaced them with a weird scribble. For a while I thought someone had built a bot, so consistently and quickly were unexplainable votes being cast. But eventually we found out the truth.

Unfortunately, a still-unexplained outage lost most of the logos. We managed to recover a few good ones from a back-up; the others influenced the design process only indirectly, leaving an impression in our minds that allowed us to try more logos before settling on a final choice.