Generate random fixed-sum integers with constraints

How to generate 6 random numbers that are up to 8, and each of them is less than or equal to 2?

eg. 1,2,1,2,2,0

So far I have found a method that gives random integers with a fixed amount, but how to impose restrictions on these integers.

+4
source share
3 answers

I would recommend a hit and skip approach to ensure an even distribution of the generated sequences that satisfy the constraint. It is easy to understand that the probability of 6 random integers in {0,1,2} with the addition of up to 8 is approximately 12.3%, so there aren’t so many tests before the hit. Here is a Python implementation:

import random

def randNums(n,a,b,s):
    #finds n random ints in [a,b] with sum of s
    hit = False
    while not hit:
        total, count = 0,0
        nums = []
        while total < s and count < n:
            r = random.randint(a,b)
            total += r
            count += 1
            nums.append(r)
        if total == s and count == n: hit = True
    return nums

Here is the result of 5 starts:

>>> for i in range(5): print(randNums(6,0,2,8))

[2, 1, 0, 2, 1, 2]
[0, 2, 2, 1, 1, 2]
[2, 2, 0, 2, 0, 2]
[2, 2, 0, 1, 1, 2]
[1, 2, 1, 1, 1, 2]

: , , . 6 {0,1,2} 0 3 ^ 6-1 = 728, 3. -3 . = 8:

def toBase3(n):
    digits = []
    q,r = divmod(n,3)
    while q > 0:
        digits.append(r)
        q,r = divmod(q,3)
    digits.append(r)
    return ''.join(str(i) for i in reversed(digits))

def dsum(s):
    return sum(int(d) for d in s)

hits = []
for n in range(729):
    s = toBase3(n)
    if dsum(s) == 8: hits.append(s)

hits = [('0'*(6-len(s)))+s for s in hits] #left-pad with '0' if needed

s = ''.join(hits)

print("%d valid sequences for prob. of %f" % (len(hits),len(hits)/3.0**6))
print("%d zeros in those sequences for a prob. of %f" % (s.count('0'),s.count('0')/540.0))
print("%d ones in those sequences for a prob. of %f" % (s.count('1'),s.count('1')/540.0))
print("%d twos in those sequences for a prob. of %f" % (s.count('2'),s.count('2')/540.0))

:

90 valid sequences for prob. of 0.123457
90 zeros in those sequences for a prob. of 0.166667
180 ones in those sequences for a prob. of 0.333333
270 twos in those sequences for a prob. of 0.500000

, 6 8, ,

90/729 = 0.123456790 (repeating)

, 0.1234567. , 8 7.

+1

:

  • .
  • . , , , .
  • 2

[0,2] ( , ), .

+3

-, , .

, 2 6 {0,1,2}, 8. , . - , , . , 2,2,?,?,?,?.

, , 4 {0,1,2}, 4. - ( 0) 2, 2 1, 1. 3 . ... , , . :

var possibles = [
    [2,2,2,2,0,0],
    [2,2,2,1,1,0],
    [2,2,1,1,1,1]
];

var randomInd = Math.floor( Math.random()*possibles.length ); // random number from 0-2
var myArr = possibles[randomInd]; // picks a random entry from possibles

, , , . :

function shuffle(arr)
{
    var curInd = arr.length, tempVal, randInd;
    while (0 !== curInd) {
        randInd = Math.floor(Math.random()*curInd);
        curInd -= 1;
        tempVal = arr[curInd];
        arr[curInd] = arr[randInd];
        arr[randInd] = tempVal;
    }
}

shuffle(myArr);
alert(myArr); // will give "random" sequence

"" , possibles (.. 2 1).

Note . I do not see any specific language, so for those who are interested in what javascript is. JSFiddle can be seen here: https://jsfiddle.net/6xaeLp4g/

+2
source

Source: https://habr.com/ru/post/1626458/


All Articles