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

R语言中使用while循环更新列表对象时遇到问题

R语言模拟随机市场:事件驱动的while循环实现

这是一个典型的事件驱动模拟场景,我们可以通过while循环跟踪市场运行时间,每次生成下一个事件的触发时间,执行对应操作后更新时间,直到市场关闭(时间≥600分钟)。下面是完整的实现思路和代码:

1. 初始化参数与市场状态

首先定义模拟所需的核心参数,包括各事件的发生强度,以及数量、价格的正态分布参数;同时初始化市场时间和供需状态:

# 事件强度(单位:事件/分钟)
lambda_supply_gen <- 0.8   # 供给产生强度
lambda_demand_gen <- 0.7   # 需求产生强度
lambda_supply_drop <- 0.3  # 供给消失强度
lambda_demand_drop <- 0.2  # 需求消失强度

# 数量与价格的正态分布参数(均值+标准差)
supply_qty_params <- c(mean = 10, sd = 3)
supply_price_params <- c(mean = 50, sd = 8)
demand_qty_params <- c(mean = 8, sd = 2)
demand_price_params <- c(mean = 55, sd = 7)

# 初始化市场状态
current_time <- 0
supply_list <- list()  # 存储当前供给:每个元素是list(qty, price, create_time)
demand_list <- list()  # 存储当前需求:每个元素是list(qty, price, create_time)

2. 核心while循环模拟

循环的核心逻辑是:每次生成四个事件的绝对触发时间,选择最早发生的事件执行,然后更新市场时间和状态:

while (current_time < 600) {
  # 生成每个事件的下一次触发时间(当前时间 + 指数分布间隔)
  next_supply_gen <- current_time + rexp(1, lambda_supply_gen)
  next_demand_gen <- current_time + rexp(1, lambda_demand_gen)
  next_supply_drop <- current_time + rexp(1, lambda_supply_drop)
  next_demand_drop <- current_time + rexp(1, lambda_demand_drop)
  
  # 找到最早发生的事件
  event_times <- c(
    supply_gen = next_supply_gen,
    demand_gen = next_demand_gen,
    supply_drop = next_supply_drop,
    demand_drop = next_demand_drop
  )
  next_event <- names(which.min(event_times))
  current_time <- event_times[next_event]
  
  # 执行对应事件操作
  switch(next_event,
         "supply_gen" = {
           # 生成供给数量(确保>0)
           qty <- max(rnorm(1, supply_qty_params["mean"], supply_qty_params["sd"]), 0.1)
           # 生成供给价格(确保>0)
           price <- max(rnorm(1, supply_price_params["mean"], supply_price_params["sd"]), 0.1)
           # 添加到供给列表
           supply_list[[length(supply_list) + 1]] <- list(qty = qty, price = price, create_time = current_time)
           cat(sprintf("%.2f分钟:新增供给,数量=%.1f,价格=%.2f\n", current_time, qty, price))
         },
         "demand_gen" = {
           qty <- max(rnorm(1, demand_qty_params["mean"], demand_qty_params["sd"]), 0.1)
           price <- max(rnorm(1, demand_price_params["mean"], demand_price_params["sd"]), 0.1)
           demand_list[[length(demand_list) + 1]] <- list(qty = qty, price = price, create_time = current_time)
           cat(sprintf("%.2f分钟:新增需求,数量=%.1f,价格=%.2f\n", current_time, qty, price))
         },
         "supply_drop" = {
           if (length(supply_list) > 0) {
             # 随机移除一个供给
             drop_idx <- sample(1:length(supply_list), 1)
             dropped <- supply_list[[drop_idx]]
             supply_list <- supply_list[-drop_idx]
             cat(sprintf("%.2f分钟:移除供给,数量=%.1f,价格=%.2f\n", current_time, dropped$qty, dropped$price))
           } else {
             cat(sprintf("%.2f分钟:尝试移除供给,但当前无供给\n", current_time))
           }
         },
         "demand_drop" = {
           if (length(demand_list) > 0) {
             drop_idx <- sample(1:length(demand_list), 1)
             dropped <- demand_list[[drop_idx]]
             demand_list <- demand_list[-drop_idx]
             cat(sprintf("%.2f分钟:移除需求,数量=%.1f,价格=%.2f\n", current_time, dropped$qty, dropped$price))
           } else {
             cat(sprintf("%.2f分钟:尝试移除需求,但当前无需求\n", current_time))
           }
         }
  )
}

# 模拟结束后输出最终状态
cat("\n市场关闭(600分钟),最终状态:\n")
cat(sprintf("当前供给数量:%d\n", length(supply_list)))
cat(sprintf("当前需求数量:%d\n", length(demand_list)))

关键细节说明

  • 事件间隔模拟:用rexp()生成指数分布的事件间隔,这是因为指数分布具有无记忆性,非常适合模拟泊松过程中的事件间隔(即事件发生概率与已等待时间无关)。
  • 正数值处理:用max(..., 0.1)确保生成的数量和价格为正,如果你需要更严谨的截断正态分布,可以使用truncnorm包的rtruncnorm()函数。
  • 事件选择逻辑:通过比较四个事件的绝对触发时间,每次只处理最早发生的事件,保证模拟的时序正确性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:41:18