0

摘要:
您选择您注册的模块。
每个模块都有许多组。
每个组代表给定模块的讲座。
每个组合应仅包含每个模块中的一个组。

示例:
COS 121 -3 组
COS 132 -2 组

这将为您提供 6 个选项:[1,1]、[1,2]、[2,1]、[2,2]、[3,1]、[3,2]

我的角度:我需要使用每个组合来生成时​​间表,所以我使用一个数组来存储当前正在使用的组和组的总数:arrSubjects[subject,currentGroup,maxGroups]

从逻辑上讲,您应该能够遍历此数组以利用每个组组合。

我只是无法掌握这个解决方案,可能是因为我使用了错误的角度。任何帮助/建议将不胜感激。

我目前的实现:我对此感到很尴尬,因为它需要很多时间,但它确实有效。这是伪代码的基本内容:

for (all the groups multiplied with eachother) do {
  for (all the modules selected) do {
    Select a random group between 1 and the nmr of groups 
  }
}

之后我必须摆脱所有重复项。

提前致谢

我目前正在处理的代码:

arrPermutations[0,0]:=1;//Current group for 1st module
arrPermutations[0,1]:=3;//Max groups for 1st module
arrPermutations[1,0]:=1;
arrPermutations[1,1]:=3;
arrPermutations[2,0]:=1;//Current group for 3rd module
arrPermutations[2,1]:=3;//Max groups for 3rd module
iCurrent:=iMax; //2
while (arrPermutations[0,0]<=arrPermutations[0,1]) do
begin
//Display arrPermutations
if arrPermutations[iCurrent,0]=arrPermutations[iCurrent,1] then
begin
  Inc(arrPermutations[iCurrent-1,0]);
  for i := iCurrent to iMax do
    arrPermutations[i,0]:=1;
  iCurrent:=iMax;
end else
begin
  Inc(arrPermutations[iCurrent,0]);
end;
end;

目前我只遍历最后两组。这是我检查时得到的输出:
============运行 1==============
模块,当前组,最大组
1,1,3
2, 1,3
3,1,3
============运行 2==============
模块,当前组,最大组
1,1,3
2, 1,3
3,2,3
============运行 3==============
模块,当前组,最大组
1,1,3
2, 1,3
3,3,3
============运行 4==============
模块,当前组,最大组
1,1,3
2, 2,3
3,1,3
============运行 5==============
模块,当前组,最大组
1,1,3
2, 2,3
3,2,3
============运行 6==============
模块,当前组,最大组
1,1,3
2,2,3
3,3,3
============运行 7==============
模块,当前组,最大组
1,1,3
2,3,3
3,1,3
============运行 8==============
模块,当前组,最大组
1,1,3
2,3,3
3,2,3
============运行 9==============
模块,当前组,最大组
1,1,3
2,3,3
3,3,3
============运行10==============/////这里是问题
模块,当前组,最大组
1,1,3
2,4,3
3,1,3

4

1 回答 1

1

新答案:

首先,可能组合的数量是每个模块中组数的乘积。例如,如果有 3 个模块,分别包含 5、2 和 7 组,那么就有 5*2*7 = 70 种可能的组合。将此称为 TOTALCOMBOS。

所以,如果你想遍历所有可能的组合,你可以从 0 循环到 TOTALCOMBOS-1。

for I in 0..TOTALCOMBOS-1 do
    COMBO = (convert I to a combination)
    (do something with COMBO)

现在,要将索引转换为组合,将整数索引视为从右到左的“数字”列表会有所帮助。这最容易看出每个模块是否有十个组,并且组号是否从 0 而不是 1 开始。然后可以将整数 468 读取为列表 (8,6,4),这意味着来自模块 1 的组 8,模块 2 中的第 6 组,模块 3 中的第 4 组。在伪代码中,将索引转换为组合类似于

DIGITS = I
for M in 1..(number of modules) do
   D = DIGITS mod (number of groups in module M)
   DIGITS = DIGITS / (number of groups in module M)
   (add group D from module M to the current combination)

如果您希望组号从 1 而不是 0 开始,那么只需在最后一行使用组 D+1,而不是组 D。

旧答案:

使用递归。递归函数可以获取一个模块列表,并返回一个组合列表。每个组合将包含来自输​​入列表中每个模块的一组。

作为基本情况,如果模块列表为空,则返回一个空的组合列表。

否则,令 M 为第一个模块,让 REST 为其余模块。调用 REST 上的递归函数以获取其余模块的所有组合(调用此组合列表 COMBOS)。请注意,COMBOS 中的这些组合包含来自 M 的组。

现在,我们将列出所有组合,这次包括来自 M 的组。将列表 ANSWERS 初始化为空。使用两个嵌套循环。对于 M 中的每个组 G,以及 COMBOS 中的每个组合 C,将 G 添加到 C,并将此扩展组合添加到 ANSWERS。

返回答案。

(假设:没有组出现在一个以上的模块中,或者在同一个模块中出现两次。没有模块出现在模块列表中超过一次。如果你愿意,你可以放宽这些假设,但你需要定义你想要的在这些情况下的行为。)

(评论 1:我在上面说“列表”,但所有这些列表都可以很容易地成为数组或其他类型的容器。)

(评论2:在我说“将G添加到C”的地方,重要的是C本身不要被改变,因为它会被重复使用很多次,M中的每个组一次。)

于 2012-06-26T12:48:48.877 回答