如何通过向量化替代矩阵列循环实现对手得分交换并提速?
锦标赛失分计算的向量化实现需求
引言
假设有一场4名选手的锦标赛,赛程如下:
Rd 1: 1-4, 2-3. Rd 2: 4-3, 1-2. Rd 3: 2-4, ---.
锦标赛结果通常用交叉表展示,例如:
N P|A B C D|Tot. ---+-------+--- 1 A|x 0 . 1| 1 2 B|0 x 2 2| 4 3 C|. 0 x 2| 2 4 D|1 0 0 x| 1 ---+-------+--- Tot.|1 0 2 5| 8
得失分可直接通过行和列的求和得出。另一种展示格式是赛事文件,按选手和回合展示对手、颜色/主客场及结果:
Rd1 Rd2 Rd3 Tot. 1 A 4w1 2w0 --- 1 2 B 3w2 1b0 4w2 4 3 C 2b0 4b2 --- 2 4 D 1b1 3w0 2b0 1 Tot. 8
这种结构可用opponents和results两个矩阵(若有需要还可添加colours矩阵)表示。部分场景下需要计算失分,当胜负分总和固定时可直接推导,但很多情况并非如此(比如国际象棋的0-0平局)。
一种解决方案是交换选手与对手的得分,再求行和得到失分,现有循环实现的函数t.sparse如下:
现有循环实现函数
# 反转矩阵m中的胜负结果 # 通过在列内交换对手的得分实现 t.sparse <- function(m, opp) { for (k in seq_len(ncol(m))) { m[, k] <- m[, k][opp[, k]] } return(m) }
示例数据
# 矩阵按选手、回合索引 # 第一回合:选手1对阵选手4,选手2对阵选手3 opponents <- matrix(c(4, 2, NA, 3, 1, 4, 2, 4, NA, 1, 3, 2 ), nrow = 4, byrow = TRUE ) # 第一回合:选手1与选手4战平,选手2击败选手3 results <- matrix(c(1, 0, NA, 2, 0, 2, 0, 2, NA, 1, 0, 0 ), nrow = 4, byrow = TRUE ) # 在results矩阵中,两名选手间的结果会被反转 t.sparse(results, opponents) # 输出结果: # [,1] [,2] [,3] # [1,] 1 0 NA # [2,] 0 0 0 # [3,] 2 0 NA # [4,] 1 2 2
需求说明
矩阵规模最大为1300×10,还有125×12、40×39等规模。GitHub Copilot给出的tv.sparse函数与原函数不等价,现需要寻求正确的R风格向量化实现方式,并验证该实现与原函数的一致性及性能。
内容的提问来源于stack exchange,提问作者clp
相关产品推荐
相关产品推荐

