我经常教一节课,里面有大约160名学生。我需要尽可能有效地将评分论文归还给学生。我将这些文件拆分成一组四个大小均匀的垃圾箱。我通常使用房间的四个角来做这件事;每个角落一个垃圾箱,以减少交通问题,从而迅速恢复文件。
问题在于知道如何尽可能等效地拆分垃圾箱。这有点变化,因为姓氏的第一个字母的分布是1),在整个字母表中并不统一,2),经验分布从学期到学期略有变化。一个学期的一组箱可能是A-D,E-H,I-K和L-Z,但每个学期的起点和终点可能会改变(当然,除了第一个箱中的A和最后一个箱中的Z)。请注意,例如,bin A-D将包括具有姓氏的第一个字母“A”,“B”,“C”和“D”的学生。不允许将字母移出序列。
是否有人知道如何使用R(我将R用于课堂上的其他所有内容而学生数据在R中)以生成每个R的最有效(即大致相同大小)的起点和终点每学期四个箱子?
我想也许使用“expand.grid”可能有助于生成所有可能的bin组合,并通过消除不正确的bin来递归地向后工作。我想到了一种严格的算法方法,它带有一组嵌套循环,不仅可以构建各种bin组合,还可以使用累积和来检查bin大小。我还认为这可能是LP求解器的整数编程/约束逻辑/背包程序的变体。
有什么想法吗?
由于
答案 0 :(得分:3)
使用这群奇怪的学生:
set.seed(123); who = apply(matrix(sample(letters,160*8,TRUE),ncol=8),1,paste0,sep="",collapse="")
首先得到他们名字的第一个字母:
fl = substr(who,1,1)
首字母表的累计总和:
cs = cumsum(table(fl))
看起来像这样:
> cs
a b c d e f g h i j k l m n o p q r s t
3 8 15 25 29 35 44 48 56 62 71 79 86 89 95 100 105 114 118 123
u v w x y z
130 135 138 148 155 160
这告诉我们,按字母顺序排列的第40名学生以F开头,第80位是L,第120位是S.我们可以得到这样的人:
> names(tail(which(cs <40) ,1))
[1] "f"
> names(tail(which(cs <80) ,1))
[1] "l"
> names(tail(which(cs <120) ,1))
[1] "s"
所以我们的报告桩被标记为A-F,G-L,M-S和T-Z
将字母转换为数字并将第一个字母向量切割为由这些间隔定义的范围(再次转换为字母数字),这样我们就可以得到每个角落的学生数量:
> table(cut(as.numeric(factor(fl)),c(0,7,12,19,27)))
(0,7] (7,12] (12,19] (19,27]
44 35 39 42