List all k-tuples with entries summing to n, ignoring rotations

风格不统一 提交于 2019-12-05 12:22:53

You can first generate the partitions (which ignore order completely) as a tuple (x_1, x_2, ..., x_n)

where x_i = number of times i occurs.

So Sum i* x_i = n.

I believe you already know how to do this (from your comments).

Once you have a partition, you can now generate the permutations for this (viewing it as a multiset {1,1,...,2,2...,...n}, where i occurs x_i times) which ignore rotations, using the answer to this question:

Is there an algorithm to generate all unique circular permutations of a multiset?

Hope that helps.

You could just sort your solutions and eliminate rotations that way.
OR
you can try to make your recursive solution build tuples that will only ever be sorted

how? here's something I made up quickly

static list<tuple> tups;
void recurse(tuple l, int n, int k, int m)
{
  if (k == 0 && n == 0)
  {
    tups.add(l);
    return;
  }
  if (k == 0)
    return;

  if (k*m > n) //prunes out tuples that could not possibly be sorted
    return;
  else
    for(int x = m; x <= n; x++)
      recurse(l.add(x), n-x, k-1, x); //try only tuples that are increasing
}

call this with m = 0 and an empty list for the initial step.

here's a C# console app implementation : http://freetexthost.com/b0i05jkb4e

Oh, I see my mistake in the assumption of rotation, I thought you just meant permutations, not an actual rotation. However, you can extend my solution to create non-rotational permutations of the unique increasing tuples. I'm working on it now

You need to generate Integer Partitions in lexicographical order.

Here is a very good paper with fast algorithms.

HTH.

Note that CAS programs usually implement these functions. For example in Mathematica:

Innput: IntegerPartitions[10, {3}]
Output: {{8, 1, 1}, {7, 2, 1}, {6, 3, 1}, 
         {6, 2, 2}, {5, 4, 1}, {5, 3, 2}, 
         {4, 4, 2}, {4, 3, 3}}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!