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

如何基于两两身高比较数据计算所有人员的总体身高排序

解决方案

方案1:有向图拓扑排序(最适合无矛盾比较的全序推导)

这是成对比较排序的标准实现,逻辑简单、效率高,还能自动检测比较结果中的矛盾(比如出现A>B、B>C、C>A的循环关系)。

实现逻辑

  • 把每个人员作为图的节点
  • 对每一条比较记录生成有向边:
    • 若height == 1,添加边 person1 → person2,代表person1身高高于person2
    • 若height == 0,添加边 person2 → person1,代表person2身高高于person1
  • 对生成的有向无环图执行拓扑排序,输出的顺序就是身高从高到低的总排序

R代码示例

# 加载依赖包
library(igraph)

# 你的示例数据
df <- data.frame(person1 = c('A', 'C', 'B', 'D'),
                 person2 = c('B', 'D', 'C', 'A'),
                 height = c(0, 0, 0, 1))

# 生成边列表
edges <- lapply(1:nrow(df), function(i) {
  if (df$height[i] == 1) {
    c(df$person1[i], df$person2[i])
  } else {
    c(df$person2[i], df$person1[i])
  }
})
edges <- unlist(edges)

# 构建有向图
g <- graph(edges = edges, directed = TRUE)

# 检查是否有环(有环代表比较数据存在矛盾)
if (is_dag(g)) {
  # 执行拓扑排序
  rank_order <- topological.sort(g)
  final_rank <- V(g)$name[rank_order]
  cat(paste(final_rank, collapse = ", "), "\n")
} else {
  stop("比较数据存在矛盾的循环关系,请检查原始数据")
}

运行上述代码会直接输出你需要的结果:D, C, B, A

注意:如果数据中存在无任何比较关联的人员,拓扑排序会返回多个合法的排序结果,你可以根据业务需求选择保留并列,或者改用Elo评分得到唯一的近似排序。

方案2:Elo评分法(适合存在无法比较的个体、数据量极大的场景)

如果你的数据中存在部分人员没有任何直接/间接的比较关系,无法得到严格全序,或者数据量极大,可以用Elo评分的方式得到近似排序:

  • 初始所有人员的Elo得分设为相同值(比如1000)
  • 迭代遍历所有比较记录,按照胜负关系更新双方的得分(获胜方加分,失败方减分,双方分差越小加减分幅度越大)
  • 迭代到所有人员得分波动小于阈值后停止,按最终得分从高到低排序即可

简单R实现参考

# 初始化得分
all_people <- unique(c(df$person1, df$person2))
elo_score <- rep(1000, length(all_people))
names(elo_score) <- all_people

# Elo更新参数
k <- 32 # 调整系数,数值越大得分波动越大
max_iter <- 1000
threshold <- 1e-5

for (iter in 1:max_iter) {
  old_score <- elo_score
  for (i in 1:nrow(df)) {
    p1 <- df$person1[i]
    p2 <- df$person2[i]
    # 实际胜者标记
    actual_win <- ifelse(df$height[i] == 1, 1, 0)
    # 计算预期胜率
    e_win <- 1 / (1 + 10^((elo_score[p2] - elo_score[p1])/400))
    # 更新双方得分
    elo_score[p1] <- elo_score[p1] + k * (actual_win - e_win)
    elo_score[p2] <- elo_score[p2] + k * ((1-actual_win) - (1-e_win))
  }
  # 得分稳定则停止迭代
  if (max(abs(elo_score - old_score)) < threshold) break
}

# 输出排序结果
final_rank <- names(sort(elo_score, decreasing = TRUE))
cat(paste(final_rank, collapse = ", "), "\n")

内容的提问来源于stack exchange,提问作者Hakki

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 04:45:10