test=[0 1 1 1 0 0 0 0
0 0 1 1 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0
0 0 1 1 0 1 1 1
0 0 1 1 0 0 1 1
1 1 0 0 0 0 0 1
1 1 0 0 0 0 0 0];
%test=[0 1 1 1 0 0 1 1
%0 0 1 1 0 0 1 1
%0 0 0 1 0 0 0 0
%0 0 0 0 0 0 0 0
%0 0 1 1 0 1 1 1
%0 0 1 1 0 0 1 1
%0 0 0 0 0 0 0 1
%0 0 0 0 0 0 0 0];
x=randperm(8);
%对出来的随机序列进行组合,相当于8个中选两个
y=nchoosek(x,2);
yy=[];
%对出来的随机序列,看它对应(或其转置的位置)的test矩阵是否为一
%这一步的目的是获得随机序列中与test对应的那些对
%yy这个矩阵是为了获得那些符合要求的组合
for i=1:length(y)
if test(y(i,1),y(i,2))==0
if test(y(i,2),y(i,1))==1
yy=[yy;[y(i,2),y(i,1)]];
end
else
yy=[yy;y(i,:)];
end
end
%下面的算法使用了回溯法(数据结构中有学)
%这个向量是用来表示有哪几个组合已经在stack中了
visited=zeros(1,length(yy));
%初始的时候是让第一个进入stack
visited(1)=1;
%建的栈,用来贮存合格的组合的标号,并且在stack中的顺序就是要找的顺序
stack1=1;
%代表符合要求的长度,当为7时就行了
len=1;
%代表每次循环的下标,(对于能够找到合法的,就下次从1开始,如果找不到,就弹栈,从弹出的下一个开始)
beginindex=1;
while len<7
flag=0;
for j=beginindex:length(yy)
%寻找的合法组合,要求为还没不在stack中,并且它的第一个数和stack中的最后一个组合的第二数是一样的
if visited(j)==0&&yy(j,1)==yy(stack1(end),2)
len=len+1;
visited(j)=1;
flag=1;
stack1=[stack1,j];
beginindex=1;
break;
end
end
%表明没有成功找到,这时要弹栈
if flag==0
len=len-1;
index=stack1(end);
visited(index)=0;
beginindex=index+1;%从弹出的下一个开始--;
stack1(end)=[];
%弹栈的时候会出现stack空的可能,于是就要为这个stack从新放入第一个组合,原则是选弹出的最后一个的下面那个,
%并且beginindex=1;
if len==0
stack1=index+1;
visited(stack1(end))=1;
len=1;
beginindex=1;
end
end
end
xh=yy(stack1,:);
xh1=xh';
xh2=xh1(:)';
lastresult=xh2(1:2:end);
disp(lastresult)
这个程序现在是好用的,但是当我改变test(我注释掉的那个test)的时候,就出现如下错误:??? Attempted to access yy(21,2); index out of bounds because size(yy)=[20,2].
Error in ==> guanxijuzhen at 48
if visited(j)==0&&yy(j,1)==yy(stack1(end),2)
>>