How to pick a random number from 1-10

Imagine you have to generate a uniform random number from 1 to 10. That is, an integer from 1 to 10 inclusive, with an equal chance (10%) of selecting each one. But, let’s say you have to do this without access to coins, computers, radioactive material, or other such access to traditional (pseudo) random number generators. All you have is a room of people.

For the sake of argument, let’s say this room has a little over 8500 students in it.

The easy thing to do is to ask someone “Hey, pick a random number from 1 to 10!”. The person replies “7!”. Great! Now you have a number. However, you start to wonder, is the number uniformly random?

So you decide to ask a few more people. You continue to ask people and count their responses, rounding non-integers and ignoring answers from people who think that 1 to 10 includes 0. Eventually you start to see that the pattern is not flat at all:

library(tidyverse) probabilities <- read_csv("https://git.io/fjoZ2") %>% count(outcome = round(pick_a_random_number_from_1_10)) %>% filter(!is.na(outcome), outcome != 0) %>% mutate(p = n / sum(n)) probabilities %>% ggplot(aes(x = outcome, y = p)) + geom_col(aes(fill = as.factor(outcome))) + scale_x_continuous(breaks = 1:10) + scale_y_continuous(labels = scales::percent_format(), breaks = seq(0, 1, 0.05)) + scale_fill_discrete(h = c(120, 360)) + theme_minimal(base_family = "Roboto") + theme(legend.position = "none", panel.grid.major.x = element_blank(), panel.grid.minor.x = element_blank()) + labs(title = '"Pick a random number from 1-10"', subtitle = "Human RNG distribution", x = "", y = NULL, caption = "Source: https://www.reddit.com/r/dataisbeautiful/comments/acow6y/asking_over_8500_students_to_pick_a_random_number/")

Data originally from reddit

You kick yourself. Of course it’s not uniformly random. After all, you can’t trust people.

So, what to do? What if we could find some function that transforms the “Human RNG” distribution above into a unform distribution? The intuition for this is relatively simple. All we want to do is move the probability mass where the bars are larger than 10%, and move it to the bars where they are less than 10%. You can imagine this like chopping and reaarranging the bars such that they are all level: Extending this intuition, we can see that such a function should exist. In fact, there should be many different functions (re-arrangements). To take an extreme example, say we “cut” each bar into infinitesimally small blocks, then we could use these blocks to build up the distribution in whatever shape we wanted (like Lego). Of course, such an extreme example is a bit cumbersome. Ideally we want to preserve as much of the initial distribution (i.e. do as little chopping and changing) as possible.

How do you find such a function? Well, our explanation above is beginning to sound a lot like linear programming. To crib from Wikipedia: Linear programming (LP, also called linear optimization) is a method to achieve the best outcome … in a mathematical model whose requirements are represented by linear relationships. … Standard form is the usual and most intuitive form of describing a linear programming problem. It consists of the following three parts: A linear function to be maximized

Problem constraints of the following form

Non-negative variables We can formulate our redistribution problem problem in a similar way.