如何通过行列和对角线的总和来约束矩阵

时间:2017-09-20 00:06:03

标签: matlab

我正在尝试创建一个NxN矩阵,随机将N个零变为1。

N=4;
board=zeros(N);
board(randperm(numel(board), N))=1;
while i = find(sum(board) > 1)
  board(randperm(numel(board), N))=1;
end
while i = find(sum(board,2) > 1)
    board(randperm(numel(board), N))=1;
end
while t= sum(diag(board) > 1)
    board(randperm(numel(board), N))=1;
end

board

我的前三行代码完成了预期的工作。它随机将N个“0”变为“1”。但是现在我试图设置限制,使得每行,每列和对角线只能有一个“1”。我的逻辑是矩阵应该首先确保没有单个列可以求和大于1。我希望这个展示位置受到限制。接下来我希望矩阵确保没有单个行可以求和大于1。除了第一个约束之外,这将是第二个约束。最后,矩阵应确保没有对角线可以求和大于1。

目标是NxN矩阵,其具有N个“1”,每列,行和对角线中只有一个“1”。我的代码是否在正确的轨道上?

编辑:

while (sum(board) > 1)
  board(randperm(numel(board), N))=1;
end

如果我从列开始,这将给我一个输出。但是,我怎样才能看到每个列的总和,以便它知道继续寻找解决方案?

编辑2:

prompt = 'Please input number of queens: ';
N = input(prompt);
board=zeros(N);
board(randperm(numel(board), N))=1;
while any(sum(board) > 1) || any(sum(board,2) > 1) || any(sum(spdiags(board)) > 1)
    board = zeros(N); 
    board(randperm(numel(board), N))=1;
end

for index = 1:numel(board)
    if board(index) == 0
        board(index) = 8;
    end
end


board

if sum(board(:)==1) == N
    disp('Solution!')
else
    disp('Failed solution!')
end

我添加了一些额外的好东西。我理解为什么应该添加一个休息时间(我明白为什么我这样做的方式效率很低)但是我只需要上升到N = 8所以我决定将它删除。唯一不起作用的部分是我的对角线

最终编辑: 我懂了!

||any(sum(spdiags(board))>1)||any(sum(spdiags(rot90(board)))>1)

非常感谢你的帮助!

1 个答案:

答案 0 :(得分:0)

由于您似乎正在尝试将此作为学习示例,我不会向您提供完整的答案。这应该足以帮助你了解你的路。如果您想让我详细说明,请告诉我。

我修复了小错误并添加了一个休息时间。剩下要做的是修改while条件以包括行和对角线和。对于此查找或语句(N=4; board=zeros(N); board(randperm(numel(board), N))=1; nIter = 1; while any(sum(board) > 1) board = zeros(N); % Make sure to reset the board, otherwise it'll become a matrix of ones! board(randperm(numel(board), N))=1; nIter = nIter + 1; % Keep track of the amount of iterations. If it becomes too much just end the loop. if nIter > 1000 warning('Exceeded iteration threshold') break end end board )。请注意,随着N的大小增加,这种方法将变得非常低效,因此内置中断是明智的。

{{1}}