A Simple Algorithm for randomly selecting a specified number of records based on the weight (C #) [including source code]

Source: Internet
Author: User
Tags random seed

I. Application scenarios:

Sometimes we need to randomly select a specified number of records from some column data based on the weight. Here we need weight and random. The higher the weight, the higher the probability of occurrence. For example, the advertising system can adjust the probability of advertisement appearance based on the amount paid by the customer. The larger the payment amount, the more frequent the advertisement appears. For example, 10 advertisements are added, then each advertisement has a weight. Each time we select five Advertisements based on the weight for display. We can solve the problem as needed. This article uses a simple algorithm to achieve random selection based on weights.

 

II. Implementation of simple algorithms:

According to our needs, I found a lot of information online and did not find a suitable solution. I thought of a simple implementation solution and tried it. The effect was quite good, I would like to share with you the unreasonable or incorrect information. I hope you can correct it. The algorithm is actually very simple, as follows:

1. Each advertisement has a weight, represented by W. We assume that the minimum weight is 1, and the larger the number, the higher the weight.
2. Calculate the total weights of all ads, expressed by SUM.
3. traverse each advertisement and add its weight W to a random number from 0 to (SUM-1) (that is, a random number within the SUM of weights) to obtain a new weight sorting value, in seconds.
4. Sort the order value S from large to small based on the weight of the advertisement.
5. Select the first few records based on the sorting result, which is the result we need.
The simple principle is as follows:

1. assume that we have four advertisements, A, B, C, and D, and their weights are 1, 2, 3, and 4, respectively, the total weight is SUM = 1 + 2 + 3 + 4 = 10.

2. According to its weight value and a random value smaller than SUM (because SUM = 10, the random value range is 0 ~ 9) Add to get a weight sorting value, as shown below:
 

Advertisement Weight Minimum weight sorting Value Maximum weight sorting 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, we can see that A is 1 ~ The number between 10, and the range of D is 4 ~ 13. It can be seen that the probability of a random number greater than D is relatively high. Therefore, we only need to sort the order based on the probability of occurrence, and then select the first few items with a relatively large weight sorting value. This gives us the expected advertisement Based on the probability of weight selection.

III. C # Implementation of code algorithms:
1. First, declare a weight base class RandomObject. Later, you only need to inherit this class. The Code is as follows:
/// <Summary>
/// Weight object
/// </Summary>
Public class RandomObject
{
/// <Summary>
/// Weight
/// </Summary>
Public int Weight {set; get ;}
}

This class only defines one Weight attribute. Other attributes can be implemented by the class inheriting it according to the specific business.
 
2. Create a helper class RandomHelper and add a function to randomly select a number based on the weight. The Code is as follows:
 
/// <Summary>
/// Algorithm:
/// 1. The weight of each ad item + 1 is named as w to prevent the value from being 0.
/// 2. Calculate the total weight n.
/// 3. Add a random number from 0 to (n-1) to the weight w of each ad item to obtain the new weight sorting value s.
/// 4. sort by the new weight sorting value s, and take the largest number of values in the previous s.
/// </Summary>
/// <Param name = "list"> original list </param>
/// <Param name = "count"> Number of randomly selected entries </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; // Weight + 1 to prevent the value from being 0.
}

// Random Weight Assignment
Random ran = new Random (GetRandomSeed (); // GetRandomSeed () Random Seed to prevent the same Random problem caused by fast and frequent calls
List <KeyValuePair <int, int> wlist = new List <KeyValuePair <int, int> (); // The first int Is the list subscript index, and the first int Is the weight sorting value.
For (int I = 0; I <list. Count; I ++)
{
Int w = (list [I]. weight + 1) + ran. next (0, totalWeights); // random number (weight + 1) + 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;
});

// Select the first few items based on the actual situation
List <T> newList = new List <T> ();
For (int I = 0; I <count; I ++)
{
T entiy = list [wlist [I]. Key];
NewList. Add (entiy );
}

// Random rule
Return newList;
}
 

 
To suit various scenarios, we define T as a generic class, which must inherit the RandomObject class and implement its own class information. This method has related comments and will not be described in detail here.
 
Pay special attention to the GetRandomSeed () function, which is used to prevent repeated Random numbers (that is, Random numbers are not Random) When Random is frequently created and called in a short period of time ), 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:
The call method is very simple. You only need to declare your own entity, integrate the Object, and then directly call the RandomHelper. GetRandomList () method based on the actual situation.
As follows:
 
// 1. Declare an object class that inherits RandomObject, such :*
Public class AdvertEntity: RandomObject
{
/// <Summary>
/// Name
/// </Summary>
Public string Name {set; get ;}
/// <Summary>
/// Description
/// </Summary>
Public string Description {set; get ;}
//... Other related fields/attributes
}

// 2. initialize the call data, such:
// Initialize the simulated 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 });
// Randomly retrieve the specified number of records based on the weight
List <Advert> newList = RandomHelper. GetRandomList <Advert> (list, 2); // This is the usage. newList is the records randomly retrieved (the second parameter is the number of random Records)

 
 
 
 
 
4. The test result is as follows:




 


 

5. Source Code download: http://www.bkjia.com/uploadfile/2012/0323/20120323085926146.zip
 


From sporadic incidents
 

 

Related Article

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.