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

R语言马尔可夫链模拟:正确使用break语句终止序列

R马尔可夫链吸收态模拟修正方案

原修改代码存在以下核心错误:

  • 函数无显式返回值:R函数默认返回最后执行的语句结果,原代码最后执行的是for循环结构,无有效返回值,因此运行后得到NULL
  • 循环逻辑错误:嵌套repeat会在同一序列位置反复重采样直到抽到1或5,完全违背马尔可夫链逐次转移的规则,且抽到终止值后没有跳出外层生成逻辑
  • 预分配固定长度向量不符合需求:首次命中1/5的步数是随机的,提前分配固定长度n的输出向量会残留无效空值,也未覆盖初始值本身就是1/5的边界场景

修正后的单链模拟函数

# 初始分布与转移矩阵定义
alpha <- c(0,1,0,0, 0)
mat <- matrix(c(1,0,0,0,0,
                0.2,0.2,0.5,0.05,0.05, 
                0.3,0.1,0.1,0.2,0.3, 
                0.2,0.2,0.2,0.2,0.2, 
                0,0,0,0,1), 
              nrow = 5, ncol = 5, byrow = TRUE) 

chainSim <- function(alpha, trans_mat, max_step = 1000) {
  # 生成初始状态
  chain <- sample(1:5, 1, prob = alpha)
  # 初始状态为吸收态直接返回
  if (chain[1] %in% c(1, 5)) return(chain)
  # 逐次转移直到命中吸收态
  repeat {
    current_last <- tail(chain, 1)
    next_state <- sample(1:5, 1, prob = trans_mat[current_last, ])
    chain <- c(chain, next_state)
    # 命中吸收态终止循环
    if (next_state %in% c(1, 5)) break
    # 最大步数保护,避免转移矩阵设置错误导致无限循环
    if (length(chain) >= max_step) {
      warning("达到最大模拟步数仍未命中吸收态,已终止模拟")
      break
    }
  }
  return(chain)
}

单次运行测试:

> chainSim(alpha, mat)
[1] 2 3 2 4 4 3 1

批量100次模拟实现

由于每次命中吸收态的步数随机,生成的序列长度不一致,直接转等长data.frame会报错,先以列表存储再对齐即可:

# 重复模拟100次,结果存为列表
sim <- replicate(n = 100, expr = chainSim(alpha, mat), simplify = FALSE)
# 对齐长度补NA,转为数据框
max_chain_len <- max(sapply(sim, length))
sim_final <- as.data.frame(
  t(sapply(sim, function(x) c(x, rep(NA, max_chain_len - length(x)))))
)

你提供的转移矩阵中状态1和5都是吸收态(转移到自身的概率为1),命中后序列不会再发生状态变化,停止生成的逻辑完全符合吸收马尔可夫链的模拟规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 18:22:47