标准是最多允许一个空对象,并且每个对象只能重复一次。
这是我目前为止的尝试。
假设n=3,k=3。让0表示为空对象。
一些可能的例子:
011 101 110 112
012 102 120 113
013 103 130 121
... ... ... ...
033 303 330 332
因此,我创建了一个{0,1,1,2,2,3,3}的“池”。将使用逻辑向量的排列从池中选择三个对象
(例如,逻辑向量{0,1,0,0,0,1,1}从池中选择1,3,3)
然后将三个选定对象的所有排列添加到集合中。
然而会有一些重复,因为{0,1,0,0,0,1,1}被认为等同于{0,0,1,0,0,1,1,},因为两者都将从池中选择1,3,3。
对于更高的n和k,例如当n=8和k=6时,此代码在计算上变得非常昂贵。有没有更有效的方法?
我的C++代码:
set< vector<int> > generate_kperms ( int n, int k )
{
set< vector<int> > kperms;
// create vector of integers { 0, 1, 1, 2, 2, ..., n, n }
vector<int> pool( 2*n + 1 );
pool[0] = 0;
for ( int i = 1; i <= n; ++i )
pool[2*i-1] = pool[2*i] = i;
// create logical vector with k true values, to be permuted
vector<bool> logical( pool.size() );
fill( logical.end()-k, logical.end(), true );
do {
vector<int> kperm( k );
vector<int>::iterator itr = kperm.begin();
for ( int idx = 0; idx < (int) pool.size(); ++idx ) {
if ( logical[idx] )
*(itr++) = pool[idx];
}
do {
kperms.insert( kperm );
} while ( next_permutation ( kperm.begin(), kperm.end() ) );
} while ( next_permutation( logical.begin(), logical.end() ) );
return kperms;
} /* ----- end of function generate_kperms ----- */