randomly select 3 numbers whose sum is 356 and each of these 3 is more than 30

please how can I randomly select 3 numbers whose sum is 356 and each of these 3 is more than 30?

So output should be for example [100, 34, 222] (but not [1,5,350])

I would like to use random module to do this. thank you!

Answers


import random

def rnd_to_sum_with_min(desired_sum=356, numbers=3, minimum=31):
    selection = []
    for i in range(numbers-1):
        upper_limit = desired_sum - sum(selection) - (numbers - i) * minimum
        choice = random.randint(minimum, upper_limit)
        selection.append(choice)
    selection.append(desired_sum - sum(selection))
    return selection

This solution uses a function. This is so that parameters can be modified on-the-fly. This makes for a robust solution.

The method is to select the first N-1 numbers randomly, and determine the last number according to the difference to the desired sum. Each number is determined by first knowing the minimum value desired, and then calculating the upper limit of that number based on the desired sum, and what numbers have already been chosen, making sure to leave enough behind for the next n numbers.

I also wrote a recursive function just for fun (Which is faster):

def recursive_rnd_sum_by_n_with_min(_sum=356, _num=3, _min=31):
    def f(_sel=[]):
        left = _num - len(_sel) 
        so_far = sum(_sel)
        if left == 1:
            return _sel + [_sum - so_far]
        return f(_sel + [random.randint(_min, _sum - so_far - left * _min)])
    return f()  

This question is rather subjective to the definition of random, and the distribution you wish to replicate.

The simplest solution:

  • Choose a one random number, rand1 : [30,296]
  • Choose a second random number, rand2 : [30, (326-Rand1)]
  • Then the third cannot be random due to the constraint so calc via 356-(rand1+rand2)

When choosing the first number, it needs to be 31 or more, and it must leave at least 62 on the table (assuming numbers don't have to be different) since the other two numbers will need to 31 or higher as well.

So it needs to come from the inclusive range 31..(356-31-31).

For the second number, it has to be 31 or more and it has to leave at least 31 on the table for the last number.

So its inclusive range will be 31..(356-31-first).

Then, the final number is simply 356-first-second and there you have it.

There's already plenty of answers on SO about generating random numbers in a range in Python so I won't rehash that information, but the following code shows how to select the ranges for the two numbers and calculate the third:

import random
first = random.randint(31,356-31-31)
second = random.randint(31,356-31-first)
third = 356 - first - second
print first, second, third, (first + second + third)

It may be different depending on whether you allow duplicates but this answer should give you the basic approach.


Need Your Help

General Good Practice Using Bootstrap panel class

css twitter-bootstrap responsive-design

So I have been using Bootstrap's panel class for a few months now and I can not determine if what I have been doing with the panel class is good or not. So I used to use the panel class like so

Can I serialize a single object into nested XML?

c# xml serialization xml-serialization

I need to create some XML with nested attributes that looks something similar to this:

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.