Matlab 优化算法,生成每个二进制状态下的单元数

Matlab 优化算法,生成每个二进制状态下的单元数,matlab,performance,sum,combinatorics,binary-data,Matlab,Performance,Sum,Combinatorics,Binary Data,TL;DR:我需要找到N行向量(大小1xB)的所有可能组合,它们的行和产生所需的结果向量(大小1xB) 我有一个大小为nxb的二进制矩阵(仅1或0个条目),其中N表示单元数,B表示单元数。矩阵的每个单元(即每行)可以处于2^B状态之一。也就是说,如果B=2,可能的状态是{0,0}、{0,1}、{1,0}或{1,1}。如果B=3,则可能的状态为{0,0,0}、{0,0,1}、{0,1,0}、{0,1,1}、{1,0,0}、{1,0,1}、{1,1,0}或{1,1,1,1}。基本上是从0到2^B-

TL;DR:我需要找到
N
行向量(大小
1xB
)的所有可能组合,它们的行和产生所需的结果向量(大小
1xB


我有一个大小为nxb的二进制矩阵(仅1或0个条目),其中N表示单元数,B表示单元数。矩阵的每个单元(即每行)可以处于2^B状态之一。也就是说,如果B=2,可能的状态是{0,0}、{0,1}、{1,0}或{1,1}。如果B=3,则可能的状态为{0,0,0}、{0,0,1}、{0,1,0}、{0,1,1}、{1,0,0}、{1,0,1}、{1,1,0}或{1,1,1,1}。基本上是从0到2^B-1的数字的二进制表示

对于矩阵,我知道矩阵行的和,例如,{1,2}。这个和可以通过不同的二进制矩阵来实现,比如
[0,0;0,1;1,1]
[0,1;0,1;1,0]
。对于每个矩阵,每个状态中的单元数分别为{1,1,0,1}和{0,2,1,0},其中第一个数对应于第一个状态{0,0},第二个数对应于第二个状态{0,1},依此类推。我的问题是找到满足特定矩阵和的这些状态数的所有可能向量

现在,为了在MATLAB中实现这一点,我使用了递归和全局变量。这对我来说是最简单的方法,但是,它需要很多时间。我使用的代码如下所示:

function output = getallstate()
   global nState % stores all the possible vectors
   global nStateRow % stores the current row of the vector
   global statebin %stores the binary representation of all the possible states
   nState = [];
   nStateRow = 1;
   nBin = 2; % number of columns or B
   v = [1 2]; % should always be of the size 1 x nBin
   N = 3; % number of units
   statebin = de2bi(0:(2 ^ nBin - 1), nBin) == 1; % stored as logical because I use it to index later
   getnstate(v, 2 ^ nBin - 1, nBin) % the main function
   checkresult(v, nState, nBin) % will result in false if even one of the results is incorrect
   % adjust for max number of units, because the total of each row cannot exceed this number.
   output = nState(1:end-1, :); % last row is always repeated (needs to be fixed somehow)
   output(:, 1) = N - sum(output(:, 2:end), 2); % the first column, that is the number of units in the all 0 state is always determined by the number of units in the other states
   if any(output(:, 1) < 0)
      output(output(:, 1) < 0, :) = [];
   end
end

function getnstate(r, state, nBin)
   global nState
   global nStateRow
   global statebin

   if state == 0
      if all(r == 0)
         nStateRow = nStateRow + 1;
         nState(nStateRow, :) = nState(nStateRow - 1, :);
      end
   else
      for a = 0:min(r(statebin(state + 1, :)))
         nState(nStateRow, state + 1) = a;
         getnstate(r - a * statebin(state + 1, :), state - 1, nBin);
      end
   end
end

function allOk = checkresult(r, nState, nBin)
   % just a function that checks whether the obtained vectors all result in the correct sum
   allstate = de2bi(0:(2 ^ nBin - 1), nBin);
   allOk = true;
   for iRow = 1:size(nState, 1)
      sumR = sum(bsxfun(@times, allstate, nState(iRow, :).'), 1);
      allOk = allOk & isequal(sumR,r);
   end
end

function b = de2bi(d, n)
d = d(:);
[~, e] = log2(max(d));
b = rem(floor(d * pow2(1-max(n, e):0)), 2);
end
函数输出=getallstate()
全局nState%存储所有可能的向量
全局nStateRow%存储向量的当前行
全局statebin%存储所有可能状态的二进制表示
nState=[];
nStateRow=1;
nBin=2;%列数或B
v=[12];%尺寸应始终为1 x N英寸
N=3;%件数
statebin=de2bi(0:(2^nBin-1),nBin)=1;%作为逻辑存储,因为我以后使用它来索引
getnstate(v,2^nBin-1,nBin)%main函数
即使其中一个结果不正确,checkresult(v、nState、nBin)%也将导致false
%调整最大单位数,因为每行的总数不能超过此数字。
输出=nState(1:end-1:);%最后一行总是重复(需要以某种方式修复)
输出(:,1)=N-和(输出(:,2:end),2);%第一列,即“全部0”状态下的单位数始终由其他状态下的单位数确定
如果有(输出(:,1)<0)
输出(输出(:,1)<0,:)=[];
结束
结束
函数getnstate(r、state、nBin)
全球nState
全球nStateRow
全局statebin
如果state==0
如果全部(r==0)
nStateRow=nStateRow+1;
nState(nStateRow,:)=nState(nStateRow-1,:);
结束
其他的
对于a=0:min(r(statebin(state+1,:))
nState(nStateRow,state+1)=a;
getnstate(r-a*statebin(state+1,:),state-1,nBin);
结束
结束
结束
函数allOk=检查结果(r、nState、nBin)
%只是一个函数,用于检查获得的向量是否都得到正确的和
allstate=de2bi(0:(2^nBin-1),nBin);
allOk=真;
对于iRow=1:大小(nState,1)
sumR=sum(bsxfun(@times,allstate,nState(iRow,:))),1);
allOk=allOk&isequal(sumR,r);
结束
结束
函数b=de2bi(d,n)
d=d(:);
[~,e]=log2(max(d));
b=rem(地面(d*pow2(1-最大值(n,e):0)),2);
结束
上面的代码工作正常,并给出了所有可能的状态,但正如预期的那样,随着列数(B)和单元数(N)的增加,速度会变慢。此外,它还使用globals。以下是我的问题:

  • 有没有一种方法可以在不使用全局变量的情况下生成这些值
  • 这个算法有非递归的方法吗
  • 编辑1

  • 在何种情况下,上述系统仍然具有比当前版本更快的优化算法
  • 编辑2


    添加了
    de2bi
    函数以删除对
    通信工具箱的依赖关系

    您是否对该问题执行了“大O”分析?似乎越大的
    N
    B
    ,要筛选的组合数量显著增加,可能呈指数级增长——因此,较大输入的放缓似乎是不可避免的。两个问题的答案都是“是”。使用动态规划应该可以节省大量时间。检查和@Dev iL的答案我知道对于较大的
    N
    B
    ,任何算法都需要更长的时间,但是对于像
    N=1
    B=3
    这样的小值,这个算法也需要很长的时间。我还添加了一个新问题,这实际上是我想要的。另外,谢谢您的编辑。@obchardon谢谢,我会检查它的。您已经有一些解决方案来检查代码了吗?