是否有更优雅(更少代码)的方式来查找矩阵OUT,
使用colSums(OUT)< = a和rowSums(OUT)< = b,
给定ORD =填充顺序
sum(OUT) - >最大化
类似Sudoku的问题,(数字不是唯一的,并且给出了填充顺序,因此不是真正的数独)。我觉得这个问题有一些更简单的解决方案。
a <- c(4,2,1)
b <- c(3,2,2)
ORD <- matrix(c(1,5,6,8,2,9,7,4,3),ncol=3)
MIN <- outer(a,b,pmin)
OUT <- matrix(0,ncol=ncol(ORD),nrow=nrow(ORD))
L <- cbind(as.vector(row(ORD)),as.vector(col(ORD)))[order(ORD),]
for( i in 1:nrow(L)){
r <- L[i,1]
c <- L[i,2]
OUT[r,c] <- min(a[c],b[r])
a[c] <- max(a[c] - OUT[r,c],0)
b[r] <- max(b[r] - OUT[r,c],0)
}
OUT
编辑: 谢谢!最后我结束了这个(一个超级简单的问题的代码很长;):
cs <- c(4,2,1)
rs <- c(3,3,2)
ORD <- matrix(c(1,5,6,8,2,9,7,4,3),ncol=length(cs),byrow=T)
OUT <- matrix(0, nrow = length(rs), ncol = length(cs))
ROW <- row(OUT)
COL <- col(OUT)
for (i in order(ORD)){
r <- ROW[i]
c <- COL[i]
k <- min(cs[c],rs[r])
if(k>0){
OUT[i] <- k
cs[c] <- cs[c] - k
rs[r] <- rs[r] - k
}
if(all(cs==0) | (all(rs==0)))
break
}
答案 0 :(得分:1)
如果不修改你的算法,我可以把它缩短一点:
OUT <- matrix(0, nrow = length(b), ncol = length(a))
ROW <- row(OUT)
COL <- col(OUT)
for (i in order(ORD)) {
r <- ROW[i]
c <- COL[i]
OUT[i] <- min(a[c], b[r])
a[c] <- max(a[c] - OUT[i], 0)
b[r] <- max(b[r] - OUT[i], 0)
}
如果您只关心行数,那么您可以这样做:
OUT <- matrix(0, nrow = length(b), ncol = length(a))
for (i in order(ORD)) {
OUT[i] <- min(a[col(OUT)[i]], b[row(OUT)[i]])
a[col(OUT)[i]] <- max(a[col(OUT)[i]] - OUT[i], 0)
b[row(OUT)[i]] <- max(b[row(OUT)[i]] - OUT[i], 0)
}
但我强烈推荐第一个版本,因为它具有更好的可读性。
答案 1 :(得分:0)
这是一个优雅的(按照你的定义),但可能是缓慢的方式,它使用控制流来通过蛮力获得这样的矩阵。
while({OUT <- matrix(sample(0:max(a, b), 9, T), 3)
!all(colSums(OUT) <= a & rowSums(OUT) <= b)}) {}
OUT