好吧,这可能看起来像一个奇怪的问题,但请耐心等待。
所以我在.m文件中有一个随机向量,内置了一些约束。这是我的代码:
randvecall = randsample(done, done, true);
randvec = randvecall([1;diff(randvecall(:))]~=0);
“完成”只是我们从中获取样本的值的范围,所以不要担心。正如您所看到的,这些样本来自一系列值,然后使用diff函数修剪此随机向量,以便删除连续的重复值。载体中仍有可能存在重复值,但它们根本不能连续。
这一切都很好,并且完美无缺。
所以,说,randvec看起来像这样:
randvec =
54
47
52
26
39
2
14
51
24
6
19
56
34
46
12
7
41
18
29
7
它实际上要长得多,有60-70个值,但你明白了。
我想要做的是为此向量添加一些额外的约束。当我从这个向量中采样时,这些值根据它们的范围进行分类。所以1-15的值是1类,16-30是2类,依此类推。造成这种情况的原因并不重要,但它是该计划中非常重要的一部分。因此,如果您查看我上面提供的值,您会看到如下所示的部分:
7
41
18
29
7
这实际上对我的程序不利。因为值范围是分开处理的,所以41,18和29的使用方式与7不同。因此,对于所有意图和目的,7在我的脚本中连续出现。我想要做的是以某种方式解析/修改/生成它时的任何向量,使得某个范围内的相同数字不能“连续”出现两次,无论它们之间有多少来自不同范围的其他数字。这是否有意义/我是否对此有所描述?因此,我希望MATLAB搜索向量,对于某些范围内的所有值(1-15,16-30,31-45,46-60),请确保来自相同范围的“连续”值不相同。 / p> 那么,那就是我想做的事情。这绝不是最好的方法,所以任何建议/替代方案当然都是值得赞赏的。我知道我可以使用多个向量更好地做到这一点,但由于各种原因,我需要将它作为单个长向量(我的脚本设计的方式如果我为每个值范围都有一个单独的向量,它将无法工作) 。
答案 0 :(得分:3)
你可能想要做的是创建四个随机向量,每个类别一个,确保它们不包含任何两个连续的相等值,然后通过从随机类别中有序选择值来构建最终的随机向量,即< / p>
%# make a 50-by-nCategories array of random numbers
categories = [1,16,31,46;15,30,45,60]; %# category min/max
nCategories = size(categories,2);
randomCategories = zeros(50,nCategories);
for c=1:nCategories
%# draw 100 numbers for good measure
tmp = randi(categories(:,c),[100 1]);
tmp(diff(tmp==0)) = []; %# remove consecutive duplicates
%# store
randomCategories(:,c) = tmp(1:50);
end
%# select from which bins to pick. Use half the numbers, so that we don't force the
%# numbers of entries per category to be exactly equal
bins = randi(nCategories,[100,1]);
%# combine the output, i.e. replace e.g. the numbers
%# '3' in 'bins' with the consecutive entries
%# from the third category
out = zeros(100,1);
for c = 1:nCategories
cIdx = find(bins==c);
out(cIdx) = randomCategories(1:length(cIdx),c);
end
答案 1 :(得分:2)
首先,我们为每个元素分配它所在范围的bin编号:
[~,bins] = histc(randvec, [1 16 31 46 61]);
接下来,我们循环每个范围,并找到这些类别中的元素。例如,对于1-16的第一个范围,我们得到:
>> ind = find(bins==1); %# bin#1 of 1-16
>> x = randvec(ind)
ans =
2
14
6
12
7
7
现在您可以应用删除连续重复项的相同过程:
>> idx = ([1;diff(x)] == 0)
idx =
0
0
0
0
0
1
>> problematicIndices = ind(idx) %# indices into the vector: randvec
对所有范围执行此操作,并收集有问题的索引。接下来决定你想如何处理它们(删除它们,在它们的位置生成其他数字等等)
答案 2 :(得分:1)
如果我理解你的问题是正确的,我认为这是一个解决方案。它使用唯一,但将其应用于向量的每个子范围。识别出在一系列索引中重复的值,以便您可以处理它们。
cat_inds = [1,16,31,46,60]; % need to include last element
for i=2:numel(cat_inds)
randvec_part = randvec( cat_inds(i-1):cat_inds(i) );
% Find the indices for the first unique elements in this part of the array
[~,uniqInds] = unique(randvec_part,'first');
% this binary vector identifies the indices that are duplicated in
% this part of randvec
%
% NB: they are indices into randvec_part
%
inds_of_duplicates = ~ismember(1:numel(randvec_part), uniqInds);
% code to deal with the problem indices goes here. Modify randvec_part accordingly...
% Write it back to the original vector (assumes that the length is the same)
randvec( cat_inds(i-1):cat_inds(i) ) = randvec_part;
end
答案 3 :(得分:1)
这是一种与其他人一直折腾的方法不同的方法。我在这里工作的前提是你希望在一个向量中随机排列值,而不需要重复。在我们给出输入之前,我不确定您正在应用的其他约束。
我的想法是使用randperm函数。
以下是一些示例代码如何工作:
%randvec is your vector of random values
randvec2 = unique(randvec); % This will return the sorted list of values from randvec.
randomizedvector = randvec2(randperm(length(randvec2));
% Note: if randvec is multidimensional you'll have to use numel instead of length
此时randomizedvector
应该包含初始randvec
中的所有唯一值,但在独特函数调用后进行'混洗'或重新随机化。现在你可以不同地为randvec播种,以避免需要唯一的函数调用,只需调用randperm(n)
将返回一个值为1到n的随机向量。
离开墙壁2美分= P享受!