RFID-二进制树搜索

说明

MATLAB编程实现二进制树搜索与二分支搜索。

二进制树搜索

原理

二进制搜索技术以唯一的序列号来识别射频电子标签为基础。为了从一簇射频电子标签中选择其中之一, 射频读写器发出一个读命令, 将射频电子标签序列号传输时的数据碰撞引导到射频读写器, 即由射频读写器判断是否有碰撞发生。 如果有, 则进一步搜索。在二进制算法的实现中, 起决定作用的是射频读写器所使用的信号编码必须能够确定碰撞发生的准确位置。
二进制树搜索算法是由在一个射频读写器和多个射频电子标签之间规定的相互作用(命令和应答)顺序(规则)构成的,目的在于从较大的一组中选出一个标签。算法规定,射频电子标签之间要严格同步,以便准确地监测碰撞位的发生,并且要求能辨认出读写器中数据碰撞的比特位的准确位置,一般采用曼切斯特编码。
为了实现这种算法,就需要一组命令,这组命令由射频读写器发出,可由射频电子标签处理,命令如下:
REQUEST:此命令发送一序列号作为参数给射频电子标签。射频电子标签把自己的序列号与接收的序列号比较。如果小于或等于请求序列号,则此射频电子标签回送其序列号给射频读写器。这样就可以缩小预选的射频电子标签的范围请求;
SELECT:用某个事先确定的序列号作为参数发送给射频电子标签。具有相同序列号的射频电子标签将此作为执行其他命令(例如读出和写入数据)的切入开关, 选择这个射频电子标签。具有其他序列号的射频电子标签只对REQUEST命令应答;
READ-DATA:选中的射频电子标签将其存储的数据发送给射频读写器;
UNSELECT:取消一个选中的射频电子标签,使射频电子标签进入“静默”状态, 这种状态中电于标签完全是非撤活的,对收到的REQUEST命令不作应答。为了更新激活射频电子标签,暂时离开射频读写器的作用范围(等于没有供应电压),以实现复位。

代码

  • request
%request函数
%射频电子标签把自己的序列号与接收的序列号比较。如果小于或等于,返回。
function [bit,D_max]=request(new_label,new_n)
bit=ones(1,8);           %81
for k=1:8
    sum=0;
    for j=1:new_n
        sum=sum+new_label(j,k);    
    end
    if sum==0           %即对应位全为0
        bit(1,k)=0;
    elseif sum==new_n   %对应为全为1
        bit(1,k)=1;
    else
        D_max=k;        %碰撞位,且设为0
        bit(1,k)=0;
        break;
    end
end
end
  • select
%select函数
%用某个事先确定的序列号作为参数发送给射频电子标签
function [new_label2,new_n]=select(new_label,new_bit,new_max,n)
new_n=0;
for a=1:n
    if new_label(a,new_max)==new_bit(new_max)
        new_n=new_n+1;
        new_label2(new_n,:)=new_label(a,:);
    else
    end
end
end    
  • unselect
%unselect函数
function [h,nlabel]= unselect(new_label,nlabel,h)
for nn=1:h
    result = isequal(new_label,nlabel(nn,:));
    if result 
        nlabel(nn,:)=[];  
        h=h-1;
        break;
    end
end        
end
  • 界面核心代码
%主要代码位于pushbutton1_Callback

% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
tic
tag_count1=get(handles.edit1,'String');  %获取输入的标签总数
ctag=str2num(tag_count1);              
rand1=rand(ctag,1)*256;                  %随机生成标签
rand2=dec2bin(rand1);                       
tgrand=num2str(rand2);
rand3=sort(rand1);                       
rand4=dec2bin(rand3);                  
rand5=num2str(rand4);
toc                                      %记录程序运行时间
set(handles.listbox1,'String',tgrand);   %输出
set(handles.listbox2,'String',rand5);
set(handles.edit2,'String',num2str(toc));

界面结果

在这里插入图片描述

二分支

原理

该方法采用递归的工作方式,遇到碰撞就随机地进行分支,成为多个子集。在接下来的时隙中,主要解决信息包所发生的碰撞。如果再次发生碰撞,就继续随机地分为多个分支。然后依次进行查询,标签被分支后,由于响应的标签数量减少,再次发生碰撞的概率降低,通过不断的分支,减少响应标签的数量,直至分支内没有或仅有一个标签响应。

  1. 先随机生成16位的标签号,定义标签的左右子树;
  2. 先找出标签碰撞的位数,若得到碰撞的位,根据碰撞的位将标签号分为左右两子树(定义左子树位1,右子树位0);
  3. 判断左子树是否只有一个标签或无标签,若是,则该次调用结束,判断上步的右子树是否只有一个标签或无标签,若不是,则进入该右子树的左子树进行查验,以此循环。

我们定义每一个左右子树都要进行一次查询和一次响应,因为可以计算出操作次数,并定义吞吐量等于标签数目除以总的操作次数。

代码

  • pick函数
%定义pick函数:碰撞算法
function c=pick(A,tag_count,b,len)  %A为标签数组,tag_count为标签数目,b已经使用的时隙数,len为标签长度
A
tag_count
m=1;                                %左子树标签数目
n=1;                                %右子树标签数目
b=b+2;                              %查询、响应
D_max=len;                          %初始化最高碰撞位
x=0;
len_l=len;                          %初始化标签长度

if tag_count==1                     %若标签数目为1,直接返回
    c=b;
    return;
end

for j=1:1:len_l                     %对标签每一位进行判断是否碰撞
    sum=0;
    for k=1:1:tag_count             %所有标签对应为求和
        x=A(k,j);
        sum=sum+x;
    end
    if sum==0                       %即对应为全为0,无碰撞
        ;     
    elseif sum==tag_count           %即对应为全为1,无碰撞
        ;
    else                            %碰撞
        D_max=j;                    %最高碰撞位
        break;
    end
end
for i=1:tag_count                   %把标签分成左、右子树
   x=A(i,D_max);
    if x==1                         %左子树为1
        left_tag(m,:)=A(i,:);
        m=m+1;                      %左子树+1
    else
        right_tag(n,:)=A(i,:);
        n=n+1;
    end
end
if m==2||m==1                      %左子树有一个标签或无标签则响应完毕
    b=b+2;
    c=b;
else
    b=pick(left_tag,m-1,b,len);    %如果标签数大于2,则递归调用
end

if n==2||n==1                      %同上
    b=b+2;
    c=b;   
else
    b=pick(right_tag,n-1,b,len);
end
c=b;                               %返回操作总的次数
return;
  • 主函数核心代码
%主要代码位于pushbutton1_Callback
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
ctag=str2num(get(handles.edit1,'String'));       %获取输入的标签总数
ID_length=str2num(get(handles.edit2,'String'));  %获取输入的标签长度
for i=1:ctag
    tagg(i,:)=randi([0,1],1,ID_length);          %随机生成tagcount个长为ID_length的标签
end
tag1 = unique(tagg,'rows');                      %去除重复
tag_count=size(tag1,1);                          %计算不重复的标签总数
r = randperm(tag_count);                         %打乱
tag=tag1(r,:);
tag;
sum=0;a=0;
a=pick(tag,tag_count,0,ID_length)                %调用pick函数
sum=sum+a;                                       %计算操作次数
cc=sum;
tuntu=tag_count/cc;                              %计算吞吐量
set(handles.edit4,'String',cc);                  %输出操作次数
set(handles.edit5,'String',tuntu);               %输出吞吐量
tag = num2str(tag); 
tag;
set(handles.listbox2,'String',tag);              %输出待识别的标签
guidata(hObject,handles);

% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
close;                                            %关闭窗口

结果界面

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值