You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中生成区间[a,b]内总和接近k的n个随机数?

解决方案

要生成26个范围在[100,120]的整数,使其总和落在[3000,3050]区间内,同时保持随机分布,可以按照以下步骤实现:

核心思路

  1. 随机选定目标总和(在3000-3050区间内)
  2. 给每个数分配基础值100,计算需要额外补充的额度
  3. 将额外额度随机分配到各个数上,确保每个数最终不超过120
  4. 验证结果并可视化分布质量

完整代码实现

import numpy as np
import scipy.stats as stats
import matplotlib.pyplot as plt

# 设定固定参数
n_days = 26
min_daily = 100
max_daily = 120
target_min = 3000
target_max = 3050

# 1. 随机选择目标总和
target_sum = np.random.randint(target_min, target_max + 1)

# 2. 计算基础总和与待分配的额外额度
base_sum = n_days * min_daily
remaining = target_sum - base_sum

# 3. 用多项式分布随机分配额外额度
additions = np.random.multinomial(remaining, [1/n_days]*n_days, size=1)[0]

# 防御性调整:处理极端情况中单个数值超上限的问题
max_add = max_daily - min_daily
while any(additions > max_add):
    # 收回超标的额度
    excess_mask = additions > max_add
    excess = additions[excess_mask] - max_add
    additions[excess_mask] = max_add
    remaining_excess = excess.sum()
    
    # 将收回的额度重新分配给未达上限的元素
    available_mask = additions < max_add
    additions[available_mask] += np.random.multinomial(remaining_excess, 
                                                      [1/available_mask.sum()]*available_mask.sum(), 
                                                      size=1)[0]

# 生成最终的每日收入数组
daily_values = min_daily + additions

# 验证结果
total = daily_values.sum()
print(f"生成的每日收入:{daily_values}")
print(f"总和:{total},符合目标区间:{target_min} ≤ {total} ≤ {target_max}")

# 4. 可视化分布(对比正态分布PDF)
sorted_vals = np.sort(daily_values)
mean_val = np.mean(daily_values)
std_val = np.std(daily_values)

plt.figure(figsize=(10,6))
plt.hist(daily_values, bins=range(min_daily, max_daily+2), edgecolor='black', alpha=0.7, label='生成值分布')
plt.plot(sorted_vals, stats.norm.pdf(sorted_vals, mean_val, std_val)*len(daily_values), 
         '-o', alpha=0.6, label='拟合正态分布')
plt.xlabel('每日收入(€)')
plt.ylabel('频次')
plt.title('每日收入分布对比')
plt.legend()
plt.show()

代码说明

  • 目标总和选择:随机选取3000-3050之间的整数,确保总和直接符合要求
  • 额度分配:使用numpy.random.multinomial实现额外额度的随机分配,保证数值分布的随机性
  • 防御性调整:处理极端情况下可能出现的单个数值超上限问题,确保结果合法性
  • 分布可视化:将生成值的直方图与拟合的正态分布对比,验证分布的合理性

简化替代方案(快速生成)

如果不需要严格精确的目标总和,也可以先生成初始随机数,再逐步调整总和到目标区间:

import numpy as np

n_days = 26
min_daily = 100
max_daily = 120
target_min = 3000
target_max = 3050

# 生成初始随机数(注意randint左闭右开,上限写121才能包含120)
daily_values = np.random.randint(min_daily, max_daily + 1, n_days)
current_sum = daily_values.sum()

# 循环调整总和到目标区间
while not (target_min <= current_sum <= target_max):
    idx = np.random.randint(n_days)
    if current_sum < target_min:
        if daily_values[idx] < max_daily:
            daily_values[idx] += 1
            current_sum += 1
    else:
        if daily_values[idx] > min_daily:
            daily_values[idx] -= 1
            current_sum -= 1

print(f"调整后总和:{current_sum}")
print(f"每日收入:{daily_values}")

这个方案逻辑简单,适合对生成效率要求不高的场景。

内容的提问来源于stack exchange,提问作者Mario

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 03:57:28