首页/文章/ 详情

Matlab 最详细的生成固定和&固定元素个数&随机整数矩阵方法分享

3年前浏览3907

image.png

 过冷水诚挚邀请你加入Matlab仿真秀官方交流群进行Matlab学习、问题咨询、 Matlab相关资料下载,qq:927550334

QQ图片20210424105303.png

经常使用matlab绘图或者做计算自然而然遇到一个很基础的步骤,数据处理,本期过冷水就和大家分享一下matlab数据预处理技巧。

过冷水最近在学习过程中遇到这么一个问题,需要生成一个向量,该向量具有以下特点:

1 元素都为整数;

2元素和为指定值;

3 元素分布不能具有倾向性,最大值和最小值不能受约束(可操控);

4 元素个数可固定。

过冷水基本上把不符合上述特性方法都摸索排除了一遍,我们先看一下网上攻略。

1.jpg

image.png

ansonzxy 方法十分简单,看上去似乎是正确的,过冷水多次尝试,向量元素不是随机整数,向量和不是固定值。

x=randn(1,4) 45
average=sum(sum(x))/4
x =
   44.6258   45.6953   45.8776   46.0336
average =
   45.5581

image.png

        qingningleyun 方法确实可以生成一个指定向量元素个数,元素和为定值,元素值为整数,but!该矩阵具有明显的倾向性。

 m = 1;   % 根据每个元素的平均值,以正态分布产生随机值,方法较笨,参考参考
n = 45;s m = 54;
R = [];
S M = sum(R(:))
while S M ~= s m    ss = s m;
    rc = m*n;
    R = [];
    for k=1:(m*n)   
        pp = ss/rc;
        r = abs(round(pp*randn));
        R = [R r];
        ss = ss - r;
        rc = rc - 1;
    end
    S* = sum(R(:));
end
R = reshape(R,m,n)
R =
  列 1 至 34
 1     1     1     1     0     4     2     0     1     2     1     1     1     0     3     2     1     0     0     0     0     0     2     1     0     0     1     3     2     1     0     0     1     0
  列 35 至 45
1     1     3     2     0     4     2     1     4     0     3 
R =
  列 1 至 34
1     0     1     1     3     0     0     0     2     2     1     1     0     1     1     1     0     2     0     1     1     1     0     1     1     1     2     0     1     3     3     1     1     0
列 35 至 45
4     1     4     1     2     2     0     1     2     3     0

R =
列 1 至 34
0     1     1     1     0     0     1     1     1     2     1     0     0     2     0     0     0     1     1     2     2     0     1     1     1     0     1     0     3     0     1     3     2     1
列 35 至 45
2     3     0     0     1     2     3     7     4     0     1
 54

    可以很明显的发现,前面数普遍偏小,后面数偏大,从其方法中就可以看出,其平均值方法就限定了元素值不能为54,等较大的值,所以该方法是有一点不合适的。

image.png

sum(cell2mat(arrayfun(@(x)randperm(45)==x,ones(54,1),'UniformOutput',false)),1)

ans =
列 1 至 34
4     1     0     0     1     0     1     1     3     3     0     2     2     1     2     0     0     3     2     1     1     1     0     2     3     0     1     1     1     0     0     0     0     1
列 35 至 45
2     0     0     1     1     2     3     1     2     4     0
a =
列 1 至 34
 1     0     0     1     4     2     0     1     0     0     3     1     1     2     2     3     0     2     2     0     1     1     0     0     1     1     0     2     3     0     0     1     0     1
列 35 至 45
3     0     2     2     2     3     1     1     1     3     0
 a =
列 1 至 34
5     1     3     0     1     0     0     3     2     0     1     1     1     0     3     1     1     1     1     0     2     1     4     1     2     0     1     1     2     2     0     0     1     1
列 35 至 45
2     0     0     0     0     0     1     1     1     2     4
 a =
列 1 至 34
1     0     0     3     1     0     0     1     2     1     0     2     3     1     1     1     1     2     1     2     0     2     1     1     2     1     0     0     1     2     1     0     4     3
列 35 至 45
2     1     0     3     0     0     0     3     1     1     2

    maybe该方法是可以的,可是过冷水反复测试,发现生成元素值普遍偏小,我们并不能控制其元素取值范围。所以有一点小瑕疵。过冷水不知道如何在基于该方法的基础上控制元素值范围 。

3.png

该方法指定了向量元素范围,随机整数,固定和,完美!

clear
S=54;
Amin=0;%数据最小值
Amax=5;%数据最大值
SumA=S-1;
n=0;
while SumA<S
    n=n 1;
    temp=round(rand(1)*S);
    while temp>Amax
        temp=Amin round((Amax 1-Amin)*rand(1));
    end
    STemp=SumA temp;
    if STemp<=S
        A(n)=temp;
        SumA=sum(A);
    else
        n=n-1;
    end
end
disp('A')
disp(A)
A
1     5     3     4     5     0     4     0     0     5     5     0     5     3     5     2     4     3
A
1     3     1     4     0     2     4     3     3     3     1     0     1     2     3     2     3     2     5     4     1     2     2     2
A

1     4     3     4     1     0     2     5     1     5     3     4     1     3     3     3     1     4     2     4

    运行几次后,可以很明显的发现每次生成的向量元素个数都不固定。经过大量不完美案例演示,好了可以明显的发现,以上给出的方法并不是严格意义上的随机。总是有各种条件约束限制,过冷水就想如何综合各种方法,做出符合要求的向量,上面方法中可取的优点有round((Amax 1-Amin)*rand(1))

1 round((Amax 1-Amin)*rand(1))函数可以生成一个最大值和最小值之间的随机整数。

2 S=S-temp 的循环赋值方法可以保证向量和为固定值。

    过冷水思路为生成一个1*n的空向量,每个元素代号为n1、n2、n3,第一个元素赋值n1=S,生成一个随机整数m1,S-m1为零, 赋值: n1=S,n2~nn=0;S-m为负,赋值:n1=S,n2~nn=0。S-m为正,可认为是剩余n-1项元素和,进行赋值n1=m1,n2=S-m1,进入循环赋值 再生成一个随机数m2,做n2-m2 的判断。

程序为:

clear
S=54;
Amin=0;%数据最小值
Amax=5;%数据最大值
SumA=S-1;
n=0;
A=zeros(1,45);
A(1,1)=S;
for i=1:44
    temp=round(rand(1)*(Amax-Amin) 1)
    B=A(1,i)-temp
    if B>=0
        A(1,i 1)=B
        A(1,i)=temp
    else B<0
        A(1,i 1)=0
    end
end
disp('A')
disp(A)
A
  列 1 至 34
4     5     5     2     3     5     2     6     1     5     3     4     4     4     1     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
列 35 至 45
0     0     0     0     0     0     0     0     0     0     0
A
列 1 至 34
2     1     3     1     3     4     3     4     1     2     3     2     2     2     5     3     5     2     5     1     0     0     0     0     0     0     0     0     0     0     0     0     0     0
列 35 至 45
0     0     0     0     0     0     0     0     0     0     0
A
列 1 至 34
6     5     5     5     2     5     4     3     4     6     1     5     3     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
列 35 至 45
0     0     0     0     0     0     0     0     0     0     0

    看上去过冷水编的程序没有问题,元素个数固定,元素和固定,but经过大致一看,该向量也是有明显的倾向性,基本后面的元素都是为0,就前面的元素数值,该问题通过程序就可以发现。过冷水在前人的程序中发现 randperm(n)函数可以剩下1~n的n个元素的乱序矩阵,就可以用该函数对A进行重排

rowrank = randperm(45); 
B = A(1,rowrank)
rowrank = randperm(45); % 随机打乱的数字,从1~行数打乱
B = A(1,rowrank)
B =
  列 1 至 34
0     0     0     0     5     0     0     0     6     0     0     4     0     0     4     0     0     6     0     5     0     2     0     0     0     0     0     0     5     0     0     0     0     3
列 35 至 45
5     0     0     0     0     0     5     0     1     0     3

    问题完美解决,我们也可以对temp=round(rand(1)*(Amax-Amin) 1)进行修改更好的控制元素值的分布。过冷水在刚接触到生成随机整数矩阵的时候,觉得这个问题So easy, 随着实际过程发现问题并没有想象中的简单,也是不断翻阅资料,才知道问题出在什么地方,如何特定问题,所以做的多了解才深入,才能学的多,关于随机数生成读者有其它类似的问题,可留言讨论,共同学习,共同进步。

图片

        过冷水发表于仿真秀 平台原创文章,未经授权禁止私自转载,如需转载请需要和作者沟通表明授权声明,未授权文章皆视为侵权行为,必将追责。如果您希望加入Matlab仿真秀官方交流群进行Matlab学习、问题咨询、 Matlab相关资料下载均可加群:927550334。

精品回顾

matlab绘制农夫过河动态图

分子动力学的原子空间运动轨迹演示编程

过冷水带你用matlab制作演示动画

python批量移动文件&重命名代码分享

过冷水和你分享 matlab读取存储各种文件的方法 文末有独家金曲分享

image.png

MATLAB
著作权归作者所有,欢迎分享,未经许可,不得转载
首次发布时间:2021-07-22
最近编辑:3年前
过冷水
博士 | 讲师 讨论号:927550334
获赞 358粉丝 180文章 107课程 11
点赞
收藏
未登录
还没有评论
课程
培训
服务
行家
VIP会员 学习 福利任务 兑换礼品
下载APP
联系我们
帮助与反馈