Data structures 复置换/组合

Data structures 复置换/组合,data-structures,permutation,combinations,Data Structures,Permutation,Combinations,摘要: 您可以选择要注册的模块。 每个模块都有若干组。 每组代表给定模块的讲座。 每个组合应仅包含每个模块中的一个组 例如: COS 121-3组 COS 132-2组 这将为您提供6个选项:[1,1]、[1,2]、[2,1]、[2,2]、[3,1]、[3,2] 我的角度: 我需要使用每个组合来生成时间表,因此我使用一个数组来存储当前使用的组和组的总数:arrcombites[subject,currentGroup,maxGroups] 从逻辑上讲,您应该能够遍历此数组,以利用每个组的组合 我

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

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

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

我的角度: 我需要使用每个组合来生成时间表,因此我使用一个数组来存储当前使用的组和组的总数:
arrcombites[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;
arrPermutations[0,0]:=1//第一个模块的当前组
arrPermutations[0,1]:=3//第一个模块的最大组数
arrPermutations[1,0]:=1;
arrPermutations[1,1]:=3;
arrPermutations[2,0]:=1//第三个模块的当前组
arrPermutations[2,1]:=3//第三个模块的最大组数
i电流:=iMax//2.
而(排列[0,0]新答案:

首先,可能的组合数是每个模块中组数的乘积。例如,如果有三个模块,分别包含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上调用递归函数以获取其余模块的所有组合(称为此组合组合列表)。请注意,组合中的这些组合不包含来自M的组

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

返回答案

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

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


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

嗨,克里斯。谢谢你快速而彻底的回复。虽然我特别想寻找一种顺序通过排列的方法,因为我想使用每个排列而不必存储。请看我更新的帖子以获得更好的理解。好的,听起来你想要某种数组。我已经修改了如果你只是想在不存储所有组合的情况下对组合进行迭代,那么答案就是。嗨,克里斯。该算法工作得非常完美!我真的非常感谢你的帮助。你给了我更多使用stackoverflow的信心!