matlab:获取特定逻辑矩阵的所有排列

时间:2012-02-29 14:12:22

标签: matlab permutation combinations

让我们假设我有以下逻辑矩阵:

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]

所以我有以下几种可能性:

  • 购物篮2:0件
  • 篮子1:可以包含对象1或对象。 3
  • 篮子3:可以包含对象2,obj。 3或obj。 4

总而言之,我有完整的排列(一行描述一个排列,列描述篮子,数字描述对象):

1 0 2
1 0 3
1 0 4
2 0 2
2 0 3
2 0 4

如何将其变成一个很好的算法,适应任意数量的篮子和对象?我只能想到嵌套和丑陋的循环:( 非常感谢!

3 个答案:

答案 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。