一、获取代码方式

获取代码方式1:
完整代码已上传我的资源:【优化算法】多目标人工蜂群算法(MOABC)【含Matlab源码 1236期】

获取代码方式2:
通过订阅紫极神光博客付费专栏,凭支付凭证,私信博主,可获得此代码。

备注:
订阅紫极神光博客付费专栏,可免费获得1份代码(有效期为订阅日起,三天内有效);

二、人工蜂群算法简介

1 蜜蜂采蜜
自然界中的蜜蜂总能在任何环境下以极高的效率找到优质蜜源,且能适应环境的改变。蜜蜂群的采蜜系统由蜜源、雇佣蜂、非雇佣蜂三部分组成,其中一个蜜源的优劣有很多要素,如蜜源花蜜量的大小、离蜂巢距离的远近、提取的难易程度等;雇佣蜂和特定的蜜源联系并将蜜源信息以一定概率形式告诉同伴;非雇佣蜂的职责是寻找待开采的蜜源,分为跟随蜂和侦查蜂两类,跟随峰是在蜂巢等待而侦查蜂是探测蜂巢周围的新蜜源。蜜蜂采蜜时,蜂巢中的一部分蜜蜂作为侦查蜂,不断并随机地在蜂巢附近寻找蜜源,如果发现了花蜜量超过某个阈值的蜜源,则此侦査蜂变为雇佣蜂开始釆蜜,采蜜完成后飞回蜂巢跳摇摆舞告知跟随峰。摇摆舞是蜜蜂之间交流信息的一种基本形式,它传达了有关蜂巢周围蜜源的重要信息如蜜源方向及离巢距离等,跟随峰利用这些信息准确评价蜂巢周围的蜜源质量。当雇佣蜂跳完摇摆舞之后,就与蜂巢中的一些跟随蜂一起返回原蜜源采蜜,跟随蜂数量取决于蜜源质量。以这种方式,蜂群能快速且有效地找到花蜜量最高的蜜源。

蜜蜂采蜜的群体智能就是通过不同角色之间的交流转换及协作来实现的。具体采蜜过程如图所示。在最初阶段,蜜蜂是以侦查蜂的形式出现,且对蜂巢周闱的蜜源没有任何了解,由于蜜蜂内在动机和外在的条件不同侦查蜂有两种选择:①成为雇佣蜂,开始在蜂巢周围随机搜索蜜源,如图中路线②成为跟随峰,在观察完摇摆舞后开始搜索蜜源,如图中路线。假设发现两个蜜源和,在发现蜜源后,该侦查蜂变成一只雇佣蜂,雇佣蜂利用其自身属性记住蜜源的位置,并立刻投入到采蜜中。采蜜完成后蜜蜂带着满载花蜜返回蜂巢,将花蜜卸载到卸蜜房,卸载完成后雇佣蜂有三种可能的行为①放弃自己发现的花蜜量不高的蜜源,变成一个不受约束的非雇佣蜂,如图中的路线;②在招募区跳摇摆舞,招募一些待在蜂巢中跟随峰,带领其再次返回所发现的蜜源如图中的路线;③不招募其他蜜蜂,继续回到原来的蜜源采蜜如图中的路线。在现实生活中并不是所有的蜜蜂一开始就立刻采蜜,另外大多数蜜蜂在一次采蜜完成后都会选择回到招募区跳摇摆舞来招募更多的蜜蜂去采蜜。

2 算法模型
人工蜂群算法就是模拟蜜蜂的采蜜过程而提出的一种新型智能优化算法,它也是由食物源、雇佣蜂和非雇佣蜂三部分组成。
食物源:食物源即为蜜源。在任何一个优化问题中,问题的可行解都是以一定形式给出的。在人工蜂群算法中,食物源就是待求优化问题的可行解,是人工蜂群算法中所要处理的基本对象。食物源的优劣即可行解的好坏是用蜜源花蜜量的大小即适应度来评价的。
雇佣蜂:雇佣蜂即为引领蜂与食物源的位置相对应,一个食物源对应一个引领蜂。在人工蜂群算法中,食物源的个数与引领蜂的个数相等;引领蜂的任务是发现食物源信息并以一定的概率与跟随蜂分享;概率的计算即为人工蜂群算法中的选择策略,一般是根据适应度值以轮盘赌的方法计算。
非雇佣蜂:非雇佣蜂包括跟随蜂和侦査蜂跟随蜂在蜂巢的招募区内根据引领蜂提供的蜜源信息来选择食物源,而侦查蜂是在蜂巢附近寻找新的食物源。在人工蜂群算法中,跟随蜂依据引领蜂传递的信息,在食物源附近搜索新食物源,并进行贪婪选择。若一个食物源在经过次后仍未被更新,则此引领蜂变成侦査蜂,侦查蜂寻找新的食物源代替原来的食物源。

3 算法搜索过程

4 分类
人工蜂群算法中将人工蜂群分为引领蜂、跟随蜂和侦查蜂三类,每一次搜索过程中,引领蜂和跟随蜂是先后开采食物源,即寻找最优解,而侦查蜂是观察是否陷入局部最优,若陷入局部最优则随机地搜索其它可能的食物源。每个食物源代表问题一个可能解,食物源的花蜜量对应相应解的质量(适应度值fiti)。
(1)人工蜂群算法搜索过程中,首先需要初始化,其中包括确定种群数、最大迭代次数MCN、、控制参数limit和确定搜索空间即解的范围,在搜索空间中随机生成初始解xi(i=1,2,3,……,SN),SN为食物源个数,每个解xi是一个D维的向量,D是问题的维数。初始化之后,整个种群将进行引领蜂、跟随蜂和侦查蜂搜寻过程的重复循环,直到达到最大迭代次数MCN或误差允许值 ε。
(2)在搜索过程开始阶段,每个引领蜂由式(2-3)产生一个新解即新食物源,
vij=xij+Φij(xij-xkj) (2-3)
式中,k∈﹛1,2,…,SN﹜,j∈{1,2,…,D},且k ≠i;Φij为[-1,1]之间的随机数。计算新解的fiti并评价它,若新解的fiti优于旧解,则引领蜂记住新解忘记旧解。反之,它将保留旧解。
(3)在所有引领蜂完成搜寻过程之后,引领蜂会在招募区跳摇摆舞把解的信息及信息与跟随蜂分享。跟随蜂根据式计算每个解的选择概率,
pi=fiti/∑k=1SNfitk。 (2-4)
然后在区间[-1,1]内随机产生一个数,如果解的概率值大于该随机数,则跟随蜂由式(2-3)产生一个新解,并检验新解的fiti,若新解的fiti比之前好,则跟随蜂将记住新解忘掉旧解;反之,它将保留旧解。
四、在所有跟随蜂完成搜寻过程之后,如果一个解经过limit次循环仍然没有被进一步更新,那么就认为此解陷入局部最优,该食物源就会被舍弃。设食物源xi被舍弃,则此食物源对应的引领蜂转成一个侦查蜂。侦察蜂由(2-5)式产生一个新的食物源代替它。

                                                             xij=xminj+rand(0,1)(xmaxj-xminj)          (2-5)

其中j∈{1,2…,D}。然后返回引领蜂搜索过程,开始重复循环。
五、人工蜂群算法的食物源质量一般是越大越好,即适应度值越大越好,而对应于要优化的问题,需要分两种情况考虑:即最小值问题、最大值问题。设fi是优化问题的目标函数,所以若优化最小值问题时,适应度函数为fi的变形,一般用式(2-6)表示;若优化最大值问题,适应度函数即目标函数。

fiti={1+abs(fi) fi>=01/1+fi fi>0 (2-6)
人工蜂群算法在评价食物源时一般进行贪婪选择按式(2-7)进行。

vi={xi fit(xi)<=fit(vi)vi fit(vi)>fit(xi) (2-7)
人工蜂群算法就是通过循环搜索,最终找到最优食物源或最优解。

5 算法步骤
人工蜂群算法具体实现步骤:
步骤1:初始化种群:初始化各个参数,蜂群总数SN、食物源被采集次数即最大迭代次数MCN及控制参数limit,确定问题搜索范围,并且在搜索范围内随机产生初始解xi(i=1,2,…SN) 。
步骤2:计算并评估每个初始解的适应度。
步骤3:设定循环条件并开始循环
步骤4:引领蜂对解xi按照式(2-3)进行邻域搜索产生新解(食物源)vi,并计算其适应度值;
步骤5:按照式(2-7)进行贪婪选择:如果vi的适应度值优于xi,则利用vi替换xi,将vi作为当前最好的解,否则保留xi不变;
步骤6:根据式(2-4)计算食物源的概率pi;
步骤7:跟随蜂依照概率pi选择解或食物源,按照式(2-3)搜索产生新解(食物源)vi,并计算其适应度。
步骤8:按式(2-7)进行贪婪选择;如果vi的适应度优于xi,则用vi代替xi,将vi作为当前最好解,否则保留xi不变;
步骤9:判断是否有要放弃的解。若有,则侦查蜂按式(2-5)随机产生新解将其替换;
步骤10:记录到目前为止的最优解;
步骤11:判断是否满足循环终止条件,若满足,循环结束,输出最优解,否则返回步骤4继续搜索。

三、部分源代码

%%%%%%%%%%%%
%主程序开始clc;
clear;TestProblem='UF7';
nVar=10;fobj = cec09(TestProblem);xrange = xboundary(TestProblem, nVar);% Lower bound and upper bound
lb=xrange(:,1)';
ub=xrange(:,2)';
FoodNumber = 100;
Limit = 100;
maxCycle = 200;runtimes=1;
GD=zeros(runtimes,1);
IGD=zeros(runtimes,1);
Spread=zeros(runtimes,1);
TPF=xlsread('Case3.xls',TestProblem);
%种群初始化
M=2;                %目标函数值个数                %函数维度
%蜂群初始化
Range = repmat((ub - lb),[FoodNumber 1]);
Lower = repmat(lb,[FoodNumber 1]);
for r=1:runtimes
Foods = rand(FoodNumber,nVar).*Range+Lower;
Funcvalue = zeros(FoodNumber,M);        %记录种群中所有个体的目标函数值
trial = zeros(1,FoodNumber);
%%%%%计算所有个体的所有目标函数值for i=1:FoodNumberFuncvalue(i,:)=fobj(Foods(i,:)')';  %计算个体所有目标函数的函数值    %Funcvalue 中每一行代表一个个体的所有目标函数值
end
%%%%%%%%%%%%%外部档案集初始化  %%%%%%%%%%%%%%
pop=[Foods,Funcvalue];                      %将种群个体和其对应的目标函数值组合成一个矩阵  %每一行前6列为每维自变量值,7和8列分别为对应的两个目标函数的值
Rpop=quick_sort(pop);%%  外部档案Rpop
%快速排序,传入参数    %全部种群,种群中所有个体的目标函数值,以及当前优化的问题序号   %非支配集初始化
Npop=Rpop;                                  %外部档案和非支配解集中为所有非支配解及其对应的目标函数值
iter=1;
j=1;
while((iter<=maxCycle))%%%%%%%%%%%%%采蜜蜂----邻域搜索,寻找局部最优解for i=1:(FoodNumber)%在外部档案中随机选取一个解,对当前的邻域搜索进行指导[P,Q]=size(Rpop);s=1+fix(rand*P);Param2Change=fix(rand*nVar)+1; %随机选取一维sol=Foods(i,:);sol(Param2Change)=Foods(i,Param2Change)+(Rpop(s,Param2Change)-Foods(i,Param2Change))*(rand-0.5)*2; %对当前解的随机一维进行领域搜索指导%使用外部档案中的随机解对当前解进行更新ind=find(sol<lb);sol(ind)=lb(ind);ind=find(sol>ub);sol(ind)=ub(ind);FuncSol=fobj(sol')'; %计算邻域解的目标函数值%%%%%%%%%以pareto支配为标准的新贪婪准则  %%%%%%%%%%if Dominates(FuncSol',Funcvalue(i,:)')Foods(i,:)=sol;Funcvalue(i,:)=FuncSol;trial(i)=0;elsetrial(i)=trial(i)+1;endendprob=calprob(Foods,Funcvalue); %计算跟随概率%%%%%%%%%%%%%%% 观察蜂模式,根据概率随机选择蜜源  %%%%%%%%%%%i=1;t=0;while(t<FoodNumber)   %循环完后用完FoodNumber个观察蜂if(rand<prob(i))   %%%如果成立,才往下执行,用去一只跟随蜂t=t+1;sol(Param2Change)=Foods(i,Param2Change)+(Rpop(s,Param2Change)-Foods(i,Param2Change))*(rand-0.5)*2;%使用外部档案中的随机解对当前解进行更新ind=find(sol<lb);sol(ind)=lb(ind);ind=find(sol>ub);sol(ind)=ub(ind);FuncSol=fobj(sol')';%%%%%%%%% 以pareto支配为标准的新贪婪准则  %%%%%%%%if Dominates(FuncSol',Funcvalue(i,:)')Foods(i,:)=sol;Funcvalue(i,:)=FuncSol;trial(i)=0;elsetrial(i)=trial(i)+1;endendi=i+1;if(i==(FoodNumber)+1)i=1;endend%%%%%%% 更新外部档案 %%%%%%%%pop=[Foods,Funcvalue];          %将种群和目标函数值写入同一矩阵Npop=quick_sort(pop);       %将当前种群的所有非支配解写入非支配解集temp_set=[Rpop;Npop];           %将Npop加入外部档案,构成新的临时外部档案temp_setRpop=quick_sort(temp_set);  %新的外部档案集while(size(Rpop,1))>100         %根据拥挤距离对外部档案进行裁剪,使其中的解不多于100个crowd_dictance=[];crowd_dictance=crowd_distance_measure(Rpop);min_distance_num=1;          %找外部档案中拥挤距离最小的个体for i=2:size(crowd_dictance,1)if crowd_dictance(i)<crowd_dictance(min_distance_num)min_distance_num=i;endendfor i=min_distance_num:(size(Rpop,1)-1)Rpop(i,:)=Rpop(i+1,:);            %把拥挤距离最小的支配解删除,同时把最后一个支配解移动一次。删除一个拥挤距离最小的支配解且新生成的支配解集仍然连续。end                                   %从拥挤距离最小的非支配解的位置开始  左移,后一个非支配解覆盖前一个非支配解。Rpop=Rpop(1:size(Rpop,1)-1,:);       %size(Rpop,1)-1减一是为了把最后一个非支配解给去除,因为它已经被移动到倒数第二个位置上!end%%%%%%%%%%%%%绘制优化结果 %%%%%%%%%%%%%%
plot(Rpop(:,nVar+1),Rpop(:,nVar+2),'ro');
GD(r)=GD_matlab(Rpop(:,nVar+1:nVar+2),TPF);
IGD(r)=IGD_matlab(Rpop(:,nVar+1:nVar+2),TPF);
Spread(r)=Spread_matlab(Rpop(:,nVar+1:nVar+2),TPF);
end%%%%%%%%%主程序结束 %%%%%%%%%%
%%%%%%%%%%%寻找支配解%%%%%%%%
function non_dom=quick_sort(pop)npop=size(pop,1);K=10;pop(:,K+3)=0;for i=1:npoppop(i,K+3)=0;for j=1:i-1if pop(j,K+3)==0if Dominates(pop(i,K+1:K+2)',pop(j,K+1:K+2)')pop(j,K+3)=1;elseif Dominates(pop(j,K+1:K+2)',pop(i,K+1:K+2)')pop(i,K+3)=1;break;endendendendind=find(pop(:,K+3)==0);non_dom=pop(ind,1:K+2);% [N,P]=size(pop);
% M=2;                    %目标函数值的个数
% V=10;                    %每个目标函数值的维数
% non_dom=[];
% individual=pop;         %pop:种群(自变量+目标函数值),行数为种群数量
% while ~isempty(individual)  %individual为空时停止循环
%     temp1=[];
%     temp2=[];
%     flag=0;
%     %Number of individuals that dominate this individual  支配i的解的个数
%     %individual(i).n=0;
%     %Individuals which this individual dominate            被i支配的解
%     %individual(i).p=[]
%     for i=2:size(individual,1)               %size(individual,1)为individual的行数
%         dom_less=0;
%         dom_equal=0;
%         dom_more=0;
%         for j=1:M                            %M=2,两个目标函数
%             if(individual(1,V+j)<individual(i,V+j))  %V=6,每个目标函数均为六维   %%pareto支配判断
%                 dom_less=dom_less+1;         %解1有可能支配解i
%             elseif  (individual(1,V+j)==individual(i,V+j))
%                 dom_equal=dom_equal+1;       %互不支配
%             else
%                 dom_more=dom_more+1;         %解1有可能被解i支配
%             end
%         end
%         if dom_less==0 && dom_equal~=M       %该行为真时,表示解i支配解1
%             flag=flag+1;                     %flag中存放解i支配解1的个数
%             temp1=[temp1;individual(i,:)];   %temp1中存放支配解i
%         elseif dom_more==0 && dom_equal~=M   %该行为真时,表示解1支配解i
%             temp2=[temp2;individual(1,:)];   %temp2中存放支配解1
%         else                                 %其余情况:两个解互不支配
%             temp1=[temp1;individual(i,:)];   %temp1中也存放有可能支配的解i
%         end                                  %则称j优于i,则把此时的j放入individual(i)_p中%此时temp1中存放的就是通过上次比较后剩下的非支配解(非支配解即不受其他解支配)
end
function out=calvalue(x,pro)  %计算目标函数值%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if pro==1f=[];f(1)=x(1);                 %目标函数1sum=0;for i= 2:6sum=sum+x(i)/5;endg_x=1+9*sum;                %中间函数f(2)=g_x*(1-(f(1)/(g_x))^0.5);%目标函数值2out=f;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
elseif pro==2f=[];f(1)=x(1);                 %目标函数1sum=0;for i= 2:6sum=sum+x(i)/5;endg_x=1+9*sum;                %中间函数f(2)=g_x*(1-(f(1)/(g_x))^2);%目标函数值2out=f;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
elseif pro==3f=[];f(1)=x(1);                 %目标函数1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
elseif pro==6f=[];f(1)=1-exp((-4)*x(1))*(sin(6*pi*x(1)))^6;                 %目标函数1sum=0;for i= 2:6sum=sum+x(i)/5;endg_x=1+9*sum^0.25;                %中间函数f(2)=g_x*(1-(f(1)/(g_x))^2);%目标函数值2out=f;
end
end

四、运行结果

五、matlab版本及参考文献

1 matlab版本
2014a

2 参考文献
[1] 包子阳,余继周,杨杉.智能优化算法及其MATLAB实例(第2版)[M].电子工业出版社,2016.
[2]张岩,吴水根.MATLAB优化算法源代码[M].清华大学出版社,2017.

【优化算法】多目标人工蜂群算法(MOABC)【含Matlab源码 1236期】相关推荐

  1. 【优化布局】基于matlab免疫算法求解充电站最优布局【含Matlab源码 2539期】

    ⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[生产调度]基于matlab免疫算法求解生产调度零等待问题[含Matlab源码 1178期] 点击上面蓝色字体,直接付费下载,即可. 获取 ...

  2. 【微电网优化】基于matlab粒子群算法求解综合能源系统优化问题【含Matlab源码 1969期】

    一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[微电网优化]基于matlab粒子群算法求解综合能源系统优化问题[含Matlab源码 1969期] 点击上面蓝色字体,直接付费下载,即可. ...

  3. 【数字信号去噪】基于matlab粒子群算法优化VMD分解分量选择数字信号降噪【含Matlab源码 1979期】

    ⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[数字信号去噪]基于matlab粒子群算法优化VMD分解分量选择数字信号降噪[含Matlab源码 1979期] 点击上面蓝色字体,直接付费 ...

  4. 【优化布局】免疫算法求解充电站最优布局【含Matlab源码 2539期】

    ⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[生产调度]基于matlab免疫算法求解生产调度零等待问题[含Matlab源码 1178期] 点击上面蓝色字体,直接付费下载,即可. 获取 ...

  5. 【雷达通信】基于matlab NCP算法SAR回波生成和成像【含Matlab源码 1185期】

    ⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[雷达通信]基于matlab NCP算法SAR回波生成和成像[含Matlab源码 1185期] 点击上面蓝色字体,直接付费下载,即可. 获 ...

  6. 【ABC三维路径规划】基于matlab人工蜂群算法多无人机三维路径规划【含Matlab源码 170期】

    一.无人机简介 0 引言 随着现代技术的发展,飞行器种类不断变多,应用也日趋专一化.完善化,如专门用作植保的大疆PS-X625无人机,用作街景拍摄与监控巡察的宝鸡行翼航空科技的X8无人机,以及用作水下 ...

  7. 【配送路径规划】蚁群算法求解配送路径最短问题【含Matlab源码 2222期】

    ⛄一.VRP简介 1 VRP基本原理 车辆路径规划问题(Vehicle Routing Problem,VRP)是运筹学里重要的研究问题之一.VRP关注有一个供货商与K个销售点的路径规划的情况,可以简 ...

  8. 【配送路径规划】基于matlab蚁群算法求解配送路径最短问题【含Matlab源码 2222期】

    ⛄一.VRP简介 1 VRP基本原理 车辆路径规划问题(Vehicle Routing Problem,VRP)是运筹学里重要的研究问题之一.VRP关注有一个供货商与K个销售点的路径规划的情况,可以简 ...

  9. 【PSO三维路径规划】基于matlab粒子群算法融合鸡群算法多无人机三维路径规划【含Matlab源码 1792期】

    一.无人机简介 无人机的航迹规划是指在综合考虑无人机飞行油耗.威胁.飞行区域以及自身物理条件限制等因素的前提下, 为飞行器在飞行区域内规划出从初始点到目标点最优或者满意的飞行航迹, 其本质是一个多约束 ...

  10. 【路径规划】基于matlab GUI蚁群算法机器人栅格地图最短路径规划【含Matlab源码 927期】

    ⛄一.蚁群算法简介 1 引言 在自然界中各种生物群体显现出来的智能近几十年来得到了学者们的广泛关注,学者们通过对简单生物体的群体行为进行模拟,进而提出了群智能算法.其中, 模拟蚁群觅食过程的蚁群优化算 ...

最新文章

  1. float a = 3.1; 显示警告的原因
  2. 成功跳槽百度工资从15K涨到28K,BAT大厂面试总结
  3. telnet命令的使用
  4. 春招收获阿里腾讯实习offer,学习、面试经验分享
  5. ios调用restful接口_Postman调用https异常解决
  6. 机器学习初学者_绝对初学者的机器学习
  7. 前端学习(3251):样式的模块化
  8. 贪心法——最优装载问题
  9. 【OpenCV】OpenCV函数精讲之 -- Mat和IplImage之间的相互装换(OpenCV2.0和OpenCV3.0)
  10. DWR中引用JS的路径问题
  11. 看《乡村爱情》,秒懂区块链!
  12. 与其纠结,不如放弃!
  13. 利用反射和元数据编写的通用更新和通用查询
  14. Careercup - Facebook面试题 - 4907555595747328
  15. AndroidHttpCapture抓包工具
  16. 服务器没有D盘怎么架设传奇?
  17. JS事件 内容选中事件(onselect)选中事件,当文本框或者文本域中的文字被选中时,触发onselect事件,同时调用的程序就会被执行。...
  18. python如何设置矩阵_Python Numpy如何操作数组和矩阵
  19. 《伟大的小细节:互联网产品设计中的微创新思维》——3.4 身份特征与使用习惯因素...
  20. Apache之FCGI模式部署LAMP

热门文章

  1. DevExpress DateEdit 5 常见问题解决方法
  2. 新鲜出炉,Amazon SDE 面经(电面+Onsite)
  3. SPOJ DISUBSTR Distinct Substrings 后缀数组
  4. TCP IP通讯三次握手四次挥手
  5. 传智播客Java常量进制转换数据类型
  6. 《图解算法》学习笔记之快速排序
  7. 181218每日一句
  8. HTC 一个基站老无法定位
  9. Atitit attilax涉及到的大数据 数据分析 数据挖掘 ai人工智能的处理技术 目录 1.1. 大数据 机器视觉 图像处理 数据分析 数据挖掘 知识图谱 ai人工智能方面系列项目 1 2.
  10. 二维码资料 目录 1. 二维码QR Code 1 2. 发展历程 1 3. 特点 2 4. 存储 3 5. 分类 3 5.1.1. 按原理分 3 6. 区别 与条码区别 5 7. 什么是码制?