红包手游源码-抢红包算法--四种抢红包算法对比(附源码)

还记得很久很久以前

我当时还在做《绿色征途》手游版

有一天

计划好友请求同学

一定要优化抢红包算法

先行划桨

吃瓜第一的原则

然后

我看到一堆物理名词

***法律

XXX 公式

呵呵~

我不值得

怪我不努力学习

仔细听

问题原来是

原来的红包分发算法

最先抢到的人将从总量中随机选出

稍后抢到的人将从剩余数量中随机选择

所以越早抢红包

金额越大

现在规划希望金额稍微低一些

哦,我惊呼,好人

只是这件事

有必要修复这些吗?

瞬间法则

一会儿公式

他们的最终计划

也很务实

就是大家首先要做出保证。

然后按照之前的红包算法进行分配

果然,大隐士就躲在城里了

红包手游源码-抢红包算法--四种抢红包算法对比(附源码)

翠花,配牛肉

分析:

解决这个问题的方法有四种(普通法、线段切割法、双随机法、篮球投掷法)。

前三个算法基本都是网上流传的红包手游源码,篮球投篮算法是我自己发明的一个名字。

这个算法还是源于原来的校招,面试北京涂鸦联通,面试官当场引导我一道题,用投篮篮球的例子。 而且当我写这篇博客的时候,我记得这个算法还蛮适用的,所以我把它称为篮球投篮算法。

1.普通法:每次将剩余总量随机化,随机值为第一人的值。 这个算法也是这位朋友之前写的要求优化的算法。 这种算法的优点是完全随机,缺点是很可能前辈抢的太多,后辈抢的太少。 比如100元分给10个人红包手游源码,第一个人会从0到100随机分配,平均值为50。而第二个人剩下的平均值只有25,然后是12.5。

而他们改变的计划大致就是先有保障。 然后随机,一般算法如下:

//普通法    有保底
//iTotalGold总金额    iNum份数    iBaseGold保底金额
void oldThink(int iTotalGold, int iNum, int iBaseGold)
{
  if (iBaseGold*iNum > iTotalGold)
  {
    cout << "保底太多 " << iBaseGold<<endl;
    return;
  }
  iTotalGold -= (iBaseGold *iNum);
  std::vector veGold(iNum);
  for (int i = 0; i < iNum-1; ++i)
  {
    int iAddNum = 0;
    if(iTotalGold != 0)
      iAddNum += rand() % (iTotalGold);
    veGold[i] = iAddNum + iBaseGold;
    iTotalGold -= iAddNum;
  }
  veGold[iNum - 1] = iTotalGold + iBaseGold;
  cout << "普通法:" << endl;
  copy(veGold.begin(), veGold.end(), ostream_iterator(cout, " "));
  cout << endl;
} 
​
int main()
{
    int iTotalGold = 100;
    int iNum = 10; 
    int iBaseGold = 5;
    oldThink(iTotalGold, iNum, iBaseGold);
    
    return 0;
}

2.线段切割法:将总量想象为这么长的线段,需要将其分为num份,随机num-1次,每个随机值映射到线段上。 这样做的用处是给程序赋予随机性,但缺点是有小概率会有人分配过多。 比如100人分享10个红包,我们不仅需要考虑随机值的重合性,而且每次都要完全随机,这可能会导致随机性不足。

//线段切割法    无保底
//iTotalGold总金额    iNum份数    iBaseGold保底金额
void cutline(int iTotalGold, int iNum)
{
  if (iNum > iTotalGold)
  {
    return;
  }
  if (iNum == iTotalGold)
  {
    for (int i = 0; i < iNum; ++i)
      cout << 1 << " ";
    cout << endl;
    return;
  }
  std::set setGold;
  for (int i = 0; i < iNum-1; ++i)
  {
    while (1)
    {
      int iPos = rand() % iTotalGold;
      if (setGold.find(iPos) == setGold.end())
      {
        setGold.insert(iPos);
        break;
      }
    }
  }
  cout << "线段切割法(无保底):" << endl;
  int iPreLine = 0;
  for (auto &it : setGold)
  {
    cout << it - iPreLine << " ";
    iPreLine = it;
  }
  cout << iTotalGold - iPreLine << " ";
  cout << endl;
}
​
int main()
{
    int iTotalGold = 100;
    int iNum = 10; 
    int iBaseGold = 5;
    cutline(iTotalGold, iNum);
    return 0;
}

红包手游源码-抢红包算法--四种抢红包算法对比(附源码)

这个算法已经比第一个算法更好了。 如果你觉得随机性太强,你可以为这些算法做一个保证策略。 可以预见,效果一定比第一个更好。

3、双倍随机法:每次随机,取每人平均金额的0-2倍进行随机。 这已经基本上达到了我们想要的效果,很好。 比如:100人分为10个点,每次随机都是0-100/10*2来随机化,基本可以保证每个人平均在10个左右,是一个相当平均的算法。 不过需要注意的是,最后的几个人可能还不到20人。

//双倍随机法
//iTotalGold总金额    iNum份数    iBaseGold保底金额
void twobase(int iTotalGold, int iNum, int iBaseGold)
{
  if (iNum *iBaseGold > iTotalGold)
  {
    cout << "保底太多 " << iBaseGold << endl;
    return;
  }
  std::vector veGold(iNum, iBaseGold);
  iTotalGold -= iNum*iBaseGold;
  int iBaseTmp = iTotalGold / iNum * 2;
  for (int i = 0; i = iBaseTmp)
      iTmp = rand() % iBaseTmp;
    else
      iTmp = rand() % iTotalGold;
    veGold[i] += iTmp;
    iTotalGold -= iTmp;
  }
  veGold[iNum - 1] = iTotalGold;
  cout << "双倍随机法:" << endl;
  copy(veGold.begin(), veGold.end(), ostream_iterator(cout, " "));
  cout << endl;
}
​
int main()
{
    int iTotalGold = 100;
    int iNum = 10; 
    int iBaseGold = 5;
    twobase(iTotalGold, iNum, iBaseGold);
  
    return 0;
}
​

从疗效可以看出,这种随机方法取得了非常好的随机疗效。 玩家投诉几乎杜绝。

4.我自创的名字,篮球投篮方法:之前我都是用金额消除人数num来求平均值。 篮球的投篮方式是按照投篮金额的单位价值来计算的。 以上三种算法都是尽量寻求随机性,而篮球投篮规则是保证完全平均。 例如:100人分为10分,每次取金额的最小单位值,比如1块钱,然后10个人当一个篮子,1块钱当一个足球,球每次都通过。 这样做的好处是不需要模仿完全随机,本身就是完全随机的,缺点也很明显,循环太多。

针对他循环太多的缺点,我自己做了一层优化。 使用最小数量的单位值,例如每次取三块或五块。 这种优化可以避免过多的循环。 其次,它还可以防止极端情况下结果过于随机。

//投篮球法    有保底
//iTotalGold总金额    iNum份数    iBaseGold保底金额
void basketball(int iTotalGold, int iNum, int iBaseGold)
{
  if (iBaseGold*iNum > iTotalGold)
  {
    cout << "保底太多 " << iBaseGold << endl;
    return;
  }
  iTotalGold -= (iBaseGold *iNum);
  std::vector veGold(iNum, iBaseGold);
  for (int i = 0; i < iTotalGold; i += 2) //这里基准值用了2,减少循环次数
  {
    int iPos = rand() % iNum;
    veGold[iPos] += 2;
  }
  cout << "投篮球法:" << endl;
  copy(veGold.begin(), veGold.end(), ostream_iterator(cout, " "));
  cout << endl;
}
​
int main()
{
    int iTotalGold = 100;
    int iNum = 10; 
    int iBaseGold = 5;
    basketball(iTotalGold, iNum, iBaseGold); 
      
    return 0;
}

闲人避免

红包手游源码-抢红包算法--四种抢红包算法对比(附源码)

我要假装

从物理理论的角度来看,只要随机数足够大,结果必然无限接近平衡。 因此,虽然这些算法的循环次数过多,但当数据量足够大时,它们必须是最优的、平衡的。

当然,算法是服务于功能的,上面的推论是有限的,规划者希望你得到的都是类似的。

最后,将四种算法一起运行来比较结果。

上图中还有一个小点,运行程序两次得到的结果是一模一样的。 这是因为旧版本C++中rand函数的随机因子是一个定值问题。 关于随机因素和随机数,改天有时间我会整理一篇文章来描述。

在这里,我们首先解决这些情况。 只需要在程序每次运行时重新指定随机因子即可。 例如:srand((无符号)时间(0));

运行结果:

源代码:

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
​
​
​
//普通法    有保底
//iTotalGold总金额    iNum份数    iBaseGold保底金额
void oldThink(int iTotalGold, int iNum, int iBaseGold)
{
    if (iBaseGold*iNum > iTotalGold)
    {
        cout << "保底太多 " << iBaseGold<<endl;
        return;
    }
    iTotalGold -= (iBaseGold *iNum);
    std::vector veGold(iNum);
    for (int i = 0; i < iNum-1; ++i)
    {
        int iAddNum = 0;
        if(iTotalGold != 0)
            iAddNum += rand() % (iTotalGold);
        veGold[i] = iAddNum + iBaseGold;
        iTotalGold -= iAddNum;
    }
    veGold[iNum - 1] = iTotalGold + iBaseGold;
    cout << "普通法:" << endl;
    copy(veGold.begin(), veGold.end(), ostream_iterator(cout, " "));
    cout < iTotalGold)
    {
        return;
    }
    if (iNum == iTotalGold)
    {
        for (int i = 0; i < iNum; ++i)
            cout << 1 << " ";
        cout << endl;
        return;
    }
    std::set setGold;
    for (int i = 0; i < iNum-1; ++i)
    {
        while (1)
        {
            int iPos = rand() % iTotalGold;
            if (setGold.find(iPos) == setGold.end())
            {
                setGold.insert(iPos);
                break;
            }
        }
    }
    cout << "线段切割法(无保底):" << endl;
    int iPreLine = 0;
    for (std::set::iterator it = setGold.begin(); it != setGold.end(); ++it)
    {
        cout << *it - iPreLine << " ";
        iPreLine = *it;
    }
    cout << iTotalGold - iPreLine << " ";
    cout < iTotalGold)
    {
        cout << "保底太多 " << iBaseGold << endl;
        return;
    }
    std::vector veGold(iNum, iBaseGold);
    iTotalGold -= iNum*iBaseGold;
    int iBaseTmp = iTotalGold / iNum * 2;
    for (int i = 0; i = iBaseTmp)
            iTmp = rand() % iBaseTmp;
        else
            iTmp = rand() % iTotalGold;
        veGold[i] += iTmp;
        iTotalGold -= iTmp;
    }
    veGold[iNum - 1] = iTotalGold;
    cout << "双倍随机法:" << endl;
    copy(veGold.begin(), veGold.end(), ostream_iterator(cout, " "));
    cout < iTotalGold)
    {
        cout << "保底太多 " << iBaseGold << endl;
        return;
    }
    iTotalGold -= (iBaseGold *iNum);
    std::vector veGold(iNum, iBaseGold);
    for (int i = 0; i < iTotalGold; i += 2) //这里基准值用了2,减少循环次数
    {
        int iPos = rand() % iNum;
        veGold[iPos] += 2;
    }
    cout << "投篮球法:" << endl;
    copy(veGold.begin(), veGold.end(), ostream_iterator(cout, " "));
    cout << endl;
}
​
int main()
{
    srand((unsigned)time(0));
    int iTotalGold = 100;
    int iNum = 10;
    int iBaseGold = 5;
    oldThink(iTotalGold, iNum, iBaseGold);
    cutline(iTotalGold, iNum);
    twobase(iTotalGold, iNum, iBaseGold);
    basketball(iTotalGold, iNum, iBaseGold);
    return 0;
}

建立手游平台源码,首先要了解手游平台源码是什么。 源代码是编程软件最原始的代码。 它是一种编程语言。 如果您不知道代码是什么,可以在浏览器中打开网页,然后按 F12 键。 您可以查看该页面的源代码。 源代码只有用专门的软件编译后才能运行。 可以直接更改游戏中的源代码来改变游戏类型的布局。 关于ios手游公益游戏公益相关信息,从专业的角度为您解答相关问题,为您提供优质的服务!

游戏建设

游戏源码系统平台有网站源码,可以优化网站、布局、界面等。提供100%本地系统娱乐开源游戏联运平台,方便二次开发,集成全套系统开发游戏官方网站、系统后台、渠道SKD等

源代码的好处:

1.它们会增加企业部署网络和各种服务的成本。 如果使用开源方案,只需要一台服务器,其他的可以免费使用windows,操作系统则要付费(假设没有盗版)。

红包手游源码-抢红包算法--四种抢红包算法对比(附源码)

2、二次开发可以在源代码的基础上建立或丰富现有的系统功能。

3.参考研究。 通过剖析源码,我们可以学习开发,了解开发者的视角,了解开发者如何聪明地解决业务问题。 阅读源代码是提高开发技能的捷径。

4、拥有源代码可以抢占先机。 如果开发商的报价远远超过市场价格用于后期运维或减少功能,而客户有源代码手游源码合集,则可以考虑更换开发商,而不是重新绘制整个软件。

因为每个业务、每个客户的需求可能不同,所以可以选择有源代码的公司。 您可以自由修改源代码并进行二次开发。 如何订购OEM平台? 如果难以获取源代码,就很难进行二次开发。 限制太多了。 为此手游源码合集,订阅源系统并自己控制它是最好的新交易。

选择一个可靠的手机游戏平台非常重要。 一个好的起点,可以决定你少走多少弯路,你就能快速开始赚钱。 小型手游平台是菜鸟游戏代理商的首选。 可为新手游戏代理商提供一对一的客服指导和咨询。 源代码开源,源代码开源支持二次开发。 游戏的选择将变得更加严格和精准,新手游戏代理商可以快速找到好的推广游戏。

手机游戏代理作为一种新兴的创业项目,随着游戏的流行而诞生。 可以说,只要游戏三天不涨,手游机构的收入就持续可观。 手游代理行业的发展尚未达到顶峰,仍有进一步发展的空间。

从近几年的趋势来看,手机游戏行业已经成为很多人的选择。 事实上,很多人对手游创业了解不够。 手游创业的范围比较广,但就目前热门的手游创业项目而言,我们可以采用手游代理作为手游创业的一种形式。 顾名思义,手游代理就是代理游戏,然后运营推广,最终获得收益分成。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 手游资源 红包手游源码-抢红包算法--四种抢红包算法对比(附源码) https://www.wkzy.net/game/138466.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务