【问题标题】:Shuffle a vector of repeated numbers so the numbers do not repeat in MATLAB打乱重复数字的向量,使数字在 MATLAB 中不重复
【发布时间】:2015-04-27 00:31:42
【问题描述】:

好的,所以我有一个脚本,它将生成我的某个间隔的重复整数向量,但现在有一个特定的实例,我需要确保一旦它被洗牌,数字不会重复。因此,例如,我生成了一个重复 1-5、36 次的向量,经过洗牌。如何确保洗牌后没有重复的数字?为了让事情变得更加复杂,我需要生成两个这样的向量,它们在同一索引处永远不会具有相同的值。例如,假设这些向量重复了两次 1:5,那么这就是我要寻找的:

v1     v2
4      2
2      4
3      2
5      3
4      5
1      4
5      1
1      5
3      1
2      3

我现在通过以 1 个向量为例,然后将其移开 1 以创建另一个满足要求的向量,但在我的情况下,这实际上行不通,因为我不能让它们系统化像那样依赖。

所以我尝试了一种递归技术,如果向量没有进行剪切,并且正如预期的那样,脚本并没有顺利进行,那么我就可以让脚本重新开始。我达到了最大的递归迭代,我意识到这显然不是要走的路。还有其他选择吗?

编辑:

所以我在下面的代码中找到了一种方法来满足我上面需要的一些条件:

a = nchoosek(1:5,2);
b = horzcat(a(:,2),a(:,1));
c = vertcat(a,b);

cols = repmat(c,9,1);
cols = cols(randperm(180),:);

我只需要找到一种方法来打乱 cols 也将强制列中没有重复数字,例如 cols(i,1) ~= cols(i+1,1) 和 cols(i,2) ~=列(i+1,2)

【问题讨论】:

标签: matlab vector numbers repeat


【解决方案1】:

这可行,但对于大型数组可能不是很有效:

a = nchoosek(1:5, 2);
while (any(a(1: end - 1, 1) == a(2: end, 1)) ...
    || any(a(1: end - 1, 2) == a(2: end, 2)))
    random_indices = randperm(size(a, 1));
    a = a(random_indices, :);
end
a

如果您想要更快的速度,诀窍是将每一行按逻辑插入到满足您的条件的位置,而不是随机重新排列。例如:

n1 = 5;
n2 = 9;

a = nchoosek(1:n1, 2);
b = horzcat(a(:,2), a(:,1));
c = vertcat(a, b);
d = repmat(c, n2, 1);
d = d(randperm(n1 * n2), :);

% Perform an "insertion shuffle"
for k = 2: n1 * n2

    % Grab row k from array d.  Walk down the rows until a position is
    % found where row k does not repeat with its upstairs or downstairs
    % neighbors.
    m = 1;
    while (any(d(k,:) == d(m,:)) || any(d(k,:) == d(m+1,:)))
        m = m + 1;
    end

    % Insert row k in the proper position.
    if (m < k)
        ind = [ 1: m  k  m+1: k-1   k+1: n1 * n2 ];
    else
        ind = [ 1: k-1   k+1: m  k  m+1: n1 * n2 ];
    end

    d = d(ind,:);
end
d

【讨论】:

  • 是的!!!太感谢了!这非常有效。我只是在考虑以这样一种方式来解决这个问题,即我可以从我需要的数字中抽样而无需替换,然后在将其放入最终产品之前以某种方式应用约束。非常感谢!
【解决方案2】:

解决这个问题的一种方法是认为两个向量的创建方式如下:

对于数组 v1 和 v2 的每一行

  • 洗牌数组[1 2 3 4 5]
  • 将当前行的 v1 和 v2 的值设置为 shuffle 的第一个和第二个值。这两个值总是不同的。

代码:

s = [1 2 3 4 5];
Nrows = 36;
solution = zeros(Nrows,2);
for k=1:Nrows
   % obtain indexes j for shuffling array s
   [x,j] = sort(rand(1,5));
   %row k takes the first two values of shuffled array s
   solution(k,1:2) = s(j(1:2));
end
v1 = solution(:,1);
v2 = solution(:,2);

主要编辑:随机 => rand,

使用这种方法不会浪费时间重新滚动重复的数字,因为 shuffle [1 2 3 4 5] 的第一个和第二个值总是不同的。 如果您需要两个以上具有不同数字的数组,则更改很简单。

【讨论】:

    猜你喜欢
    • 2014-07-03
    • 1970-01-01
    • 1970-01-01
    • 2016-12-07
    • 2012-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多