笛卡尔积,但删除重复项直至循环排列

Cartesian product but remove duplicates up to cyclic permutations

给定两个整数 nr,我想根据以下规则生成所有可能的组合:

示例:

n=3, r=2
11 distinct combinations
(1,1,1), (1,1,2), (1,1,3), (1,2,2), (1,2,3), (1,3,2), (1,3,3), (2,2,2), (2,2,3), (2,3,3) and (3,3,3)

n=2, r=4
6 distinct combinations
(1,1,1,1), (1,1,1,2), (1,1,2,2), (1,2,1,2), (1,2,2,2), (2,2,2,2)

它的算法是什么?以及如何在 C++ 中实现它? 预先感谢您的建议。

python 中有一个天真的解决方案:

  • 根据 {1, 2, ...,n} 的笛卡尔积与其自身 r 次生成所有组合;
  • 每个等价物只保留一个代表组合class;删除与此代表组合等效的所有其他组合。

这意味着我们必须有一些方法来比较组合,例如,只保留每个等价的最小组合 class。

from itertools import product

def is_representative(comb):
    return all(comb[i:] + comb[:i] >= comb
               for i in range(1, len(comb)))

def cartesian_product_up_to_cyclic_permutations(n, r):
    return filter(is_representative,
                  product(range(n), repeat=r))

print(list(cartesian_product_up_to_cyclic_permutations(3, 3)))
# [(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 1, 1), (0, 1, 2), (0, 2, 1), (0, 2, 2), (1, 1, 1), (1, 1, 2), (1, 2, 2), (2, 2, 2)]

print(list(cartesian_product_up_to_cyclic_permutations(2, 4)))
# [(0, 0, 0, 0), (0, 0, 0, 1), (0, 0, 1, 1), (0, 1, 0, 1), (0, 1, 1, 1), (1, 1, 1, 1)]

你提到你想用 C++ 实现算法。 python 代码中的 product 函数的行为就像一个大的 for 循环,它生成笛卡尔积中的所有组合。请参阅此相关问题以在 C++ 中实现笛卡尔积:Is it possible to execute n number of nested "loops(any)" where n is given?