【问题标题】:Iterating through every combination of elements with repetitions without generating whole set通过重复的元素的每个组合迭代而不生成整个集合
【发布时间】:2018-01-17 13:24:34
【问题描述】:

我需要迭代每个可能的元素组合(有重复),最多 n 个元素。

我已经为这个问题找到了多种解决方案。但是所有这些都是递归地生成每个可能组合的集合,然后对其进行迭代。虽然这可行,但对于大型元素集合和组合大小,它会导致大量内存使用,因此我正在寻找一种解决方案,该解决方案允许我从前一个组合计算下一个组合,知道元素的数量和组合的最大大小。

这甚至可能吗?是否有任何特定的算法可以在这里工作?

【问题讨论】:

  • Next Permutation 你是否在与 c++ 中提供的类似行为之后?
  • @SamerTufail 不幸的是没有。我需要遍历组合(元素的顺序无关紧要,组合的顺序应该是可预测的但不是很重要),所以每个排列都应该被视为相同的组合。
  • 您要解决的问题是什么?有时您不必遍历集合来计算集合上的函数。有关示例,请参阅此 questionmy answer
  • @fjardon 我必须选择几个满足一组条件的最佳(按目标函数)组合。所以这实际上是优化问题。

标签: algorithm iteration combinations


【解决方案1】:

生成组合,以便对每个组合进行排序。 (这里假设元素本身可以很容易地按顺序排列。精确的排序关系并不重要,只要它是全序即可。)

从最小元素的 n 次重复组成的组合开始。从任何给定组合产生下一个组合:

  1. 向后扫描,直到找到一个不是最大元素的元素。如果找不到,就完蛋了。

  2. 将该元素和所有后续元素替换为该元素的下一个较大元素。

如果您想要不超过 n 的所有长度的组合,请针对不超过 n 的每个长度运行该算法。或者从一个包含空槽的向量开始,并使用上述算法,并理解空槽之后的“下一个较大元素”是最小元素。

示例:长度为 3,共 3 个值:

1 1 1
1 1 2
1 1 3
1 2 2
1 2 3
1 3 3
2 2 2
2 2 3
2 3 3
3 3 3

【讨论】:

  • 这实际上是我想避免的方法,主要是由于您需要保存在内存中的集合大小。例如,考虑到元素是 4 字节数字,在 25 个元素长集合中有 6 个元素的 593775 个组合。它超过 2 MB,没有任何开销。这就是为什么我要问是否有任何聪明的数学解决方案。
  • @k.kowalczyk:但您不需要一次全部生成它们。生成一个,做任何你需要的,然后生成下一个。这就是迭代的意思。该算法告诉您如何“生成下一个”。
  • 对,我之前误解了答案。这正是我所需要的,谢谢。
猜你喜欢
  • 2014-06-08
  • 2021-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-06
  • 1970-01-01
  • 2012-09-10
  • 1970-01-01
相关资源
最近更新 更多