抽獎問題分析

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

普通抽獎問題

問題描述

使用者隨機抽獎,資料如下:

// map中,key代表使用者名稱,value代表成使用者下單數var users map[string]int64 = map[string]int64{  "a": 10,  "b": 6,  "c": 3,  "d": 12,  "f": 1,}

思路

隨機問題,一般就是通過隨機函數從某個範圍內隨機取出某個數值,則該數值對應的就是中獎使用者

在這裡,如果我們能給map中每個元素設定對應的索引,即轉化為數組,是不是就可以解決問題了呢?

代碼實現

func GetAwardUserName(users map[string]int64) (name string) {    size := len(users)    awardIndex := rand.Intn(size)    i := 0    for userName, _ := range users {        if i == awardIndex {            name = userName            return        }        i++    }    return}

單元測試

func Test_GetAwardUserName(t *testing.T) {    var users map[string]int64 = map[string]int64{        "a": 10,        "b": 6,        "c": 3,        "d": 12,        "f": 1,    }    rand.Seed(time.Now().Unix())    awardCount := make(map[string]int)    for i := 0; i <= 1000000; i++ {        awardName := GetAwardUserName(users)        if count, ok := awardCount[awardName]; ok {            awardCount[awardName] = count + 1        } else {            awardCount[awardName] = 0        }    }    for n, c := range awardCount {        fmt.Printf("%v:%v\n",n,c)    }}

測試結果:

為了驗證獲獎機率的正確性,迴圈執行100萬次,每個使用者獲獎的次數基本在20萬左右,每個使用者的獲獎機率相等

c:200102f:199853b:198942a:200395d:200704

權重抽獎

問題描述:

資料結構和上面抽獎問題一致,只是這裡,要求中獎機率和使用者的訂單數成正比

思路

==本質==還是隨機函數獲得一個數值,數值對應的使用者即獲獎使用者;這裡要實現訂單數對獲獎機率的影響問題,即==訂單數對應隨機數的某個範圍,訂單數越大,範圍越大,隨機數落在範圍內的機率越大==

代碼實現

func getAwardUser_weight(users map[string]int64) (name string) {    type awardUser struct {        name   string        offset int64        count  int64    }    userSli := make([]*awardUser, 0,len(users))    var sumCount int64 = 0    for n, c := range users {        a := awardUser{            name:   n,            offset: sumCount,            count:  c,        }        //整理所有使用者的count資料為數軸        userSli = append(userSli, &a)        sumCount += c    }    awardIndex := rand.Int63n(sumCount)    for _, u := range userSli {        //判斷獲獎index落在那個使用者區間內        if u.offset+u.count>awardIndex {            name = u.name            return        }    }    return}

單元測試

func Test_getAwardUser_weight(t *testing.T) {    var users map[string]int64 = map[string]int64{        "a": 10,        "b": 6,        "c": 3,        "d": 12,        "f": 1,    }    rand.Seed(time.Now().Unix())    awardCount := make(map[string]int)    for i := 0; i <= 100000; i++ {        awardName := getAwardUser_weight(users)        if count, ok := awardCount[awardName]; ok {            awardCount[awardName] = count + 1        } else {            awardCount[awardName] = 0        }    }    for n,c := range awardCount {        fmt.Printf("%v:%v \n",n,c)    }}

測試結果:

迴圈遍曆了100萬次,獲獎的次數,與使用者的訂單數成正比

c:93479 f:31206 d:375614 b:186933 a:312764 

總結

解決實際問題,往往都有數學模型去對應,比如抽獎問題,就可以轉化為初中所學習的數軸知識,畫個草圖,簡單易理解,也不需要多高深的數學知識

問題本身並不難,重要的是轉換思路,將抽象問題簡化為具體的數學問題,然後去解決

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.