数学建模清风微信公众号的习题答案(挑战篇1)

以下题目是来自微信公众号数学建模清风老师的题目

以下是个人结合在微信公众号上学到的知识去做的,若有不正确或不足之处,欢迎指正!

Q1.A是一个矩阵,A(:)可以按照列方向的顺序(线性索引)将A中每个元素输出为一个向量,请问怎样按照行方向的顺序输出A中的所有元素。
在这里插入图片描述
解:使用A(:)后是线性索引,故想要得到以上结果通过观察,先取转置,在使用A(:)就可以了

在这里插入图片描述

A=[1 4 2;3 6 8];
B=A';
B(:)'

ans =

     1     4     2     3     6     8

Q2.利用MATLAB模拟随机丢一枚骰子N次,骰子有均匀的六个面。
在这里插入图片描述
解:大家自行去查一下“伯努利大数定律”,以下只给代码

N=6000;
A=randi(6,1,N);
ind=find(A==6);
n=length(ind)
p=n/N
bias=abs(p-1/6)

n =

   981


p =

    0.1635


bias =

    0.0032

Q5.MATLAB中有一个非常有用的函数:randperm函数,它能够将一个数字序列进行随机打乱。它有两种最为常见的用法:

用法1:randperm(n)可以将向量1:n中元素的顺序随机打乱,生成一个长度仍为n的新向量,因此所有可能出现的情况共n!种(全排列)。例如,当你运行randperm(4)时,你可能得到[1 4 3 2],也可能得到[3 2 4 1]。

用法2:randperm(n,k)表示从打乱的1:n序列中随机的选择k个数出来,显然这k个数都不相同,且k要小于等于n。例如,当你运行randperm(10,3)时,你可能得到[5 1 10],也可能得到[6 5 8]。

请回答下面的问题:

(1)根据上面的介绍,请你在MATLAB中测试randperm函数的功能。特别地,如果n是负数或者小数会出现怎样的情况?如果k大于n会出现怎样的情况?
解:话不多说,直接看

 randperm(10,-2)
错误使用 randperm
输入必须为非负标量整数。

randperm(10,2.5)
错误使用 randperm
输入必须为非负标量整数。

 randperm(10,11)
错误使用 randperm
K 必须小于或等于 N。

(2)假设一个商品推销员要去10个城市推销商品,该推销员随机从一个城市出发,需要经过其他所有城市后,回到出发城市(中途经过的城市不重复),请你为该推销员随机的生成一条路线。为了方便,这10个城市就用数字1至10表示

解:

randperm(10)

ans =

     9     8     3    10     1     6     5     2     7     4

(3)完成下列场景中的这段程序:假设你是一名高数老师,你正在给同学们讲不定积分的计算。这时候你的PPT上出现了你备课时准备的4道练习题,你需要随机的抽取四名幸运同学来黑板上进行计算。已知你的班上共有50名同学,他们的学号分别是2021001至2021050,你在MATLAB中运行了你写的这个程序,0.1s后这四名同学的学号在MATLAB中被随机的输出出来。

解:

A=randperm(50,4);
B=2021000;
B+A

ans =

     2021049     2021026     2021047     2021045

(4)假设某公司在年会上设置了抽奖环节。主办方准备了一个抽奖用的不透明盒子,盒子内有10张奖券,其面值分别为[1 25 10 20 50 100 200 500 1000],每名员工从中随机的抽取3张,将这3张奖券的面值相加就是最终获得的红包奖励。请你设计一个程序,模拟清风老师在该抽奖环节中抽取一次能获得的红包金额。

解:上面这个向量[1 25 10 20 50 100 200 500 1000]只有9个元素,不知道我有没有理解错。然后我就在这个向量的第一个位置加了一个元素0,相当于1你运气不好,抽到谢谢惠顾了哈哈。不过意思在就OK了。我们把10张卷的面值分别用1~10来代替,然后将随机抽到的再对应奖券的面值就OK了

A=[0 1 25 10 20 50 100 200 500 1000];
 disp('抽到的序号为:')
 B=randperm(10,3)
 for i=1:3
     k(i)=A(B(i));
 end
 disp('抽到的3张卷的面值为:')
 k
 disp('抽到兑换的红包奖励为:')
 sum(k)
抽到的序号为:

B =

     8    10     3

抽到的3张卷的面值为:

k =

         200        1000          25

抽到兑换的红包奖励为:

ans =

        1225

(5)一副扑克牌有54张,其中大王和小王各一张,A,2,3,4,5,6,7,8,9,10,J,Q,K各有4张。假设我们不考虑桃杏梅方这四种花色,请你设计一个发牌程序,为地主发20张牌,两个农民各发17张牌。为了方便,A,2,3,4,5,6,7,8,9,10,J,Q,K分别用数字1至13代替,小王用14代替,大王用15代替。

解:这个题对我们初学者还是有一点点难度的,不过难度不大。首先我们要知道这边牌是随机的。且每张牌发出去后就不能再有了(也就是不重复)。但是不能直接用randperm(54,20)、randperm(5,17)、randperm(54,17)。因为这样生成出来会有重复。所以我们可以把1~54分成5个部分 ,即第一部分为1–13,第二部分为14,15,(即大王小王),接下来是16~28、29–41、42–54,你也可以理解为牌的花色。

数字数字代表的牌花色
1–13A 1 2…J Q K黑桃
14–15小王、大王
16–28A 1 2…J Q K梅花
29–41A 1 2…J Q K方块
42–54A 1 2…J Q K红桃
  1. 首先使用randperm(54,20),得到1–54的20个乱序的数,即地主的牌的数字,然后把大于数字15的化为1–15内,地主的牌就得到了。
  2. 接下来是第一个农民的牌,我们已经在54个数中取出了20个,那么我们使用R=setdiif(K,dz) 函数取差集,也就是说1–54个数中哪些没被地主取走。剩下34个数字,取17个数,我们使用nm1=randperm(34,17) ,得到1–34的17个随机乱序的数,再将这17个数的位置索引对应着取过差集的R,即得到第一家农民的牌的数字(在1–54之间的数字),再把大于数字15的化为1–15内,就得到第一家地主的牌了。
  3. 直接用nm2=setdiff(R,nm11),即剩下的1–54中的17个数字就是第二家农民的的牌的数字,然后直接把大于数字15的化为1–15内,第二家农民的牌也得到了。代码如下:
clear,clc
K=1:54;
dz=randperm(54,20);  %地主在54中随机选出来的个牌
%%
%转化为1~15个数之间
for h=1:length(dz);
    if dz(h)<16   ;     %标号在1~15
        dz1(h)=dz(h);
   elseif  dz(h)>15&dz(h)<29 ;   %标号在16~28
        dz1(h)=dz(h)-15;
    elseif  dz(h)>28&dz(h)<42 ;    %标号在29~41
        dz1(h)=dz(h)-28;
    else dz(h)>41&dz(h)<55 ;   %标号在42~54
        dz1(h)=dz(h)-41;
    end
end
disp('地主的牌为:')
dz1
R=setdiff(K,dz);     %去掉地主取到的标号
k1=1:34;
nm1=randperm(34,17);    %第一家在剩下的34张中随机分配到的17%%
%这里是把在1~34选到的对应到剩下的牌的标号
for j=1:length(nm1);
    nm11(j)=R(nm1(j));
end
nm11;                %第一家农民随机在54张中分配到的的17%%
%转化为1~15个数之间
for h=1:length(nm11);
    if nm11(h)<16;
        nm111(h)=nm11(h);
    elseif nm11(h)>15&nm11(h)<29;
        nm111(h)=nm11(h)-15;
   elseif  nm11(h)>28&nm11(h)<42;
        nm111(h)=nm11(h)-28;
    else nm11(h)>41&nm11(h)<55;
        nm111(h)=nm11(h)-41;
    end
end
disp('第一个农民的牌为:')
nm111
%%
nm2=setdiff(R,nm11);     %54张随机分配给地主家20张,第一家农民17张后剩下的17张的原始标号
%转化为1~15个数之间
for h=1:length(nm2);
     if nm2(h)<16;
        nm22(h)=nm2(h);
    elseif nm2(h)>15&nm2(h)<29;
        nm22(h)=nm2(h)-15;
    elseif  nm2(h)>28&nm2(h)<42;
        nm22(h)=nm2(h)-28;
    elseif  nm2(h)>41&nm2(h)<55;
        nm22(h)=nm2(h)-41;
    end
end
disp('第二家农民的牌为:')
nm22

%%
%下面相当于把牌给排序了的
disp('排序后的牌:')
dizhu=sort(dz1)       %地主家排序后的牌
nonmin1=sort(nm111)    %第一家农民排序后的牌
nonmin2=sort(nm22)      %第二家农民排序后的牌


结果如下(注意:每一次运行的结果都会不一样,即相当于重新洗牌发牌)

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值