⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bv.m

📁 用BV算法可以实现交换机的高吞吐量
💻 M
字号:
function [schedultable,schedullen,bandsize,matrixnumb]=bv(T) %流量矩阵T的行或列元素之和>10的矩阵

N=4; %交换机端口数
T=[3,2,4,1;2,5,1,2;4,1,3,5;2,4,2,3];%流量矩阵T的行或列元素之和>10的矩阵
INF=100;

%%%%%%备份原流量矩阵T
backupT=T; 
T1=T;
T2=T;
constbackT=T;  

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%     计算最小需求带宽minbandwith      %%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
minbandwith=0;%%% 表示最小需求带宽
g=zeros(1,N);%%%创建(1*N)的全零数组
h=zeros(1,N);

%%%%%%%  对T的列向量进行冒泡排序,按降序排列 
for j=1:N     
    for k=1:N-1  
        for i=1:N-k
            if T1(i,j)<T1(i+1,j)
                temp=T1(i,j);
				T1(i,j)=T1(i+1,j);
				T1(i+1,j)=temp;
            end
        end
    end
end
T1
%%%%%%%%%%%%%%   计算流量矩阵 T 的最小需求带宽    %%%%%%%%%%%
    %找出每行的最大值存入g[i]中
    for i=1:N 
        for j=1:N
            if T1(i,j)>g(i)
                g(i)=T1(i,j);
            end
        end
    end
    g
    %对T的行向量进行冒泡排序,按降序排列
    for i=1:N  
        for k=1:N-1
            for j=1:N-k
                if T2(i,j)<T2(i,j+1)
                    temp=T2(i,j+1);
                    T2(i,j+1)=T2(i,j);
                    T2(i,j)=temp;
                end 
            end
        end
    end 
    T2
 %找出每列的最大值存入h[i]中
 for j=1:N  
     for i=1:N
         if T2(i,j)>h(j)
             h(j)=T2(i,j);
         end
     end
 end  
 h
   tempminbandwith=0;   
   for i=1:N
       tempminbandwith=tempminbandwith+g(i);
   end
   minbandwith=0;
   for i=1:N
       minbandwith=minbandwith+h(i);
   end
   if tempminbandwith>minbandwith
       minbandwith=tempminbandwith;
   end
   fprintf('最小需求带宽等于');minbandwith
    
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    
 %%%%%%%%%%%%%%%%           构造双随机矩阵T          %%%%%%%%%%%%%%%  
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %初始化 
   sumr=zeros(1,N);	%sumr[i]为第i行的元素和;
   suml=zeros(1,N);%suml[i]为第i列的元素和;
   decr=zeros(1,N);%decr[i]为第i行元素和与minbandwith的差;
   decl=zeros(1,N);%decrl[i]为第i列元素和与最大值max的差;  
 %%%%%%%%%        计算每行、每列元素和        %%%%%%%%%%%%
   for i=1:N
	   for j=1:N
           sumr(i)=sumr(i)+T(i,j);
	       suml(i)=suml(i)+T(j,i);
       end
   end   
 %%%%%%%%%       计算每行、每列元素和与最小需求带的差     %%%%%%%%%%%%
   for i=1:N
        decr(i)=minbandwith-sumr(i);
        decl(i)=minbandwith-suml(i);
   end  
 maxsum=0;%%% 每个元素所在的行和与列和的最大值
   for i=1:N
	   for j=1:N
           maxsum=sumr(i);
           if suml(j)>maxsum 
               maxsum=suml(j);
           end
           e=minbandwith-maxsum; %%% e表示矩阵T中每个元素应该加的值
           T(i,j)=T(i,j)+e;
           sumr(i)=sumr(i)+e;
           suml(j)=suml(j)+e;
           if sumr(i)==minbandwith
               break;
           end
       end %for j
   end%for i   
   fprintf('转换后的双随机矩阵T如下');T 
   
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
  %%%%%%%%%%%%%%%             进行BV分解             %%%%%%%%%%%%%%%% 
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  BANDWITH=2; %预先分配得到的调度矩阵的个数为2,后面matlab可以根据实际数修改
  p=zeros(N,N,BANDWITH);   %预附三维排列矩阵p为全零矩阵
    
  %%%% 循环分解得到一组排列矩阵的集合,直到T为0为止  
  bandsize=0;       %存放实际得到的需求带宽 
  matrixnumb=0;  %%%分解得到的排列矩阵个数  
  notzerotag=1;   %表示T是否为全零的标记,=0为全零矩阵   
  while notzerotag        
	  temp=1;       
      lieb=randseed();%产生的置换排列放于lieb[]中
      for i=1:N
          j=lieb(i);
          temp=temp*T(i,j);  %for循环产生了一组置换列向量 
      end
      if temp~=0 
          min=INF;
          for i=1:N     %%%%%%  计算置换矩阵的系数=矩阵中非零元素的最小值
              k=lieb(i);
              if T(i,k)<min
                  min=T(i,k);
              end
          end 
          matrixnumb=matrixnumb+1;
          minq(matrixnumb)=min; %%%%% 存放分解得到的矩阵系数
          for i=1:N
              temp=lieb(i);
              p(i,temp,matrixnumb)=1;
              T(i,temp)=T(i,temp)-minq(matrixnumb);
          end 
          %判断分解后剩下的矩阵R是否为全零矩阵    
          notzerotag=0;
          for i=1:N    
              for j=1:N
                  if T(i,j)~=0 
                      notzerotag=1;
                      break;
                  end                      
              end
              if notzerotag==1
                  break;
              end
          end
      end %if
    end %while  
    fprintf('BV分解共得到的排列矩阵个数:');matrixnumb
    fprintf('个矩阵的系数分别为');minq
   for i=1:matrixnumb
	   bandsize=bandsize+minq(i);   
   end
   fprintf('\n实际的带宽需求等于');bandsize  
   fprintf('\n得到的调度表如下 ');   p
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%下面对p[i][j][t]进行LJ调度 得到调度表schedul[N][t],每一列对应一个时隙的调度
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    t=matrixnumb;    
    V=minbandwith;%%%  交换机端口速率      
    for i=1:t      
        selecttag(i)=minq(i);   %对t个标记的被选择标记附初值=0:被调度完,~=0:未被调度完
        minq(i)=minq(i)/V;    %minq表示t个排列矩阵的系数
        tagclass(i)=1/minq(i);%对t个排列矩阵预附标记初值
        select(i)=tagclass(i);        
        position(i)=i;        
    end       
    selecttag,select,position
    
    for k=1:bandsize 
        for i=1:t     %对t个标记进行冒泡排序,按升序排列在select数组中
            for j=1:t-1
                if select(j)>select(j+1) 
                    temp2=select(j+1);
                    select(j+1)=select(j);
                    select(j)=temp2;     
                    temp1=position(j+1);
                    position(j+1)=position(j);
                    position(j)=temp1;
                    temp1=selecttag(j+1);
                    selecttag(j+1)=selecttag(j);
                    selecttag(j)=temp1;
                end
            end
        end%一次排序完成  
        k,select,selecttag,position
        for i=1:t
            if selecttag(i)~=0
                mintag=position(i);
                temp1=i;
                break;
            end
        end	
        %下面对p[][][mintag]调度
        for i=1:N
            for j=1:N
                if p(i,j,mintag)==1
                    schedul(i,k)=j;
                end
            end
        end
        %%%%%%%%%%修改被调度的排列矩阵的标记
        select(temp1)=select(temp1)+tagclass(mintag);
        selecttag(temp1)=selecttag(temp1)-1;
        select,selecttag,position
    end
    fprintf('\n得到的调度矩阵如下');
    schedul 
    
  %%%修改得到的调度表,删除冗余调度使其等于原流量
      for i=1:N
         for j=1:bandsize 
             if schedul(i,j)~=0
                 temp=schedul(i,j); 
                 if backupT(i,temp)>=1	
                     backupT(i,temp)=backupT(i,temp)-1;
                 else
                     schedul(i,j)=0;
                 end
             end
         end
     end 
     fprintf('\n删除冗余调度后得到的调度矩阵如下');schedul 
     
  %%%%  删除全零调度向量
  delenumb=0;% 删除向量的个数  
  for j=1:bandsize
      zeronumb=0;%计数器,计0的个数,为4时即为一个零调度向量应删除
      for i=1:N
          if schedul(i,j)==0
              zeronumb=zeronumb+1;
          end
      end
      if zeronumb==4
          for k=j+1:bandsize-delenumb
              for t=1:N
                  schedul(t,k-1)=schedul(t,k);
              end
          end
          delenumb=delenumb+1;
          zeronumb=0;
      end
  end
  fprintf('\n先删除全零调度后的调度表为:');   schedul  
  delenumb   

     schedullen=bandsize-delenumb;
     schedultable=zeros(N,2);
     for i=1:N
         for j=1:schedullen
             schedultable(i,j)=schedul(i,j);
         end
     end     
     T=constbackT;T
     fprintf('最终得到的调度表如下');schedultable 
     fprintf('size is');schedullen  
     

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -