优化算法,在每个二进制状态下生成单位数

时间:2019-06-12 05:57:21

标签: matlab performance sum combinatorics binary-data

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


我有一个大小为N x B的二进制矩阵(仅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}。基本上是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

上面的代码可以正常工作并给出所有可能的状态,但是,正如您所期望的,随着列数(B)和单位数(N)的增加,它会变慢。此外,它使用全局变量。以下是我的问题:

  1. 有没有一种方法可以在不使用全局变量的情况下生成它们?
  2. 此算法是否有非递归方法?

编辑1

  1. 以上哪种方式仍然可以提供比当前版本更快的优化算法?

编辑2

添加了de2bi函数以消除对Communications Toolbox的依赖。

0 个答案:

没有答案