在没有for循环的情况下创建具有逐渐变化的值的矩阵

时间:2014-12-08 18:48:49

标签: r for-loop matrix vector s

在R中,我正在构建一个矩阵M,它为游戏的20轮中的每一轮存储4个变化的权重。

我从权重向量W1(4x1)开始,并以权重向量W2(4x1)结束游戏。

在更改开始轮次C1(= 5)之前,权重值保持不变。

在回合C1之后,权重开始以相等的增量w2cw3c突变超过C(= 10)轮次。

权重必须始终添加到1

我使用for循环来构建矩阵M。结果如下:

      [,1] [,2] [,3] [,4]
 [1,] 0.30 0.50 0.10 0.10
 [2,] 0.30 0.50 0.10 0.10
 [3,] 0.30 0.50 0.10 0.10
 [4,] 0.30 0.50 0.10 0.10
 [5,] 0.30 0.50 0.10 0.10
 [6,] 0.28 0.46 0.12 0.14
 [7,] 0.26 0.42 0.14 0.18
 [8,] 0.24 0.38 0.16 0.22
 [9,] 0.22 0.34 0.18 0.26
[10,] 0.20 0.30 0.20 0.30
[11,] 0.18 0.26 0.22 0.34
[12,] 0.16 0.22 0.24 0.38
[13,] 0.14 0.18 0.26 0.42
[14,] 0.12 0.14 0.28 0.46
[15,] 0.10 0.10 0.30 0.50
[16,] 0.10 0.10 0.30 0.50
[17,] 0.10 0.10 0.30 0.50
[18,] 0.10 0.10 0.30 0.50
[19,] 0.10 0.10 0.30 0.50
[20,] 0.10 0.10 0.30 0.50

这是我的R代码:

输入:

N=4 # 4 number of weights
R=20 #rounds
M <- matrix(0, ncol=N, nrow=R) 
C=10 # change duration in rounds
C1=5 # round at which change starts
C2=C1+C # round at which change ends
w1=0.1 #small weight
w2=0.3 #average weight
w3=0.5 #large weight
w2c=(w2-w1)/C #change increment for average weight mutation
w3c=(w3-w1)/C #change increment for large weight mutation
W1<-c(w2, w3, w1, w1) #starting weight vector
W2<-c(w1, w1, w2, w3) #ending weight vector 

For循环,构建矩阵M

for(n in 1:N){
  M[,n]<-W1[n]
  for(r in 1:R) {
    if(r>=C2){M[r,n] <- W2[n]}
  }
}

for(r in C1:(C2-1)) {
  T<-r-C1;
  M[r,1] =  M[r,1]-w2c*T;
  M[r,2] =  M[r,2]-w3c*T;
  M[r,3] =  M[r,3]+w2c*T;
  M[r,4] =  M[r,4]+w3c*T;
}
M

如果没有for循环,是否有更有效的方法来实现相同的结果?

2 个答案:

答案 0 :(得分:2)

您可以通过更改时间步数来对权重进行矢量化乘法,然后将这些向量添加到更改前的值(例如,使用sweep)。

x <- rbind(c(0.30, 0.50, 0.10, 0.10))
M <- rbind(x[rep(1, C1), ],
           sweep( sapply(c(-w2c, -w3c, w2c, w3c), '*', seq_len(C)),
                    2, x, '+'))
M <- rbind(M, M[ nrow(M), , drop=FALSE][ rep(1, R-C1-C), ])

#       [,1] [,2] [,3] [,4]
#  [1,] 0.30 0.50 0.10 0.10
#  [2,] 0.30 0.50 0.10 0.10
#  [3,] 0.30 0.50 0.10 0.10
#  [4,] 0.30 0.50 0.10 0.10
#  [5,] 0.30 0.50 0.10 0.10
#  [6,] 0.28 0.46 0.12 0.14
#  [7,] 0.26 0.42 0.14 0.18
#  [8,] 0.24 0.38 0.16 0.22
#  [9,] 0.22 0.34 0.18 0.26
# [10,] 0.20 0.30 0.20 0.30
# [11,] 0.18 0.26 0.22 0.34
# [12,] 0.16 0.22 0.24 0.38
# [13,] 0.14 0.18 0.26 0.42
# [14,] 0.12 0.14 0.28 0.46
# [15,] 0.10 0.10 0.30 0.50
# [16,] 0.10 0.10 0.30 0.50
# [17,] 0.10 0.10 0.30 0.50
# [18,] 0.10 0.10 0.30 0.50
# [19,] 0.10 0.10 0.30 0.50
# [20,] 0.10 0.10 0.30 0.50

答案 1 :(得分:2)

分别填写顶部,中部和底部的三个电话:

M[1:C1,  ] <- rep(W1, each = C1)
M[C1:C2, ] <- mapply(seq, from = W1, to = W2, length = C2 - C1 + 1)
M[C2:R,  ] <- rep(W2, each = R - C2 + 1)

如果像我一样,你喜欢非常对称(或一致)的代码,你可以概括并说出顶部和底部部分就像中间部分:它们从W1线性移动到{{1}分别从W1W2。因此:

W2