Results 1 to 30 of 30

Thread: [RESOLVED] Randomly selected item from list which have a %

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Aug 2011
    Posts
    70

    Resolved [RESOLVED] Randomly selected item from list which have a %

    Basically, I know how to get a random number but I'm not sure how to select an item from a list which has a percentage of being randomly selected.

    EG. If this is my list

    Red - 10%
    Blue - 25%
    Green - 7%
    Yellow - 58%

    I then declare a random which selects an item based off their percentage. So yellow is likely to be selected and green the least likely.

    How would I go around doing that.



    [RESOLVED]

    I used some of these posts solutions and wrote the code myself. Its minimal which i like and it works on bigger decimal probabilities.

    Code:
     Dim useRandom As New Random
            Select Case (Math.Round(useRandom.NextDouble(), 2))
                Case 0 To 0.25
                    MsgBox("Red")
                Case 0.26 To 0.5
                    MsgBox("Blue")
                Case 0.51 To 0.75
                    MsgBox("Green")
                Case 0.76 To 1
                    MsgBox("Yellow")
            End Select
    Last edited by xx_dan_xx; May 24th, 2013 at 09:24 AM.

  2. #2
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 2012
    Posts
    8,245

    Re: Randomly selected item from list which have a %

    Select a random number from 1 to 100, then use a select case. 1-10 is Red, 11-35 is Blue and so on.
    As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"

    Reviews: "dunfiddlin likes his DataTables" - jmcilhinney

    Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!

  3. #3

    Thread Starter
    Lively Member
    Join Date
    Aug 2011
    Posts
    70

    Re: Randomly selected item from list which have a %

    Yeah I had that idea but for some reason I thought they may of been a easier way because I'll have to figure out what number ranges equals what % because some get really small. Thanks

  4. #4
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 2012
    Posts
    8,245

    Re: Randomly selected item from list which have a %

    It's just adding up.

    1 to P1
    P1+1 to P1 + P2
    P1+P2+1 to P1+P2+P3

    If you have fractional percentages (eg. 30.5% then multiply everything by 10 as many times as it takes to make all the values integers)
    As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"

    Reviews: "dunfiddlin likes his DataTables" - jmcilhinney

    Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!

  5. #5
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Posts
    12,376

    Re: Randomly selected item from list which have a %

    What is done in role playing board/computer games is a dice is rolled to determine an outcome. JMcIlhinney has a code bank post here that is a Die(singular of dice) class. I would be tempted to use that.
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | HtmlLessons | CssLessons | Code Tags | Sword of Fury - Jameram

  6. #6
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,415

    Re: Randomly selected item from list which have a %

    here's my attempt at a solution:

    Code:
    Imports System.Text.RegularExpressions
    
    Public Class Form1
    
        Dim r As New Random
        Dim colors As New Dictionary(Of Integer, String)
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            colors.Add(7, "Green")
            colors.Add(10, "Red")
            colors.Add(25, "Blue")
            colors.Add(58, "Yellow")
            ListBox1.Items.AddRange(Array.ConvertAll(colors.Values.ToArray, Function(s) s & " (0)"))
        End Sub
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            For y As Integer = 1 To 10000
                Dim x As Integer = r.Next(1, 1451)
                Dim listIndex As Integer
                '/7 = 1450
                '/10 = 1015
                '/25 = 406
                '/58 = 175
    
                Select Case x
                    Case Is > 1015
                        listIndex = r.Next(0, 4)
                    Case Is > 406
                        listIndex = r.Next(1, 4)
                    Case Is > 175
                        listIndex = r.Next(2, 4)
                    Case Is > 0
                        listIndex = 3
                End Select
    
                Dim rx As New Regex("(Red|Blue|Green|Yellow)\s\((\d+)\)")
                ListBox1.Items(listIndex) = Regex.Replace(ListBox1.Items(listIndex).ToString, rx.ToString, "$1 (" & (CInt(rx.Match(ListBox1.Items(listIndex).ToString).Groups(2).Value) + 1).ToString & ")")
            Next
        End Sub
    
    End Class

  7. #7
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 2012
    Posts
    8,245

    Re: Randomly selected item from list which have a %

    Quote Originally Posted by dday9 View Post
    What is done in role playing board/computer games is a dice is rolled to determine an outcome. JMcIlhinney has a code bank post here that is a Die(singular of dice) class. I would be tempted to use that.
    How is that different to getting a random number from 1 to 100?
    As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"

    Reviews: "dunfiddlin likes his DataTables" - jmcilhinney

    Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!

  8. #8
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 2012
    Posts
    8,245

    Re: Randomly selected item from list which have a %

    here's my attempt at a solution:
    Have you been at the Horlick's again?
    As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"

    Reviews: "dunfiddlin likes his DataTables" - jmcilhinney

    Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!

  9. #9
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Posts
    12,376

    Re: Randomly selected item from list which have a %

    Quote Originally Posted by dunfiddlin View Post
    How is that different to getting a random number from 1 to 100?
    It's all the same, just a different spin on it. I personally prefer the rolling a die method, somebody else may prefer the method you presented.
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | HtmlLessons | CssLessons | Code Tags | Sword of Fury - Jameram

  10. #10
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,415

    Re: Randomly selected item from list which have a %

    ok. maybe there's a better solution.

  11. #11
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: Randomly selected item from list which have a %

    Quote Originally Posted by dday9 View Post
    It's all the same, just a different spin on it. I personally prefer the rolling a die method, somebody else may prefer the method you presented.
    Maybe I am just being dense, but how does the roll of a die work in this case?
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  12. #12
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 2012
    Posts
    8,245

    Re: Randomly selected item from list which have a %

    Quote Originally Posted by dbasnett View Post
    Maybe I am just being dense, but how does the roll of a die work in this case?
    it doesn't strictly speaking. Those of us that can remember the heyday of board games that used actual boards will be familiar with percentage dice, two dice of differing colours numbered 0 - 9. You'd roll them and take the red one as tens, and the blue as units, for example, to get a number from 00 - 99.
    As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"

    Reviews: "dunfiddlin likes his DataTables" - jmcilhinney

    Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!

  13. #13
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,415

    Re: Randomly selected item from list which have a %

    Quote Originally Posted by dunfiddlin View Post
    Have you been at the Horlick's again?
    I reckon you should post a proveable solution...

  14. #14
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 2012
    Posts
    8,245

    Re: Randomly selected item from list which have a %

    Isn't Horlick's a suspension rather than a solution?
    As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"

    Reviews: "dunfiddlin likes his DataTables" - jmcilhinney

    Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!

  15. #15
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: Randomly selected item from list which have a %

    Quote Originally Posted by dunfiddlin View Post
    it doesn't strictly speaking. Those of us that can remember the heyday of board games that used actual boards will be familiar with percentage dice, two dice of differing colours numbered 0 - 9. You'd roll them and take the red one as tens, and the blue as units, for example, to get a number from 00 - 99.
    Ten sided die? What about the other colors the OP mentioned?
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  16. #16
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 2012
    Posts
    8,245

    Re: Randomly selected item from list which have a %

    Yup 10 sided.

    Name:  d10-image-1.jpg
Views: 250
Size:  53.2 KB

    I've still got a couple of pairs knocking around somewhere. You could also get 12 and 20 sided though I never personally found a use for them.
    As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"

    Reviews: "dunfiddlin likes his DataTables" - jmcilhinney

    Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!

  17. #17

    Thread Starter
    Lively Member
    Join Date
    Aug 2011
    Posts
    70

    Re: Randomly selected item from list which have a %

    Colours were an example. I have a list of 20+ items each assigned a percentage. Then a random is used to return one of those items based of the percentage and some % are below 1. Would be inefficient I think to use dice.

  18. #18
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,415

    Re: Randomly selected item from list which have a %

    Code:
    Dim greens() As Integer = Enumerable.Range(0, 7).Select(Function(i) 0).ToArray 'seven elements of one hundred assigned value 0
    Dim reds() As Integer = Enumerable.Range(0, 10).Select(Function(i) 1).ToArray 'ten elements of one hundred assigned value 1 
    Dim blues() As Integer = Enumerable.Range(0, 25).Select(Function(i) 2).ToArray 'twenty five elements of one hundred assigned value 2
    Dim yellows() As Integer = Enumerable.Range(0, 58).Select(Function(i) 3).ToArray 'fifty eight elements of one hundred assigned value 3
    
    Dim possibles() As Integer = greens.Concat(reds).Concat(blues).Concat(yellows).ToArray 'join the four arrays
    
    Dim x As Integer = r.Next(0, 100) 'pick a random number 0 to 99
    Dim listIndex As Integer = possibles(x) 'listIndex will equal 0, 1, 2, or 3 with a 7% chance of 0, 10% chance of 1, 25% chance of 2, + 58% chance of 3
    edit: to make it more random:

    Code:
    possibles = possibles.OrderBy(Function(i) r.NextDouble).ToArray
    Last edited by .paul.; May 23rd, 2013 at 03:52 PM.

  19. #19
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: Randomly selected item from list which have a %

    Quote Originally Posted by xx_dan_xx View Post
    Colours were an example. I have a list of 20+ items each assigned a percentage. Then a random is used to return one of those items based of the percentage and some % are below 1. Would be inefficient I think to use dice.
    Do the percentages add up to 100%?
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  20. #20

    Thread Starter
    Lively Member
    Join Date
    Aug 2011
    Posts
    70

    Re: Randomly selected item from list which have a %

    Quote Originally Posted by dbasnett View Post
    Do the percentages add up to 100%?
    Yes they do. And ill take a look at that paul thanks.

  21. #21

    Thread Starter
    Lively Member
    Join Date
    Aug 2011
    Posts
    70

    Re: Randomly selected item from list which have a %

    Paul haven't had time to test it since I had exams yesterday and today but I'm not sure that would work for decimal percentages. For instance I have a percentage at 0.20%.

  22. #22
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Randomly selected item from list which have a %

    Here's a class that will do the job for you:
    Code:
    ''' <summary>
    ''' Generates random values from a list with weighted likelihoods.
    ''' </summary>
    ''' <typeparam name="T">
    ''' The type of the items to be selected.
    ''' </typeparam>
    Public Class WeightedRandom(Of T)
    
        ''' <summary>
        ''' The random number generator.
        ''' </summary>
        ''' <remarks>
        ''' There is one instance for all instances of the class.
        ''' </remarks>
        Private Shared rng As New Random
    
        ''' <summary>
        ''' Values keyed on the maximum weight for which they will be selected.
        ''' </summary>
        Private ReadOnly valuesByWeightThreshold As New Dictionary(Of Integer, T)
    
        ''' <summary>
        ''' The weights of all values summed.
        ''' </summary>
        Private ReadOnly totalWeight As Integer
    
        ''' <summary>
        ''' Initialises a new instance of the <see cref="WeightedRandom(Of T)"/> class.
        ''' </summary>
        ''' <param name="weightsByValue">
        ''' A list of values and the weights for each one.
        ''' </param>
        Public Sub New(weightsByValue As IDictionary(Of T, Integer))
            Dim rollingWeight As Integer
    
            For Each key In weightsByValue.Keys
                'Get the weight for all values up to and including this one.
                rollingWeight += weightsByValue(key)
    
                'Add the value against that summed weight.
                valuesByWeightThreshold.Add(rollingWeight, key)
            Next
    
            'Random numbers will be generated less than the total weight.
            totalWeight = rollingWeight
        End Sub
    
        ''' <summary>
        ''' Gets the next random value.
        ''' </summary>
        ''' <returns>
        ''' A value based on a weighted random selection
        ''' </returns>
        Public Function NextValue() As T
            'Generate a random number in the range specified by the combined weights.
            Dim number = rng.Next(totalWeight)
            Dim value As T
    
            'Find the first weight threshold that is greater than
            'the generated number and return the corresponding value.
            For Each weight In valuesByWeightThreshold.Keys
                If number < weight Then
                    value = valuesByWeightThreshold(weight)
                    Exit For
                End If
            Next
    
            Return value
        End Function
    
    End Class
    Using your colours and weights from post #1, here's a usage sample:
    Code:
            Dim weightsByValue As New Dictionary(Of Color, Integer) From {{Color.Red, 10},
                                                                          {Color.Blue, 25},
                                                                          {Color.Green, 7},
                                                                          {Color.Yellow, 58}}
            Dim colourGenerator As New WeightedRandom(Of Color)(weightsByValue)
            Dim redCount As Integer
            Dim blueCount As Integer
            Dim greenCount As Integer
            Dim yellowCount As Integer
    
            For i = 1 To 100
                Select Case colourGenerator.NextValue()
                    Case Color.Red
                        redCount += 1
                    Case Color.Blue
                        blueCount += 1
                    Case Color.Green
                        greenCount += 1
                    Case Color.Yellow
                        yellowCount += 1
                End Select
            Next
    
            MessageBox.Show(String.Format("Reds:{1}{0}Blues:{2}{0}Greens:{3}{0}Yellows:{4}",
                                          Environment.NewLine,
                                          redCount,
                                          blueCount,
                                          greenCount,
                                          yellowCount))
    Run that a few times and you'll see that the results are, as you would expect, around about the weights specified but not quite and they are a bit different each time.

    That class has a few benefits:

    1. You define the values and their weights once and then you don't have to think about them again.
    2. You simply call a method and get back one of the values without having to worry about manipulating any numbers.
    3. The same class can be used with objects of any type in a list of any length.
    4. The weights don't have to add up to 100. They can be anything you like.
    Last edited by jmcilhinney; May 24th, 2013 at 03:37 AM.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  23. #23
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Randomly selected item from list which have a %

    Just note that that constructor doesn't prevent zero or negative weights being used or total weights greater than Int32.MaxValue. I had to leave a bit of work for someone else.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  24. #24

    Thread Starter
    Lively Member
    Join Date
    Aug 2011
    Posts
    70

    Re: Randomly selected item from list which have a %

    Quote Originally Posted by .paul. View Post
    Code:
    Dim greens() As Integer = Enumerable.Range(0, 7).Select(Function(i) 0).ToArray 'seven elements of one hundred assigned value 0
    Dim reds() As Integer = Enumerable.Range(0, 10).Select(Function(i) 1).ToArray 'ten elements of one hundred assigned value 1 
    Dim blues() As Integer = Enumerable.Range(0, 25).Select(Function(i) 2).ToArray 'twenty five elements of one hundred assigned value 2
    Dim yellows() As Integer = Enumerable.Range(0, 58).Select(Function(i) 3).ToArray 'fifty eight elements of one hundred assigned value 3
    
    Dim possibles() As Integer = greens.Concat(reds).Concat(blues).Concat(yellows).ToArray 'join the four arrays
    
    Dim x As Integer = r.Next(0, 100) 'pick a random number 0 to 99
    Dim listIndex As Integer = possibles(x) 'listIndex will equal 0, 1, 2, or 3 with a 7% chance of 0, 10% chance of 1, 25% chance of 2, + 58% chance of 3
    edit: to make it more random:

    Code:
    possibles = possibles.OrderBy(Function(i) r.NextDouble).ToArray
    That works for whole numbers but I have decimal percentages. EG (0.25%, 14.3%, etc.) Is there another method than random to pick randomly.

  25. #25
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: Randomly selected item from list which have a %

    Wasn't something like this suggested?
    Code:
            Dim d As Double = prng.NextDouble()
            Select Case d
                Case Is <= 0.0025
                Case Is <= 0.01
                Case Is <= 0.143
                Case Is <= 0.25
                Case Is <= 0.58
    
            End Select
    Also, jmc's (aka jim) code can probably be modified to use doubles instead of integers.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  26. #26
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,415

    Re: Randomly selected item from list which have a %

    you just need to scale it up:

    Code:
    Dim greens() As Integer = Enumerable.Range(0, 730).Select(Function(i) 0).ToArray 'seven hundred + thirty elements of ten thousand (7.3%) assigned value 0
    Dim reds() As Integer = Enumerable.Range(0, 1025).Select(Function(i) 1).ToArray 'one thousand + twenty five elements of ten thousand (10.25%) assigned value 1 
    Dim blues() As Integer = Enumerable.Range(0, 2545).Select(Function(i) 2).ToArray 'two thousand five hundred + forty five elements of ten thousand (25.45%) assigned value 2
    Dim yellows() As Integer = Enumerable.Range(0, 5700).Select(Function(i) 3).ToArray 'five thousand seven hundred elements of ten thousand (57%) assigned value 3
    
    Dim possibles() As Integer = greens.Concat(reds).Concat(blues).Concat(yellows).ToArray 'join the four arrays
    possibles = possibles.OrderBy(Function(i) r.NextDouble).ToArray
    
    Dim x As Integer = r.Next(0, 10000) 'pick a random number 0 to 9999
    Dim listIndex As Integer = possibles(x) 'listIndex will equal 0, 1, 2, or 3 with a 7.3% chance of 0, 10.25% chance of 1, 25.45% chance of 2, + 57% chance of 3

  27. #27

    Thread Starter
    Lively Member
    Join Date
    Aug 2011
    Posts
    70

    Re: Randomly selected item from list which have a %

    I finally came up with my own solution using your guys ideas. It would support decimal percentages to huge decimal places, random and short.

    Code:
     Dim useRandom As New Random
            Select Case (Math.Round(useRandom.NextDouble(), 2))
                Case 0 To 0.25
                    MsgBox("Red")
                Case 0.26 To 0.5
                    MsgBox("Blue")
                Case 0.51 To 0.75
                    MsgBox("Green")
                Case 0.76 To 1
                    MsgBox("Yellow")
            End Select

  28. #28
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Randomly selected item from list which have a %

    Quote Originally Posted by xx_dan_xx View Post
    That works for whole numbers but I have decimal percentages. EG (0.25%, 14.3%, etc.) Is there another method than random to pick randomly.
    You do realise that you can simply multiply those decimals by factors of 10 and they become whole numbers, right? If the largest number of decimal places is 2 then you simply multiple everything by 100 . You can then use .paul.'s suggestion or mine as is. That said, here's my WeightedRandom class adapted to use Doubles:
    Code:
    ''' <summary>
    ''' Generates random values from a list with weighted likelihoods.
    ''' </summary>
    ''' <typeparam name="T">
    ''' The type of the items to be selected.
    ''' </typeparam>
    Public Class WeightedRandom(Of T)
    
        ''' <summary>
        ''' The random number generator.
        ''' </summary>
        ''' <remarks>
        ''' There is one instance for all instances of the class.
        ''' </remarks>
        Private Shared rng As New Random
    
        ''' <summary>
        ''' Values keyed on the maximum weight for which they will be selected.
        ''' </summary>
        Private ReadOnly valuesByWeightThreshold As New Dictionary(Of Double, T)
    
        ''' <summary>
        ''' The weights of all values summed.
        ''' </summary>
        Private ReadOnly totalWeight As Double
    
        ''' <summary>
        ''' Initialises a new instance of the <see cref="WeightedRandom(Of T)"/> class.
        ''' </summary>
        ''' <param name="weightsByValue">
        ''' A list of values and the weights for each one.
        ''' </param>
        Public Sub New(weightsByValue As IDictionary(Of T, Double))
            Dim rollingWeight As Double
    
            For Each key In weightsByValue.Keys
                'Get the weight for all values up to and including this one.
                rollingWeight += weightsByValue(key)
    
                'Add the value against that summed weight.
                valuesByWeightThreshold.Add(rollingWeight, key)
            Next
    
            'Random numbers will be generated less than the total weight.
            totalWeight = rollingWeight
        End Sub
    
        ''' <summary>
        ''' Gets the next random value.
        ''' </summary>
        ''' <returns>
        ''' A value based on a weighted random selection
        ''' </returns>
        Public Function NextValue() As T
            'Generate a random number in the range specified by the combined weights.
            Dim number = rng.NextDouble() * totalWeight
            Dim value As T
    
            'Find the first weight threshold that is greater than
            'the generated number and return the corresponding value.
            For Each weight In valuesByWeightThreshold.Keys
                If number < weight Then
                    value = valuesByWeightThreshold(weight)
                    Exit For
                End If
            Next
    
            Return value
        End Function
    
    End Class
    The sample usage is exactly the same except that the Dictionary values are type Double instead of type Integer, e.g.
    Code:
    'Proportional weightings of 1:38:20:51.
    Dim weightsByValue As New Dictionary(Of Color, Double) From {{Color.Red, 0.25},
                                                                  {Color.Blue, 9.5},
                                                                  {Color.Green, 5},
                                                                  {Color.Yellow, 12.75}}
    Dim colourGenerator As New WeightedRandom(Of Color)(weightsByValue)
    Dim redCount As Integer
    Dim blueCount As Integer
    Dim greenCount As Integer
    Dim yellowCount As Integer
    
    For i = 1 To 100
        Select Case colourGenerator.NextValue()
            Case Color.Red
                redCount += 1
            Case Color.Blue
                blueCount += 1
            Case Color.Green
                greenCount += 1
            Case Color.Yellow
                yellowCount += 1
        End Select
    Next
    
    MessageBox.Show(String.Format("Reds:{1}{0}Blues:{2}{0}Greens:{3}{0}Yellows:{4}",
                                  Environment.NewLine,
                                  redCount,
                                  blueCount,
                                  greenCount,
                                  yellowCount))
    Sub
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  29. #29

    Thread Starter
    Lively Member
    Join Date
    Aug 2011
    Posts
    70

    Re: Randomly selected item from list which have a %

    I found a different method, which isminimal and that would require more lines of code when I already have a solution which is small.

  30. #30
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Randomly selected item from list which have a %

    Quote Originally Posted by xx_dan_xx View Post
    I found a different method, which isminimal and that would require more lines of code when I already have a solution which is small.
    You "found" a solution that just happens to be almost exactly what was suggested in post #2 nearly 24 hours ago. Anyway, I'm not saying that mine is the only or even the best solution but what it does do is create a reusable class so, once that exists, you have to write very little code to use it, plus it can be used to select values of any type. VB is an OO language for a reason so making use of that is rarely a bad thing.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width