使用两个规则创建受约束的随机元素列表

问题描述 投票:0回答:1

我正在尝试使用 R 创建一个包含 32 个项目(这些是实验项目)的随机列表,具有以下约束:

  1. 第1项至第24项有3个不同的条件,即第1项条件1;第 2 项条件 2;第3项条件3;第4项条件1;第5项条件2;等等。限制是同一条件的连续项不能超过三个。例如。 1,4,7,10 不可接受。
  2. 第 25-32 项都具有条件 10,并且该条件连续项不能超过两个。 EG 25、26、27 不可接受。

此外,我需要 32 个不同的商品订单来满足此限制。

我写了这段代码,但是 while 循环似乎永无休止,我无法调试它。

# Define the number of items
num_items <- c(seq(1:32))
conditions <- c(rep(1:3, 8), rep(10, 8))
items <- data.frame(cbind(num_items, conditions))

check_constraint_it <- function(items) {
  consecutive_condition_count <- 1
  for (i in 2:nrow(items)) {
    if (items$conditions[i] <9) {
      if (items$conditions[i] == items$conditions[i - 1]) {
        consecutive_condition_count <- consecutive_condition_count + 1
        if (consecutive_condition_count > 3) {
          return(FALSE)
        }
      } else {
        consecutive_condition_count <- 1
      }
    }
    else {
      if (items$conditions[i] == items$conditions[i - 1]) {
        consecutive_condition_count <- consecutive_condition_count + 1
        if (consecutive_condition_count > 2) {
          return(FALSE)
        }
      } else {
        consecutive_condition_count <- 1
      }
    }
    }
  return(TRUE)
}


# Randomly shuffle items until the constraint is met
items_m <- data.frame()

for (i in 1:32) {
  while (TRUE) {
    # Create a copy of the items dataframe
    current_items <- items
    
    # Randomly shuffle items
    shuffled_items <- sample(current_items$num_items)
    current_items$shuffled_order <- shuffled_items
    
    # Check if the constraint is met
    if (check_constraint_it(current_items)) {
      items_m <- rbind(items_m, current_items$shuffled_order)
      break
    }
  }
}```


I tried the code shown above, and I expected that each order were saved at the "items_m" dataframe.
r constraints
1个回答
0
投票

您可以定义一个

checker
函数,然后验证每个随机顺序。如果
checker
返回
TRUE
,则保留;否则,请跳过。

代码示例

checker <- function(v) {
  with(
    rle(v),
    all(lengths[values == 10] < 3) && all(lengths <= 3)
  )
}

n <- nrow(items)
l <- 32
res <- NULL
repeat {
  if (length(res) == l) break
  idx <- sample.int(n)
  if (checker(items$conditions[idx])) {
    res <- c(res, list(items[idx, ]))
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.