TL; DR :我需要找到N
行向量(大小为1xB
)的所有可能组合,其行总和产生所需的结果向量(尺寸为1xB
)。
对于矩阵,我知道矩阵各行的总和,例如{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
添加了de2bi
函数以消除对Communications Toolbox
的依赖。