婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > 解決Go中使用seed得到相同隨機數的問題

解決Go中使用seed得到相同隨機數的問題

熱門標簽:賺地圖標注的錢犯法嗎 濮陽自動外呼系統代理 長沙ai機器人電銷 烏魯木齊人工電銷機器人系統 澳門防封電銷卡 地圖標注測試 智能電銷機器人營銷 福州鐵通自動外呼系統 廣東語音外呼系統供應商

1. 重復的隨機數

廢話不多說,首先我們來看使用seed的一個很神奇的現象。

func main() {
  for i := 0; i  5; i++ {
  rand.Seed(time.Now().Unix())
    fmt.Println(rand.Intn(100))
  }
}

// 結果如下
// 90
// 90
// 90
// 90
// 90

可能不熟悉seed用法的看到這里會很疑惑,我不是都用了seed嗎?為何我隨機出來的數字都是一樣的?不應該每次都不一樣嗎?

可能會有人說是你數據的樣本空間太小了,OK,我們加大樣本空間到10w再試試。

func main() {
  for i := 0; i  5; i++ {
  rand.Seed(time.Now().Unix())
    fmt.Println(rand.Intn(100000))
  }
}

// 結果如下
// 84077
// 84077
// 84077
// 84077
// 84077

你會發現結果仍然是一樣的。簡單的推理一下我們就能知道,在上面那種情況,每次都取到相同的隨機數跟我們所取的樣本空間大小是無關的。那么唯一有關的就是seed。我們首先得明確seed的用途。

2. seed的用途

在這里就不賣關子了,先給出結論。

上面每次得到相同隨機數是因為在上面的循環中,每次操作的間隔都在毫秒級下,所以每次通過time.Now().Unix()取出來的時間戳都是同一個值,換句話說就是使用了同一個seed。

這個其實很好驗證。只需要在每次循環的時候將生成的時間戳打印出來,你就會發現每次打印出來的時間戳都是一樣的。

每次rand都會使用相同的seed來生成隨機隊列,這樣一來在循環中使用相同seed得到的隨機隊列都是相同的,而生成隨機數時每次都會去取同一個位置的數,所以每次取到的隨機數都是相同的。

seed 只用于決定一個確定的隨機序列。不管seed多大多小,只要隨機序列一確定,本身就不會再重復。除非是樣本空間太小。解決方案有兩種:

在全局初始化調用一次seed即可
每次使用納秒級別的種子(強烈不推薦這種)

3. 不用每次調用

上面的解決方案建議各位不要使用第二種,給出是因為在某種情況下的確可以解決問題。比如在你的服務中使用這個seed的地方是串行的,那么每次得到的隨機序列的確會不一樣。

但是如果在高并發下呢?你能夠保證每次取到的還是不一樣的嗎?事實證明,在高并發下,即使使用UnixNano作為解決方案,同樣會得到相同的時間戳,Go官方也不建議在服務中同時調用。

Seed should not be called concurrently with any other Rand method.

接下來會帶大家了解一下代碼的細節。想了解源碼的可以繼續讀下去。

4. 源碼解析-seed

4.1 seed

首先來看一下seed做了什么。

func (rng *rngSource) Seed(seed int64) {
  rng.tap = 0
  rng.feed = rngLen - rngTap

  seed = seed % int32max
  if seed  0 { // 如果是負數,則強行轉換為一個int32的整數
    seed += int32max
  }
  if seed == 0 { // 如果seed沒有被賦值,則默認給一個值
    seed = 89482311
  }

  x := int32(seed)
  for i := -20; i  rngLen; i++ {
    x = seedrand(x)
    if i >= 0 {
      var u int64
      u = int64(x)  40
      x = seedrand(x)
      u ^= int64(x)  20
      x = seedrand(x)
      u ^= int64(x)
      u ^= rngCooked[i]
      rng.vec[i] = u
    }
  }
}

首先,seed賦值了兩個定義好的變量,rng.tap和rng.feed。rngLen和rngTap是兩個常量。我們來看一下相關的常量定義。

const (
  rngLen  = 607
  rngTap  = 273
  rngMax  = 1  63
  rngMask = rngMax - 1
  int32max = (1  31) - 1
)

由此可見,無論seed是否相同,這兩個變量的值都不會受seed的影響。同時,seed的值會最終決定x的值,只要seed相同,則得到的x就相同。而且無論seed是否被賦值,只要檢測到是零值,都會默認的賦值為89482311。

接下來我們再看seedrand。

4.2 seedrand

// seed rng x[n+1] = 48271 * x[n] mod (2**31 - 1)
func seedrand(x int32) int32 {
  const (
    A = 48271
    Q = 44488
    R = 3399
  )

  hi := x / Q    // 取除數
  lo := x % Q    // 取余數
  x = A*lo - R*hi // 通過公式重新給x賦值
  if x  0 {
    x += int32max // 如果x是負數,則強行轉換為一個int32的正整數
  }
  return x
}

可以看出,只要傳入的x相同,則最后輸出的x一定相同。進而最后得到的隨機序列rng.vec就相同。

到此我們驗證我們最開始給出的結論,即只要每次傳入的seed相同,則生成的隨機序列就相同。驗證了這個之后我們再繼續驗證為什么每次取到的隨機序列的值都是相同的。

5. 源碼解析-Intn

首先舉個例子,來直觀的描述上面提到的問題。

func printRandom() {
 for i := 0; i  2; i++ {
  fmt.Println(rand.Intn(100))
 }
}

// 結果
// 81
// 87
// 81
// 87

假設printRandom是一個單獨的Go文件,那么你無論run多少次,每次打印出來的隨機序列都是一樣的。通過閱讀seed的源碼我們知道,這是因為生成了相同的隨機序列。那么為什么會每次都取到同樣的值呢?不說廢話,我們一層一層來看。

5.1 Intn

func (r *Rand) Intn(n int) int {
  if n = 0 {
    panic("invalid argument to Intn")
  }
  if n = 131-1 {
    return int(r.Int31n(int32(n)))
  }
  return int(r.Int63n(int64(n)))
}

可以看到,如果n小于等于0,就會直接panic。其次,會根據傳入的數據類型,返回對應的類型。

雖然說這里調用分成了Int31n和Int63n,但是往下看的你會發現,其實都是調用的r.Int63(),只不過在返回64位的時候做了一個右移的操作。

// r.Int31n的調用
func (r *Rand) Int31() int32 { return int32(r.Int63() >> 32) }

// r.Int63n的調用
func (r *Rand) Int63() int64 { return r.src.Int63() }

5.2 Int63

先給出這個函數的相關代碼。

// 返回一個非負的int64偽隨機數.
func (rng *rngSource) Int63() int64 {
  return int64(rng.Uint64()  rngMask)
}

func (rng *rngSource) Uint64() uint64 {
  rng.tap--
  if rng.tap  0 {
    rng.tap += rngLen
  }

  rng.feed--
  if rng.feed  0 {
    rng.feed += rngLen
  }

  x := rng.vec[rng.feed] + rng.vec[rng.tap]
  rng.vec[rng.feed] = x
  return uint64(x)
}

可以看到,無論是int31還是int63,最終都會進入Uint64這個函數中。而在這兩個函數中,這兩個變量的值顯得尤為關鍵。因為直接決定了最后得到的隨機數,這兩個變量的賦值如下。

rng.tap = 0
rng.feed = rngLen - rngTap

tap的值是常量0,而feed的值決定于rngLen和rngTap,而這兩個變量的值也是一個常量。如此,每次從隨機隊列中取到的值都是確定的兩個值的和。

到這,我們也驗證了只要傳入的seed相同,并且每次都調用seed方法,那么每次隨機出來的值一定是相同的。

6. 結論

首先評估是否需要使用seed,其次,使用seed只需要在全局調用一次即可,如果多次調用則有可能取到相同隨機數。

總結

以上所述是小編給大家介紹的解決Go中使用seed得到相同隨機數的問題,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!
如果你覺得本文對你有幫助,歡迎轉載,煩請注明出處,謝謝!

您可能感興趣的文章:
  • GoLang 中的隨機數的示例代碼
  • Go語言排序算法之插入排序與生成隨機數詳解
  • 利用Golang生成整數隨機數方法示例
  • Golang編程實現生成n個從a到b不重復隨機數的方法
  • go語言返回1-99之間隨機數的方法
  • Go語言生成隨機數的方法

標簽:慶陽 西雙版納 太原 德州 貴陽 調研邀請 廣西 阿克蘇

巨人網絡通訊聲明:本文標題《解決Go中使用seed得到相同隨機數的問題》,本文關鍵詞  解決,中,使用,seed,得到,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《解決Go中使用seed得到相同隨機數的問題》相關的同類信息!
  • 本頁收集關于解決Go中使用seed得到相同隨機數的問題的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    日本中文字幕一区二区有限公司| 国内精品国产成人| 另类小说色综合网站| 欧美一区二区人人喊爽| 日韩在线一区二区三区| 欧美猛男gaygay网站| 午夜免费欧美电影| 日韩一区二区在线免费观看| 久久99国产精品尤物| 国产日韩精品视频一区| 成人h动漫精品一区二区| 亚洲欧美综合在线精品| 日本道精品一区二区三区| 亚洲r级在线视频| 日韩精品最新网址| 成人国产视频在线观看| 亚洲一区中文日韩| 精品免费国产一区二区三区四区| 国产精品一卡二卡| 亚洲男人的天堂在线aⅴ视频| 3d成人动漫网站| 成人一区二区三区中文字幕| 亚洲最大色网站| 精品国产髙清在线看国产毛片| 成人黄色免费短视频| 青青草精品视频| 日韩毛片在线免费观看| 午夜精品福利在线| 婷婷六月综合亚洲| 久久精品国产久精国产| 欧美成人一区二区三区| 日本大胆欧美人术艺术动态| 中文字幕亚洲综合久久菠萝蜜| 91精品国产欧美日韩| 色综合天天综合| 国产揄拍国内精品对白| 午夜电影一区二区三区| 亚洲欧美视频一区| 久久久九九九九| 色狠狠av一区二区三区| 国产一区高清在线| 理论片日本一区| 日日夜夜精品免费视频| 亚洲综合激情另类小说区| 久久精品免费在线观看| 91精品在线观看入口| 91麻豆swag| 99精品桃花视频在线观看| 极品少妇一区二区| 精品国产sm最大网站| 欧美一区二区精品久久911| 中文字幕国产精品一区二区| 欧美无人高清视频在线观看| 日韩激情视频在线观看| 亚洲影院在线观看| 亚洲大片免费看| 亚洲一本大道在线| 亚洲精品免费看| 亚洲欧美日韩成人高清在线一区| 国产欧美一区二区三区鸳鸯浴| 久久久久久久久久久久久女国产乱 | 免费在线欧美视频| 亚洲精品乱码久久久久久| ●精品国产综合乱码久久久久| 欧美激情在线看| 国产日产欧美一区二区三区| 国产视频一区不卡| 中文字幕不卡在线| 亚洲欧美日韩系列| 亚洲色欲色欲www在线观看| 中文字幕在线不卡国产视频| 亚洲欧美日韩一区二区三区在线观看| 国产精品剧情在线亚洲| 亚洲日本青草视频在线怡红院| 亚洲欧美一区二区三区国产精品| 夜夜精品视频一区二区 | 欧美刺激午夜性久久久久久久| 日韩视频一区在线观看| 精品国产区一区| 久久精品视频在线免费观看| 国产精品成人一区二区三区夜夜夜 | 国产精品国产a级| 亚洲欧美另类久久久精品2019| 亚洲精品免费一二三区| 日本大胆欧美人术艺术动态 | 在线视频国内自拍亚洲视频| 欧美精品自拍偷拍动漫精品| 日韩精品一区二区三区四区| 国产精品天美传媒沈樵| 亚洲成人av中文| 亚洲欧洲在线观看av| 欧美一区二区三区四区视频| 欧美精品一区二区三区蜜桃视频| 欧美国产精品专区| 午夜不卡在线视频| 懂色av一区二区三区免费看| 欧美视频完全免费看| 欧美精品一区二区三区视频| 国产精品高潮呻吟| 久久国产夜色精品鲁鲁99| 91在线丨porny丨国产| 91精品国产福利| 国产精品久久久久久久久搜平片| 日日骚欧美日韩| 99国产精品一区| 久久这里只有精品6| 亚洲午夜久久久久久久久电影网| 日本三级韩国三级欧美三级| 成人app网站| 日韩欧美一区二区不卡| 亚洲欧美乱综合| 成人综合激情网| 欧美精品丝袜中出| 亚洲欧美日韩在线不卡| 中文字幕在线不卡| 91麻豆产精品久久久久久| 天天操天天干天天综合网| 久久99精品久久久| 国产在线播放一区二区三区| 欧美四级电影网| 亚洲男人都懂的| 丁香婷婷综合五月| 国产亚洲欧美一级| 国产综合久久久久久久久久久久| 91精品国产一区二区人妖| 一区二区高清视频在线观看| av不卡在线播放| 中文字幕不卡三区| 国产成人精品1024| 国产视频911| 国产一区二区日韩精品| 久久久久久久久一| 国产精品77777| 中文字幕不卡一区| 99视频超级精品| ...xxx性欧美| 91社区在线播放| 一区二区三区四区蜜桃| 欧美伊人久久久久久久久影院| 亚洲激情图片小说视频| 欧美性videosxxxxx| 一区二区三区91| 欧美美女喷水视频| 日韩精品国产精品| 欧美日韩三级视频| 日本成人在线一区| 26uuu国产一区二区三区| 精彩视频一区二区| 国产女主播一区| 99re在线精品| 亚洲乱码日产精品bd| 欧美色倩网站大全免费| 亚洲国产成人91porn| 欧美绝品在线观看成人午夜影视| 午夜国产精品一区| 日韩视频免费直播| 久久综合综合久久综合| 欧美区在线观看| 丝袜美腿成人在线| 久久久久久久久97黄色工厂| 成人ar影院免费观看视频| 亚洲国产视频a| 久久色视频免费观看| 91麻豆文化传媒在线观看| 一区二区三区毛片| 激情综合网天天干| 亚洲免费高清视频在线| 日韩理论在线观看| xnxx国产精品| 亚洲欧洲性图库| 欧美视频日韩视频| 国产激情偷乱视频一区二区三区 | 亚洲成人动漫一区| 久久嫩草精品久久久精品一| 欧美在线影院一区二区| 国产伦精品一区二区三区视频青涩| 国产精品国产三级国产aⅴ入口| 欧美久久免费观看| 成熟亚洲日本毛茸茸凸凹| 日韩国产欧美在线观看| 亚洲色图在线视频| 欧美xxx久久| 99re这里只有精品首页| 久久精品国产亚洲aⅴ| 亚洲国产婷婷综合在线精品| 亚洲国产高清在线观看视频| 日韩欧美国产一二三区| 欧美视频一区二区| 一本一道久久a久久精品综合蜜臀| 精品无人码麻豆乱码1区2区| 日韩黄色小视频| 亚洲成人久久影院| 亚洲综合偷拍欧美一区色| 椎名由奈av一区二区三区| 国产欧美日本一区视频| 精品盗摄一区二区三区| 日韩精品综合一本久道在线视频| 欧美日韩中文字幕一区二区| 在线观看日韩电影| 色av综合在线|