问题描述
设一个阶对称矩阵
的所有元素要么为0要么为1。
是一个长度为
的向量,且
的第
个元素等于
矩阵第
行的所有元素之和。
现给出一个向量 ,需要找到一个满足
的约束的对称0-1阵
。
本文提供一个matlab程序,可基于给定的向量(程序中记作'vec')找到一个符合条件的矩阵。并且进一步的讨论似乎可以证明,该程序依据的“对角保守”算法找到解是这类问题的基本解。对于任何一个有意义的vec,都至少可以通过该算法找到一个这样的基本解。
MATLAB求解程序
clear,clc
N = 10;
A = genA(N);
vec = sum(A,2);
disp(vec)
res = constructAFromVec(vec);
function res = genA(N)
% 生成一个随机的 N x N 矩阵,元素是 0 或 1
A = randi([0, 1], N, N);
% 使矩阵对称:A = (A + A') / 2
res = triu(A) + triu(A, 1).'; % triu 提取上三角部分,A' 是转置
% 显示结果
disp(res);
end
function res = constructAFromVec(vec)
N = numel(vec);
diagUsed = zeros(1,N);
checked = [];
info = zeros(N);
n = 1;
while(1)
[requiredNum,maxPos] = max(vec);
notZeroNum = numel(find(vec>0));
if(requiredNum==notZeroNum)
diagUsed(maxPos) = 1;
vec(maxPos) = vec(maxPos)-1;
requiredNum = requiredNum - 1;
elseif(requiredNum>notZeroNum)
error("无解")
end
vec(maxPos) = 0;
if(sum(vec)==0)
break
end
checked(end+1) = maxPos;
[~, sortedIdx] = sort(vec, 'descend');
donors = sortedIdx(1:requiredNum);
info(n,donors) = 1;
vec(donors) = vec(donors)-1;
n = n+1;
end
info(n:end,:) = []; %删除没用到的行
res = zeros(N);
[n_rows,~] = size(info);
for p = 1:n_rows
% idx = n_rows-p+1;
row = checked(p);
col = info(p,:)>0;
res(row,col) = 1; % res(row,col) = 1
end
res = res + res.';
res = res + diag(diagUsed);
end