让我们假设我有以下逻辑矩阵:
log = [1 1 0;
0 1 1;
1 0 1;
0 0 1];
这些列描述了类似篮子的东西,单行描述了某些属性(例如不同颜色的球)可以放入这些篮子中的物体。 1
表示您可以将其放入(在列中描述的购物篮中),0
您不能。
每个篮子一次只能包含一个物体。
我想知道如何计算如何为给定配置输入对象的排列,这意味着我说:I want to have objects in basket 1 and 3 but none in basket 2, which would be [1 0 1]
:
所以我有以下几种可能性:
总而言之,我有完整的排列(一行描述一个排列,列描述篮子,数字描述对象):
1 0 2
1 0 3
1 0 4
2 0 2
2 0 3
2 0 4
如何将其变成一个很好的算法,适应任意数量的篮子和对象?我只能想到嵌套和丑陋的循环:( 非常感谢!
答案 0 :(得分:5)
您可以使用ndgrid
。此功能完全符合您的要求。
[b1 b2 b3]=ndgrid([1 2],[0],[2 3 4]);
[b1(:) b2(:) b3(:)]
ans =
1 0 2
2 0 2
1 0 3
2 0 3
1 0 4
2 0 4
要回答完整问题,您需要从日志变量中获取[1 2],[0],[2 3 4]
:
log = [1 1 0;
0 1 1;
1 0 1;
0 0 1];
log=bsxfun(@times,log,[1 0 1]);
poss=cellfun(@find,mat2cell(log,size(log,1),ones(1,size(log,2))),'UniformOutput',0)
poss(cellfun(@isempty,poss))={0}
basket=cell(1,size(log,2));
[basket{:}]=ndgrid(poss{:});
basket=cell2mat(cellfun(@(x) x(:),basket,'UniformOutput',0))
basket =
1 0 2
3 0 2
1 0 3
3 0 3
1 0 4
3 0 4
答案 1 :(得分:4)
我会递归地说:
function out = permlog(log,bag)
if bag(1)==0
curr=0;
else
curr = find(log(:,1));
end
if size(log,2)==1
out = curr;
return
else
add = permlog(log(:,2:end),bag(2:end));
out = [];
for i=1:numel(curr)
tmp = [repmat(curr(i),size(add,1),1),add];
out =[out;tmp];
end
end
给出你描述的输出:
permlog(log,[1,0,1])
ans =
1 0 2
1 0 3
1 0 4
3 0 2
3 0 3
3 0 4
答案 2 :(得分:0)
现在也在文件交换中找到了一些内容:http://www.mathworks.com/matlabcentral/fileexchange/10064-allcomb/content/allcomb.m 这有点像Olis建议通过ndgrid。