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

发布于 2024-08-16 05:19:17 字数 301 浏览 3 评论 0原文

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

给定:

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

我知道排列的公式(无序、唯一的选择),但我无法计算说明允许重复如何增加集合。

I'm trying to determine the function for determining the number of unordered combinations with non-unique choices.

Given:

n = number of unique symbols to select from
r = number of choices

Example... for n=3, r=3, the result would be: (edit: added missing values pointed out by Dav)

000
001
002
011
012
022
111
112
122
222

I know the formula for permutations (unordered, unique selections), but I can't figure out how allowing repetition increases the set.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

指尖微凉心微凉 2024-08-23 05:19:17

在 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()));

In C++ given the following routine:

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;
}

You can then proceed to do the following:

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()));
若水微香 2024-08-23 05:19:17

如果您有 N 个唯一符号,并且想要选择长度 R 的组合,那么您实际上是将 N-1 个分隔符放入 >R+1 所选符号的累积总数之间的“槽”。

0 [C] 1 [C] 2 [C] 3

C 是选择,数字是迄今为止所做选择的累积计数。当你“开始”选择某件事时,你本质上是为你可以选择的每一个可能的事物放置一个分隔线(假设你在放置任何分隔线之前先选择一个特定的事物,因此 N 中的 -1 -1 分隔线)。

如果您将所有分隔线都放置在 0 位置,那么您就为所有选项选择了最后一个。如果您将所有分隔线放在位置 3,那么您将为所有选项选择第一个。一般来说,如果您将第 i 分隔线放在 k 位置,那么您就为该事物之间的所有选择选择了 i+1 事物点和下一个分隔线的点。

由于我们试图在 R 槽周围放置 N-1 个非唯一项(分隔符不是唯一的,它们只是分隔符),我们真的只想排列 N-1 1 和 R 0,这实际上是

(N+R-1) 选择 (N-1) =(N+R-1)!/((N-1)!R!)

因此,最终的公式为 (N+R-1)!/((N-1)!R!),用于表示具有非唯一项目选择的无序组合的数量。

请注意,对于 N=3、R=3,其计算结果为 10,这与您的结果相匹配...在您添加了我在上面的评论中指出的缺少的选项之后。

If you have N unique symbols, and want to select a combination of length R, then you are essentially putting N-1 dividers into R+1 "slots" between cumulative total numbers of symbols selected.

0 [C] 1 [C] 2 [C] 3

The C's are choices, the numbers are the cumulative count of choices made so far. You're essentially putting a divider for each possible thing you could choose of when you "start" choosing that thing (it's assumed that you start with choosing a particular thing before any dividers are placed, hence the -1 in the N-1 dividers).

If you place all of the dividers are spot 0, then you chose the final thing for all of the choices. If you place all of the dividers at spot 3, then you choose the initial thing for all of the choices. In general, if you place the ith divider at spot k, then you chose thing i+1 for all of the choices that come between that spot and the spot of the next divider.

Since we're trying to put N-1 non-unique items (the dividers are non-unique, they're just dividers) around R slots, we really just want to permute N-1 1's and R 0's, which is effectively

(N+R-1) choose (N-1) =(N+R-1)!/((N-1)!R!).

Thus the final formula is (N+R-1)!/((N-1)!R!) for the number of unordered combinations with non-unique selection of items.

Note that this evaluates to 10 for N=3, R=3, which matches with your result... after you add the missing options that I pointed out in comments above.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文