我正在解决一个新问题: 我列出了4个项目,每个项目属于3个人中的一个:
Item Owner Cost
1 John 6
2 Bob 5
3 Mary 10
4 Mary 7
将这些物品打包在一起的组合是什么,授予每个人的物品不包装在单独的盒子中。
所以我目前正在使用分区包和 listParts()函数,例如:
library(partitions)
listParts(4)
[1] **(1,2,3,4)**
[2] (1,2,4)(3)
[3] (1,2,3)(4)
[4] **(1,3,4)(2)**
[5] **(2,3,4)(1)**
[6] (1,4)(2,3)
[7] **(1,2)(3,4)**
[8] (1,3)(2)(4)
[9] (1,4)(2)(3)
[10] (1,2)(3)(4)
[11] (1,3)(2)(4)
[12] (2,4)(1)(3)
[13] (2,3)(1)(4)
[14] **(3,4)(1)(2)**
[15] (1)(2)(3)(4)
请注意,我压缩了上面的输出。
第一个输出意味着项目1,2,3和4都被打包在一起。第二行表示1,2和4包装在一个包裹中,第3个包装在自己的包装中。
虽然上面提供了我正在寻找的组合逻辑,但我有两个问题:
您会看到粗线(1,4,5,7,14)是唯一可行的选项,因为它属于Mary的项目(第3项和第4项)被包装在一起而不是分开的约束。如何从完整输出中选择或过滤这些列表项?
对于上述第1点中提到的每5种可行组合,我如何将成本加在一起。我想我需要列表索引或其他东西,我不知道如何。例如,如果我计算排列的成本[14](3,4)(1)(2),我需要得到包裹1的成本10 + 7 = 17(玛丽项目的成本),包裹6 2(John项目的费用)和3包裹3(Bob项目的费用)。
答案 0 :(得分:0)
我不确定您是如何计算成本的,但我认为最简单的解决方案是首先按所有者分组,然后进行组合。
plouf <- setDT(read.table(text = "Item Owner Cost
1 John 6
2 Bob 5
3 Mary 10
4 Mary 7",
stringsAsFactors = FALSE, header = TRUE))
您可以将这两种方式分组:
library(data.table)
plouf <- setDT(plouf)
reduce <- plouf[,list(Cost = sum(Cost)), by = Owner]
或
library(dplyr)
reduce <- plouf %>%
group_by(Owner) %>%
summarise_at(vars(Cost),funs(sum))
给你
> reduce
Owner Cost
1: John 6
2: Bob 5
3: Mary 17
然后你可以使用setpart来进行组合
plop <- setparts(3)
您将其添加到结果
reduce <- cbind(reduce,as.data.frame(as.matrix(plop)))
> reduce
Owner Cost V1 V2 V3 V4 V5
1: John 6 1 1 1 2 1
2: Bob 5 1 2 1 1 2
3: Mary 17 1 1 2 1 3
列V1-&gt; v5为您提供组合。然后你可以得到总和
> lapply(paste0("V",c(1:dim(plop)[2])),function(x){ reduce[,list(cost = sum(Cost)),by = x]})
[[1]]
V1 cost
1: 1 28
[[2]]
V2 cost
1: 1 23
2: 2 5
[[3]]
V3 cost
1: 1 11
2: 2 17
[[4]]
V4 cost
1: 2 6
2: 1 22
[[5]]
V5 cost
1: 1 6
2: 2 5
3: 3 17
这里首先是同一个集合,第二个约翰和玛丽在同一个组1中,鲍勃在第二个等等。