我正在尝试确定用于确定具有非唯一选择的无序组合的数量的函数。
假设:
n = number of unique symbols to select from
r = number of choices
示例...对于n = 3,r = 3,结果将是:(编辑:添加由Dav指出的缺失值)
000
001
002
011
012
022
111
112
122
222
我知道排列的公式(无序,唯一选择),但我无法弄清楚允许重复如何增加集合。
答案 0 :(得分:7)
在C ++中给出以下例程:
template <typename Iterator>
bool next_combination(const Iterator first, Iterator k, const Iterator last)
{
/* Credits: Mark Nelson http://marknelson.us */
if ((first == last) || (first == k) || (last == k))
return false;
Iterator i1 = first;
Iterator i2 = last;
++i1;
if (last == i1)
return false;
i1 = last;
--i1;
i1 = k;
--i2;
while (first != i1)
{
if (*--i1 < *i2)
{
Iterator j = k;
while (!(*i1 < *j)) ++j;
std::iter_swap(i1,j);
++i1;
++j;
i2 = k;
std::rotate(i1,j,last);
while (last != j)
{
++j;
++i2;
}
std::rotate(k,i2,last);
return true;
}
}
std::rotate(first,k,last);
return false;
}
然后您可以继续执行以下操作:
std::string s = "12345";
std::size_t r = 3;
do
{
std::cout << std::string(s.begin(),s.begin() + r) << std::endl;
}
while(next_combination(s.begin(), s.begin() + r, s.end()));
答案 1 :(得分:3)
如果您有N
个唯一符号,并希望选择长度为R
的组合,那么您实际上是将N-1
个分隔符放入R+1
个“插槽”之间选择的符号总数。
0 [C] 1 [C] 2 [C] 3
C是选择,数字是到目前为止所做出的选择的累积计数。当你“开始”选择那个东西时,你实际上是为每个可能选择的东西放置一个分隔符(假设你在放置任何分隔符之前选择一个特定的东西开始,因此{{1}中的-1分隔符。)
如果您将所有分隔线都放在0位,那么您为所有选择选择了最后一个。如果您将所有分隔线放在第3点,那么您可以为所有选择选择最初的分隔线。一般情况下,如果您将 ith 分隔符放在 k 点上,那么您选择了 i + 1 之类的所有选项。斑点和下一个分隔物的位置。
由于我们试图在N-1
个广告位置附近放置N-1
个非唯一项(分隔线非唯一,它们只是分隔线),我们真的只想置换{{1 1和R
0,实际上是
N-1
= R
。
因此,对于具有非唯一项目选择的无序组合,最终公式为(N+R-1) choose (N-1)
。
请注意,在您添加我在上面的评论中指出的缺失选项之后,对于N = 3,R = 3评估为10,这与您的结果匹配...