对于我的一个作业问题,我们必须编写一个函数来创建一个包含1到365之间的n个随机数的数组。(完成)。然后,检查这些n
生日中的任何一个是否相同。有没有比做几个循环或几个逻辑表达式更短的方法呢?
谢谢!
代码很远,没有完成!!
function = [prob] bdayprob(N,n)
N = input('Please enter the number of experiments performed: N = ');
n = input('Please enter the sample size: n = ');
count = 0;
for(i=1:n)
x(i) = randi(365);
if(x(i)== x)
count = count + 1
end
return
答案 0 :(得分:2)
如果我正确解释您的问题,您需要检查生成n
整数或天数是否会产生n
唯一数字。鉴于您目前在MATLAB中的知识,它就像做:
n = 30; %// Define sample size
N = 10; %// Define number of trials
%// Define logical array where each location tells you whether
%// birthdays were repeated for a trial
check = false(1, N);
%// For each trial...
for idx = 1 : N
%// Generate sample size random numbers
days = randi(365, n, 1);
%// Check to see if the total number of unique birthdays
%// are equal to the sample size
check(idx) = numel(unique(days)) == n;
end
哇!让我们慢慢看看代码吧?我们首先定义样本大小和试验次数。然后,我们指定一个logical
数组,其中每个位置都会告诉您是否为该试验生成了重复的生日。现在,我们从循环开始,对于每个试验,我们生成从1到365的随机数,其为n
或样本大小。然后,我们使用unique
并找出从此随机生成生成的所有唯一整数。如果所有生日都是唯一的,则生成的唯一生日总数应等于样本大小。如果我们不这样做,那么我们会重复。例如,如果我们生成了[1 1 1 2 2]
的样本,则unique
的输出将为[1 2]
,并且唯一元素的总数为2.由于此不具有&#39}。 t 等于5或样本大小,然后我们知道生成的生日并不是唯一的。但是,如果我们有[1 3 4 6 7]
,unique
将提供相同的输出,并且由于输出长度与样本大小相同,我们知道所有日期都是唯一的。
因此,我们检查这个数字是否等于每次迭代的样本大小。如果是,那么我们输出true
。如果没有,我们输出false
。当我在我的末尾运行此代码时,这就是我为check
获得的代码。我将样本量设置为30,试验次数设置为10。
check =
0 0 1 1 0 0 0 0 1 0
请注意,如果增加样本量,则获得重复项的可能性会更高,因为randi
可视为替换样本。因此,样本量越大,获得重复值的机会就越高。我故意将样本量减小,以便我们可以看到它可以获得独特的日子。但是,如果您将其设置为100或200,那么您很可能会check
全部false
,因为每次试用很可能会重复。{/ p>
答案 1 :(得分:1)
以下是一些避免循环的方法。让
n = 20; %// define sample size
x = randi(365,n,1); %// generate n values between 1 and 365
如果true
和1
(或x
)中有两个相同的值,则以下任何代码段都会返回false
(或0
)否则:
排序然后检查两个连续元素是否相同:
result = any(diff(sort(x))==0);
手动进行所有成对比较;删除自配对和重复对;并检查是否有任何剩余的比较是真的:
result = nnz(tril(bsxfun(@eq, x, x.'),-1))>0;
计算不同值之间的距离,仅考虑每对一次,然后检查是否有任何距离为0
:
result = any(pdist(x(:))==0);
查找最常见值(模式)的出现次数:
[~, occurs] = mode(x);
result = occurs>1;
答案 2 :(得分:0)
我不知道我是否应该为你解决问题,但也许一些提示可能会让你朝着正确的方向前进(除了我不是一个matlab专家所以它会一般来说):
也许不是,但你必须问自己对你的期望。您建议的解决方案要求您在两个嵌套循环中循环遍历数组,这将意味着循环中的n *(n-1)/ 2次(即二次时间复杂度)。
有许多方法可以改善问题的时间复杂性。最直截了当的是有一个365元素表,你可以跟踪一个特定的数字是否已经被看到 - 这只需要一个循环(即线性时间复杂度),但也许这不是他们&# 39;重新寻找。但也许这个解决方案有点特别?我们基本上寻找的是快速查找,如果之前已经看到一个特定的数字 - 存在更多的内存有效结构,允许在O(1)时间和O(log n)时间内查找(如果你知道这些你有一套工具可供使用。)
当然,你可以使用pidgeonhole原理在某些特殊情况下更快地提供答案(请记住,你只需要确定两个或多个数字是否相等)。