我正在尝试创建一个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)
非常感谢你的帮助!
答案 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}}