MatLAB帮助:在不连续重复数字的情况下洗牌预定义向量(所有值的出现次数相等)

MatLAB帮助:在不连续重复数字的情况下洗牌预定义向量(所有值的出现次数相等),matlab,random,octave,shuffle,Matlab,Random,Octave,Shuffle,假设每个值都是相等重复的,我在随机洗牌一个向量而不重复数字时遇到了麻烦(例如,1 1是不可接受的,但1 2是可接受的) 更具体地说,我想将矩阵[1:4]重复十次(总共40个元素),这样1、2、3和4都会重复十次,而不是连续的 如果需要任何澄清,请让我知道,我希望这个问题是明确的 这就是我到目前为止所做的: cond_order = repmat([1:4],10,1); %make matrix cond_order = cond_order(:); %make sequence 我知道ran

假设每个值都是相等重复的,我在随机洗牌一个向量而不重复数字时遇到了麻烦(例如,1 1是不可接受的,但1 2是可接受的)

更具体地说,我想将矩阵
[1:4]
重复十次(总共40个元素),这样1、2、3和4都会重复十次,而不是连续的

如果需要任何澄清,请让我知道,我希望这个问题是明确的

这就是我到目前为止所做的:

cond_order = repmat([1:4],10,1); %make matrix
cond_order = cond_order(:); %make sequence
我知道randperm非常相关,但我不确定如何在不重复数字的条件下使用它

编辑:谢谢你的回复

  • 我意识到我很不清楚。这些是我想拒绝的示例
    [1 1 2 4 4 4…]
    。 因此,只要单个值不重复,
    [1 2 3 4]
    是否按该顺序出现并不重要。(因此
    [1 2 3 4 1 2 3 4…]
    [4 3 1 2…]
    都是可以接受的)

  • 最好我正在寻找一个洗牌向量满足的标准

  • 这是随机的
  • 没有连续重复的值(例如1 4)
  • 所有四个值显示的次数相等

  • 在这里进行了一些讨论之后,我认为在性能和应用程序的理论要求之间需要进行权衡

    如果需要从所有有效排列的集合中完全均匀地抽取,则可能需要纯拒绝抽样方法。当然,问题是,随着问题规模的扩大,拒绝率将变得非常高。为了证明这一点,如果我们考虑问题的基本例子是<代码>(1 2×3 4)< /代码>的N倍数,那么我们可以看到每个有效绘图拒绝的样本数如下(注意log y轴):

    我的替代方法是对数组进行随机排序,然后如果检测到重复项,则剩余元素将再次进行随机排序:

    cond_order = repmat(1:4,10,1); %make matrix
    cond_order = reshape(cond_order, numel(cond_order), 1);
    
    cond_order = cond_order(randperm(numel(cond_order)));
    
    i = 2;
    
    while i < numel(cond_order)
        if cond_order(i) ~= cond_order(i - 1)
            i = i + 1;
        else
            tmp = cond_order(i:end);
            cond_order(i:end) = tmp(randperm(numel(tmp)));
        end
    end
    
    cond_order
    
    cond_order=repmat(1:4,10,1);%制作矩阵
    cond_顺序=重塑(cond_顺序,numel(cond_顺序),1);
    cond_order=cond_order(randperm(numel,cond_order));
    i=2;
    而我<努梅尔(第二顺序)
    如果第二阶(i)~=第二阶(i-1)
    i=i+1;
    其他的
    tmp=第二顺序(i:结束);
    第二顺序(i:end)=tmp(randperm(numel(tmp));
    终止
    终止
    续单
    
    注意,不能保证这会收敛,但是如果很明显它不会收敛,我们可以重新开始,重新计算整个序列会更好

    这绝对符合问题的后两项要求:

    B) 没有连续的值

    C) 所有4个值显示的次数相等

    问题是它是否符合第一个“随机”要求

    如果我们采用问题的最简单版本,输入
    [1 2 3 4 1 2 3 4]
    则有864个有效排列(根据经验确定!)。如果我们运行这两种方法超过100000次,那么我们预计每个排列的高斯分布大约为115.7次

    正如预期的那样,纯拒绝采样方法给出了以下结果:

    但是,我的算法没有:

    显然对某些样品存在偏见


    最后,这取决于需求。这两种方法都对整个分布进行抽样,因此都满足了问题的核心需求。我没有包括性能比较,但对于最简单的情况以外的任何情况,我相信我的算法会快得多。然而,图纸的分布并不完全均匀。它是否足够好取决于应用程序和实际问题的大小。

    在这里进行了一些讨论之后,我认为在性能和应用程序的理论要求之间存在着权衡

    如果需要从所有有效排列的集合中完全均匀地抽取,则可能需要纯拒绝抽样方法。当然,问题是,随着问题规模的扩大,拒绝率将变得非常高。为了证明这一点,如果我们考虑问题的基本例子是<代码>(1 2×3 4)< /代码>的N倍数,那么我们可以看到每个有效绘图拒绝的样本数如下(注意log y轴):

    我的替代方法是对数组进行随机排序,然后如果检测到重复项,则剩余元素将再次进行随机排序:

    cond_order = repmat(1:4,10,1); %make matrix
    cond_order = reshape(cond_order, numel(cond_order), 1);
    
    cond_order = cond_order(randperm(numel(cond_order)));
    
    i = 2;
    
    while i < numel(cond_order)
        if cond_order(i) ~= cond_order(i - 1)
            i = i + 1;
        else
            tmp = cond_order(i:end);
            cond_order(i:end) = tmp(randperm(numel(tmp)));
        end
    end
    
    cond_order
    
    cond_order=repmat(1:4,10,1);%制作矩阵
    cond_顺序=重塑(cond_顺序,numel(cond_顺序),1);
    cond_order=cond_order(randperm(numel,cond_order));
    i=2;
    而我<努梅尔(第二顺序)
    如果第二阶(i)~=第二阶(i-1)
    i=i+1;
    其他的
    tmp=第二顺序(i:结束);
    第二顺序(i:end)=tmp(randperm(numel(tmp));
    终止
    终止
    续单
    
    注意,不能保证这会收敛,但是如果很明显它不会收敛,我们可以重新开始,重新计算整个序列会更好

    这绝对符合问题的后两项要求:

    B) 没有连续的值

    C) 所有4个值显示的次数相等

    问题是它是否符合第一个“随机”要求

    如果我们采用问题的最简单版本,输入
    [1 2 3 4 1 2 3 4]
    则有864个有效排列(根据经验确定!)。如果我们运行这两种方法超过100000次,那么我们预计每个排列的高斯分布大约为115.7次

    正如预期的那样,纯拒绝采样方法给出了以下结果:

    但是,我的算法没有:

    T
    n=4;
    k=10;
    d=42; %// random number to fail first check
    while(~all(sum(bsxfun(@eq,d,(1:n).'),2)==k)) %' //Check all numbers to appear k times.
        d=mod(cumsum([randi(n,1,1),randi(n-1,1,(n*k)-1)]),n)+1; %generate new random sample, enforcing a difference of at least 1.
    end