РЕДАКТИРОВАТЬ - обновил мой ответ на основе более внимательного прочтения ОП. Теперь определите, сколько разных команд может быть сформировано, независимо от того, как распределить работу между ними.
Да! Это ни в коем случае не самое элегантное или эффективное решение, но оно возможно. Это займет около 1 секунды с этими данными, но будет медленнее, если у вас есть реальные данные, которые являются более сложными.
Сначала я устанавливаю возможности для каждого заявителя. Я думаю, что это более интуитивно понятно, потому что нам нужно сделать одно назначение (включая возможность нуля) для каждого кандидата.
a <- c(0, 20, 30)
b <- c(0, 20, 30)
c <- c(0, 20, 30, 40)
d <- c(0, 20, 30, 40)
e <- c(0, 20, 30, 40, 50)
f <- c(0, 20, 30, 40, 50)
g <- c(0, 30, 40, 50)
h <- c(0, 30, 40, 50)
Затем я перечисляю все возможности назначения работы, используя expand.grid
, а затем фильтрую, чтобы включить только те, в которых выполняется 100% работы.
library(tidyverse)
soln_with_permutations <- expand.grid(a,b,c,d,e,f,g,h) %>%
# the Applicants come in as Var1, Var2... here, will rename below
as.tibble() %>%
rownames_to_column() %>% # This number tracks each row / potential solution
# gather into long format to make summing simpler
gather(applicant, assignment, -rowname) %>%
# rename Var1 as "a", Var2 as "b", and so on.
mutate(applicant = str_sub(applicant, start = -1) %>% as.integer %>% letters[.]) %>%
group_by(rowname) %>%
# keep only solutions adding to 100%
filter(sum(assignment) == 100) %>%
# keep only solutions involving four or fewer applicants
filter(sum(assignment > 0) <= 4) %>%
ungroup()
Каждый rowname
описывает отдельное решение с точки зрения того, как работа распределяется между претендентами, но многие являются перестановками, где работа распределяется по-разному среди одних и тех же команд. Чтобы увидеть, сколько разных групп сформировано, и сколько разных сценариев может работать для этой команды, я помечаю каждое решение командой (помеченной в алфавитном порядке) и сценарием (помеченным по убыванию).
soln_distinct_teams <- soln_with_permutations %>%
filter(assignment > 0) %>%
group_by(rowname) %>%
# Get team composition, alphabetical
mutate(team = paste0(applicant, collapse = "")) %>%
# Get allocation structure, descending
arrange(-assignment) %>%
mutate(allocation = paste0(assignment, collapse = "/")) %>%
ungroup() %>%
# Distinct teams / allocations only
distinct(team, allocation) %>%
arrange(allocation, team) %>%
mutate(soln_num = row_number()) %>%
# select(soln_num, team, allocation) %>%
spread(allocation, soln_num)
В каждой строке показана одна из 132 различных групп из 2-4 кандидатов, которые могут быть созданы, и в столбцах мы видим различные сценарии, которые могут применяться к этой команде как минимум в одной перестановке.
# A tibble: 132 x 7
team `30/30/20/20` `40/20/20/20` `40/30/30` `40/40/20` `50/30/20` `50/50`
<chr> <int> <int> <int> <int> <int> <int>
1 abc NA NA 126 NA NA NA
2 abcd 1 71 NA NA NA NA
3 abce 2 72 NA NA NA NA
4 abcf 3 73 NA NA NA NA
5 abcg 4 74 NA NA NA NA
6 abch 5 75 NA NA NA NA
7 abd NA NA 127 NA NA NA
8 abde 6 76 NA NA NA NA
9 abdf 7 77 NA NA NA NA
10 abdg 8 78 NA NA NA NA
# ... with 122 more rows