相關函數:RAND() / INT() / RANK()
EXCEL 提供了一個函數 RAND(),讓使用者可以隨機產生亂數。RAND() 會產生一個 0<=RAND()<1 的數值,每當表格內有任何變化或修改時,RAND() 都會重新產生一個新的亂數。
介於 0 和 1 之間的亂數都是小數,可能不符合實際應用,更多的時候,我們會需要整數亂數。例如,要從 20 個人中隨機抽 10 個人出來,我們就需要 10 組 1~20 之間的變數。這時候,我們可以利用這個公式
##CONTINUE##
=INT(RAND()*20)+1
並把它複製到 10 個儲存格。如下表的 B 欄。INT() 用來取得數值的整體部份,而把小數部份捨棄。
上面的公式有個問題,13 重複出現了兩次,這可能不符合實際需求。如果要產生不重複的亂數,可以再配合排名次的函數 RANK(),在 C2 輸入公式
=RANK(A2,$A$2:$A$11)
並往下複製到 C3:C11,就可以得到不重複的亂數了。
整合一下,如果要從 20 個人中隨機抽出不重複的 10 個人出來,應該怎麼做?把 A 欄和 C 欄都擴充到 20 列,C 欄就會有 20 組不重複的 1~20 的亂數,然後取前 10 個亂數 (C2:C11) 即可。
6 意見:
這個算法還是會出現重復。因為RANK函數在排序時會把相同的數排成同一個順序﹐比如數據 1﹑3﹑3﹑4﹑4﹑5﹐排序時會是1﹑2﹑2﹑4﹑4﹑6。
是的,如果出現兩個完全相同的亂數,RANK() 會排出相同的順序。只是,Excel 的亂數會算到小數點後 15 位,在一般的使用情形下,重複的機會很低。
如果你的資料量很大,那麼不建議用這個方法。甚至也不建議用 Excel,因為 Excel 能處理的資料量並不算很大。
在網上搜到的一個算法﹐也算是這個不重復亂數問題目前看到的最佳答案。
excel里面有内置的rnd()函数,可以用来生成随机数,但是,有些情形下,我们需要生成一个不重复的随机序列。
比如:我们要模拟洗牌,将一副扑克牌去掉大小怪后剩下的52张打乱。
比较笨的方法是在1-52间每生成一个随机数后,检查该随机数是否出现过,如果是第一次出现,就放到序列里,否则重新生成一个随机数作检查。在excel worksheet里面用这种办法,会造成if多层嵌套,不胜其烦,在VBA里面做简单一些,但是效率太差,越到序列的后端,效率越差。
当然也有比较好的办法,在VBA里面,将a(1)-a(52)分别赋予1-52,然后做52次循环,例如,第s次生成一个1-52间的随机数r,将a(s)与a(r)互换,这样的话,就打乱了原有序列,得到一个不重复的随机序列。
在VBA里这个算法是很容易实现的,但是,处于通用性和安全考虑,有的时候我们并不希望用VBA,我们来看看在worksheet里面如何利用内置函数实现这个功能。
1,在A1-A52间填入"=INT(RAND()*52)+1",产生1-52间的随机数,注意这里是有重复的
2,在B1-B52间填入1-52
3,在C54-BB54填入1-52
4,在C1填入"=IF(ROW()=C$54,INDEX(B$1:B$52,INDEX($A$1:$A$52,C$54)),IF(ROW()=INDEX($A$1:$A$52,C$54),INDEX(B$1:B$52,C$54),B1))"。
分项解释:
a:ROW()=C$54,如果当前行等于当前交换所排的序号
b:INDEX(B$1:B$52,INDEX($A$1:$A$52,C$54)),返回在B1到B52中选择A1:A52中的第C54个值
c:IF(ROW()=INDEX($A$1:$A$52,C$54),否则的话,如果当前行等于A1:A52中第C54个值,则:
d:INDEX(B$1:B$52,C$54),返回B1:B52中的第C54个值
e:若以上条件都不满足,则返回B1
5,将C1复制到C1:BA52这个区域里面
6,在BA1:BA52中,我们就得到了一个不重复的随机序列,按F9可以生成一个新序列。
利用这个序列,可以做很多事情,比如说,模拟发牌,统计指定人拿到某种牌型(同花顺)的概率,或者一局当中出现某种牌型的概率。囡囡爸爸在周末用水晶球模拟了50万局,发现出现同花顺的局数占6.35%,个人拿到同花顺的概率为1.64%,在第499571局的时候,南家老兄居然拿到了10张长套.就算是老牌友,一辈子能玩499571局吗?
恕小弟愚昧,無法理解這個做法~~
請問狐大:
我需要每欄有1-49亂數排列
需要6欄,
且橫向、縱向每個數字不可重覆
請問Excel能作到嗎?
請問狐大:
我需要每欄1~49亂數排列
共要6欄
其中橫、縱向數字不可重覆
Excel可以作到嗎?
張貼留言