生成一个范围内的N个正整数,总计python中的总数 [英] Generate N positive integers within a range adding up to a total in python

查看:495
本文介绍了生成一个范围内的N个正整数,总计python中的总数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看过其他类似问题的帖子.我知道如何生成N个正整数.我也知道如何限制随机生成的整数的总和.唯一的问题是要满足N个值均不超出指定范围的条件.

I have seen other posts addressing similar problem. I know how to generate N positive integers. I also know how to restrict the sum of randomly generated integers. The only problem is satisfying the condition that none of the N values fall out of the specified range.

例如generate_ints(n, total, low, high)应该生成n个值数组,以使每个值都介于低和高之间,并且总和加起来.任何指针/帮助将不胜感激.

e.g. generate_ints(n, total, low, high) should generate n value array such that each value is between low and high and the sum adds up to the total. Any pointers/ help would be greatly appreciated.

例如generate_ints(4, 40, 4, 15)应该生成类似

[7,10,13,10]

我不在乎数字是否重复,只要它们不会高度偏斜即可.我正在使用np.randon.randint(5,15,n)选择整数.

I don't care if the numbers are repeated, as long as they are not highly skewed. I am using np.randon.randint(5,15,n) to select the integer.

到目前为止,我已经尝试了以下方法,但是它不起作用-

So far, I have tried the following, but it doesn't work -

import numpy as np 
import random 
from random import uniform as rand 

total=50 
n=10 
low=2 
high=15 
result=[] 
m=0 
nobs=1 
while nobs <= n: 
    if m >= (total - low): 
        last_num= total -new_tot 
        result.append(last_num) 
    else: 
        next_num=np.random.randint(low,high,1) 
        new_tot = sum(result) + next_num 
        result.append(next_num) 
        m=new_tot 
    nobs +=1 

print result 
print sum(result)

再次感谢.

推荐答案

import numpy as np

def sampler(samples, sum_to , range_list):
    assert range_list[0]<range_list[1], "Range should be a list, the first element of which is smaller than the second"
    arr = np.random.rand(samples)
    sum_arr = sum(arr)

    new_arr = np.array([int((item/sum_arr)*sum_to) if (int((item/sum_arr)*sum_to)>range_list[0]and int((item/sum_arr)*sum_to)<range_list[1]) \
                            else np.random.choice(range(range_list[0],range_list[1]+1)) for item in arr])
    difference = sum(new_arr) - sum_to
    while difference != 0:
        if difference < 0 :
                for idx in np.random.choice(range(len(new_arr)),abs(difference)):
                    if new_arr[idx] != range_list[1] :
                        new_arr[idx] +=  1

        if difference > 0:
                for idx in np.random.choice(range(len(new_arr)), abs(difference)):
                    if new_arr[idx] != 0 and new_arr[idx] != range_list[0] :
                        new_arr[idx] -= 1
        difference = sum(new_arr) - sum_to
    return new_arr

new_arr = sampler (2872,30000,[5,15])
print "Generated random array is :"
print new_arr
print "Length of array:", len(new_arr)
print "Max of array: ", max(new_arr)
print "min of array: ", min(new_arr)
print "and it sums up to %d" %sum(new_arr)

结果:

Generated random array is :
[ 9 10  9 ...,  6 15 11]
Length of array: 2872
Max of array:  15
min of array:  5
and it sums up to 30000

这篇关于生成一个范围内的N个正整数,总计python中的总数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆