Simple algorithm implementation for selecting a specified number of records based on weights randomly (C #)

Source: Internet
Author: User
Tags random seed


A. Application scenario:

Sometimes we need to choose from a number of columns in accordance with the weight of the random selection of the specified number of records, here need to weight, random, we according to the greater the weight, the probability of the greater the occurrence . For example, the advertising system: can be based on the amount of customer payments to control the probability of the customer's advertising, the greater the amount of customer pay, the more frequent the frequency of advertising, for example: added 10 ads, and then each ad has a weight, we have to choose 5 ads per weight to show. With the need, we will solve, this article is to use a simple algorithm to achieve random selection according to weights.

Two. Implementation of the simple algorithm:

According to our needs, the Internet to find a lot of information, have not found a more suitable solution, on their own think of a simple implementation plan, try a bit, the effect is quite good, and now share with you, there are unreasonable or wrong place, but also hope you master correction. Less nonsense, in fact the algorithm is very simple, as follows:

    1. Each ad has a weight, expressed in W. We assume that the minimum weight is 1, and the larger the number the higher the weight.
    2. Calculates the sum of the weights for all ads, denoted by sum.
    3. Iterate through each ad, add its weight w to a random number from 0 to (SUM-1) (that is, the random number within the sum of the weights), and get a new weighted sort value, expressed in S.
    4. Sort values from large to small according to the ad weights.
    5. Selecting the first few records based on the sorting results is the result we need.

The simple principle is as follows:

1. If we have a, B, C, D four ads, the weights are 1, 2, 3, 4, the total weight of sum=1+2+3+4=10.

2. By its weight value and a random value less than sum (due to sum=10, the range of random values is 0~9) is added, to get a weight sorting value, as follows:

Advertising
Weight value
Minimum weight sort value
Maximum weight sort value

A
1
1+0=1
1+9=10

B
2
2+0=2
2+9=11

C
3
3+0=3
3+9=12

D
4
4+0=4
4+9=13

3. The range of a, B, C and D can be obtained from the above, it can be seen that a is the number between 1~10, and the range of D is 4~13, thus it can be seen that D obtains the probability of large random number is relatively large. So we just order according to its occurrence probability, and then select the ranking in the weight of a larger than the first few items, this can get what we need according to the weight of the selection of the probability of advertising.

Three. Implementation of the C # code algorithm:

1. First we declare a weight base class Randomobject, and then just inherit the class. The code is as follows:

<summary>
Weight Object
</summary>
public class Randomobject
{
<summary>
Weight
</summary>
public int Weight {set; get;}
}

In this class we define only one weight attribute, and other attributes can be implemented by the class that inherits it according to the specific business.

2. Create a helper class Randomhelper, and add a function that implements random selection of the number of bars based on the weights, with the following code:

<summary>
Algorithm:
1. The weight of each ad item +1 is named W, which prevents 0 cases.
2. Calculate the total weight n.
3. Each ad item weights w plus a random number from 0 to (n-1) (that is, a random number within the total weight), to get the new weighted sort value s.
4. According to get the new weight sort value s to order, take the front s maximum several.
</summary>
<param name= "List" > original list </param>
<param name= "Count" > number of randomly drawn strips </param>
<returns></returns>
public static list<t> getrandomlist<t> (list<t> List, int count) where t:randomobject
{
if (list = = NULL | | list. Count <= Count | | Count <= 0)
{
return list;
}

Calculate the sum of weights
int totalweights = 0;
for (int i = 0; i < list. Count; i++)
{
Totalweights + = List[i]. Weight + 1; A weight of +1 prevents the condition from being 0.
}

Random Assignment weights
Random ran = new Random (Getrandomseed ()); Getrandomseed () random seed to prevent quick and frequent calls causing random problems
List<keyvaluepair<int, int>> wlist = new List<keyvaluepair<int, int>> (); The first int is the list subscript index, the first int is the weight sort value
for (int i = 0; i < list. Count; i++)
{
int w = (List[i]. Weight + 1) + ran. Next (0, totalweights); (weight + 1) + random number from 0 to (total weight-1)
Wlist. ADD (New Keyvaluepair<int, int> (i, W));
}

Sort
Wlist. Sort (
Delegate (Keyvaluepair<int, int> kvp1, Keyvaluepair<int, int> KVP2)
{
Return KVP2. Value-kvp1. Value;
});

According to the actual situation to take the first few
list<t> NewList = new list<t> ();
for (int i = 0; i < count; i++)
{
T entiy = List[wlist[i]. Key];
Newlist.add (entiy);
}

Random law
return newlist;
}

For each scenario, we define t as a generic class that must inherit the Randomobject class and implement its own class information. This method has a related comment, which is not repeated in detail here.

Pay special attention to the Getrandomseed () function, which is to prevent the frequent creation and invocation of random in a short period of time, there will be a repeated number of randomly (that is, random is not a random problem), the function code is as follows:

    <summary>
Random seed value
</summary>
<returns></returns>
private static int getrandomseed ()
{
byte[] bytes = new Byte[4];
System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider ();
Rng. GetBytes (bytes);
Return Bitconverter.toint32 (bytes, 0);
}

3. Call Method:

Invoking the method is simple, just declare one of your own entities, integrate the object, and then call the Randomhelper.getrandomlist () method directly according to the actual situation.

As follows:

//1. Declares an entity class that inherits Randomobject, such as: * 
public class Advertentity:randomobject
{
///<summary>
// Name
//</summary>
public string name {set; get;}
//<summary>
//Description
//</summary>
public string Description {set; get;}
//... Other related fields/properties
}

//2. Initialize call data, such as:
/Initialize simulation weight data
list<advert> List = new list<advert> ();
List. ADD (new advert {Name = "A", Weight = 1});
List. ADD (new advert {Name = "B", Weight = 2});
List. ADD (new advert {Name = "C", Weight = 2});
List. ADD (new advert {Name = "D", Weight = 3});
List. ADD (new advert {Name = "E", Weight = 4});
List. ADD (new advert {Name = "F", Weight = 5});
List. ADD (new advert {Name = "G", Weight = 60});
//Random fetch of the specified number of records by weight
list<advert> newlist = randomhelper.getrandomlist<advert> (List, 2); This is the usage, NewList is the random record (the second parameter is the number of random fetch)

Four. The test run results are as follows:

Simple algorithm implementation for selecting a specified number of records based on weights randomly (C #)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.