根据权重抽奖..

根据用户名(id)和权重抽奖

package main

import (
    "fmt"
    "math/rand"
    "time"
)

//return res[0]: userid, res[1]: weight
func GetRandomByWeight(m map[int64]int64, max_weight int64) (res [2]int64) {
    rand.Seed(time.Now().UnixNano())
    for uid, weight := range m {
        r := rand.Int63n(max_weight) + 1
        if r <= weight {
            res[0] = uid
            res[1] = weight
            return res
        }
    }
    return res
}

//生成指定数量的用户,并随机的给他们分配权重
func mock_user(user_count, max_weight int64) map[int64]int64 {
    rand.Seed(time.Now().UnixNano())
    m := make(map[int64]int64)
    for i := int64(0); i < user_count; i++ {
        m[i] = rand.Int63n(max_weight) + 1
    }
    return m
}

//测试模型是否正确,对10万用户抽奖1000万次,权重和中奖次数应该大致上成正比
func test_model() {
    user_count := int64(100000)
    max_weight := int64(20)
    times := 10000000
    weight_map := make(map[int64]int64)
    mock_user := mock_user(user_count, max_weight)
    //开始抽奖
    begin := time.Now().Unix()
    for i := 0; i < times; i++ {
        tmp := GetRandomByWeight(mock_user, max_weight)
        weight_map[tmp[1]] += 1
    }
    for i := int64(1); i < max_weight+1; i++ {
        fmt.Println("权重:", i, "此权重中奖次数:", weight_map[i])
    }
    end := time.Now().Unix()
    fmt.Println("用户数", user_count, ",抽奖", times, "次,耗时(秒):", end-begin)
}

func main() {
    //验证模型是否可用
    //test_model()

    //模拟1亿用户抽奖,用户权重范围为1...10000
    user_count := int64(100000000)
    max_weight := int64(20)
    mock_user := mock_user(user_count, max_weight)
    //开始抽奖
    begin := time.Now().UnixNano()
    res := GetRandomByWeight(mock_user, max_weight)
    end := time.Now().UnixNano()
    fmt.Println("中奖用户ID:", res[0], "权重:", res[1], "抽奖耗时(纳秒):", end-begin)
}

test_model运行结果

权重: 1 此权重中奖次数: 49514
权重: 2 此权重中奖次数: 96324
权重: 3 此权重中奖次数: 144704
权重: 4 此权重中奖次数: 191649
权重: 5 此权重中奖次数: 239856
权重: 6 此权重中奖次数: 284260
权重: 7 此权重中奖次数: 319638
权重: 8 此权重中奖次数: 377491
权重: 9 此权重中奖次数: 431406
权重: 10 此权重中奖次数: 481927
权重: 11 此权重中奖次数: 522153
权重: 12 此权重中奖次数: 581450
权重: 13 此权重中奖次数: 628319
权重: 14 此权重中奖次数: 659269
权重: 15 此权重中奖次数: 706728
权重: 16 此权重中奖次数: 760366
权重: 17 此权重中奖次数: 814852
权重: 18 此权重中奖次数: 862671
权重: 19 此权重中奖次数: 903833
权重: 20 此权重中奖次数: 943590
用户数 100000 ,抽奖 10000000 次,耗时(秒): 110

为了更直观一点,做成表格:

根据权重抽奖.._第1张图片
图片4.png

1亿用户抽奖1次结果

中奖用户ID: 18163051 权重: 18 抽奖耗时(纳秒): 0

你可能感兴趣的:(根据权重抽奖..)