The problem
I understand that you need to generate a fixed length list of N random booleans, that obeys a distribution rule by position and that complies with a contraint about the number of T. Quite challenging ! I'll answer assuming that you have a reliable random number generator that guarantees a uniform distribution;
First approach
The proposed idea is to create N lists, that reflect the distribution requirements of each position. In your example:
[ T, T, T, F ]
[ T, F]
[ T, F]
[ T, F]
[ T, F]
Using a random generator with uniform distribution, you would then select in each list one element. Since the distribution is uniform, each element in each list has equal number of chances to be selected. The weighting is achieved via the repetitive elements. The composed list of results would then be checked against the constraints: if doesn't fit the expected number of Ts, it's rejected. Randomness and distribution should be respected as each position is selected independently.
The drawback with this approach is that you may have to generate several candidate lists before finding one that matches the constraint regarding the number of Ts. But if you would take shortcuts, you might flaw the individual distribution of the positions. For example, puting remaing positions to F as soon as all the Ts are there, would favor an overrepresentation of Ts in the first boolean positions and an underrepresentation in the last boolean positions.
Alternative
An alternative to that approach with less waste could be to construct a shuffle-set, that contains candidate lists that respect the constraint. The shuffle set would repeat some combinations so that the distribution per position is respected. You'd then use your uniform random number generator to pick one candidate list in the set. Since each candidate has the same chance of being selected, the distribution is again obtained by repeating combinations according to the weighting.
This approach would require more memory. The difficulty is transferred to the construction of the candidate set: the main risk is that by trying to add repetitive items for the positions with the highest weight, you could distort randomness of the remaining positions (i.e. creating an unwanted correlation between some positions). This risk seems relatively high in the given example in view of the over-contraint issue raised in Hans-Martin’s answer. I nevertheless imagine that your real distributions by position are certainly more consistent than in your example.
In any case, I'd strongly suggest to create a tester that checks the distribution over a large number of generations.
random()
to obtain a value from the [0.0, 1.0) range, and then check if the result is < 3/4 - or, more generally, you can do something like this[random.random() < w/(w+1) for w in weights]
, whereweights
is your list of weights. P.S. Don't take the downvotes too personally, it's just a feedback mechanism, it will go up and down.