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

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

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

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

阿晨1998 2021-05-03 12:49:38
我正在嘗試了解以下任務(wù)的解決方案:從大小為N的數(shù)組中隨機(jī)生成一組M個(gè)元素。每個(gè)元素的選擇概率必須相同。我找到了以下解決方案(我已經(jīng)讀過(guò)這個(gè)問(wèn)題,但是它不能回答我的問(wèn)題):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可以在“破解編碼訪談”一書(shū)中找到此代碼(Section Hard,任務(wù)3)。作者解釋如下:假設(shè)我們有一種算法可以m從size數(shù)組中提取隨機(jī)元素集n - 1。我們?nèi)绾问褂迷撍惴╩從大小數(shù)組中提取隨機(jī)元素集n?我們首先可以從前幾個(gè)n - 1元素中隨機(jī)抽取大小為m的集合。然后,我們只需要確定是否array[n]應(yīng)將其插入子集即可(這將需要從子集中抽出一個(gè)隨機(jī)元素)。一種簡(jiǎn)單的方法是從0到n中選擇一個(gè)隨機(jī)數(shù)k。如果k < m,然后插入array[n]到subset[k]。這都將“公平地”(即具有成比例的概率)插入array[n]進(jìn)入子集并“公平地”從子集中刪除隨機(jī)元素。迭代編寫(xiě)甚至更干凈。在這種方法中,我們將數(shù)組子集初始化為m原始數(shù)組中的第一個(gè)元素。然后,我們遍歷數(shù)組,從element開(kāi)始,每當(dāng)m插入array[i]到(隨機(jī))位置的子集中。kk < m我想作者想說(shuō)我們需要生成的不是set,而是數(shù)組。所以,我認(rèn)為正確的任務(wù)描述應(yīng)該是:隨機(jī)產(chǎn)生一個(gè)陣列M個(gè)元素的大小從N的一個(gè)陣列的每個(gè)元素必須具有被選擇的同等概率。如果為true,則上述代碼將無(wú)法正常工作。原因:例如,我們有一個(gè)數(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)不會(huì)生成以下集合: {2, 1}; {2, a}; {2, b}因此,這意味著它是不正確的。
查看完整描述

3 回答

?
LEATH

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

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


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


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


假設(shè)N >= M。


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


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


讓我們從遞歸開(kāi)始。


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


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


可以從中選擇一組M元素。可以從中選擇 一組元素。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)該決定是否替換其中一個(gè)元素。我們需要一個(gè)(N-M)/N概率。為此,我們可以在0和之間生成一個(gè)隨機(jī)數(shù)N。如果該數(shù)字小于M,我們將替換。


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

if (replace) {

   // then replace

}

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


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

if (replace) {

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

}

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


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

boolean replace = r < M;

if (replace) {

   subset[r] = original[N];

}

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


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


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


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

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

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

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

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


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

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

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

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


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

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

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


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


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


當(dāng)i為3時(shí),r為0、1、2或3。b以1/4的概率移至索引0,以1/4的概率移至索引1,并且沒(méi)有以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個(gè)單元格中的每個(gè)單元具有相等的概率,即1/12。讓我們檢查一下:[1,2],[1,a],[1,b],[a,2]和[b,2]分別存在兩次。[a,b]和[b,a]各自出現(xiàn)一次,但是它們是同一集合,因此該集合也出現(xiàn)兩次。這涵蓋了所有可能的子集,因此它們的可能性也相同。


查看完整回答
反對(duì) 回復(fù) 2021-05-12
  • 3 回答
  • 0 關(guān)注
  • 225 瀏覽
慕課專(zhuān)欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號(hào)

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