我有下面的代码,我被告知我需要使用不同的种子来生成我的随机数10次,然后平均那些以获得更平滑的图形。我没有太多使用Matlab的经验,因此即使阅读完文档后我也不太了解这些种子是如何工作的。
% Create an array
S = 0:20;
CW = 0:5:100;
S(1) = 0;
CW(1) = 0;
counter = 2; % Counter for the nuber of S
N = 20; % Number of nodes
% Collect data for each increment of 5 up to 100 for CW values
for i = 5:5:100
T = 10000 / i; % Total number of cycles
% Create array of next transmission times for N nodes
transmission_time = floor(i * rng(1, N));
total_success = 0;
% Loop for T cycles
for t = 1:T
% For 0 to the number of contention windows
for pos = 0:i-1
% Count the number of nodes that have the current CW
count = 0;
for node = 1:N
if transmission_time(node) == pos
count = count + 1;
end
end
% If there is more than 1, then a collision occurs
collision = false;
if count > 1
collision = true;
% If there is exactly 1, then there is a success
elseif count == 1
total_success = total_success + 1;
end
% If there is a collision, reassign new transmissions times
if collision == true
for node = 1:N
if node == pos
transmission_time(node) = floor(i * rand(1));
end
end
end
end
end
% Display the ratio of successes
S(counter) = total_success / (T * i);
counter = counter + 1;
end
% Plot the graph for Success vs CW
plot(CW, S, 'o-');
xlabel('Contention Window, CW');
ylabel('Throughput, S');
答案 0 :(得分:1)
来自matlab doc
频繁重新生成发电机并不能改善统计数据 输出的属性并不会使输出更随机 真正意义上的。重新启动MATLAB或重新启动时非常有用 在运行涉及随机数的大型计算之前。然而, 在会话中过于频繁地重新生成发电机并不是一件好事 想法,因为您的随机数的统计属性可以 受到不利影响。
您不需要在rand
使用不同的种子:每次运行时都不会生成相同的数字序列。例如
R = zeros(1e5,1);
for ii = 1:1e5
R(ii) = rand;
end
Rsorted = sort(R);
dRsorted = diff(Rsorted);
find(dRsorted == 0)
将返回并清空矩阵:rand
永远不会在100,000次连续调用中返回相同的随机数。
此外,在您的代码中,有一些错误。第transmission_time = floor(i * rng(1, N));
行应为transmission_time = floor(i * rand(1, N));
。
如果您想为每个周期使用不同的种子,您可以在第一次使用rand之前添加以下调用:rng(i);
。有了它,您将能够控制生成的随机数(rand
将产生可预测的数字序列)。
答案 1 :(得分:1)
确实如果你有某种模拟,用相同的随机数多次运行它是没用的。基本上有两种解决方案:
<强> 1。非常简单,不会产生可重复的结果
在代码开头,将rng
设置为基于now
的内容。
这样每次都会有不同的结果。
<强> 2。简单和推荐,可生成可重复的结果
如果你每次从模拟中得到不同的结果(从而允许你平均),那么你可以循环地模拟你的模拟,并且结果仍可以重现。
请注意,通常如果您想减少模拟的波动性,您不需要多次运行它,但可以让它运行更长时间。
答案 2 :(得分:1)
拥有单个流并简单生成10倍的数据样本似乎更为直接。但是,如果要并行提取,可以创建10个具有不同种子的随机流,例如,可以使用parfor
。如果您仍在寻找一种方法,我知道有两种记录良好的方法:
'mrg32k3a'
和'mlfg6331_64'
类型首先创建一个包含10个不同种子流的单元格数组的示例:
s = 0:9;
r = arrayfun(@(t)RandStream('mcg16807','Seed',t),s,'uni',false); % RandStreams
在s
中使用相同的种子将给出确定性模拟,它总是给出相同的结果。也就是说,
>> r = arrayfun(@(t)RandStream('mcg16807','Seed',t),s,'uni',false);
>> r{1}.rand
ans =
0.21895918632809
>> r{2}.rand
ans =
0.512908935785717
>> clear r
>> r = arrayfun(@(t)RandStream('mcg16807','Seed',t),s,'uni',false);
>> r{1}.rand
ans =
0.21895918632809
>> r{2}.rand
ans =
0.512908935785717
存储在单元格数组RandomStream
中的r
个实例具有以下常用方法:rand
,randn
,randi
和randperm
。 reset
方法将启动相同的随机数序列。
如果您不希望模拟具有确定性,但在某种意义上更随机,您可以通过未记录的 {{1}基于时间创建不同的种子向量s
方法:
shuffleSeed
并重新生成流。
子流尝试在随机数流中均匀分布种子(或#34;检查点&#34;)。然而,据称子流的真正好处只是简单的再现性。这似乎最简单,因为您只需创建一个流并在需要时切换到不同的流。例如,
s = zeros(1,10);
for i=1:numel(s), s(i)=RandStream.shuffleSeed; end
然后改变子流并获得更多样本:
>> stream = RandStream('mrg32k3a');
>> stream.get('Substream')
ans =
1
>> samps1 = stream.rand(1,20); % some samplesfrom substream 1
但请注意,这仍然无法改善样本的随机性:
你不必担心&#34;用完&#34;在移动到下一个子流之前,每个子流中的所有值,但是每次生成新值时,采取另一个极端并跳转到不同的子流是没有意义的。子流不会增加随机性,只是让重现价值更容易。
因此,我不认为在您的应用程序中使用多个随机数流/种子生成随机数。
答案 3 :(得分:0)
抱歉所有的困惑。我认为你们中的一些人说得对,我不需要生成不同的流。
在上面的代码中有一行显示“if node == pos”,这是不正确的,应该是“if transmission_time(node)== pos”。
这一行是导致我的图表全部失控的原因。我还需要为成功的数据包生成新的随机数。
感谢您的所有建议!我现在知道更多关于随机性如何在Matlab中使用种子了!