美文网首页
C#实现基于权重的随机算法

C#实现基于权重的随机算法

作者: 不方马斯特 | 来源:发表于2021-03-18 15:18 被阅读0次

一、线性扫描

最简单常用的算法,获取随机值,直接遍历。

public static int GetRandomIndexLinear(int[] list, int totalWeight)
{
    var value = random.Next(0, totalWeight);
    for (int i = 0; i < list.Length; i++)
    {
        value -= list[i];
        if (value <= 0)
        {
            return i;
        }
    }
    return -1;
}

二、预处理

首先对权重进行处理,填充PrepareAdRewardWeight。

public static (float, int)[] PrepareAdRewardWeight;

设置n个空桶,空桶容量为平均权重,按平均权重区分大权重与小权重,依次将小权重填入桶中,剩余部分由大权重的一部分填满,大权重减去填充部分后,如果小于平均值,则后续当做小权重处理。
一轮遍历后,填充好的数据为小权重的占比和大权重的索引。

public static void InitAdRewardWeight(int[] weightList)
{
    var total = weightList.Sum();
    int length = weightList.Length;
    var avg = 1f * total / length;
    List<(float, int)> smallAvg = new List<(float, int)>();
    List<(float, int)> bigAvg = new List<(float, int)>();
    for (int i = 0; i < weightList.Length; i++)
    {
        (weightList[i] > avg ? bigAvg : smallAvg).Add((weightList[i], i));
    }
    PrepareAdRewardWeight = new (float, int)[weightList.Length];
    for (int i = 0; i < weightList.Length; i++)
    {
        if (smallAvg.Count > 0)
        {
            if (bigAvg.Count > 0)
            {
                PrepareAdRewardWeight[smallAvg[0].Item2] = (smallAvg[0].Item1 / avg, bigAvg[0].Item2);
                bigAvg[0] = (bigAvg[0].Item1 - avg + smallAvg[0].Item1, bigAvg[0].Item2);
                if (avg - bigAvg[0].Item1 > 0.0000001f)
                {
                    smallAvg.Add(bigAvg[0]);
                    bigAvg.RemoveAt(0);
                }
            }
            else
            {
                PrepareAdRewardWeight[smallAvg[0].Item2] = (smallAvg[0].Item1 / avg, smallAvg[0].Item2);
            }
            smallAvg.RemoveAt(0);
        }
        else
        {
            PrepareAdRewardWeight[bigAvg[0].Item2] = (bigAvg[0].Item1 / avg, bigAvg[0].Item2);
            bigAvg.RemoveAt(0);
        }
    }
}

预处理结束后,获取随机值的复杂度为O(1)。

public static int GetRandomIndex()
{
    var randomNum = random.NextDouble() * PrepareAdRewardWeight.Length;
    int intRan = (int)Math.Floor(randomNum);
    var p = PrepareAdRewardWeight[intRan];
    if (p.Item1 > randomNum - intRan)
    {
        return intRan;
    }
    else
    {
        return p.Item2;
    }
}

三、总结

随机目标的数量越大,第二种方法越高效。

参考

https://zhuanlan.zhihu.com/p/146216606

相关文章

  • C#实现基于权重的随机算法

    一、线性扫描 最简单常用的算法,获取随机值,直接遍历。 二、预处理 首先对权重进行处理,填充PrepareAdRe...

  • go常见负载均衡算法及其实现

    go 负载均衡器,支持一下几种算法: 基于随机算法的负载均衡 基于RoundRobin算法的负载均衡 基于带权重R...

  • java 权重随机算法实现

  • 协同过滤

    协同过滤算法有多个方法实现,基于邻域算法、隐语义模型、基于图的随机游走等基于邻域算法公认效果较好的算法,分以下2类...

  • Dubbo的四种负载均衡方式

    (1) 基于权重的轮询负载均衡 计算权重,根据权重配置查询次数,然后轮询。 (2)基于权重的随机负载均衡 ...

  • Dubbo的服务治理

    负载均衡 Dubbo 里面默认就集成了负载均衡的算法和实现,默认提供了 4 中负载均衡实现: 权重随机:round...

  • TOTP 介绍及基于C#的简单实现

    TOTP 介绍及基于C#的简单实现 Intro TOTP 是基于时间的一次性密码生成算法,它由 RFC 6238 ...

  • 使用Spring Session和Redis解决分布式Sessi

    前言 对于分布式使用Nginx+Tomcat实现负载均衡,最常用的均衡算法有IP_Hash、轮训、根据权重、随机等...

  • c#实现随机产生不重复数字原理

    c#实现随机产生不重复数字原理:随机产生数字 及检查重复 随机产生使用关键字:Random

  • 协同过滤算法

    协同过滤算法:基于用户行为数据设计的推荐算法,分为:基于邻域的方法、隐语义模型(LFM)、基于图的随机游走算法 1...

网友评论

      本文标题:C#实现基于权重的随机算法

      本文链接:https://www.haomeiwen.com/subject/jszucltx.html