1

I have a code which generates either 0 or 9 randomly. This code is run 289 times...

import random
track = 0
if track < 35:
    val = random.choice([0, 9])
    if val == 9:
        track += 1
    else:
        val = 0

According to this code, if 9 is generated 35 times, then 0 is generated. So there is a heavy bias at the start and in the end 0 is mostly output.

Is there a way to reduce this bias so that the 9's are spread out quite evenly in 289 times.

Thanks for any help in advance

4
  • 2
    Why is it indented like that? Commented Apr 27, 2015 at 2:44
  • Why don't you remove the 'else' branch? It doesn't do anything. And why don't you write val = random.choice([0, 10]). Then you could also remove the complete if statement. Commented Apr 27, 2015 at 3:23
  • "According to this code, if 9 is generated 35 times, then 0 is generated. So there is a heavy bias at the start and in the end 0 is mostly output." No. random.choice might generate 35 times 0 at first, but does not necessarily do so. It's random. The elements of the list should be drawn with uniform probability. Commented Apr 27, 2015 at 3:26
  • See also: random Commented Apr 27, 2015 at 3:29

2 Answers 2

1

Apparently you want 9 to occur 35 times, and 0 to occur for the remainder - but you want the 9's to be evenly distributed. This is easy to do with a shuffle.

values = [9] * 35 + [0] * (289 - 35)
random.shuffle(values)
Sign up to request clarification or add additional context in comments.

1 Comment

@OliviaCassendre so put this code into a function, and have it do a yield for each value you need to generate. If there are additional constraints you'll need to state them explicitly. P.S. It's impossible to get an even distribution if you don't know ahead of time how many values will be required.
1

It sounds like you want to add some bias to the numbers that are generated by your script. Accordingly, you'll want to think about how you can use probability to assign a correct bias to the numbers being assigned.

For example, let's say you want to generate a list of 289 integers where there is a maximum of 35 nines. 35 is approximately 12% of 289, and as such, you would assign a probability of .12 to the number 9. From there, you could assign some other (relatively small) probability to the numbers 1 - 8, and some relatively large probability to the number 0.

Walker's Alias Method appears to be able to do what you need for this problem.

General Example (strings A B C or D with probabilities .1 .2 .3 .4):

abcd = dict( A=1, D=4, C=3, B=2 )
# keys can be any immutables: 2d points, colors, atoms ...
wrand = Walkerrandom( abcd.values(), abcd.keys() )
wrand.random()  # each call -> "A" "B" "C" or "D"
    # fast: 1 randint(), 1 uniform(), table lookup

Specific Example:

numbers = dict( 1=725, 2=725, 3=725, 4=725, 5=725, 6=725, 7=725, 8=725, 9=12, 0=3 )
wrand = Walkerrandom( numbers.values(), numbers.keys() )
#Add looping logic + counting logic to keep track of 9's here
track = 0
i = 0
while i < 290
    if track < 35:
        val = wrand.random()
        if val == 9:
            track += 1
    else:
        val = 0
    i += 1

4 Comments

You'll need to grab the module from the linked site and import it into your code. This link contains information on importing custom modules.
i have pasted in the code to my file... but am having trouble set up the custom module
So at the start of my file, I have "import walkerrandom"
The module 'walkerrandom.py' module is placed in the same directory as the program that I import it in according to your link

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.