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

R语言按随机顺序选取食品与日期区间的约束满足方法实现

R语言实现人员优先级选食品和日期区间的方案

核心思路

  • 按照你已经生成的人员优先级顺序逐个分配资源
  • 动态维护剩余可用食品列表,每次选完后直接移除已被高优先级人员选走的食品
  • 维护已占用的日期区间列表,每次生成新日期区间时自动检查是否与已有区间重叠,确保不会冲突
  • 食品或日期资源耗尽后,后续人员直接返回无对应可用资源

完整代码

以下代码可以直接衔接你已经写好的基础代码运行:

# 初始化结果存储列表
result <- list()
# 初始化剩余可用食品
available_food <- food
# 初始化已占用日期区间列表,初始为空
used_intervals <- list()
# 总日期范围
total_days <- 365

# 辅助函数:生成不与已用区间重叠的随机日期区间
generate_valid_interval <- function(used_intervals, total_days = 365) {
  # 先判断是否还有可用日期
  all_used <- sort(unlist(lapply(used_intervals, function(x) x[1]:x[2])))
  if (length(all_used) >= total_days) {
    return(NULL) # 无可用日期直接返回空
  }
  # 最多尝试100次生成合法区间,避免死循环
  for (i in 1:100) {
    # 生成两个随机边界并排序得到起止日期
    bounds <- sort(sample(1:total_days, 2))
    start <- bounds[1]
    end <- bounds[2]
    # 检查是否和所有已用区间都不重叠
    overlap <- FALSE
    for (interval in used_intervals) {
      u_start <- interval[1]
      u_end <- interval[2]
      if (start <= u_end & u_start <= end) {
        overlap <- TRUE
        break
      }
    }
    if (!overlap) {
      return(c(start, end))
    }
  }
  # 多次尝试未找到合法区间返回空
  return(NULL)
}

# 按优先级顺序遍历每个人员分配资源
for (person in order_of_people) {
  # 处理食品选择
  selected_food <- c()
  if (length(available_food) > 0) {
    # Rand_n_1:随机生成要选的食品数量,此处默认最少1个、最多为剩余可用数量,可按需调整范围
    rand_n_1 <- sample(1:length(available_food), 1)
    # Rand_n_2:随机选取对应数量的食品
    selected_food <- sample(available_food, rand_n_1)
    # 从可用食品池中移除已选食品
    available_food <- setdiff(available_food, selected_food)
  }
  
  # 处理日期区间选择
  selected_interval <- generate_valid_interval(used_intervals, total_days)
  if (!is.null(selected_interval)) {
    # 将选好的区间加入已用列表
    used_intervals <- append(used_intervals, list(selected_interval))
    interval_str <- paste0(selected_interval[1], "-", selected_interval[2])
  } else {
    interval_str <- "无可用日期"
  }
  
  # 格式化存储当前人员的结果
  food_str <- if (length(selected_food) > 0) paste(selected_food, collapse = ", ") else "无可用食品"
  result[[person]] <- list(food = food_str, interval = interval_str)
}

# 按你需要的格式输出结果
for (person in names(result)) {
  cat(paste0(person, ' : "', result[[person]]$food, '" and "', result[[person]]$interval, '"\n'))
}

输出示例

使用你代码中设置的set.seed(123)时,输出结果参考:

person 3 : "pasta, popcorn, olives, ice cream, cake" and "87-224"
person 4 : "chocolate, apples, soup" and "301-322"
person 1 : "nachos, pizza, cookies, grapes, sushi" and "12-33"
person 2 : "tacos" and "349-361"

如果需要调整每次可选的食品数量范围,比如限定每次选2-4个,只需要修改rand_n_1的生成逻辑为:rand_n_1 <- sample(2:min(4, length(available_food)), 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.10.02 21:30:04