Click here to Skip to main content
15,885,674 members
Articles / Programming Languages / C#
Tip/Trick

Weighted Generic Lottery in C#

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
26 Jun 2013CPOL 27.6K   793   14   2
A class to conduct a lottery, based on different chances of winning for every participant

Introduction

Generating a random number is quite easy in C# but if you need to pick a winner from a list based on different chances for different participants, you'll need to do more than just generating some random numbers. 

Here is a generic class allowing you to define a lottery and add tickets with different weights (or equal). By calling the Draw() method, you'll get the next winner. The removeWinner parameter specifies whether the winner will be removed from the list or not.

Math

Assume all tickets are in an array called tickets[] and every ticket has a weight of w and the sum of all weights in the array is stored in sum, then the probability of each ticket (ticket.p) is:

C#
tickets[i].p = tickets[i].w / sum

Using the Code

Copy the following class into your solution:

C#
public class Lottery<T>
{
    public class Ticket
    {
        public T Key { get; private set; }
        public double Weight { get; private set; }
        public Ticket(T key, double weight)
        {
            this.Key = key;
            this.Weight = weight;
        }
    }
    List<Ticket> tickets = new List<Ticket>();
    static Random rand = new Random();
    public void Add(T key, double weight)
    {
        tickets.Add(new Ticket(key, weight));
    }
    public Ticket Draw(bool removeWinner)
    {
        double r = rand.NextDouble() * tickets.Sum(a => a.Weight);
        double min = 0;
        double max = 0;
        Ticket winner = null;
        foreach (var ticket in tickets)
        {
            max += ticket.Weight;
            //-----------
            if (min <= r && r < max)
            {
                winner = ticket;
                break;
            }
            //-----------
            min = max;
        }
        if (winner == null) throw new Exception();
        if (removeWinner) tickets.Remove(winner);
        return winner;
    }
}

And use it like:

C#
var lottery = new Lottery<string>();
lottery.Add("Mr. A", 1);
lottery.Add("Ms. B", 2);
lottery.Add("Ms. C", 3);
var winner = lottery.Draw(true);

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) FDK
Iran (Islamic Republic of) Iran (Islamic Republic of)
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionNot Bad Pin
Jason Storey20-Jun-13 6:06
Jason Storey20-Jun-13 6:06 
AnswerRe: Not Bad Pin
Hossein Montazeri19-Jul-13 19:11
professionalHossein Montazeri19-Jul-13 19:11 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.