如何枚举在R中构建课程时间表的所有有效选项

huangapple go评论61阅读模式
英文:

How to enumerate all valid options for building a course schedule in R

问题

如何使用R来列举构建课程时间表的所有可能方式?

如果一个学生有四门必修课程,这些课程在不同时间提供,我如何映射学生可以通过这些课程的所有可能“路径”而不创建时间表冲突?

class_offerings <- tibble::tribble(
  ~time,   ~class1,    ~class2,    ~class3,    ~class4,
   "8:00",   1,          0,          0,          0,
   "9:00",   0,          0,          0,          1,
   "10:00",  0,          0,          1,          1,
   "11:00",  0,          1,          0,          1,
   "12:00",  1,          0,          0,          1,
)

上表显示了四门课程提供的不同时间。很容易看出一些不同的选择,例如:

  • 8点上class1,
  • 11点上class2,
  • 10点上class3,
  • 9点上class4。

但我如何列出所有无冲突的上这四门课程的方式?

我尝试了嵌套的for循环来尝试解决这个问题... 但我很想找到更巧妙的方法来解决,也许可以通过一些创造性的数据处理、图形方法,或者至少一个巧妙的for循环?

一旦你涉及到,比如8门不同的课程,每门课程在一周内提供8不同的时间,我们就会得到巨大的可能性数(8^8),这对于一个for循环来说是巨大的计算量。

英文:

How can I use R to enumerate all possible ways to build a course schedule?

If a student has four compulsory subjects offered at various times, how can I map all possible "paths" the student could take through these subjects without creating a schedule conflict?

class_offerings &lt;- tibble::tribble(
  ~time,   ~class1,    ~class2,    ~class3,    ~class4,
   &quot;8:00&quot;,   1,          0,          0,          0,
   &quot;9:00&quot;,   0,          0,          0,          1,
   &quot;10:00&quot;,  0,          0,          1,          1,
   &quot;11:00&quot;,  0,          1,          0,          1,
   &quot;12:00&quot;,  1,          0,          0,          1,
  )

The table above shows the different times that the four subjects are being offered. It's easy to see a few different options here, such as:

  • class1 at 8,
  • class2 at 11,
  • class3 at 10, and
  • class4 at 9.

But how can I list all conflict-free ways to take these four classes?

I've tried a nested for loop to brute force my way through this... BUT I'd love a more clever way to get to a solution, perhaps through some creative data wrangling, graph methods, or at least a clever for loop?

Once you get to, say 8 different classes--each of which being offered 8 different times throughout a week--we end up with huge numbers (8^8) for a for loop to be running through every possibility.

答案1

得分: 4

这是一种方法 - 将数据转换为长格式并进行筛选以获取时间和班级对,按班级拆分并展开以获取所有组合,并筛选掉具有重复时间的行。

library(dplyr)
library(tidyr)

class_offerings %>%
  pivot_longer(-time, names_to = "class") %>%
  filter(value == 1) %>%
  select(-value) %>%
  split(~class) %>%
  lapply(`[[`, 1) %>%
  expand.grid() %>%
  filter(apply(., 1, \(x) !any(duplicated(x))))

结果如下:

  class1 class2 class3 class4
1   8:00  11:00  10:00   9:00
2  12:00  11:00  10:00   9:00
3   8:00  11:00  10:00  12:00
英文:

Here is one way - pivot the data to long format and filter to get time and class pairs, split by class and expand to get all combinations and filter out any rows that have duplicate times.

library(dplyr)
library(tidyr)

class_offerings %&gt;%
  pivot_longer(-time, names_to = &quot;class&quot;) %&gt;%
  filter(value == 1) %&gt;%
  select(-value) %&gt;%
  split(~class) %&gt;%
  lapply(`[[`, 1) %&gt;%
  expand.grid() %&gt;% 
  filter(apply(., 1, \(x) !any(duplicated(x))))

  class1 class2 class3 class4
1   8:00  11:00  10:00   9:00
2  12:00  11:00  10:00   9:00
3   8:00  11:00  10:00  12:00

huangapple
  • 本文由 发表于 2023年6月9日 09:57:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/76436727.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定