Compared stable algorithm red envelope / c language

Distribution of red packets distributed, personally think that can be applied to the normal distribution is excellent, few people are lucky, luck, poor people are less, but Benpian algorithm does not intend to use the characteristics of the normal distribution to achieve allocated envelopes algorithm (I too much food), but produce a relatively stable red envelope, to some extent, can be considered a positive too is in line algorithm distribution characteristics (distributed to some extent the world a lot of things on the normal distribution are met, I understand: 1, the total amount is fixed constant (remember specific characteristics) ,; 2, distribution is less presented both sides more than the middle;).

Here the idea of ​​the algorithm involved in the more important point

    1. random dichotomy (I take the name probably means that the use of a random number, a larger value randomly divided into two smaller values).

    2. Each time the set (out of the split node) in the maximum value of the split node.

 The basic data structure algorithms involved in the introduction:

    1. Node, red nodes, attributes (amount, front-rear adjacent node pointer red)

    2. List, the list attribute (the total number of red packets, the total amount of red, head pointer pointing to the maximum amount of red, and a tail pointer pointing to the minimum amount)

Algorithmic process:

    1 first initializes the list (the total number of red and the total amount), and the total amount of insertion envelopes node linked list; 

    2. Remove the node maximum red, the amount of which is divided, the divided amount of generated red two nodes;

    3. The segmented node into the list of red;

    4. The number of red performs 2, 3 process until the expected split

    ... todo, you can get a red envelope nodes descending order by traversing the list. May be implemented in accordance with the rules (as acquired large red person who is relatively fast, etc.), regular node or irregular upset then placed in the queue, it is removed when the red grab i.e. from the queue can.

 

The following is the source code algorithms:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <malloc.h>

const float MIN = 0.01;
const float MIN_LIMIT_PERCENT = 0.5;
const float ROUND_FLOAT = 0.005;

/*----------- 涉及到的数据结构的定义*/
/*=======Node */
typedef struct Node{
    float val;          //值
    struct Node * pre;
    struct Node * next;
} nod;

nod * create_node(float value)
{
    nod * node = (nod *)malloc(sizeof(nod));
    node->val = value;
    node->pre = NULL;
    node->next = NULL;
    return node;
}

void rep_node(nod * before, nod * cur)
{
    cur->next = before->next;
    cur->pre = before;
    before->next->pre = cur;
    before->next = cur;
}

/*=======list */
typedef struct List{
    nod * tail;    //链表尾部
    nod * head;    //链表头部
    int number;     //结点数量
    float value;    //链表总值
} LT;

void init_lt(LT * l, float value, int number)
{
    l->tail = NULL;
    l->head = NULL;
    l->number = number;
    l->value = value;
}

nod * get_head(LT * l)
{
    return l->head;
}

nod * pop(LT * l)
{
    nod * node = l->head;
    if(!node)
    {
        return node;
    }
    nod * n_head = node->next;
    node->next = NULL;
    l->head = n_head;
    if(!l->head)
    {
        l->tail = NULL;
    }
    return node;
}

void inst_node(LT * l, nod * node)
{
    nod * head = l->head;
    if(!head)
    {
        l->head = node;
        l->tail = node;
        return;
    }
    nod * before;
    nod * go = head;
    while(go && go->val > node->val)
    {
        before = go;
        go = go->next;
    }
    if(!go)
    {
        before->next = node;
        l->tail = node;
    }
    else
    {
        //链表头节点置换
        if(go == head)
        {
            node->next = head;
            l->head = node;
        }
        else
        {
            rep_node(before, node);
        }
    }
    return;
}


/*----------- 涉及到的算法*/
float random(int mask)
{
    int random = rand();
    //printf("random:%d, mask:%d, div:%d, mid:%0.4f\n", random, mask, (random%mask+1), (float)(random%mask+1)/(mask+2));
    return (float)((int)((((float)(random%mask+1)/(mask+2))+0.0005)*1000))/1000;
}

//分割一个数
float divide(float value, float percent)
{
    //printf("percent:%f\n", percent);
    return (float)((int)((value*percent+ROUND_FLOAT)*100))/100;
}

/*----------- process*/
void work(LT * l, float money, int count)
{
    srand(time(NULL));
    nod * mey = create_node(money);
    inst_node(l, mey);
    int mask = count-1;
    //将money分割count次
    while(count-- > 0)
    {
        //将最大节点弹出
        nod * max_value_node = pop(l);
        //printf("node:%0.2f, count:%d\n", max_value_node->val, count);
        //产生一个随机数, 随机切分最大节点的值c,产生两个数a、b, c = a+b;
        //float div_left = divide(max_value_node->val, random(count+1));    //波动幅度较下面的小
        float div_left = divide(max_value_node->val, random(mask));         //波动幅度较上面的大
        //当数值及其小时,采取对分的方法,将value分割开来
        if(div_left - 0 < MIN || max_value_node->val - div_left < MIN)
        {
            div_left = (float)((int)(((max_value_node->val*MIN_LIMIT_PERCENT)+ROUND_FLOAT)*100))/100;
        }
        float div_right = max_value_node->val - div_left;
        //生成两个节点a, b;
        nod * left_nod = create_node(div_left);
        nod * right_nod = create_node(div_right);
        //printf("left:%0.2f, right:%0.2f\n", div_left, div_right);
        //依次插入链表中
        inst_node(l, left_nod);
        inst_node(l, right_nod);
        free(max_value_node);
    }
    printf("============= result =============\n");
    _print(l);
}


/*----------- test*/
void _print(LT * l)
{
    nod * go = l->head;
    int count = 0;
    float sum = 0.00;
    while(go)
    {
        count++;
        sum += go->val;
        printf("node->value:%0.3f\n", go->val);
        go = go->next;
    }
    printf("sum:%0.2f, count:%d", sum, count);
}

/*----------- main*/
int main()
{
    float money = 100.00;        //红包总金额
    int number = 100;            //红包个数
    if(money/number - MIN < 0) {
        return 0;
    }
    //创建一个链表
    LT * l = (LT *)malloc(sizeof(LT));
    init_lt(l, money, number);
    //printf("number:%d, value:%0.2f\n", l->number, l->value);
    work(l, money, number-1);
    return 0;
}

 

Before going to bed think of a question, and then come up with this method, Oh ~

Published 31 original articles · won praise 3 · views 10000 +

Guess you like

Origin blog.csdn.net/qq_36557960/article/details/100171512