matlab 0-1 矩阵 16乘以332 每行仅有83个1,每列有且仅有4个1 会的快来,谢谢了!

2024-12-16 05:42:26
推荐回答(2个)
回答1:

这个问题的思路是先构造一个基本的(4*4)*(4*83)的矩阵并使其满足行列加和要求,这样的矩阵最简单的就是诸如下面的矩阵
A 0 0 0
0 A 0 0
0 0 A 0
0 0 0 A
其中每个A为4*83的全1矩阵
可以明显的证明:对这个矩阵任意两行或两列进行交换(或对行/列中相同个数的相等元素做行/列交换),其行列加和值不变。这样随机进行N次交换就可以获得需要的随机矩阵。
以下给出matlab源代码:

lena=4;
lenb=83;
loop=4;
len_A=lena*loop;%矩阵行
len_B=lenb*loop;%矩阵列
datai=ones(lena,lenb);%单个4*83矩阵
data_t=zeros(len_A,len_B);

%构造初始化矩阵
for i=0:loop-1
data_t(lena*i+1:lena*i+lena,lenb*i+1:lenb*i+lenb)=datai;
end

shift_times=1000;%位移循环次数

%位移方法为随机2行和2列进行交换
for i=1:shift_times
m1=ceil(len_A*rand);
m2=ceil(len_A*rand);
n1=ceil(len_B*rand);
n2=ceil(len_B*rand);
temp=data_t(m1,:);
data_t(m1,:)=data_t(m2,:);
data_t(m2,:)=temp;

temp=data_t(:,n1);
data_t(:,n1)=data_t(:,n2);
data_t(:,n2)=temp;
end
%---------------------------------%
第一种交换方法组合较少是因为按行或按列整体移动时关联性太大,改成按元素进行交换就好了,下面给出源代码

clear;
clc;
lena=4;
lenb=83;
loop=4;
len_A=lena*loop;%矩阵行
len_B=lenb*loop;%矩阵列
datai=ones(lena,lenb);%单个4*83矩阵
data_t=zeros(len_A,len_B);

%构造初始化矩阵
for i=0:loop-1
data_t(lena*i+1:lena*i+lena,lenb*i+1:lenb*i+lenb)=datai;
end

shift_times=2000;%位移循环次数

%位移方法为随机两个等于1的元素交换列号
%注意只有对应位置为0时才能交换
for i=1:shift_times
m1=ceil(loop*lena*lenb*rand);
m2=ceil(loop*lena*lenb*rand);
[temp1,temp2]=find(data_t==1);
if(data_t(temp1(m1),temp2(m2))==0&&data_t(temp1(m2),temp2(m1))==0)
data_t(temp1(m1),temp2(m1))=0;
data_t(temp1(m1),temp2(m2))=1;
data_t(temp1(m2),temp2(m2))=0;
data_t(temp1(m2),temp2(m1))=1;
end
end

回答2:

我倒有个办法,你看看行不行,unidrnd(a,m,n)这个函数是随机生成m行n列1到a,a个数的命令,,你可以先用unidrnd(2,16,332)生成1,2的随机序列,然后再对整个矩阵减一就能得到所求了,实现起来也不麻烦!