MATLAB生成n个项目可以放入m个箱子的所有方式?
我想找到所有方法,使MATLAB生成n个项目可以放入m个箱子的所有方式?,matlab,combinations,vectorization,permutation,Matlab,Combinations,Vectorization,Permutation,我想找到所有方法,使n项可以在m箱中拆分。例如,对于n=3和m=3,输出将是(顺序无关紧要): 该算法应尽可能高效,对于循环,最好是矢量化/使用内置函数,而不是。谢谢大家! 这应该非常有效 它的工作原理是在m处生成实区间[0,n]的所有可能拆分−1个整数值,可能是重合的分割点。结果子区间的长度给出了解决方案 例如,对于n=4和m=3,在m处拆分间隔[0,4]的一些可能方法−1点是: 在0,0:这将给出长度0,0,4的子间隔 在0,1:这将给出长度0,1,3的子间隔 在4,4:这将给出长度4,
n
项可以在m
箱中拆分。例如,对于n=3
和m=3
,输出将是(顺序无关紧要):
该算法应尽可能高效,对于循环,最好是矢量化/使用内置函数,而不是
。谢谢大家! 这应该非常有效
它的工作原理是在m处生成实区间[0,n]的所有可能拆分−1个整数值,可能是重合的分割点。结果子区间的长度给出了解决方案
例如,对于n=4
和m=3
,在m处拆分间隔[0,4]的一些可能方法−1点是:
- 在
0
,0
:这将给出长度0
,0
,4
的子间隔
- 在
0
,1
:这将给出长度0
,1
,3
的子间隔
- 在
4
,4
:这将给出长度4
,0
,0
的子间隔
代码:
结果是按字典顺序排列的
例如,对于m=3
箱中的n=4
项,输出为
result =
0 0 4
0 1 3
0 2 2
0 3 1
0 4 0
1 0 3
1 1 2
1 2 1
1 3 0
2 0 2
2 1 1
2 2 0
3 0 1
3 1 0
4 0 0
我想建议一种基于外部功能和accumarray的解决方案(从R2015a开始应该可以工作,因为):
其中创建一个矩阵,其行是通过重复选择向量V
的K
元素创建的所有组合
说明:
m=3和n=4的VChooseKR(1:m,n)
的输出为:
1 1 1 1
1 1 1 2
1 1 1 3
1 1 2 2
1 1 2 3
1 1 3 3
1 2 2 2
1 2 2 3
1 2 3 3
1 3 3 3
2 2 2 2
2 2 2 3
2 2 3 3
2 3 3 3
3 3 3 3
我们现在需要做的就是使用正整数容器“histcount”每行上的数字,以获得所需的结果。第一个输出行将是[4 0 0]
,因为所有4个元素都放在第一个箱子中。第二行是[3 1 0]
,因为3个元素放在第一个箱子里,1个放在第二个箱子里,以此类推。@SomeGuy这是组合的总数。你能列举所有这些吗?不是指控。我只是真的很好奇。目标是获得所有的安排,而不是有多少安排。对不起,我误解了这个问题,列举所有的安排毕竟不是那么容易!非常非常好!非常优雅!我花了一些认真的脑力去理解发生了什么:)@SomeGuy是的,写起来比读起来容易:-)我加了一个例子,应该会让事情变得更清楚谢谢,这很好!但是等一下,你的nchoosek
将返回(n+2)C(m-1)组合(最终将得到分割),理论上应该有(n+m-1)C(m-1)分割方法,仅仅因为这些情况下有m-1=2
?第三行应该是VChooseKR(1:m,double(n))代码>工作(至少对我来说)。此外,由于某种原因,此方法对于较大的n
,m
值失败。例如,如果n=6
和m=6
,那么出于某种原因result(end,:)
是0 241 251 252 252
@space\u voyager对于OP的小示例,uint8就足够了,但是对于n,m,导致更多的组合,您可能需要uint16甚至更多。我现在还不能测试它,但它看起来像是一个简单的整数溢出的例子。是的,我刚刚发现了这一点。使用result=accumarray([repelem(1:size(whichBin,2),uint16(n))。'uint16(whichBin(:)]),1)代码>适用于较大的n,m值
result =
0 0 4
0 1 3
0 2 2
0 3 1
0 4 0
1 0 3
1 1 2
1 2 1
1 3 0
2 0 2
2 1 1
2 2 0
3 0 1
3 1 0
4 0 0
n = uint8(4); % number of items
m = uint8(3); % number of bins
whichBin = VChooseKR(1:m,n).'; % see FEX link below. Transpose saves us a `reshape()` later.
result = accumarray([repelem(1:size(whichBin,2),n).' whichBin(:)],1);
1 1 1 1
1 1 1 2
1 1 1 3
1 1 2 2
1 1 2 3
1 1 3 3
1 2 2 2
1 2 2 3
1 2 3 3
1 3 3 3
2 2 2 2
2 2 2 3
2 2 3 3
2 3 3 3
3 3 3 3