[已答复] matlab如何随机生成N(已知)个整数且他们之和为一个定值M?

[复制链接]
J-Rain 发表于 2017-4-24 20:32:44
本帖最后由 J-Rain 于 2017-4-24 20:34 编辑

matlab如何随机生成N个(N已知)整数且他们之和为一个定值M(M已知)?

我会随机生成整数,也会随机生成之和未定值的小数,但是该怎么随机生成和为定值的整数呢?而且要保证生成的随机数个数为N个。

18 条回复


jingzhaos 发表于 2017-4-24 20:57:11
本站讨论过这个问题,
www.ilovematlab.cn/thread-434209-2-1.html

J-Rain 发表于 2017-4-24 21:05:03
jingzhaos 发表于 2017-4-24 20:57
本站讨论过这个问题,
www.ilovematlab.cn/thread-434209-2-1.html

但是这个求得的随机数不是整数,我想让他为整数该怎么做?

张无忌 发表于 2017-4-24 21:39:50
这实际上不就是生成N-1个随机数吗
第N个数等于M-sum(1:N-1)

jingzhaos 发表于 2017-4-24 21:50:37
张无忌 发表于 2017-4-24 21:39
这实际上不就是生成N-1个随机数吗
第N个数等于M-sum(1:N-1)

如果没有范围限制,当然可以这样。但一般情况下,随机数往往有范围限制。比如最简单要求正值的情况下,其他都是正值,最后一个是负值的可能性非常大。

J-Rain 发表于 2017-4-24 22:21:04
我做出来了,不过不知道有没有更简便的方法,供大家参考下

我这里是随机生成667个0~3的数,使它们的和为1001,并且生成100个这样的数组。


  1. j=0;
  2. while(j<100)%迭代次数为100次,即我想生成100个这种随机数
  3.     j=j+1;
  4.     for i=1:667
  5.         B=0:1:3;
  6.         C=randperm(4);
  7.         n(i,j)=B(C(1:1));%随机生成0~3个
  8.     end
  9.     if sum(n(1:667,j))~= 1001
  10.            j=j-1;
  11.     end
  12. end
复制代码

张无忌 发表于 2017-4-24 23:43:43
jingzhaos 发表于 2017-4-24 21:50
如果没有范围限制,当然可以这样。但一般情况下,随机数往往有范围限制。比如最简单要求正值的情况下,其 ...

那我理解,问题就等价于一个n-1维的整数规划问题了
x1+x2+...xn-1<M
0<xi<M
可以试试用lingo求解

jingzhaos 发表于 2017-4-25 07:12:30
本帖最后由 jingzhaos 于 2017-4-25 07:38 编辑
张无忌 发表于 2017-4-24 23:43
那我理解,问题就等价于一个n-1维的整数规划问题了
x1+x2+...xn-1

没有用过lingo,不知道能解等于的问题不能。楼主要求的是等于,而且这是整数规划。更关键的问题,这是生成随机数,有无限多个解。比如按照楼主的要求,667个0~3之间,总合1001,最简单的是333个3,加1个2,剩下的是0;或者332个2,再加2个2,1个1。这是整数规划似乎也无法解决的。lingo能解决?

maple1314168 发表于 2017-4-25 09:32:23
本帖最后由 maple1314168 于 2017-4-25 09:36 编辑

这个是 多元一次不定方程的正整数解。
(1)考虑顺序的话:可能的个数C(M-1,N-1),至于如何生成,你可以搜索一下。
     如果对每个数还有限制的话,参考《带限制条件的不定方程正整数解的计数问题》,这是简单的区间限制。
(2)不考虑顺序的话:整数的拆分。拉马努金在这方面好出名的。这个你自己搜索!

张无忌 发表于 2017-4-25 19:30:14
本帖最后由 张无忌 于 2017-4-25 23:13 编辑

失败了

Attender 发表于 2017-4-26 21:55:52
我有一个理解,这个问题可以等价为在线段上取整数点;
如果按照2楼给的链接贴中内容,相当于在一条长度为1001的线段上,包括首尾共取了668个点,这些点之间的距离就是667个随机数,如果用round函数将这些点取整,重新构成的取点方案应该能满足你的要求。

winner245 发表于 2017-4-28 07:51:45
“如何随机生成N个(N已知)整数且他们之和为一个定值M(M已知)”,这里楼主还需进一步明确几个信息:N个数的范围(如果不给定范围就无从求解,或者有无数种可能)、离散分布的类型(是否均匀分布)

回到楼主的问题,按楼主的要求,不妨考虑 “N个非负整数(和为定值 M) + 离散均匀分布” 的具体情形,这一问题 “求解M个相同球放入N个不同盒子的放法” 的问题有很大的关联,解决该问题有个著名的办法 —— 隔板法,搞懂了这种内在关联,就不难理解下面的代码,它实现的是 “生成N个和为定值M的均匀分布非负整数”:

f = @(M,N)diff([0,sort(randperm(M+N-1,N-1)),M+N])-1;
验证:
M = 1000; N = 100;
sum(f(M,N)) == M

顺便说一下,2楼所附链接针对的是和为定值的实数情形,考虑的是连续分布,不适用于这里的问题。另外,11楼提到的按照2楼链接中的方法再取整的办法也无法达到目的,因为和为定值的实数取整之后再求和,无法保证和不变。



jingzhaos 发表于 2017-4-28 10:16:17
winner245 发表于 2017-4-28 07:51
“如何随机生成N个(N已知)整数且他们之和为一个定值M(M已知)”,这里楼主还需进一步明确几个信息:N个 ...

提点严格的要求,如果要求是正整数呢?即不包含0。

winner245 发表于 2017-4-28 12:38:27
jingzhaos 发表于 2017-4-28 10:16
提点严格的要求,如果要求是正整数呢?即不包含0。

你可以参考我上面给出的代码,依葫芦画瓢写出正整数情形:

f = @(M,N)diff([0,sort(randperm(M-1,N-1)),M])

验证:
M = 1000; N = 100;
sum(f(M,N))==M & all(f(M,N)>0)

jingzhaos 发表于 2017-4-28 14:28:03
winner245 发表于 2017-4-28 12:38
你可以参考我上面给出的代码,依葫芦画瓢写出正整数情形:

f = @(M,N)diff([0,sort(randperm(M-1,N-1)), ...

谢谢,真正懂数学的。

winner245 发表于 2017-4-30 15:58:52
另外,如需一次产生 n 组和为定值的随机数序列,可以用下述方式向量化实现:

1. 非负整数情形

M = 10; N = 5; n = 6;
[~,idx] = sort(rand(M+N-1,n));
x = diff([zeros(1,n);sort(idx(1:N-1,:));ones(1,n)*(M+N)]) - 1;

all(x(:) >= 0) & all(sum(x) == M)  % 用于验证


2. 正整数情形
M = 10; N = 5; n = 6;
[~,idx] = sort(rand(M-1,n));
x = diff([zeros(1,n);sort(idx(1:N-1,:));ones(1,n)*M]);

all(x(:) > 0) & all(sum(x) == M)   % 用于验证


最后结果 x 是所需的 n 列矩阵,每一列是一组和为定值的随机数序列

jujuliu 发表于 2019-6-9 22:32:56
winner245 发表于 2017-4-28 07:51
“如何随机生成N个(N已知)整数且他们之和为一个定值M(M已知)”,这里楼主还需进一步明确几个信息:N个 ...

版主,看了您几年前的回答,不是很理解什么意思,比如说我想生成N个和为定值M的整数,要求每一个整数在[a,b]之间,怎么实现呢?

蓝色天空. 发表于 2021-11-6 22:03:34
winner245 发表于 2017-4-30 15:58
另外,如需一次产生 n 组和为定值的随机数序列,可以用下述方式向量化实现:

1. 非负整数情形

您好,请问[~,idx] = sort(rand(M-1,n))中的[~,idx] 是啥意思?

蓝色天空. 发表于 2021-11-6 22:06:27
jingzhaos 发表于 2017-4-28 14:28
谢谢,真正懂数学的。

您好,请问[~,idx] = sort(rand(M-1,n))中的[~,idx] 什么意思?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

相关帖子
相关文章
热门教程
站长推荐
快速回复 返回顶部 返回列表