用于确定具有非唯一选择的无序组合的数量的函数

时间:2009-12-25 00:20:33

标签: language-agnostic math combinatorics

我正在尝试确定用于确定具有非唯一选择的无序组合的数量的函数。

假设:

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

我知道排列的公式(无序,唯一选择),但我无法弄清楚允许重复如何增加集合。

2 个答案:

答案 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,这与您的结果匹配...