对重复数字的向量进行洗牌,使这些数字不会在MATLAB中重复
好的,我有一个脚本,它将生成特定间隔的重复整数向量,但是现在有一个特殊的例子,我需要确保一旦它被洗牌,数字不会重复。例如,我产生了一个重复1-5次的向量,36次,洗牌。如何确保洗牌后没有重复的数字?为了让事情变得更复杂,我需要生成两个这样的向量,它们在同一个索引中没有相同的值。例如,假设1:5对这些向量重复了两次,那么这就是我要寻找的:对重复数字的向量进行洗牌,使这些数字不会在MATLAB中重复,matlab,vector,numbers,repeat,Matlab,Vector,Numbers,Repeat,好的,我有一个脚本,它将生成特定间隔的重复整数向量,但是现在有一个特殊的例子,我需要确保一旦它被洗牌,数字不会重复。例如,我产生了一个重复1-5次的向量,36次,洗牌。如何确保洗牌后没有重复的数字?为了让事情变得更复杂,我需要生成两个这样的向量,它们在同一个索引中没有相同的值。例如,假设1:5对这些向量重复了两次,那么这就是我要寻找的: v1 v2 4 2 2 4 3 2 5 3 4 5 1 4 5 1 1
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)~=cols(I+1,2)这是可行的,但对于大型数组来说可能不是很有效:
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
n1=5;
n2=9;
a=nchoosek(1:n1,2);
b=水平坐标(a(:,2),a(:,1));
c=垂直猫(a,b);
d=repmat(c,n2,1);
d=d(randperm(n1*n2),:);
%执行“插入洗牌”
对于k=2:n1*n2
%从数组d中获取行k。沿着行走,直到找到一个位置
%发现k行与其楼上或楼下不重复
%邻居。
m=1;
而(any(d(k,:)==d(m,:)| | any(d(k,:)==d(m+1,:))
m=m+1;
结束
%将k行插入正确的位置。
if(m
解决此问题的一种方法是将这两个向量都按如下方式创建:
对于数组v1和v2的每一行
- 洗牌数组
[1 2 3 4 5]
- 使用随机播放的第一个和第二个值设置当前行的v1和v2值。这两个值总是不同的
如果您需要两个以上具有不同数字的数组,更改很简单。您关心周期性吗?你能洗牌一个小数组,然后使用repmat吗?相关的(不是重复的)问题:是的!!!非常感谢你!这很有效。我只是想以这样一种方式来处理这个问题,我可以从我需要的数量中抽取w/o替换样本,然后在将其放入最终产品之前以某种方式应用约束条件。非常感谢!
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);