Simon Says

Aspiring Polymath

The Mathematically Optimal Wardrobe

First published: 24th February 2025

When I was a child, about once a year when the sales were on, my mum would make me go through my wardrobe and decide which clothes to get rid of. These would be taken to a charity shop, and then we would go on a family shopping trip and buy new clothes.

As a child, it was sufficient to remove things that no longer fit (not that I always found this easy at the time). As I was continually growing, it was guaranteed that any given item would eventually be too small and the number of clothes I owned would remain finite. Now that I am a grown-up [citation needed] , I no longer outgrow clothes but still accumulate them. Some I buy, some are gifts, some are from University careers fairs, conferences, or similar, and then I had a recent phase where I was addicted to Vinted. I need a new method to decide what to cull.

We need to go beyond "does this spark joy?" and ask "Exactly how much joy does this spark? How many days of shrimp torture is this worth?".

The problem with simply getting rid of the things you wear the least often, is that these are usually "special occasion" clothes. I might wear a suit once a year or less. It still makes sense to keep it over a T-shirt that I wear twice a year. This is because when a suit-wearing occasion comes around, the next-best alternative to a suit might be a long way down. But when an occasion perfect for one science-pun T-shirt comes around, another science-pun T-shirt will do almost as well. So I should choose to get rid of all my science-pun T-shirts except one before seriously weighing the final one against the suit.

All of this can be formalised mathematically by k-means clustering. All I need to do is plot each of my clothes in n-dimensional space, take k to be the number of things I can fit in my wardrobe, and let the algorithm go.

The difference between a shirt and a pair of trousers is much larger than the difference between any two shirts, so rather than having a dimension of clothes-space be used for category, I chose to segment my wardrobe by category (long-sleeved button shirts, short-sleeved button shirts, T-shirts, trousers, shorts, jumpers) and run the algorithm separately on each. This allows me to choose k independently for each category, and also reflects on the way I actually store my clothes.

T-shirts

I decided somewhat arbitrarily that the dimensions of T-shirt space are:

As an example, this shirt scored 7 for colourful, 0 for nerdy, 4 for fit, 8 for pattern scale, 3 for edgy and 1 for suitability for clubbing:

Meanwhile, this shirt scored 2 for colourful, 1 for nerdy, 4 for fit, 7 for pattern scale, 8 for edgy and 10 for suitability for clubbing:

I estimate that my T-shirt draw can comfortably hold about 20 items. These are the groups that the algorithm put my shirts into:

Cluster Description
0 Cats on the moon
0 Firetrap - Lightning
0 Firetrap - Smoke
1 Sicily Sailing Boat
1 Blue Leaf Ombre
2 42 Venn Diagram
2 Planet balloons
2 Planet Newton's Cradle
3 Black red and yellow tie dye
3 Centre Stage Performing Arts Academy
4 Einstein Love Is The Answer
4 Van Gogh Pi in the Sky
5 Levi's rainbow - black background
5 Rainbow Tie-Dye
6 Jane Street - Enter the Monad
6 Steampunk wolf
6 Twilio
7 44Con JIT-Loader
7 44Con 2024
8 Jane Street - Purple with triangles
8 Embrace the Detours
9 Studded Skulls
9 Alestorm skeletons
10 White and Rainbow Altair Designs
11 CyberDog Pink
12 Firetrap - Birds
12 Cyberdog red and black
12 Black and White Roses Ombre
13 Don't follow me, I'm lost
13 Pastel Stripes
13 Yellow Pink Blue Ombre
14 Space Surfer
15 Plain white 3 button
16 Polka dots on black
16 Paint splashes on black, curved bottom
17 Bsides London 2021 - Skyline
18 UK Chemistry Olympiad 2016
18 Bsides London 2023 - 30 Years of Connecting Peers
19 Buttons, White on Black Paisley
19 Buttons, Black on White Paisley

We can plot a projection of these onto any two dimensions:

Yes, I have too many T-shirts. It's a problem. That's why I'm doing this.

Everything in cluster 0 is something I would call one of my favourites. I'm keeping those, and you can't tell me not to. Sometimes you do need a few similar things in case one of them is in the wash.

So instead, let's make up a new algorithm:

A Better Algorithm

There are a few nice-to-have features that an algorithm should have:

Order Invariance

Suppose I have a set W of shirts, and can keep k of them. The algorithm ought to select the same k shirts if given any subset of W that contains all of those k.

Weirdness Is Not A Survival Strategy

In the algorithm that we looked at above, a shirt could get by being very different to all other shirts without actually being something that I like. An old bedsheet is unlike any shirt that I own. Does that mean I should keep it with my T-shirts?

What I really want is to define the worth of a set of T-shirts, not to define the worth of a single shirt. My goal is, for a given situation, to be able to choose something appropriate. I'll make a list of situations that I sometimes find myself in. Then, I'll rate each shirt for how well suited it is to that occasion.

For each occasion, I'll specify a list of scores that it can assign to different shirts. I need a lot of different shirts for chilling and for being in the office, but I very rarely go to a conference 2 days in a row (and if I did, it wouldn't be that terrible to wear the same shirt on those days). So, waving my hands a lot, these weights are some combination of:

The situations I've chosen are:

A few of these have been redacted out of privacy concerns. Rest assured they were normal everyday situations that we all find ourselves in from time to time.

For example, this shirt scored 1 for "office" and 10 for "concert":

This one didn't go below 6 for anything:

This one scored 10 for "conference" and 1 for "date":

There are 15 pairs (a,b) where a is strictly worse than b in all scenarios. This doesn't mean we can immediately get rid of a, as it might be the second best in a situation that awards points for that. It also doesn't necessarily mean I will have to keep b, as you can imagine adding a terrible shirt that scores 1 in all situations, and a slightly-less-terrible one that scores 2 in all situations.

I currently have 40 T-shirts, which is too many to evaluate all of the subsets. I tried iteratively adding the shirt that creates the best subset of size n+1 to the best subset of size n. The results were:

Description Cumulative Score
Plain white 3 button 602
Levi's rainbow - black background 922
Black and White Roses Ombre 1013
Cats on the moon 1049
Bsides London 2021 - Skyline 1075
Steampunk wolf 1090
Studded Skulls 1104
Bsides London 2023 - 30 Years of Connecting Peers 1113
Black red and yellow tie dye 1121
CyberDog Pink 1128
White and Rainbow Altair Designs 1134
Alestorm skeletons 1140
Rainbow Tie-Dye 1145
Cyberdog red and black 1148
Jane Street - Purple with triangles 1150
Buttons, White on Black Paisley 1152
Blue Leaf Ombre 1153
Jane Street - Enter the Monad 1153
42 Venn Diagram 1153
Planet balloons 1153

As expected, the biggest gain is going from 0 to 1 shirt, and after that we get marginal returns. In fact, the last 3 aren't adding any value at all. This suggests that really I should only keep the first 17 in this table.

I also tried iteratively adding the 2 shirts that create the best subset of size n+2. The results were indistinguishable.

When I added 3 at a time, I couldn't go for 20 shirts of course, so I went for 21, which resulted in one more zero-value shirt making it in.

Considering sets of size 4 gets the same set of 20:

Description Cumulative Score
Steampunk wolf
Bsides London 2021 - Skyline
Plain white 3 button
Levi's rainbow - black background
1051
Cats on the moon
Bsides London 2023 - 30 Years of Connecting Peers
Studded Skulls
Blue Leaf Ombre
1116
Black red and yellow tie dye
White and Rainbow Altair Designs
CyberDog Pink
Alestorm skeletons
1142
Jane Street - Purple with triangles
Rainbow Tie-Dye
Buttons, White on Black Paisley
Cyberdog red and black
1152
Jane Street - Enter the Monad
42 Venn Diagram
Planet balloons
Black and White Roses Ombre
1153

All of the previous runs added "Black and White Roses Ombre" among the first 4 shirts. This time, it didn't make it until the final round. This highlights the need for a better algorithm than the simple greedy approach when you are under pressure for space.

Unfortunately, my laptop couldn't cope with considering all subsets of size 5, so I stopped here. But in all of these runs, the score maxes out at 1153. It appears 17 shirts is enough to fill all of my needs.

For comparision, these are the scores of 10 randomly chosen subsets of size 20:

1120, 1119, 1095, 1123, 1108, 1110, 1136, 1118, 1119, 1094

The optimal set is outside of the range of variation of the random sets, but not by as much as I would have expected. I suppose the lesson is that I have space for plenty of shirts.

If I exclude all the shirts that I bought on Vinted, I score only 1103, which is less than I can now get out of my top 7 shirts. Two of the Vinted shirts didn't make the cut, so I really should have run all of this analysis before buying them.

If I only had space for 4 shirts, I would be getting that score of 1051 from the first row of the table above. Here are the scores of 10 random sets of size 4:

958, 1016, 899, 925, 750, 859, 877, 959, 940, 883

This demonstrates that thinking hard is more worthwhile when you are limited for space.

Buying new clothes

This model implies that when I am thinking of buying a shirt, I should ask myself, "If I already had this shirt, and ran my algorithm, would the new shirt win?" And then, "What would it kick out?" And instead of asking "Would I pay X money to have this shirt?", I should ask "Would I pay X money to replace that shirt with this one?"

Using this set of 17, we can take a look at how many points each scenario is getting:

Situation Maximum Score Achieved Score
Chilling 150 150
Office 60 60
Restaurant 40 40
Boardgames 40 39
Beach 50 50
Date 90 89
Birthday 30 30
Concert 70 70
Clubbing 70 70
Forest 100 99
Cocktails 60 54
Conference 70 70
REDACTED 70 70
Ceilidh 50 45
REDACTED 20 16
Halloween 40 36
Museum 70 56
REDACTED 60 48
REDACTED 70 63

The theoretical maximum total score would be 1210. There is room for improvement here, and this can be used to guide choices for those extra 3 slots.

Further research

Change to the scoring algorithm

The scoring algorithm relies on some pretty arbitrary decisions. It might be interesting to see how sensitive the outcomes are to the weightings assigned to the different situations.

Computational Speedups

It would be good to think of ways to run this faster and get good results. Ideally a heuristic algorithm could be found that could run on a very large set (such as: all the shirts I can buy below a certain price) and find a high-scoring set.

Conclusion

All of the rejected T-shirts will be donated to The Whitechapel Mission where they are currently listed under "We need help!"

Finding a good general model turned out to be a much harder problem than I first realised, and I feel justified in finding this decision hard. On the other hand, finding the perfect set of T-shirts to keep that would both fit in the available space and also equip me for all likely scenarios turned out to be much easier than expected.

I am now satisfied that I have arrived at a logical answer to the question of which things I will keep. As a bonus, I can now easily run the same evaluation in the future on any other collection that is starting to outgrow its allotted cupboard. Stay tuned to join me as I rank my shoes, my boardgames, my sex toys, and my friends (just kidding - unlike a shirt I rarely wear, a friend I rarely spend time with doesn't permanently take up space in my flat).