我需要在MATLAB中生成一些5x6矩阵。它们需要由1-6范围内的随机生成的整数组成,但是,在特定的行或列中,整数不能出现多次。
以下是我目前用于生成随机5x6矩阵的脚本:
mat=zeros(5,6);
rows=5;
columns=6;
for i=1:rows
for j=1:columns
mat(i,j)=round(rand*(high-low)+low);
end
end
disp(mat)
但我不知道如何将关于重复的规则插入到此中。
我确信这是一个相对简单的问题,但我对MATLAB很新,并且无法生成满足这些条件的东西。我会很乐意为任何人提供帮助。
答案 0 :(得分:4)
试试这个:
m = zeros(5,6);
for row = 1:5
flag = 1;
while(flag)
flag = 0;
R = randperm(6);
for testRow = 1:row
flag = flag + sum(m(testRow,:) == R);
end;
if (~flag)
m(row,:) = R;
end;
end;
end;
m
答案 1 :(得分:3)
不要试图一次完全随机地填充矩阵。作为有效拼图网格的可能性非常低。
相反,use the same method as used by Sudoku generators - 以空白矩阵开头,并按规则限制一次填写一个元素。
如果您对该条目有多个选择,请随机选择其中一个。
你可能会进步这样的事情(简洁的4x4例子 - 允许的数字1-4)
x x x x
x x x x
x x x x
x x x x
用骰子掷骰子选择第一个数字:3。
3 x x x
x x x x
x x x x
x x x x
从允许数字列表中选择第二个数字:[1,2,4]。
3 1 x x
x x x x
x x x x
x x x x
从允许数字列表中选择第三个数字,[1,4]:
3 1 4 x
x x x x
x x x x
x x x x
等等。
如果某个插入步骤中的“允许号码列表”为空集,则无法挽救您的矩阵,您可能需要重新开始。
另外一个10x10矩阵有5个唯一的整数显然是不可能的 - 插入一些逻辑来测试这个琐碎的错误情况。
编辑:因为它不是传统意义上的作业,因为这是一个有趣的问题......
function arena = generate_arena(num_rows, num_cols, num_symbols)
% Generate an "arena" by repeatedly calling generate_arena_try
% until it succeeds.
arena = 0;
number_of_tries = 0;
while ~(arena)
arena = generate_arena_try(num_rows, num_cols, num_symbols);
number_of_tries = number_of_tries + 1;
end
sprintf('Generating this matrix took %i tries.', number_of_tries)
end
function arena = generate_arena_try(num_rows, num_cols, num_symbols)
% Attempts to generate a num_rows by num_cols matrix of random integers
% from the range 1:num_symbols, with no symbols repeated in each row or
% column.
%
% returns 0 on failure, or the random matrix if it succeeds.
arena = zeros(num_rows, num_cols);
symbols = 1:num_symbols;
for n = 1:num_rows
for m = 1:num_cols
current_row = arena(n,:);
current_col = arena(:,m);
% find elements in $symbols that are not in the current row or col
choices = setdiff ( symbols, [current_row current_col'] );
if isempty(choices)
arena = 0;
return;
end
% Pick one of the valid choices at random.
arena(n,m) = choices(randi(length(choices)));
end
end
return;
end
调用和输出如下:
>> generate_arena(5,6,6)
ans =
Generating this matrix took 5 tries.
ans =
2 3 6 4 5 1
6 1 5 3 4 2
1 5 4 2 6 3
4 6 2 1 3 5
3 4 1 5 2 6
不要说我从来没有给你什么。 ;)
答案 2 :(得分:3)
这是另一种方法:
从一个已知的有效解决方案开始,比如说这个:
>> A = mod(meshgrid(1:size) - meshgrid(1:size)', size) + 1
A =
1 2 3 4 5 6
6 1 2 3 4 5
5 6 1 2 3 4
4 5 6 1 2 3
3 4 5 6 1 2
2 3 4 5 6 1
然后随机交换行和列。您可以证明每个交换在每行和每列中保留“无重复”属性。
假设您交换第1行和第2行。您没有更改行的内容,因此“每行中没有重复”属性保持为真。同样,您没有更改任何列的内容 - 只是排序 - 因此“每列中没有重复”属性也保持为真。
以下是我提出的建议:
function arena = gen_arena_2 (size)
arena = mod(meshgrid(1:size) - meshgrid(1:size)', size) + 1;
%repeatedly shuffle rows and columns
for i = 1:10
arena = arena(:,randperm(size))'; %shuffle columns and transpose
end
end
使用示例:
>> gen_arena_2(6)
ans =
3 5 4 2 1 6
6 2 1 5 4 3
5 1 6 4 3 2
4 6 5 3 2 1
1 3 2 6 5 4
2 4 3 1 6 5
我不确定这可能是“随机”的另一种方式 - 但这种方式很快,并且不需要任何逻辑来检测故障(因为它(可证明地)总是会产生正确的结果。 )