在上对角线元素上生成具有条件的随机方阵

时间:2016-08-04 09:20:24

标签: matlab matrix random

我想在MATLAB中生成一个方形随机矩阵,其上对角线具有相等数量的元素,小于0.5且大于0.5。我想保持所有对角线元素等于零并且具有与上述对角线(上三角形)元素相同的对角线下方(下三角形)。所以预期的输出可能如下所示

  0 a1 a2 a3
  a1 0 a4 a5
  a2 a4 0 a6
  a3 a5 a6 0

其中ai是在(0,0.5)和(0.5,1)之间平均分配的随机数。

3 个答案:

答案 0 :(得分:0)

req=zeros(n);    %initializing a matrix of size nxn

%finding the indexes of upper diagonal elements
Up_tri_ind = find(triu(true(size(req)), 1));

%finding the number of upper diagonal elements
temp=length(Up_tri_ind);

%Filling first half of the indexes with values less than 0.5 
%and the other half with greater than 0.5
req(Up_tri_ind(1:temp/2))= 0.5*rand(1,temp/2);
req(Up_tri_ind(temp/2+1:end))= 0.5+0.5*rand(1,temp/2);

%Replacing the same elements in the lower diagonal
req=req+req.';

请注意,只有当上对角线或下对角线中的元素数量为偶数时,才能实现这一点,因为偶数的一半也是整数,而奇数的一半则不是整数。

因此,只有当 n 属于以下系列时才有可能:
4,5,8,9,12,13,16,17,....

答案 1 :(得分:0)

可以生成2组同样大的随机数(0,0.5)和(0.5,1)并将它们加密到矩阵中。

function test()
upperMatrix = triu(ones(4),1);
r0 = 0.5*rand(3,1); % smaller set
r1 = 0.5*rand(3,1)+0.5; % larger set
rfull = [r0;r1] % full set
permutation = randperm(6) % generate a scrambled vector of random number 1:6

upperMatrix(upperMatrix == 1) = rfull(permutation) % insert values to upper matrix
upperMatrix = upperMatrix + upperMatrix.' % make the matrix symmetric.

请注意,我假设存在偶数个唯一的非零元素。这就是问题公式中所述的内容,如果您需要其他东西,则需要应用特殊情况。例如,可以将最后一个元素设置为0.5,或者添加额外的(0.5,1)数字或额外的(0,0.5)数字或其他您可以提供的其他元素并为您工作。

答案 2 :(得分:0)

你写道,你想要“在对角线下方(下三角形)[元素与上面的对角线(上三角形)元素相同)。”将来你可以说你想要一个矩阵是“对称的”,这很清楚。

我写了一些代码,我认为这些代码可以用于您的目的:

function mat = generate_matrix( n )

% "n" is the number of rows / columns the output named "mat" will have.

sml_val_min = 0;
sml_val_max = 0.5;
big_val_min = 0.5;
big_val_max = 1;

% The number of elements in the upper triangular portion of the matrix can be
% represented by an Arithmetic Series.
% There is a row with one element, then a row with 2 elements, then a row
% with 3, on up to a row with n - 1 elements.
% So, there are 1 + 2 + ... + n-1 = (n-1)*n/2 elements in total. 

numel_in_up_tri_portion = (n-1)*n/2;

% determine how many distinct small values we need to generate and how many large values
numel_sml = floor(numel_in_up_tri_portion/2);
numel_big = ceil(numel_in_up_tri_portion/2);

% Generate small values and large values
sml_vals = (sml_val_max - sml_val_min).*rand(1, numel_sml) + sml_val_min;
big_vals = (big_val_max - big_val_min).*rand(1, numel_big) + big_val_min;

% decide where in the matrix small values will go and where large values will go
sml_val_locations = randsample(numel_in_up_tri_portion, numel_sml);
big_val_locations = setdiff(1:numel_in_up_tri_portion, sml_val_locations);

% 
[rs, cs] = convert_linear_index_to_row_and_col( sml_val_locations );
[rb, cb] = convert_linear_index_to_row_and_col( big_val_locations );

mat = zeros(n);
for k = 1:numel_sml
    mat(rs(k), cs(k)) = sml_vals(k);
end
for k = 1:numel_big
    mat(rb(k), cb(k)) = big_vals(k);
end

mat = mat + mat';

end % of function definition  


function [row, col] = convert_linear_index_to_row_and_col( lin_ind )

unity = ones(size(lin_ind)); 

% Solve the quadratic equation (row^2 - row)/2 = lin_ind
row = ceil(0.5 * (unity + (unity + 8*lin_ind).^0.5));

%
col = lin_ind - 0.5*(row - unity).*(row - 2*unity);

end % of function definition