Version 1:
昨天写了一个模拟微信红包的算法,后来发现粗略的以红包里剩余的钱为每个红包的最大值会导致第一个红包很容易抢的很大,所以这次修改了每个红包的最大值,代码如下:
#include "stdio.h"
#include "stdlib.h"
#include "time.h"
void EntryPoint(double money,int count){
double value = money;
srand((unsigned)time(NULL)); //makesure the random every time is diffrent
int max = money / count * 1.5 * 100; //max value of each redpacket
double LuckMan = 0.1;
int LuckManNum = 1;
double UnLuckMan = money;
int UnLuckManNum = 1;
double MaxGap = 0;
for (int index = 1; index <= count; index++)
{
if (index == count){ //the last people
value = money;
}
else
{
value = rand() % max + 1;
value = value / 100;
for (; value > money - 0.1 * (count - index);)
{
value = rand() % max + 1;
value = value / 100;
}
}
LuckMan = value > LuckMan ? value : LuckMan;
LuckManNum = LuckMan <= value ? index : LuckManNum;
UnLuckMan = value < UnLuckMan ? value : UnLuckMan;
UnLuckManNum = UnLuckMan >= value ? index : UnLuckManNum;
MaxGap = LuckMan - UnLuckMan;
money = money - value;
printf("this is the %d red packet,value is =%.2f\n",index,value);
}
printf("the Luck Man's number is %d,value is %.2f; \n",LuckManNum,LuckMan);
printf("the Unluck Man's number is %d,value is %.2f;\n",UnLuckManNum,UnLuckMan);
printf("the max gap is %.2f \n",MaxGap);
}
int main() {
double money = 4.88;
int count = 5;
EntryPoint(money,count);
return 0;
}
运行效果如下,如此分析,前面抢的人红包范围都比较稳定,最后一个人属于风险比较大,取决于前面人抢完后,红包里钱的多少,即容易抢到最大的红包,也容易因为前面人都抢的很多,抢到剩下很少的红包。
但是数据多了之后还是很不合理!
所以还是需要改进。
Version 2:
#include "stdio.h"
#include "stdlib.h"
#include "time.h"
#include "math.h"
#define PeopleNum 10
#define RedPacetNum 500
struct RedPacketDate
{
int LuckManNum;
int UnLuckManNum;
double Variance;
};
int PacketAllocate(int PacketNum, double Money, RedPacketDate &OneCase){
int index;
double CurrentValue = Money;
double LuckManMoney = 0.1;//This value will increase when there is a bigger Redpackge
int LuckManNum = 1;
double UnLuckManMoney = Money;//This value will reduse when there is a less Redpackge
int UnLuckManNum = 1;
int max = Money / PacketNum * 2.2 * 100; //max value of each redpacket
OneCase.Variance = 0;
for (index = 1; index <= PacketNum; index++)
{
if (index == PacketNum){ //the last people
CurrentValue = Money;
}
else
{
CurrentValue = rand() % max + 1;
CurrentValue = CurrentValue / 100;
for (; CurrentValue > Money - 0.1 * (PacketNum - index);)
{
CurrentValue = rand() % max + 1;
CurrentValue = CurrentValue / 100;
}
}
//update the correct value
LuckManNum = LuckManMoney <= CurrentValue ? index : LuckManNum;
LuckManMoney = CurrentValue > LuckManMoney ? CurrentValue : LuckManMoney;
//printf("luckmannum = %d \n",LuckManNum);
UnLuckManNum = UnLuckManMoney >= CurrentValue ? index : UnLuckManNum;
UnLuckManMoney = CurrentValue < UnLuckManMoney ? CurrentValue : UnLuckManMoney;
Money = Money - CurrentValue;
OneCase.Variance = (OneCase.Variance + pow((CurrentValue - Money / PacketNum), 2)) / 2;
}
OneCase.LuckManNum = LuckManNum;
OneCase.UnLuckManNum = UnLuckManNum;
return 1;
}
void EntryPoint(int packetcount,double money,int count){
int status;
double value = money;
double temp = money;
srand((unsigned)time(NULL)); //makesure the random every time is diffrent
int max = money / count * 2.2 * 100; //max value of each redpacket
RedPacketDate OnePacketCase[RedPacetNum];
int LuckManMoney[PeopleNum] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
double Variance[500];
double AveVariance = 0;
int index = 0;
for (index = 0; index < packetcount; index++){
status = PacketAllocate(count, money, OnePacketCase[index]);
LuckManMoney[OnePacketCase[index].LuckManNum-1] += 1;
money = temp;
}
for (index = 0; index < sizeof(LuckManMoney)/sizeof(int); index++){
printf("the chence of the Man's number is %d got the LuckManMoney is %0.2f%%\n", index + 1, ((double)LuckManMoney[index] / packetcount*100));
}
for (index = 0; index < packetcount;index++){
AveVariance += OnePacketCase[index].Variance;
}
printf("variance is %f \n", AveVariance/packetcount);
}
int main() {
int packcount = 500;
double money = 100;
int count = 10;
EntryPoint(packcount,money,count);
return 0;
}
这版本的代码就是增加了一个统计的功能,初步设定了500个红包,每个红包里面都是100元,分别给十个人抢,最后统计运气王是第几个人抢到的,然后算这些每个红包的方差然后把所有方差平均一下;这样方便我们看到这个红包分配算法之下,抢红包的顺序不同所造成的影响;
当然腾讯是不会用这么low的红包分配算法的啦,我们只是写着瞎玩娱乐嘛!