You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

R语言新手求助:构建物品置换交易安排脚本

嘿,作为R新手能想到用代码解决交易匹配问题已经很棒啦!你的需求本质是找持有物品和心仪物品的闭合循环——毕竟只有形成循环,大家才能互相交换拿到想要的东西。不过确实不是所有情况都有解,下面我给你一步步拆解实现方案:

物品交易匹配的R脚本实现方案

1. 先模拟你的数据集

先搭一个和你需求一致的示例数据集,方便后续演示(你之后直接替换成自己的真实数据就行):

# 已剔除「持有物品=心仪物品」的人员
traders <- data.frame(
  person = c("p1", "p2", "p3", "p4"),
  has_item = c("A", "B", "C", "D"),
  wants_item = c("B", "C", "A", "B") # 这里p4想要B,但没法融入现有循环,用来演示无解场景
)

2. 核心函数:寻找交易循环

交易能完成的核心是形成闭合循环(比如p1→p2→p3→p1,每个人都能从下一个人手里拿到自己想要的)。下面这个函数会自动找出所有可行的循环,同时标记无法匹配的人员:

find_trading_cycles <- function(traders_df) {
  # 先做个物品→持有者的映射,方便快速查谁有某个物品
  item_to_owner <- setNames(traders_df$person, traders_df$has_item)
  # 标记已经匹配过的人,避免重复处理
  already_matched <- rep(FALSE, nrow(traders_df))
  # 存找到的所有循环
  cycles_list <- list()

  # 逐个处理每个未匹配的人
  for (i in seq_len(nrow(traders_df))) {
    if (!already_matched[i]) {
      current_person <- traders_df$person[i]
      current_want <- traders_df$wants_item[i]
      current_chain <- c(current_person)

      while (TRUE) {
        # 找到持有当前需求物品的人
        next_person <- item_to_owner[current_want]
        # 如果找不到人,或者绕回起点了,就停
        if (is.na(next_person) || next_person == current_person) break
        
        # 如果这个人已经在当前链条里,说明形成闭合循环了
        if (next_person %in% current_chain) {
          # 提取闭合的那一段循环
          cycle_start_pos <- which(current_chain == next_person)
          full_cycle <- current_chain[cycle_start_pos:length(current_chain)]
          cycles_list[[length(cycles_list)+1]] <- full_cycle
          # 标记这些人已匹配
          already_matched[traders_df$person %in% full_cycle] <- TRUE
          break
        }

        # 没形成循环就继续延伸链条
        current_chain <- c(current_chain, next_person)
        current_want <- traders_df$wants_item[traders_df$person == next_person]
      }
    }
  }
  return(cycles_list)
}

3. 运行函数并查看结果

把函数跑起来,就能看到哪些人可以完成交易,哪些人没法匹配:

# 找到所有可行的交易循环
trading_cycles <- find_trading_cycles(traders)

# 输出结果
if (length(trading_cycles) == 0) {
  cat("抱歉,没找到任何可行的交易循环,没人能完成交易\n")
} else {
  cat("找到以下可行的交易循环:\n")
  for (i in seq_along(trading_cycles)) {
    cycle <- trading_cycles[[i]]
    # 把循环里的交易路径打印得更直观
    trade_path <- paste0(
      cycle, 
      " (持有", traders$has_item[traders$person == cycle], 
      " → 想要", traders$wants_item[traders$person == cycle], ")", 
      collapse = " → "
    )
    cat(sprintf("循环 %d: %s\n", i, trade_path))
  }

  # 检查有没有人没被匹配到
  all_matched <- all(traders$person %in% unlist(trading_cycles))
  if (!all_matched) {
    unmatched_people <- traders$person[!traders$person %in% unlist(trading_cycles)]
    cat("\n注意:以下人员无法参与交易循环,拿不到心仪物品:", paste(unmatched_people, collapse = ", "), "\n")
  }
}

针对示例数据集,运行后会输出:

找到以下可行的交易循环:
循环 1: p1 (持有A → 想要B) → p2 (持有B → 想要C) → p3 (持有C → 想要A)

注意:以下人员无法参与交易循环,拿不到心仪物品:p4

4. 关键说明

  • 只有当所有剩余人员的需求能完全拆分成闭合循环时,才能让所有人都拿到心仪物品;如果存在孤立的需求链,就会有人没法完成交易
  • 你只需要把自己的真实数据替换示例里的traders数据框,就能直接用这个脚本
  • 如果想处理更复杂的场景(比如多人交叉交易),可以研究一下「匹配理论」相关的算法,不过对新手来说这个方案足够应对大部分基础场景啦

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

火山引擎 最新活动