如何重新排列数字列表,以便每N个数字都不重复?

时间:2014-02-04 03:12:20

标签: matlab sorting

所以我有一个190个数字的列表,范围从1:19(每个数字重复10次),我需要一次采样10个。在每个10的样本中,我不希望数字重复,我尝试合并一个while循环,但计算时间太长了。到目前为止,我正处于可以生成数字并查看每个子集中是否存在重复的位置。有什么想法吗?

        N=[];
        for i=1:10
            N=[N randperm(19)];
        end
        B=[];
        for j=1:10
            if length(unique(N(j*10-9:j*10)))<10
               B=[B 1];
            end
        end
        sum(B)

以下是代码的更新版本。这可能会更清楚地显示我想要的东西。 (19个目标一次10个,不重复,直到所有19个目标重复10次)

nTargs = 19;
pairs = nchoosek(1:nTargs, 10);
nPairs = size(pairs, 1);
order = randperm(nPairs);
values=randsample(order,19);
targs=pairs(values,:);
Alltargs=false;
while ~Alltargs
    targs=pairs(randsample(order,19),:);
    B=[];
    for i=1:19
    G=length(find(targs==i))==10;
    B=[B G];
    end
    if sum(B)==19
        Alltargs=true;
    end
end

4 个答案:

答案 0 :(得分:2)

以下是执行此操作的一些非常简单的步骤,基本上您只需将矢量洗牌一次,然后获取最后10个唯一值:

v = repmat(1:19,1,10);

v = v(randperm(numel(v)));

[a idx]=unique(v);
result = unique(v);
v(idx)=[];

算法应该相当有效,如果你想做下一个10,只需再次运行最后一部分并将result组合成totalResult

答案 1 :(得分:1)

你想以10块为单位随机抽取数字1:19而不重复。 Matlab函数'randsample'有一个可选的'replacement'参数,如果你不想重复,可以设置为'false'。例如:

N = [];
replacement = false; 
for i = 1:19
N = [N randsample(19,10,replacement)];
end

这会在[1,..,19]范围内生成一个19 x 10的随机整数矩阵,而不会在每列中重复。

编辑:这是一个解决方案,解决了每个整数[1,..,19]正好出现10次的要求,此外每个列/样本中没有重复:< / p>

nRange = 19; nRep = 10; 
valueRep = true; % true while there are repetitions 
nLoops = 0; % count the number of iterations
while valueRep
    l   = zeros(1,nRep); 
    v = []; 
    for m = 1:nRep
    v  = [v, randperm(nRange,nRange)]; 
    end
    m1  = reshape(v,nRep,nRange); 
    for n = 1:nRep
     l(n) = length(unique(m1(:,n))); 
    end
    if all(l == nRep)
    valueRep = false; 
    end
nLoops = nLoops + 1; 
end
result = m1; 

对于问题中的参数,需要大约300次迭代才能找到结果。

答案 2 :(得分:0)

我认为你应该建设性地接触

  1. 通过重新排列系列1:19:series1 = repmat(1:19,1,10);rearranged= reshape(series1,10,19)
  2. ,最初可以轻松找到满足您条件的19个群组
  3. 然后洗牌
    1. 我会选择两个随机列复制它们并在两个随机位置切换值
    2. 然后进行测试,如果它符合您的条件 - 例如:test = @(x) numel(unique(x))==10 - 如果是,则替换您的列
    3. 只是随时待命,直到你的时间用光或你很开心
  4. 当然,您可能会提出更有效的改组或测试

答案 3 :(得分:0)

我通过MATLAB论坛获得了另一个解决方案,该解决方案非常有效(在MATLAB论坛上感谢Niklas Nylen)。计算时间也很低。它基本上将数字混洗,直到每10个值内没有重复。谢谢大家的帮助。

 y = repmat(1:19,1,10);
 % Run enough iterations to get the output random enough, I selected 100000
 for ii = 1:100000
     % Select random index
     index = randi(length(y)-1);
     % Check if it is allowed to switch places
     if y(index)~=y(min(index+10, length(y))) && y(index+1)~=y(max(1,index-9))
         % Make the switch
         yTmp = y(index);
         y(index)=y(index+1);
         y(index+1)=yTmp;
     end
 end