智能生成组合的组合
假设我有一个 30 名学生的班级,想要生成各种可能的方式将他们分成 5 人一组(顺序无关)。
我知道如何找到学生的所有组合以单独组成一个小组(http://www.merriampark. com/comb.htm)。通过使用该迭代器和一些递归,我可以找到可能的组组合的排列。但是,选择组的顺序并不相关,我想最大限度地减少执行时间。那么我如何找到可能组的独特组合呢?
上面的算法使用字典顺序来避免生成重复的组合...有没有一种方法可以让我在组而不是对象上使用这个想法?
我很了解 Ruby,但不太了解 Java/Python。预先感谢您的任何建议!
Let's say I have a class of 30 students and want generate every possible way in which they can be partitioned into groups of 5 (order is irrelevant).
I know how to find all the combinations of students to form one group individually (http://www.merriampark.com/comb.htm). By using that iterator and some recursion, I can find PERMUTATIONS of the possible group combinations. However, order in which the groups are selected isn't relevant and I'd like to minimize my execution time. So how do I find the unique COMBINATIONS of the possible groups?
The above algorithm uses lexicographical ordering to avoid generating duplicate combinations... is there a way that I can use that idea on groups instead of on objects?
I know Ruby well and Java/Python less well. Thanks in advance for any advice!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
嗯,有 (30C5*25C5*20C5*15C5*10<子>C5*5C5)/6! = 30!/(6!*5!6) = 123,378,675,083,039,376 个不同的分区,每组 30 个,每组 5 个,因此无论使用什么方法,生成它们都需要一些时间。
不过,一般来说,选择此类分区的一个好方法是对元素使用某种排序,并找到最高未分组元素的分组,然后对其余元素进行分组。
这样您只需生成每个分区一次
Well, there's (30C5*25C5*20C5*15C5*10C5*5C5)/6! = 30!/(6!*5!6) = 123,378,675,083,039,376 different partitons of 30 into groups of 5, so generating them all will take some time, no matter what method you use.
In general, though, a good method to selecting such a partition is to use some ordering on the elements, and find the grouping for the highest ungrouped element, and then group the rest.
This way you're only generating each partition once
这是一个老问题,但无论如何,为了记录,这就是我在 Ruby 中的方式:
我使用枚举器,因为输出可以快速增长,严格的输出(例如数组)不会有用。一个使用示例:
This is an old question, but anyway, for the record, that's how I would it in Ruby:
I use an enumerator because the output can grow very quickly, a strict output (an array for example) wouldn't be useful. A usage example:
您可以对排列进行一些后处理。一些伪代码(用您选择的语言实现......):
可能不是最有效的;我会添加排序 &与亲自生成排列的代码进行比较。
You could do some post-processing on the permutations. Some pseudo-code (implement in the language of your choice...):
Probably not the most efficient; I'd add the sort & compare to the code that generates the permutations personally.
一种可能性是找到所有组合来形成一个单独的组,然后遍历并生成不包含该单独组的成员的组合。类似于:
这不是最有效的方法,但它应该生成所有组的组合。我怀疑如果您要生成临时组合列表,其中所有不能出现的组都被删除,那么可以获得更好的性能,但这会更复杂一些。
顺便说一句,30 名学生组成 5 人一组,应该有 142,506 种组合。我的<讽刺>太棒了数学技能建议应该有大约 10^17 = 100 万亿个学生组组合 (30!/((5!^6)*6!); 30! 学生的排序,6 组 5 人的排序并不重要,并且这 6 组的顺序并不重要)。您可能会坐在那里等待这一切完成。
One possibility would be to find all combinations to form an individual group, then go through and generate combinations that don't contain members of that individual group. Something like:
It won't be the most efficient method to go about it, but it should generate all combinations of groups. I suspect better performance could be had if you were to generate temporary lists of combinations, where in all groups that can't occur were removed, but that would be a bit more complex.
As a slight aside, there should be 142,506 combinations of 30 students to form a single group of 5. My <sarcasm> awesome </sarcasm> math skills suggest that there should be about 10^17 = 100 quadrillion combinations of groups of students (30!/((5!^6)*6!); 30! orderings of students, ordering of 6 groups of 5 does not matter, and ordering of those 6 groups doesn't matter). You might be sitting there a while waiting for this to finish.