Click here to Skip to main content
Click here to Skip to main content

Weighted Generic Lottery in C#

, 26 Jun 2013
Rate this:
Please Sign up or sign in to vote.
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:

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

Using the Code

Copy the following class into your solution:

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:

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)

About the Author

Hossein Montazeri
Software Developer (Senior) FDK
Iran (Islamic Republic Of) Iran (Islamic Republic Of)
No Biography provided

Comments and Discussions

 
QuestionNot Bad PinmemberJason Storey20-Jun-13 6:06 
AnswerRe: Not Bad PinmemberHossein Montazeri19-Jul-13 19:11 

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

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

| Advertise | Privacy | Mobile
Web04 | 2.8.140721.1 | Last Updated 27 Jun 2013
Article Copyright 2013 by Hossein Montazeri
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid