鱼C论坛

 找回密码
 立即注册
查看: 9747|回复: 13

[已解决]怎么一下生成30个随机数使他们的和等于1000

[复制链接]
发表于 2016-5-10 14:23:48 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
import random
time = 0
number = random.randint(0,1000)
a=number
print(number)
while time<29:
    number = random.randint(0,(1000-a))
    print(number)
    a = a + number
    time = time +1
我这样写的代码到后面几个随机数就都是0了
最佳答案
2016-5-10 15:31:16
我的思路,首先将1000想象成一个从0到1000的数轴,再生成29个0~1000的随机数并从大到小排序作为数轴的分隔点,将数轴分为30段,这样就得到了30个总和为1000的随机数。
  1. >>> import random
  2. >>> list1 = [random.randint(0, 1000) for i in range(29)]
  3. >>> list1.sort()
  4. >>> list2 = []
  5. >>> list2.append(list1[0])
  6. >>> for i in range(28):
  7.         list2.append(list1[i + 1] - list1[i])
  8. >>> list2.append(1000 - list1[28])
  9. >>> list2
  10. [18, 112, 6, 31, 24, 28, 56, 68, 28, 11, 53, 35, 27, 20, 37, 56, 19, 24, 23, 4, 31, 123, 41, 23, 22, 0, 21, 15, 32, 12]
  11. >>> sum(list2)
  12. 1000
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2016-5-10 14:54:38 | 显示全部楼层
你可以把每次取随机数的范围稍稍调小些,我写了个供参考:
  1. import random
  2. def generate_rand(n, sum_v):
  3.     temp = random.randint(0, sum_v//20)
  4.     print(temp)
  5.     if n>0:
  6.         generate_rand(n-1, sum_v-temp)

  7. generate_rand(30,1000)
复制代码

结果是:
  1. 49
  2. 7
  3. 31
  4. 16
  5. 12
  6. 3
  7. 14
  8. 1
  9. 3
  10. 31
  11. 25
  12. 24
  13. 12
  14. 6
  15. 37
  16. 16
  17. 21
  18. 29
  19. 1
  20. 0
  21. 21
  22. 31
  23. 7
  24. 19
  25. 9
  26. 4
  27. 22
  28. 14
  29. 25
  30. 14
  31. 19
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-5-10 15:06:01 | 显示全部楼层
holdme 发表于 2016-5-10 14:54
你可以把每次取随机数的范围稍稍调小些,我写了个供参考:

结果是:

但是这样的话得到的结论不能保证和等于1000啊
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-5-10 15:11:38 | 显示全部楼层
这题我看过,其实和微信发红包原理是一样的,链接在这里,楼主慢慢看https://www.zhihu.com/question/22625187
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-5-10 15:26:54 | 显示全部楼层
哈哈,我犯二了,稍微修一下就可以了!
  1. import random
  2. def generate_rand(n, sum_v):
  3.     temp = random.randint(0, sum_v//20)
  4.     print(temp)
  5.     if n>1:
  6.         generate_rand(n-1, sum_v-temp)
  7.     else:
  8.         print(sum_v-temp)

  9. data = generate_rand(30,1000)
复制代码

这样稳稳的!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-5-10 15:31:16 | 显示全部楼层    本楼为最佳答案   
我的思路,首先将1000想象成一个从0到1000的数轴,再生成29个0~1000的随机数并从大到小排序作为数轴的分隔点,将数轴分为30段,这样就得到了30个总和为1000的随机数。
  1. >>> import random
  2. >>> list1 = [random.randint(0, 1000) for i in range(29)]
  3. >>> list1.sort()
  4. >>> list2 = []
  5. >>> list2.append(list1[0])
  6. >>> for i in range(28):
  7.         list2.append(list1[i + 1] - list1[i])
  8. >>> list2.append(1000 - list1[28])
  9. >>> list2
  10. [18, 112, 6, 31, 24, 28, 56, 68, 28, 11, 53, 35, 27, 20, 37, 56, 19, 24, 23, 4, 31, 123, 41, 23, 22, 0, 21, 15, 32, 12]
  11. >>> sum(list2)
  12. 1000
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2016-5-10 15:36:46 | 显示全部楼层
holdme 发表于 2016-5-10 15:26
哈哈,我犯二了,稍微修一下就可以了!

这样稳稳的!

恩恩~~谢啦
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-5-10 15:38:16 | 显示全部楼层
冬雪雪冬 发表于 2016-5-10 15:31
我的思路,首先将1000想象成一个从0到1000的数轴,再生成29个0~1000的随机数并从大到小排序作为数轴的分隔 ...

这方法完美!非常感谢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-5-10 15:38:27 | 显示全部楼层
又想了一下,其实这个实现可以很简单,是我之前把问题复杂化了,下面这样写更好一些:
  1. import random
  2. def generate_rand(n, sum_v):
  3.     Vector = [random.random() for i in range(n)]
  4.     Vector = [ int(i / sum(Vector) * sum_v) for i in Vector]
  5.     if sum(Vector) < sum_v:
  6.         Vector[0] += sum_v-sum(Vector)
  7.     return Vector

  8. print(generate_rand(30,1000))
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-5-11 22:53:06 | 显示全部楼层
感谢楼主的分享,受益匪浅。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-5-14 13:14:06 | 显示全部楼层
都是高手啊,我怎么看不懂啊。我都快学了一个月python了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-5-14 16:41:51 | 显示全部楼层
哇塞,学习学习
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-5-16 12:26:50 | 显示全部楼层
厉害厉害。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-5-16 15:04:59 | 显示全部楼层
刚刚开始学习。一起加油
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2026-2-20 23:53

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表