矩阵1,2,3我怎么能产生?

时间:2013-10-25 21:47:41

标签: matlab random matrix

我想控制在这个矩阵中创建随机数:

Mp = floor(1+(10*rand(2,20)));
mp1 = sort(Mp,2);

我想修改此代码以获得如下输出:

1 1 2 2 3 3 3 4 5 5 6 7 7 8 9 9 10 10 10 10
1 2 3 3 3 3 3 3 4 5 6 6 6 6 7 8 9  9  9  10 

我必须以递增的顺序填充每一行的所有数字从1到10,并且计算每个数字出现次数的第二个矩阵应该是这样的:

1 2 1 2 1 2 3 1 1 2 1 1 2 1 1 2 1 2 3 4
1 1 1 2 3 4 5 6 1 1 1 2 3 4 1 1 1 2 3 1

和我上周以来一直在寻找的最棘手的矩阵是第三个矩阵,它应该浏览第一个矩阵的每一行,并返回每个数字的出现次数和最后一次出现的位置。这是代码应该如何工作的一个例子。此示例显示了在遍历第一个矩阵的第一行之后的预期结果。

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 (positions)
1     2    
2         2
3               3
4                  1
5                      2              
6                         1
7                               2                    
8                                  1
9                                        2
10                                                    4

(数)

此示例显示了在遍历第一个矩阵的第二行之后的预期结果。

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 (positions)
1   1 2    
2     1   2
3               3 6
4                  1 1
5                      3              
6                         1         4
7                               2      1              
8                                  1     1
9                                        2         3
10                                                    4

(数)

所以想要的矩阵必须从头开始用零填充,每次在遍历第一个矩阵的每一行之后,我们将新结果添加到前一个...

3 个答案:

答案 0 :(得分:0)

我相信以下代码会执行您要求的所有内容。如果我不明白,你需要更清楚地提出你的问题......

注意 - 我硬编码了一些值/大小。在“真实代码”中,你显然永远不会这样做。

% the bit of code that generates and sorts the initial matrix:
Mp = floor(1+(10*rand(2,20)));
mp1 = sort(Mp, 2);
clc
disp(mp1)

occCount = zeros(size(mp1));

for ii = 1:size(mp1,1)
    for jj = 1:size(mp1,2)
        if (jj == 1)
            occCount(ii,jj) = 1;
        else
            if (mp1(ii,jj) == mp1(ii,jj-1))
                occCount(ii,jj) = occCount(ii, jj-1) + 1;
            else
                occCount(ii,jj) = 1;
            end
        end
    end
end

% this is the second matrix you asked for
disp(occCount)

% now the third:
big = zeros(10, 20);
for ii = 1:size(mp1,1)
    for jj = 1:10
        f = find(mp1(ii,:) == jj); % index of all of them
        if numel(f) > 0
            last = f(end);
             n = numel(f);
             big(jj, last) = big(jj, last) + n;
        end
    end
end

disp(big)

请查看这确实是您的想法。

答案 1 :(得分:0)

我正在编辑上一个答案,以检查当mp1很大时它是否很快,显然它是:

N = 20000; M = 200; P = 100;
mp1 = sort([repmat(1:P, M, 1), ceil(P*rand(M,N-P))], 2);
tic
% Initialise output matrices
out1 = zeros(M, N); out2 = zeros(P, N);
for gg = 1:M
    % Frequencies of each row
    freqs(:, 1) = mp1(gg, [find(diff(mp1(gg, :))), end]);
    freqs(:, 2) = histc(mp1(gg, :), freqs(:, 1));
    cumfreqs = cumsum(freqs(:, 2));
    k = 1;
    for hh = 1:numel(freqs(:, 1))
      out1(gg, k:cumfreqs(hh)) = 1:freqs(hh, 2);
      out2(freqs(hh, 1), cumfreqs(hh)) = out2(freqs(hh, 1), cumfreqs(hh)) + freqs(hh, 2);
      k = cumfreqs(hh) + 1;
    end
end
toc

答案 2 :(得分:0)

以下代码通过单个循环解决了第二个和第三个矩阵生成问题。为清楚起见,第二个矩阵M2是示例中包含累积发生次数的2-by-20数组。第三个矩阵M3是示例中的大小为10-by-20的稀疏矩阵,其对每个唯一值的最后一次出现的数量和位置进行编码。代码仅循环遍历行,使用accumarray完成大部分工作。它被推广到mp1的任何大小和内容,只要首先对行进行排序。

% data
mp1 = [1 1 2 2 3 3 3 4 5 5 6 7 7 8 9 9 10 10 10 10;
       1 2 3 3 3 3 3 3 4 5 6 6 6 6 7 8 9  9  9  10]; % the example first matrix
nuniq = max(mp1(:));

% accumulate
M2 = zeros(size(mp1));
M3 = zeros(nuniq,size(mp1,2));

for ir=1:size(mp1,1),
    cumSums = accumarray(mp1(ir,:)',1:size(mp1,2),[],@numel,[],true)';
    segments = arrayfun(@(x)1:x,nonzeros(cumSums),'uni',false);
    M2(ir,:) = [segments{:}];
    countCoords = accumarray(mp1(ir,:)',1:size(mp1,2),[],@max,[],true);
    [ii,jj] = find(countCoords);
    nzinds = sub2ind(size(M3),ii,nonzeros(countCoords));
    M3(nzinds) = M3(nzinds) + nonzeros(cumSums);
end

我不会打印输出,因为它们对于答案来说有点大,而且代码可以按原样运行。

注意:对于新的测试数据,我建议使用命令Mp = randi(10,[2,20]); mp1 = sort(Mp,2);。或者根据您对user2875617的请求及其回复,确保所有号码都为mp1 = sort([repmat(1:10,2,1) randi(10,[2,10])],2);但不是真的随机...

编辑:代码修复错误。