1701010165
我和数学有约:趣味数学及算法解析 9.2 100内取10个正数,和等于100
1701010166
1701010167
【问题】100内如何取10个正整数,使得它们相加和等于100?
1701010168
1701010169
【分析】
1701010170
1701010171
这个问题看起来挺简单,但是人工计算,计算量则显得很大,怎么合理地分配资源,怎么快速的求解出有效解,这是大家应该考虑的问题。
1701010172
1701010173
对于选取的10个数,采用枚举法,是可以很简单的。例如,先选取1、2、3、4、5、6、7、8和9这九个数,这九个数之和为45,那么再添加一个55即可构成100,满足题目要求。
1701010174
1701010175
同样,也可以考虑重复的情况,例如选取9个1,这九个数之和为9,那么再选取一个91,即可构成100,同样能够满足要求。
1701010176
1701010177
但是在实际应用中,用户要求系统满足一定的随机性,其取值应该尽可能的满足变化无规律,这10个数,应该是系统自动分配的,采用计算机进行模拟有以下几种情况。
1701010178
1701010179
(1)可能出现异常值的模拟
1701010180
1701010181
计算机模拟如下:
1701010182
1701010183
clc,clear,close all %清屏和清除变量 warning off %消除警告 c=zeros(10,1); %初始化 cs=zeros(10,1); %初始化 lr=0; %初始化 for i=1
:9 c(i)=(100-lr)*rand(1); %0 — (100-lr)中随机选取数字 cs(i)=fix(c(i)); %取整 lr=cs(i)+lr; %更新 end cs(10)=100-lr; %第10个数为100减去前9个数之和
1701010184
1701010185
运行程序输出结果如下:
1701010186
1701010187
ans = 54 13 24 1 5 0 1 1 0 1
1701010188
1701010189
结果显示,10个数字之和满足100,然而出现了0,这个不包含在1~100之内的整数范围,因此该计算机模拟存在一定的弊端。
1701010190
1701010191
(2)rand随机赋值查询
1701010192
1701010193
程序如下:
1701010194
1701010195
clc,clear,close all %清屏和清除变量 warning off %消除警告 cs=zeros(10,1); %初始化 while sum(cs)~=100 %cs和为100,则跳出程序,输出结果 c = rand(10,1); c1 = c./sum(c); %归一化 cs = round(c1*100); %10个reader分别管控多少个tag,总和100 if min(cs)==0 %判断是否存在0的情况 cs=cs+100; end end cs’
1701010196
1701010197
运行程序输出结果如下:
1701010198
1701010199
ans = 11 1 16 1 2 12 2 19 19 17
1701010200
1701010201
输出结果不包含0值,结果可以接受,然而有时需要考虑10个数不重复的情况,因此该程序需要继续改进。
1701010202
1701010203
(3)基于变量取值区间的查询
1701010204
1701010205
考虑到100个数,每一个数字的取值范围为1~100,因此,可以采用查询的方式,一一查询,用户很轻松的书写代码如下:
1701010206
1701010207
clc,clear,close all %清屏和清除变量 warning off %消除警告 ans = rand; %产生一个随机数 while sum(ans)~=100 %判断和是否等于100 randperm(100,10); %在1~100中,找10个整数相加等于100 end ans sum(ans)
1701010208
1701010209
程序如同出现死循环一般,电脑一直在运行,但是没有结果,由于10个数字,每一种数字100种可能,100^10次方的查询,导致电脑运行超级慢,这也使得该程序有欠妥之处,主要原因是没有考虑变量的取值范围可以缩小。
1701010210
1701010211
之前我们讨论过,系统存在1、2、3、4、5、6、7、8、9和55这种情况,从这个可行解可看出,当系统不出现重复的数字的情况,每一个数的取值范围应该在1~55之间,因此使得系统搜索范围大大降低,同样程序如下:
1701010212
1701010213
while sum(ans)~=100 randperm(55,10); %在1~55中,找10个整数相加等于100 end
[
上一页 ]
[ :1.701010164e+09 ]
[
下一页 ]