第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

從大小為N的數(shù)組生成一組M個元素

從大小為N的數(shù)組生成一組M個元素

阿晨1998 2021-05-03 12:49:38
我正在嘗試了解以下任務(wù)的解決方案:從大小為N的數(shù)組中隨機(jī)生成一組M個元素。每個元素的選擇概率必須相同。我找到了以下解決方案(我已經(jīng)讀過這個問題,但是它不能回答我的問題):int rand(Random random, int min, int max) {  return random.nextInt(1 + max - min) + min;}char[] generateArray(char[] original, int subsetSize) {  char[] subset = new char[subsetSize];  Random random = new Random();  for (int i = 0; i < subsetSize; i++) {    subset[i] = original[i];  }  for (int i = subsetSize; i < original.length; i++) {    int r = rand(random,0, i);    boolean takeIthElement = r < subsetSize;    if (takeIthElement) {      subset[r] = original[i];    }  }  return subset;}// rand() function returns inclusive value // i.e. rand(0, 5) will return from 0 to 5可以在“破解編碼訪談”一書中找到此代碼(Section Hard,任務(wù)3)。作者解釋如下:假設(shè)我們有一種算法可以m從size數(shù)組中提取隨機(jī)元素集n - 1。我們?nèi)绾问褂迷撍惴╩從大小數(shù)組中提取隨機(jī)元素集n?我們首先可以從前幾個n - 1元素中隨機(jī)抽取大小為m的集合。然后,我們只需要確定是否array[n]應(yīng)將其插入子集即可(這將需要從子集中抽出一個隨機(jī)元素)。一種簡單的方法是從0到n中選擇一個隨機(jī)數(shù)k。如果k < m,然后插入array[n]到subset[k]。這都將“公平地”(即具有成比例的概率)插入array[n]進(jìn)入子集并“公平地”從子集中刪除隨機(jī)元素。迭代編寫甚至更干凈。在這種方法中,我們將數(shù)組子集初始化為m原始數(shù)組中的第一個元素。然后,我們遍歷數(shù)組,從element開始,每當(dāng)m插入array[i]到(隨機(jī))位置的子集中。kk < m我想作者想說我們需要生成的不是set,而是數(shù)組。所以,我認(rèn)為正確的任務(wù)描述應(yīng)該是:隨機(jī)產(chǎn)生一個陣列M個元素的大小從N的一個陣列的每個元素必須具有被選擇的同等概率。如果為true,則上述代碼將無法正常工作。原因:例如,我們有一個數(shù)組{'1', '2', 'a', 'b'}和m = 2因此,我們應(yīng)該具有生成以下幾組的資格概率:{1, 2}; {2, 1}; {1, a}; {a, 1}; {1, b}; {b, 1}; {a, 2}; {2, a}; {b, 2}; {2, b}; {a, b}; {b, a}我在這里擔(dān)心的是,該函數(shù)將永遠(yuǎn)不會生成以下集合: {2, 1}; {2, a}; {2, b}因此,這意味著它是不正確的。
查看完整描述

3 回答

?
LEATH

TA貢獻(xiàn)1936條經(jīng)驗(yàn) 獲得超7個贊

首先,從解釋和代碼中可以很清楚地看出作者所設(shè)定的含義,就像他們寫的一樣。在實(shí)際的實(shí)現(xiàn)中,可以將集合建模為數(shù)組,這并不意味著任何事情。在編程方面的挑戰(zhàn)中,人們通常使用相當(dāng)簡單的結(jié)構(gòu)-如數(shù)組代替java.util.Set。


因此,任務(wù)基本上是:


M從size數(shù)組中隨機(jī)選擇一組元素N。


假設(shè)N >= M。


現(xiàn)在最困難的部分:為什么該算法會產(chǎn)生正確的結(jié)果?


僅看算法,很難理解它是如何工作的以及為什么。我認(rèn)為這是因?yàn)樗惴▽?shí)際上是遞歸構(gòu)造的,而遞歸finall在迭代中沒有展開。


讓我們從遞歸開始。


假設(shè)我們能夠M從size數(shù)組中隨機(jī)選擇元素N - 1。我們?nèi)绾蜯從大小數(shù)組中選擇元素N?


由于數(shù)組中有一個“新”元素,因此我們可以用其中的一個替換選定的元素-或保留原樣。但是我們必須保留隨機(jī)屬性。


可以從中選擇一組M元素??梢詮闹羞x擇 一組元素。N-1(N-1)! / M!*(N-1 - M)!

MNN! / M!*(N - M)!


這意味著我們應(yīng)該保留(N-M)/N概率集,并用概率替換元素之一M/N。我們還必須選擇要用1/M概率替換的元素。


讓我們看看它在代碼中的外觀。假設(shè)subset是我們從中隨機(jī)選擇的一組M元素N-1。


首先,我們應(yīng)該決定是否替換其中一個元素。我們需要一個(N-M)/N概率。為此,我們可以在0和之間生成一個隨機(jī)數(shù)N。如果該數(shù)字小于M,我們將替換。


boolean replace = rand(random, 0, N) < M;

if (replace) {

   // then replace

}

現(xiàn)在我們必須選擇要替換的元素之一。由于我們將數(shù)組建模為一個集合,因此我們可以簡單地在0和之間M - 1(包括兩者之間)隨機(jī)選擇一個索引。這樣我們得到:


boolean replace = rand(random, 0, N) < M;

if (replace) {

   subset[rand(random, 0, M - 1)] = original[N];

}

在這里我們可以注意到,如果我們的第一個隨機(jī)值(rand(random, 0, N))小于M,則它是0和之間的一個隨機(jī)值M-1。因此,我們不需要第二個rand:


int r = rand(random, 0, N);

boolean replace = r < M;

if (replace) {

   subset[r] = original[N];

}

其余的應(yīng)該是微不足道的。


遞歸的基本情況是M == N。在這種情況下,我們什么都不會替換,因此所選元素的集合就是原始數(shù)組的簡單形式。


之后,可以將遞歸簡單地編碼為一個循環(huán)。i代表N每個步驟-這為您提供了自己的代碼。


查看完整回答
反對 回復(fù) 2021-05-12
?
小怪獸愛吃肉

TA貢獻(xiàn)1852條經(jīng)驗(yàn) 獲得超1個贊

我認(rèn)為作者想說我們需要生成的不是set而是array

不,作者真正的意思是集合,但碰巧將結(jié)果集合存儲在數(shù)組中。通過說結(jié)果是一個集合,就意味著值的順序無關(guān)緊要,這意味著{1, 2}{2, 1}是相同的集合。

鑒于此,它是確定這一結(jié)果永遠(yuǎn)不會{2, 1},只要結(jié)果與值的概率12為1/6,即無序臺(套)的概率。


如果您想要一個有序的結(jié)果,即列出它們時有12個不同的結(jié)果,那么最簡單的解決方案是改組原始數(shù)組并采用第一個M值。這樣可以保證所有結(jié)果的概率均等,并且不會重復(fù)。

通常使用Fisher-Yates shuffle來進(jìn)行數(shù)組改組,這是對數(shù)組進(jìn)行迭代并將該元素與先前的元素隨機(jī)交換。

問題中的算法是該算法的一種變體。如果跳過前M個值的隨機(jī)改組,則順序無關(guān)緊要。然后,它會隨機(jī)地將后續(xù)元素與隨機(jī)元素交換,但是如果隨機(jī)位置> M不會發(fā)生交換,并且交換掉的值將被簡單丟棄,因?yàn)樗罱K會出現(xiàn)在結(jié)果集之外。

因此,這是經(jīng)過修改的Fisher-Yates隨機(jī)播放,可以在原始數(shù)組的副本中生成隨機(jī)子集,但是經(jīng)過優(yōu)化,可以跳過不必要的隨機(jī)播放,因?yàn)槲覀冃枰粋€集合,而不是有序列表/數(shù)組,而我們只想要一個子集,而不是所有值。


查看完整回答
反對 回復(fù) 2021-05-12
?
守著星空守著你

TA貢獻(xiàn)1799條經(jīng)驗(yàn) 獲得超8個贊

如何用數(shù)學(xué)證明呢?


您的第二個for循環(huán)運(yùn)行兩次,首先i等于2,然后i等于3。


當(dāng)i為2時,r變?yōu)?、1或2,每個概率為1/3。因此,chara將以索引0或1或根本不索引的形式移到您的結(jié)果中,每個概率為1/3?,F(xiàn)在它是[a,2],[1,a]或[1,2]。


當(dāng)i為3時,r為0、1、2或3。b以1/4的概率移至索引0,以1/4的概率移至索引1,并且沒有以1/2的概率移至任何位置。


在下表中,我給出了所有可能情況下的結(jié)果。值下r,0,1和2,是在第一次迭代(可能的值i= 2)。右邊的或是r第二次迭代中的可能值。


r    0       1       2       3

0  [b, 2]  [a, b]  [a, 2]  [a, 2]

1  [b, a]  [1, b]  [1, a]  [1, a]

2  [b, 2]  [1, b]  [1, 2]  [1, 2]

因此,在表中您可以讀取到,如果r兩次都為0,則您的方法將返回[b, 2],等等。


表中的12個單元格中的每個單元具有相等的概率,即1/12。讓我們檢查一下:[1,2],[1,a],[1,b],[a,2]和[b,2]分別存在兩次。[a,b]和[b,a]各自出現(xiàn)一次,但是它們是同一集合,因此該集合也出現(xiàn)兩次。這涵蓋了所有可能的子集,因此它們的可能性也相同。


查看完整回答
反對 回復(fù) 2021-05-12
  • 3 回答
  • 0 關(guān)注
  • 238 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號