[英]How to divide a number value in N unevenly parts using Python & following a set of min- & max requirement?
I have a fairly basic math problem in Python & I dont know where to look.我在 Python 中有一个相当基本的数学问题,我不知道去哪里找。
Explanation:解释:
My only requirements are the following:我唯一的要求如下:
from random import randint, shuffle
def divide_number(number, parts_number, allow_zero = False ):
if (parts_number > number):
raise ValueError("Number of parts can't be higher than the number");
parts = {currency: []}
number_rest = number
for i in range(1, parts_number + 1):
if (i == parts_number):
parts[currency].append(number_rest)
break
else:
new_number = randint(0, number_rest) if allow_zero else randint(1, (number_rest -
(parts_number - i)) // 2)
number_rest -= new_number
parts[currency].append(new_number)
return parts
Running the function:运行函数:
divide_number(100, 10)
Output输出
[2, 37, 8, 10, 2, 4, 4, 4, 26, 3]
This piece of code I've found online seems to work just great but it doesn't meet my requirements.我在网上找到的这段代码似乎很好用,但不符合我的要求。 How do I alter it so it does meet my requirements regarding min and max values?
我如何改变它才能满足我对最小值和最大值的要求?
So basicly, I want to go from unfair distribution to fair distribution .所以基本上,我想从不公平分配转向公平分配。
Every next iteration you must ensure that you have enough money left to give at least minimum to all friends:每次下一次迭代时,您都必须确保有足够的钱留给所有朋友至少最低限度:
from random import randrange
def divide_number(number, divider, min_value, max_value):
result = []
for i in range(divider - 1, -1, -1):
part = randrange(min_value, min(max_value, number - i * min_value + 1))
result.append(part)
number -= part
return result
Usage:用法:
divide_number(100, 10, 5, 40)
Notice, that friends which took their part first will have much higher chance to get more.请注意,最先参与的朋友将有更高的机会获得更多。 You can make it a bit more "fair" by adding
shuffle()
right before function return:您可以通过在函数返回之前添加
shuffle()
使其更“公平”:
from random import shuffle
def divide_number(...):
...
shuffle(result)
return result
Is is not easy to make rather fair distribution with limits.在限制条件下进行相当公平的分配并不容易。 For reasonable sum and parts (
p
) values we can make p cells (friend pockets) and randomly put coin by coin into them (if possible)对于合理的总和和部分 (
p
) 值,我们可以制作 p 个单元格(朋友口袋)并随机将硬币一个硬币放入其中(如果可能)
import random
def randparts(summ, p, minn, maxx):
maxx = maxx - minn
summ -= p * minn
if summ < 0:
return None
if p * maxx >= summ * 2:
lst = [0] * p
while summ > 0:
r = random.randrange(p)
if lst[r] < maxx:
summ -= 1
lst[r] += 1
else:
lst = [maxx] * p
summ = maxx * p - summ
while summ > 0:
r = random.randrange(p)
if lst[r] > 0:
summ -= 1
lst[r] -= 1
for i in range(len(lst)):
lst[i] += minn
return lst
print(randparts(100, 10, 5, 40))
>>>[7, 17, 8, 10, 8, 8, 9, 12, 10, 11]
More concise and pythonic version from the comment of Olvin Roght (also removed the second branch for optimization for large summ
values)更简洁,从Olvin Roght的注释Python的版本(也取消了优化第二支大型
summ
值)
def randparts(number, divider, min_value, max_value):
sum_min = divider * min_value
if sum_min > number:
return
number -= sum_min
result = [min_value] * divider
while number:
pocket = randrange(divider)
if result[pocket] <= max_value:
result[pocket] += 1
number -= 1
return result
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.