2012-03-25 10 views
0

よりエレガントがある(以下コード)行列を見つけるの方法、colSums(OUT)< = AとrowSums(OUT)< = BとR:2つのベクトルによって制約colSumsとrowSumとマトリックス

合計(OUT)を充填するORD =順与え

- >(数字は一意ではなく、充填順序は本当に数独与えられ、そうされていない)、

数独のような問題を最大化。私はこの問題の解決策がいくつかあると感じています。

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 
} 

答えて

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) 
} 

が、私は非常に読みやすくするために最初のバージョンをお勧めします。

0

は(あなたの定義による)、エレガントな、しかし、潜在的に遅い方法ですが、それは、このような取得するために制御フローを使用しています。(超簡単な問題のために非常に長いコードを)そして最後に、私はこれで終了しましたブルートフォースによる行列。あなたのアルゴリズムを変更することなく、

while({OUT <- matrix(sample(0:max(a, b), 9, T), 3) 
!all(colSums(OUT) <= a & rowSums(OUT) <= b)}) {} 

OUT 
関連する問題