clear all; %清除所有内存变量
clc; %清除屏幕
%
Pc=0.5; %在仿真时刻t=0,将行为策略C以Pc为概率随机赋予个体
a=0;%权重,可改变,重要的仿真参数
R=1;%参数R
S=0;%参数S
P=0;%参数P
C=[1,0];%行为策略C的向量
D=[0,1];%行为策略D的向量
m0=2;
t0=input('请输入新增个体数(t):');%输入新增个体数
q=0.2;%决定第二条边连接方式的概率
times=11000;%总的博弈次数,用times表示
timecount=1000;%统计最后多少次数据的平均值
Ticount=50;%对于固定的网络参数和博弈参数的循环运行次数
steps=0.1;%博弈矩阵中b的变化步长
for Ti=1:Ticount %Ti循环开始,使得对于固定的网络参数q和博弈参数b进行重复实验
TT=1; %为存储实验结果所设置的序列号
%初始网络的生成
for i=1:m0 %将初始节点全部连接起来
Ent(i).connums=m0-1; %每个节点的连接数,初始为全连接
Ent(i).con=[1:i-1 i+1:m0]';%每个节点的连接列表,排除自己
Ent(i).H=[];%由个体连接数决定的每个个体在轮盘赌上的上届变量
Ent(i).L=[];%由个体连接数决定的每个个体在轮盘赌上的下届变量
end
m=m0;
for t=1:t0%增加新的个体,新增个体总数t0
Xsum=0;%统计个体总连接数的变量
for i=1:m
Xsum=Xsum+Ent(i).connums;
Ent(i).H=Xsum; %产生每个个体在轮盘赌上的位置
Ent(i).L=Ent(i).H-Ent(i).connums;
end
%此时Xum变量已经为现有所有个体连接数的加和
Ent(m+1).connums=2; %新增节点用m+1表示,它带有两个连接
Xsel = fix (Xsum*rand(1)+1);%生成一个介于1~Xsum之间的随机整数
for i=1;m
Xselnum=i
if(Ent(i).L< Xsel)&&(Ent(i).H>=Xsel)
%用生成的随机整数把被连接的节点选出来,实现按概率选择
Ent(i).connums = Ent(i).connums+1
%第一个被选中的节点更新连接列表,将新节点加入连接列表
Ent(m+1).con=;%新节点将第一个被选中的节点放入连接列表
Xselnum=i;
%保存第一个被选中的节点编号到变量Xselnum,选择第二条边时会用到
end
end
%此时新节点(m+1)的第一条连接已经完成,下面开始连接第二条边
if rand(1)<= q % 以概率 q 连接到已选址节点的邻居上
Xneb = fix( (Ent (Xselnum). connums -1)*rand(1)+1);
% 生成一个介于1~ (Ent (Xselnum). connums -1)之间的随机整数,即从第一个已选中节点的原有邻居中随机选中一个,排除掉新个体自己
Ent (Ent (Xselnum). con(Xneb)). con =[Ent(Ent (Xselnum). con(Xneb)).con;m+1];
%将新个体连接到第二个选中的节点上,将新个体编号写入第二个节选中节点的连接的列表中
Ent (Ent (Xselnum). con(Xneb)). connums = Ent (Ent (Xselnum). con(Xneb)). connums+1
% 将第二个节选中节点的连接数加1
Ent(m+1) . con = [ Ent(m+1) . con; Ent(Xselnum) . con(Xneb)];
% 更新新增节点的连接列表,将第二个被选中节点的编号加入
% 上面程序中(Ent (Xselnum). connums -1)为第一个被选中节点的连接数减1
% 上面程序中Ent(Xselnum) . con(Xneb)是第二个被选中节点的编号
else % 以概率1— q 按照BA模型的连接机制链接,排除掉第一个以选中节点
Fselected = 0;
while Fselected == 0
Xsell = fix(Xsum*rand(1)+1);
%生成一个介于1~Xsum之间的随机整数,Xsum为现有原有个体连接的加和
for i = 1:m
if (Ent(i) . L <Xsell)&&(Ent(i) . H >= Xsell)
if Xselnum ~= i % 排除调第一个已被选中的节点
Ent(i) . connums = Ent(i) . connums +1;
% 给第二个被选中个体的连接数加1
Ent(i). con = [Ent(i). con ; m+1];
% 更新第二个被选中个体的连接列表
Ent(m+1).con = [ Ent(m+1) . con; i ];
%更新新增节点的连接列表,将第二个被选中节点的编号加入
Fselected = 1;
end
end
end
end
end
%两条边连接完成,一个新节点已经加入网络
m=m+1;
end % 对应新增节点的循环 for t = 1 : t0
nums = m ; % 所有的t0个新节点已经加入网络
% 网络结构已经生成完毕,网络中总共有nums个节点,下面开始博弈,
for T =1.0+steps : steps : 2.0 % b 循环取值
A =[ R S; T P]; % 博弈矩阵A
% 给每个个体随机赋予初始策略C或D
for j =1 : nums
if rand (1)<=Pc
Ent(j) . CD=C; %采用C策略个体的策略向量为[1,0]
Ent (j). NextCD=C;
%采用C策略个体的下一次策略向量仍然为[1,0],后面会用到
else
Ent (j) . CD=D; %采用C策略个体的策略向量为[1,0]
Ent (j). NextCD=D;
%采用D策略个体的下一次策略向量仍然为[1,0],后面会用到
end
end
%博弈参数初始化结束,产生策略向量ent. CD博弈开始
for t =1 ;times %博弈从1开始,一直到times次结束
EntUiCTotal(t)=0; % 所有C策略个体总收益,后面要用到
EntUiTotal(t)=0; % 所有个体总收益
EntDCount(t)=0; % D策略的个体个数,为了后面算合作者密度
% 计算每个个体的博弈收益
for j = 1 : nums
SumNeb = 0; % 每个节点初始收益
for ik = 1 ; Ent(j) . connums
SumNeb = SumNeb + Ent(j). CD*A*Ent(Ent(j) . con(ik)).CD';
% 个体计算邻居给自身带来的收益加和
end
Ent(j). Ui =a*SumNeb + (1-a)*(SumNeb/Ent(j). connums);
% 计算加权收益
end
%计算结束
for j =1 ; nums
Xch = fix((Ent(j) . connums*rand(1)+1));
%生成一个从1到Ent(j) . connums的随机整数,个体从自己的邻居中随机选择了一个邻居
if Ent(Ent(j) . con(Xch)) . Ui>Ent(j) . Ui
% 比较自己和这个邻居的收益情况,(Ent(j) . con(Xch))是随机选出来的邻居的编号
If rand(1)<=(Ent(Ent(j) . con(Xch)) . Ui - Ent(j).Ui/
((1-a)*T +a*T*max(Ent(j).connums,Ent(Ent(j).con(Xch)). Connums));
% 以概率选择决定是否选择相应节点的策略
Ent(j). NextCD=Ent(Ent(j).con(Xch)).CD;
%选择节点(Ent(j).con(Xch)的策略为自己下一次的策略
end
end
if Ent(j) . CD == C
EntUiCTotal(t) = EntUiCTotal(t) +Ent(j) . Ui;% 统计所有采用策略C的个体的总收益
else
EntDCount(t) = EntDCount(t) +1
end
EntUiTotal(t) = EntDCount(t) +Ent(j) . Ui;
% 统计所有个体的总收益
EntDCount(t) = EntDCount(t) - EntDCount(t)
% 统计所有采用策略D的个体的总收益
end
% 策略调整结束
dtD(t) = EntDCount(t); % 统计所有采用策略D的个体总数
dtD(t) = numms - dtD(t); % 统计所有采用策略C的个体总数
countD = dtD(t); % 临时变量
countC = dtD(t); % 临时变量
if countD == 0
countD = 1; %临时变量,确保使计算平均收益时分母不为0
end
if countC == 0
countC = 1; %临时变量,确保使计算平均收益时分母不为0
end
ptC(t)= dtC(t)/nums; %计算C策略密度
ptD(t) = 1- ptC(t); %计算D策略密度
utAvgC(t) = EntUiCTotal(t)/countC; %计算所有采用策略C的个体的平均收益
utAvgC(t) = EntUiCTotal(t)/countD; %计算所有采用策略D的个体的平均收益
for j = 1 ; nums
Ent(j) . CD=Ent(j) . NextCD; %将新选策略付给自己的策略变量
end
str = sprintf( 'T =%g : Ti = %g: t =%g',T,Ti,t);
% 显示程序运行到什么状态了,用于估计整个程序的运行时间
disp(str);
end
%% t 循环结束,每次博弈所产生的合作者密度存储在ptC(t)中
Ttstate(TT) = T ; %将T即b的值付给行变量Ttstate(TT)
TidtC(TT,:) = dtC
%对于第TT个b的不同时刻的合作者数量,每行为times,每列为不同的b
TidtD(TT,:) = dtD;
TidtC(TT,:) = ptC;
%对于第TT个b的不同时刻的合作者密度,每行为times,每列对应于不同的b
TidtD(TT,:) = ptD;
TiutC(TT,:) = utAvgC;
%对于第TT个b的不同时刻的合作者的平均,每行为times,每列对应于不同的b
TiutD(TT,:) = utAvgD;
TiptCAvg(TT) = sum(ptC(times - timecount+1: times))/timecount;
%计算最后多少步的合作者密度的均值,每个值对应于不同b条件下的合作者均衡密度
TiptDAvg(TT) = sum(ptD(times - timecount+1: times))/timecount;
TiutCAvg(TT) = sum(utAvgC(times - timecount+1: times))/timecount;
TiutDAvg(TT) = sum(utAvgD(times - timecount+1:times))/timecount;
TT=TT+1;
% for T = 1.0 +steps : syeps : 1.1 循环结束,Ti进行了一次
% 将第Ti次的详细结果保存到结构体XTiptCAvg(Ti) . 中
XTiptCAvg(Ti) . TidtC = TidtC;
XTiptCAvg(Ti) . TiptC = TiptC;
XTiptCAvg(Ti) . TidtD = TidtD;
XTiptCAvg(Ti) . TiptD = TiptD;
XTiptCAvg(Ti) . TiutC = TiutC;
XTiptCAvg(Ti) . TiutD = TiutD;
XTiptCAvg(Ti) . TiptCAvg0 = TiptCAvg;
XTiptCAvg(Ti) . TiptDAvg0 = TiptDAvg;
XTiptCAvg(Ti) . TiutAvgC0 = TiutAvgC;
XTiptCAvg(Ti) . TiutAvgD0 = TiutAvgD;
%生成对应于Ti的矩阵,每行为第Ti次的b循环结果
DatptCAvgFinal(Ti,:)=TiptCAvg;
DatptDAvgFinal(Ti,:)=TiptDAvg;
DatuiCAvgFinal(Ti,:)=TiutAvgC;
DatuiDAvgFinal(Ti,:)=TiutAvgD;
end % Ti循环结果
% 处理数据并绘制图形
FTiptCAvg = sum(DatptCAvgFinal)/Ticount; % 将 DatptCAvgFinal矩阵的每行对应相加,然后除以Ticount次
FTiptDAvg = sum(DatptDAvgFinal)/Ticount;
FTiutAvgC = sum(DatuiCAvgFinal)/Ticount;
FTiutAvgD= sum(DatuiDAvgFinal)/Ticount;
Subplot(2, 1, 1); plot(Ttstate , FtiptCAvg);
Disp('********************运行完毕********************');