Last active
December 17, 2017 02:02
-
-
Save infotroph/aab143b06cdade1e56da34e1ec132e29 to your computer and use it in GitHub Desktop.
Find all combinations with cost in range
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library(dplyr) | |
# invent some data | |
budget_min = 2e4 | |
budget_max = 2.5e4 | |
costs = round(rnorm(n=20, mean=1e4, sd=3e3)) | |
names(costs) = LETTERS[1:20] | |
# Find upper and lower bounds on number of projects in an affordable combination | |
n_low = floor(budget_min/max(costs)) | |
n_high = ceiling(budget_max/min(costs)) | |
is_affordable = function(x, min = budget_min, max = budget_max){ | |
if(sum(x) < min || sum(x) > max){ | |
return(NULL) | |
} | |
x | |
} | |
choose_n_affordable = function(n, candidates){ | |
if(choose(length(candidates), n) > 1e5){ | |
stop("More than 1e5 possible combinations of ", n, ". You probably don't want to brute-force this one, Chris") | |
} | |
combn(x = candidates, m = n, FUN = is_affordable, simplify = FALSE) | |
} | |
all_combos = sapply((n_low):(n_high), choose_n_affordable, costs) | |
viable_combos = (all_combos | |
%>% purrr::flatten() | |
%>% purrr::compact()) | |
# Some token analysis: | |
# 1. Which projects appear most frequently in the viable solutions? | |
viable_combos %>% purrr::map(names) %>% purrr::flatten_chr() %>% table() %>% sort() | |
# O M N A I T R J P F H Q G S E B L C K D | |
# 5 11 11 12 12 12 14 22 22 24 27 27 28 28 32 41 41 46 54 71 | |
# 2. How are the total costs of viable combinations distributed? | |
viable_combos %>% purrr::map(sum) %>% purrr::flatten_dbl() %>% stem(scale=0.5) | |
# The decimal point is 3 digit(s) to the right of the | | |
# | |
# 20 | 1344 | |
# 20 | 56778899999 | |
# 21 | 001112222333334444 | |
# 21 | 556677778889999 | |
# 22 | 0112233333333344 | |
# 22 | 55555666777788888899999 | |
# 23 | 0000112222233333334444 | |
# 23 | 55556666677777788888888899 | |
# 24 | 0000000011112222222222333334444444 | |
# 24 | 55555666666777777788888888999999 | |
# 25 | 00 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Beware: Brute-force approach. Will probably melt your laptop if n_projects is large, or even if n_projects is moderate but n_per_combo is close to n_projects/2.