标签(空格分隔): matlab 排列 算法 映射
文章目录
matlab排列序列的产生,序列与序数的一一映射函数
1.1 产生排列序列
% 系统的方法
>> seps = perms(1:3)
seps =
3 2 1
3 1 2
2 3 1
2 1 3
1 2 3
1 3 2
% 我写的方法
>> seq = myPerms(3)
seq =
1 2 3
2 1 3
1 3 2
2 3 1
3 1 2
3 2 1
系统的perms()和myPerms()函数都能生成所有排列,但是myPerms()所调用的permContinue()函数能够逐个地生成排列序列,这样能节省内存。例如:
>>
n=3;
seq=1:n;
index=1:n;
[seq,index,loopJudge]=permContinue(n,seq,index)
seq =
2 1 3
index =
2 1 3
loopJudge =
1
>> [seq,index,loopJudge]=permContinue(n,seq,index)
seq =
1 3 2
index =
1 3 2
loopJudge =
1
>> [seq,index,loopJudge]=permContinue(n,seq,index)
seq =
2 3 1
index =
3 1 2
loopJudge =
1
>> [seq,index,loopJudge]=permContinue(n,seq,index)
seq =
3 1 2
index =
2 3 1
loopJudge =
1
>> [seq,index,loopJudge]=permContinue(n,seq,index)
seq =
3 2 1
index =
3 2 1
loopJudge =
1
>> [seq,index,loopJudge]=permContinue(n,seq,index)
seq =
[]
index =
[]
loopJudge =
0
1.2 序列与序数的一一映射函数
1.2.1 排列序列映射到序数
>> number = perm2num(n, [1 2 3])
number =
1
>> number = perm2num(n, [2 1 3])
number =
2
>> number = perm2num(n, [1 3 2])
number =
3
>> number = perm2num(n, [3 1 2])
number =
4
>> number = perm2num(n, [2 3 1])
number =
5
>> number = perm2num(n, [3 2 1])
number =
6
1.2.1 序数映射到排列序列
>> [seq,index]= num2perm(n,1)
seq =
1 2 3
index =
1 2 3
>> [seq,index]= num2perm(n,2)
seq =
2 1 3
index =
2 1 3
>> [seq,index]= num2perm(n,3)
seq =
1 3 2
index =
1 3 2
>> [seq,index]= num2perm(n,4)
seq =
2 3 1
index =
3 1 2
>> [seq,index]= num2perm(n,5)
seq =
3 1 2
index =
2 3 1
>> [seq,index]= num2perm(n,6)
seq =
3 2 1
index =
3 2 1
1.3 产生1~n阶所有排列
>> permsEasy(3)
s =
1
s =
1 2
2 1
s =
1 2 3
2 1 3
1 3 2
2 3 1
3 1 2
3 2 1
1.4 源代码
1.4.1 myPerms()
function seqs=myPerms(n)
%【逐个】产生所有【排列】的主函数
%% 原创算法
%单个序列生成的时间复杂度为O(n);
%总时间复杂度为O(n!*n);总空间复杂度为O(n)
%时间:2014/01/01 20:21 姓名:邓能财
%%
seqs=zeros(factorial(n),n);
i=1;
seqs(i,:)=1:n;
index=1:n;
loopJudge=true;
while true
[seqTemp,index,loopJudge]=permContinue(n,seqs(i,:),index);
if loopJudge
seqs(i+1,:)=seqTemp;
i=i+1;
else break; end
end
end
1.4.2 permContinue()
function [seq,index,loopJudge]=permContinue(n,seq,index)
% 子函数:产生下一个序列
%时间:2014/01/01 20:21 姓名:邓能财
%disp('寻找移动的数字:')
seqMoveForward=2;
while seqMoveForward~=n+1 && index(seqMoveForward)<index(seqMoveForward-1)
seqMoveForward=seqMoveForward+1;
end
if seqMoveForward==n+1, %disp('算法结束');
loopJudge=false; seq=[]; index=[];
return;
end
indexMoveForward=index(seqMoveForward);
%disp('寻找移动数字安放的位置:')
for indexMoveTo=index(seqMoveForward)-1:-1:1
if seq(indexMoveTo)<seqMoveForward, break; end
end
seqMoveTo=seq(indexMoveTo);
%sprintf('调换%d与%d',seqMoveForward,seqMoveTo)
%disp('调换前:')
%seq,index
seq(indexMoveTo)=seqMoveForward; seq(indexMoveForward)=seqMoveTo;
index(seqMoveTo)=indexMoveForward; index(seqMoveForward)=indexMoveTo;
%disp('调换后:')
%seq,index
%sprintf('将小于%d的数由逆序变为顺序',seqMoveForward)
for i=1:floor((seqMoveForward-1)/2)
seq(index(i))=seqMoveForward-i; seq(index(seqMoveForward-i))=i;
tmp=index(i); index(i)=index(seqMoveForward-i); index(seqMoveForward-i)=tmp;
end
%disp('变序后:')
%seq,index
loopJudge=true;
end
1.4.3 perm2num()
function num= perm2num(n,index)
%将【排列序列元素的索引】映射到1~n的所有排列的【序号】
%% 原创算法
%如果加入预计算的阶乘数,那么时间复杂度为O(n(n+1)/2)
%时间:2014/01/01 23:01 姓名:邓能财
%%
num=0;
%forwardMoves=[];
for i=n:-1:1, %i
forwardMove=i-index(i);
%forwardMove
for j=n:-1:i+1, %j
if index(j)<index(i), forwardMove=forwardMove+1; end
end
%forwardMoves=[forwardMoves,forwardMove]
if forwardMove~=0
num=num+forwardMove*factorial(i-1);
end
end %,forwardMoves
num=num+1;
end
1.4.4 num2perm()
function [seq,index]= num2perm(n,num)
%将1~n的所有排列中【序列的序号】映射到【序列元素的索引】
%% 原创算法
%如果加入预计算的阶乘数,那么时间复杂度为O(n(n+1)/2)
%时间:2014/01/01 23:01 姓名:邓能财
%%
seq=zeros(1,n);
index=zeros(1,n);
num=num-1;
for i=n:-1:1, %i
%带余除法
q=floor(num/factorial(i-1)); %商数
num=num-q*factorial(i-1); %余数
%由q确定i前移的位数
% % %方案2:
% % index(i)=i-q
% % for j=n:-1:i+1
% % if index(j)<=index(i)
% % j
% % index(i)=index(i)+1;
% % end
% % end,index
%方案1:
k=0;
for j=n:-1:1
if seq(j)==0
if k==q, index(i)=j;seq(j)=i;break; end
k=k+1;
end
end
end
1.4.5 permsEasy()
function permsEasy(n)
% 产生1~n阶所有排列
%时间:2014/01/01 23:01 姓名:邓能财
s=1
for i=2:n
stmp=s;
s=[];
for j=1:i
s=[s;[stmp(:,1:end-j+1),i*ones(factorial(i-1),1),stmp(:,end-j+2:end)]];
end
s
end
联系作者 [email protected]
end