生成 -x 和 y 之间的 n 随机浮点值,总和为预定义值

问题描述 投票:0回答:2

我想生成 n 个随机浮点值,这些值应该受到下限和上限的约束,总数也应该是 0 或预定义的值。

例如,我想生成 4 个介于 -10.0 和 2.0 之间的浮点值,total=0,那么以下值将起作用:

[-1.0, -1.5, 1.75, 1.75]

或 5 在 -10.0 和 1.0 之间浮动,并且 total=1.0 那么:

[0.5, -0.5, 0.0, 0.0, 1.0]

是否有通过 numpy 或通过 vanilla Python 的自定义函数的通用方法或良好的分发方法?如果由于限制,这些数字不能加起来达到预定义的值,那么函数可能会给出错误,例如:

3 在-2.0和-1.0之间浮动,total=1.0:

raise ValueError
python numpy random distribution
2个回答
-1
投票

这里有一个算法的例子。

import random

def foo(min_: int, max_: int, count: int, target: float) -> list[float]:
    # make sur the target is reachable
    if target < min_ * count or target > max_ * count:
        raise ValueError(f"Target value '{target}' is not valid for allowed range '{min_}' - '{max_}'")

    numbers = []
    
    # execute the next steps `count` times
    for i in range(count):
        # generate a random float number with the allowed range
        number = random.uniform(min_, max_)
        
        current_sum = sum(numbers) + number
        delta = target - current_sum
        current_delta = target - sum(numbers)
        renamining_tries = count - i - 1
        missing = 0
        
        # the last number is what's remaining
        if renamining_tries == 0:
            number = current_delta
        
        # insure that the target is still reachable
        elif delta > renamining_tries * max_:
            min_to_add = delta - renamining_tries * max_
            missing = random.uniform(min_to_add, max_ - number)
            
        elif delta < renamining_tries * min_:
            min_to_remove = renamining_tries * min_ - delta
            missing = -random.uniform(min_to_remove, number - min_)
            
        # correct the number if it needs to be
        number += missing
        numbers.append(number)
        
    return numbers
    
numbers = foo(min_=-10, max_=2, count=4, target=0)
print(sum(numbers), numbers) 

基本上,我生成随机浮点数并确保目标在数字范围内仍然可以到达。如果没有,我会在当前数字中添加使它可以访问所缺少的内容。最后一个数字是剩余的。因为检查,这永远不会超出允许的范围。


-2
投票

试试这个:

import numpy as np

n_numbers = 4
total = 10
upper = 100
lower = -100

parts = np.random.rand(n_numbers - 1) * (upper - lower) + lower
parts.sort()
out = np.append(parts[0], np.diff(parts, append=total))
if any(out > upper) or any(out < lower):
    raise ValueError("Oops, something went wrong")
print(out.sum())

如果这对你有用,请告诉我。我知道这并不理想,但它在大多数时候都有效......这是一项非常有趣的任务!

我的代码的问题是添加到

out
的最后一个值可能高于或低于定义的边界。

© www.soinside.com 2019 - 2024. All rights reserved.