我的问题中有三家商店,销售3种产品,如附图所示。商店由s1到s3表示,产品由p1到p3表示。商店和产品之间的界线表示商店销售产品。
我按stores<-c("s1","s2","s3")
定义商店,products <- c("p1","p2","p3")
定义商品。
我必须生成商店的所有可能组合 - 产品映射。我的主要限制是:每家商店至少销售一种产品,每种产品至少由一家商店出售。
当前矩阵将如下所示
p1 p2 p3
s1 1 0 0
s2 0 0 1
s3 0 1 0
对于这个矩阵,我需要找出所有可能的二元组合,这样,colsums和rowums最小为1(对于约束)。
任何建议,如何实现这一目标。我的实际问题有> 20家商店和产品。
编辑:为混乱道歉。让我试着说出我想要的解决方案。直观地说,我正在寻找从图片中显示的当前配置开始添加商店和产品之间的线。我将需要所有可能的矩阵,它们满足rowSum和colSum的约束。Existing matrix
p1 p2 p3
s1 1 0 0
s2 0 0 1
s3 0 1 0
Desired example matrices (addition of one link)
p1 p2 p3
s1 1 0 1
s2 0 0 1
s3 0 1 0
p1 p2 p3
s1 1 1 0
s2 0 0 1
s3 0 1 0
等。
不需要的矩阵:第一行的总和为0,即s1不销售任何产品。
p1 p2 p3
s1 0 0 0
s2 0 0 1
s3 0 1 0
答案 0 :(得分:2)
我们想要描述商店(行)和产品(列)之间的映射(交互)的所有可能组合。在交互矩阵中,交互由1
编码,其缺席为0
。约束是列和行总和大于1
。
这是一个有趣的组合问题;我列举所有可能的组合的方法效率不高;我确信有更高效的实现可以考虑矩阵的可能对称性。看到其他解决方案很有意思......
在下文中,我使用了函数gtools::permutations
。
matrixCombn <- function(nrow, ncol) {
# All possible column combinations for a matrix of dimension dim
# Here we assume two different values c(1, 0)
require(gtools);
columns <- t(permutations(n = 2, r = nrow, v = c(1, 0), repeats.allowed = TRUE));
columns <- columns[, colSums(columns) > 0];
# Construct all possible combinations of dim column vectors and
# impose constraint that row and column sum >= 1
ret <- lapply(as.data.frame(t(permutations(ncol(columns), ncol, repeats.allowed = TRUE))), function(x) {
m.cand <- columns[, x];
if (all(rowSums(m.cand) > 0) & all(colSums(m.cand) > 0)) m.cand else NULL;
})
ret <- Filter(Negate(is.null), ret);
return(ret);
}
# Example for 3x3 interaction matrix design
ret <- matrixCombn(3, 3);
这为我们提供了265种独特的组合
length(ret);
# [1] 265
例如,这是第3个
ret[1:3];
#$V6
# [,1] [,2] [,3]
#[1,] 0 0 1
#[2,] 0 0 1
#[3,] 1 1 0
#$V7
# [,1] [,2] [,3]
#[1,] 0 0 1
#[2,] 0 0 1
#[3,] 1 1 1
#$V11
# [,1] [,2] [,3]
#[1,] 0 0 1
#[2,] 0 1 0
#[3,] 1 0 0
对于3x2
交互矩阵设计,我们得到
ret <- matrixCombn(3, 2);
length(ret);
# [1] 25
使用前3个组合
ret[1:3];
#$V6
# [,1] [,2]
#[1,] 0 1
#[2,] 0 1
#[3,] 1 0
#$V7
# [,1] [,2]
#[1,] 0 1
#[2,] 0 1
#[3,] 1 1
#$V12
# [,1] [,2]
#[1,] 0 1
#[2,] 1 0
#[3,] 0 1
答案 1 :(得分:0)
您可以像这样生成笛卡尔积
stores<-c("s1","s2","s3")
products <- c("p1","p2","p3")
expand.grid(stores,products)
Var1 Var2
1 s1 p1
2 s2 p1
3 s3 p1
4 s1 p2
5 s2 p2
6 s3 p2
7 s1 p3
8 s2 p3
9 s3 p3
获得此数据框后,您可以通过添加列
来定义哪个商店销售哪个产品dt <- cbind(expand.grid(stores,products), val = sample(0:1,9, replace = T))
> dt
Var1 Var2 val
1 s1 p1 1
2 s2 p1 1
3 s3 p1 1
4 s1 p2 0
5 s2 p2 0
6 s3 p2 1
7 s1 p3 0
8 s2 p3 1
9 s3 p3 0
然后,您可以使用reshape
reshape(dt, idvar = "Var1", timevar = "Var2", direction = "wide")
Var1 val.p1 val.p2 val.p3
1 s1 1 0 0
2 s2 1 0 1
3 s3 1 1 0
答案 2 :(得分:0)
您可以添加列名并替换您喜欢的值。这适用于我:
#No. of columns
n <- 3
#Values
vec <- c(0, 1)
#function returns a column vector that is a stack of the columns of x
lst <- lapply(numeric(n), function(x) vec)
# 'expand.grid' creates a data frame that is the cartesian product of its
#arguments
preditction <- as.matrix(expand.grid(lst))
#Creating a prediction matrix that meets the condition- "**My main constraint
#is : each store will sell at least one product and each product will be
#sold by at least one store**."
preditction_matrix <- subset.matrix(x= preditction,
subset = rowSums(preditction) > 0)
View(preditction_matrix)