[英]Generate all possible column vectors in matlab
I am essentially trying to figure out how to generate code for basis vectors of different configurations of M objects into N different states (for example, if I had 2 snacks between 2 kids, I could have (2,0) (0,2) or (1,1), terrible example, but thats the idea) 我本质上是在试图找出如何为M对象的不同配置的基向量生成代码到N个不同状态的代码(例如,如果我在2个孩子之间有2个零食,我可能会拥有(2,0)(0,2)或(1,1),一个可怕的例子,但这就是想法)
I am struggling to figure out how to do this without going into many different loops (I want this to be automatic). 我正在努力弄清楚如何做到这一点,而不必进入许多不同的循环(我希望这是自动的)。 The idea would be to create a Matrix where each row is a vector of length M. I would start with vec(1) = N then an if loop where if sum(vec) == N, Matrix(1,:)=vec;
想法是创建一个矩阵,其中每一行都是长度为M的向量。我将从vec(1)= N开始,然后是一个if循环,其中if sum(vec)== N,Matrix(1,:)= vec ; Then I could take vec(1)=Ni and do the same.
然后,我可以采用vec(1)= Ni并执行相同操作。
My only issue is I do not see how to use the if and forget it so that if I had maybe 2 objects in 5 locations, how would I do this to get (1 0 0 0 1). 我唯一的问题是我看不到如何使用if并忘记了它,所以如果我可能在5个位置中有2个对象,我将如何获得(1 0 0 0 1)。
I am not seeing how to do this. 我没有看到如何执行此操作。
You could use a recursive function: 您可以使用递归函数:
function out = combos(M,N)
if N == 1
out = M;
else
out = [];
for i = 0:M
subout = combos(M-i,N-1);
subout(:,end+1) = i;
out = [out;subout];
end
end
I think this does what you want. 我认为这可以满足您的需求。
The key idea is to generate not the number of elements in each group, but the split points between groups. 关键思想是不生成每个组中元素的数量,而是生成组之间的分割点 。 This can be done via combinations with repetition .
这可以通过与重复结合来完成。 Matlab's
nchoosek
generates combinations without repetition, but these are easily converted into what we need. Matlab的
nchoosek
生成的组合没有重复,但是很容易将它们转换成我们需要的组合。
M = 5; % number of objects
N = 3; % number of groups
t = nchoosek(1:M+N-1, N-1); % combinations without repetition...
t = bsxfun(@minus, t, 1:N-1); % ...convert into combinations with repetition
t = diff([zeros(size(t,1), 1) t repmat(M, size(t,1), 1) ], [], 2); % the size of each
% group is the distance between split points
In this example, the result is 在此示例中,结果是
t =
0 0 5
0 1 4
0 2 3
0 3 2
0 4 1
0 5 0
1 0 4
1 1 3
1 2 2
1 3 1
1 4 0
2 0 3
2 1 2
2 2 1
2 3 0
3 0 2
3 1 1
3 2 0
4 0 1
4 1 0
5 0 0
This is a similar approach to Luis' without bsxfun
. 这与没有
bsxfun
Luis相似。 Because we don't like fun. 因为我们不喜欢娱乐。
n = 5;
k = 3;
c = nchoosek(n+k-1, k-1);
result = diff([zeros(c, 1) nchoosek(1:(n+k-1), k-1) ones(c, 1)*(n+k)], [], 2) - 1;
This creates the partitions of the integer n
with length k
. 这将创建长度为
k
的整数n
的分区。 Given an array of length n + (k-1)
, we find all combinations of (k-1)
places to place partitions between the (unary) integers. 给定长度为
n + (k-1)
的数组,我们找到(k-1)
位置的所有组合,以在(一元)整数之间放置分区。 For 5 items and 3 locations, we have 7 choices of where to put the partitions: 对于5个项目和3个位置,我们有7种选择来放置分区:
[ 0 0 0 0 0 0 0 ]
If our chosen combination is [2 4]
, we replace positions 2
and 4
with partitions to look like this: 如果我们选择的组合为
[2 4]
,那么我们将2
和4
替换为分区,如下所示:
[ 0 | 0 | 0 0 0 ]
The O
's give the value in unary, so this combination is 1 1 3
. O
给出一元值,因此此组合为1 1 3
。 To recover the values easily, we just augment the combinations with imaginary partitions at the next values to the left and right of the array ( 0
and n+k
) and take the difference and subtract 1
(because the partitions themselves don't contribute to the value): 为了轻松恢复这些值,我们只在数组左右两侧的下一个值(
0
和n+k
)处用虚数分区扩展组合,然后求和并减去1
(因为分区本身对价值):
diff([0 2 4 8]) - 1
ans =
1 1 3
By sliding the partitions in to each possible combination of positions, we get all of the partitions of n
. 通过将分区滑入每个可能的位置组合,我们得到
n
所有分区。
Output: 输出:
result =
0 0 5
0 1 4
0 2 3
0 3 2
0 4 1
0 5 0
1 0 4
1 1 3
1 2 2
1 3 1
1 4 0
2 0 3
2 1 2
2 2 1
2 3 0
3 0 2
3 1 1
3 2 0
4 0 1
4 1 0
5 0 0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.