[英]Partitioning a no. N into M partitions
I'm trying a problem in which I have to partition a no. 我正在尝试一个必须对一个分区进行分区的问题。 N into M partitions as many as possible. N尽可能分成M个分区。
Example: 例:
N=1 M=3 , break 1 into 3 parts N = 1 M = 3,将1分成3部分
0 0 1 0 0 1
0 1 0 0 1 0
1 0 0 1 0 0
N=3 M=2 , break 3 into 2 parts N = 3 M = 2,将3分成2部分
2 1 2 1
1 2 1 2
3 0 3 0
0 3 0 3
N=4 M=4 , break 4 into 4 parts N = 4 M = 4,将4分成4部分
0 0 0 4 0 0 0 4
0 0 4 0 0 0 4 0
0 4 0 0 0 4 0 0
4 0 0 0 4 0 0 0
0 0 1 3 0 0 1 3
0 1 0 3 0 1 0 3
0 1 3 0 0 1 3 0
. 。
. 。
. 。
and so on. 等等。
I did code a backtrack algo. 我确实编写了回溯算法。 which produce all the possible compositions step by step, but it chokes for some larger input.Because many compositions are same differing only in ordering of parts.I want to reduce that.Can anybody help in providing a more efficient method. 它会逐步生成所有可能的合成,但是会占用较大的输入。因为许多合成只是在零件排序上有所不同。我想减少这一点。任何人都可以帮助您提供一种更有效的方法。
My method: 我的方法:
void backt(int* part,int pos,int n) //break N into M parts
{
if(pos==M-1)
{
part[pos]=n;
ppart(part); //print part array
return;
}
if(n==0)
{
part[pos]=0;
backt(part,pos+1,0);
return;
}
for(int i=0;i<=n;i++)
{
part[pos]=i;
backt(part,pos+1,n-i);
}
}
In my algo. 在我的算法中。 n is N and it fill the array part[] for every possible partition of N. n为N,它为N的每个可能分区填充数组part []。
What I want to know is once generating a composition I want to calculate how many times that composition will occur with different ordering.For ex: for N=1 ,M=3 ::: composition is only one : <0,0,1> ,but it occurs 3 times. 我想知道的是一旦生成一个合成,我想计算该合成将以不同顺序发生多少次。例如:对于N = 1,M = 3 :::合成只有一个:<0,0,1 >,但发生3次。 Thats what I want to know for every possible unique composition. 那就是我想知道的每种可能的独特构图。
for another example: N=4 M=4 再举一个例子:N = 4 M = 4
composition <0 0 0 4> is being repeated 4 times. 组成<0 0 0 4>被重复4次。 Similarly, for every unique composition I wanna know exactly how many times it will occur . 同样,对于每种独特的成分,我都想确切知道它将发生多少次。
Looks like I'm also getting it by explaining here.Thinking. 看起来我也可以通过在这里解释来理解它。
Thanks. 谢谢。
You can convert an int to a partitioning as follows: 您可以将int转换为分区,如下所示:
vector<int> part(int i, int n, int m)
{
int r = n; // r is num items remaining to be allocated
vector<int> result(m, 0); // m entries inited to 0
for (int j = 0; j < m-1; j++)
{
if (r == 0) // if none left stop
break;
int k = i % r; // mod out next bucket
i /= r; // divide out bucket
result[j] = k; // assign bucket
r -= k; // remove assigned items from remaining
}
result[m-1] = r; // put remainder in last bucket
return result;
}
So you can use this as follows: 因此,您可以按以下方式使用它:
for (int i = 0; true; i++)
{
vector<int> p = part(i, 3, 4);
if (i != 0 && p.back() == 3) // last part
break;
... // use p
};
It should be clear from this how to make an incremental version of part too. 由此也应该清楚如何制作零件的增量版本。
A much simpler and mathematical approach: 一种更简单,更数学的方法:
This problem is equivalent to finding the co-efficient of x^N in the expression f(x) = (1+x+x^2+x^3+....+x^N)^M 此问题等效于在表达式f(x)=(1 + x + x ^ 2 + x ^ 3 + .... + x ^ N)^ M中找到x ^ N的系数
f(x) = ((x^(N-1) - 1)/(x-1))^M differentiate it M times(d^Nf(x)/dx^N) and the co-efficient will be (1/n!)*(d^Nf(x)/dx^N) at x = 0; f(x)=((x ^(N-1)-1)/(x-1))^ M将其微分M倍(d ^ Nf(x)/ dx ^ N)且系数为( 1 / n!)*(d ^ Nf(x)/ dx ^ N)x = 0;
differentiation can be done using any numerical differentiation technique. 可以使用任何数值微分技术来完成微分。 So the complexity of the algorithm is O(N*complexity_of_differentiation).. 因此,算法的复杂度为O(N * complexity_of_differentiation)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.