2012-06-26 117 views
0

摘要:
您选择您注册的模块。
每个模块都有多个组。
每个组代表给定模块的讲座。
每个组合应该只包含来自每个模块的一个组。复杂排列/组合

实施例:
COS 121个-3组
COS 132个-2组

这会给你6个选项:[1,1],[1,2],[2,1],[我需要使用每个组合来生成时​​间表,因此我使用一个数组来存储正在使用的当前组和总数组数: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
============ Run 9 ==============
模块,当前组,最大组
1,1,3
2,3 ,3
3,3,3
============运行10 ============== //////问题出在这里
模块,当前组,最大团
1,1,3-
2,4,3
3,1,3

回答

1

新的答案:

首先,可能COM的数目binations是每个模块中组的数量的乘积。例如,如果有三个模块,分别包含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) 

现在,要将索引转换为组合,有必要将整数索引看作从右到左的“数字”列表。这很容易看出每个模块是否有10个组,并且组号从0开始而不是1。然后一个整数468可以被读为列表(8,6,4),这意味着组8来自模块1,组6来自模块2,组4来自模块3.在伪代码中,将索引转换为组合将是像

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组

OLD答:

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

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

否则,让M为第一个模块,并让REST成为模块的其余部分。在REST上调用递归函数以获得其余模块的所有组合(称为COMBOS组合列表)。请注意,在COMBOS这些组合做包含来自M.

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

Return ANSWERS。 (假设:没有一个组出现在多个模块中,或者在同一个模块中出现两次,模块列表中不会出现多次模块,如果需要,可以放松这些假设,但是您需要定义你想要的行为是在这些情况下)

(注释1:我说的“清单”之上,但所有这些列表可以很容易地是数组或一些其他类型的容器)

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

+0

Hi C一应俱全。感谢您的快速和彻底的答复。虽然我特意寻找顺序通过排列的方式,但我希望利用每个排列而不必存储排列。请看看我更新的帖子,以获得更好的理解。 – Hendrik

+0

好吧,它听起来像你想要某种阵列。我修改了答案,如果您只是想遍历组合而不将它们全部存储起来。 –

+0

嗨克里斯。该算法完美运行!我非常感谢你的帮助。你给我信心更频繁地使用计算器! – Hendrik