【问题标题】:Generating sequentially all combination of a finite set using lexicographic order and bitwise arithmetic使用字典顺序和按位算术顺序生成有限集的所有组合
【发布时间】:2011-11-05 00:40:12
【问题描述】:

考虑以下整数数组 {1,2,3} 的长度为 3 的所有组合。

我想使用wikipedia中的以下算法遍历所有长度为3的组合

// find next k-combination    
bool next_combination(unsigned long& x) // assume x has form x'01^a10^b in binary
{
  unsigned long u = x & -x; // extract rightmost bit 1; u =  0'00^a10^b
  unsigned long v = u + x; // set last non-trailing bit 0, and clear to the right; v=x'10^a00^b
  if (v==0) // then overflow in v, or x==0
    return false; // signal that next k-combination cannot be represented
  x = v +(((v^x)/u)>>2); // v^x = 0'11^a10^b, (v^x)/u = 0'0^b1^{a+2}, and x ← x'100^b1^a
  return true; // successful completion
}

对于 {1,2,3} 的所有组合,该算法的起始值应该是多少? 当我得到算法的输出后,如何恢复组合?

我尝试了以下直接改编,但我是按位算术的新手,我不知道这是否正确。

// find next k-combination, Java    
int next_combination(int x)
{
  int u = x & -x; 
  int v = u + x; 
  if (v==0) 
    return v; 
  x = v +(((v^x)/u)>>2); 
  return x; 
}

【问题讨论】:

  • 您是否尝试过运行代码?注: Wikipedia 算法使用x 作为输入和输出参数。 Java 没有这些。
  • @MattBall 当我运行代码时,它返回一个整数。不知道怎么解释,也不知道怎么翻译成组合。我将编辑我的 Java 改编版本。这是第一次尝试,只是在调试模式下分析 wiki 算法。感谢您指出这一点。
  • @Mr.Wizard 我按照你的建议继续。谢谢。

标签: java bit-manipulation combinations combinatorics


【解决方案1】:

我找到了一个可以完全解决这个问题的课程。在此处查看类 CombinationGenerator

https://bitbucket.org/rayortigas/everyhand-java/src/9e5f1d7bd9ca/src/Combinatorics.java

要恢复一个组合做

for(Long combination : combinationIterator(10,3))       
    toCombination(toPermutation(combination);

感谢大家的意见。

【讨论】:

    【解决方案2】:

    我编写了一个类来处理处理二项式系数的常用函数,这是您的问题所属的问题类型。它执行以下任务:

    1. 以适合任何 N 选择 K 的格式将所有 K 索引输出到文件。 K-indexes 可以替换为更具描述性的字符串或字母。这种方法使得解决这类问题变得非常简单。

    2. 将 K 索引转换为已排序二项式系数表中条目的正确索引。这种技术比依赖迭代的旧已发布技术快得多。它通过使用帕斯卡三角形固有的数学属性来做到这一点。我的论文谈到了这一点。我相信我是第一个发现并发表这种技术的人,但我可能是错的。

    3. 将已排序二项式系数表中的索引转换为相应的 K 索引。我相信它可能比您找到的链接更快。

    4. 使用Mark Dominus方法计算二项式系数,该方法不太可能溢出并且适用于较大的数字。

    5. 该类是用 .NET C# 编写的,并提供了一种通过使用通用列表来管理与问题相关的对象(如果有)的方法。此类的构造函数采用一个名为 InitTable 的 bool 值,当它为 true 时,将创建一个通用列表来保存要管理的对象。如果此值为 false,则不会创建表。无需创建表即可执行上述 4 种方法。提供访问器方法来访问表。

    6. 有一个关联的测试类显示如何使用该类及其方法。它已经过 2 个案例的广泛测试,没有已知的错误。

    要了解该课程并下载代码,请参阅Tablizing The Binomial Coeffieicent

    将此类转换为 Java 应该不难。

    【讨论】:

      猜你喜欢
      • 2013-04-22
      • 1970-01-01
      • 2013-07-15
      • 2011-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-28
      相关资源
      最近更新 更多