You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过向量化替代矩阵列循环实现对手得分交换并提速?

锦标赛失分计算的向量化实现需求

引言

假设有一场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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 05:06:11