相信很多兄弟一开始接触peersim,对配置文件还是有点不适应,我看了好久的样例的配置文件,一层层去找对应的文件的方法,终于好像悟懂了一点,记下来以后回顾。
贴上代码,一点点分析。
首先要说下所谓的配置文件,其实就是一个txt文件,语法也是非常简单,类似java里的给类里的变量赋值,这也正对应了配置文件的作用,配置文件,当然就是为实验的参数进行配置用的,所以配置文件的主要功能就是配置各类参数,定义一些协议类、控制类、初始化类以及一些常数。
# PEERSIM EXAMPLE 1 #配置文件中#是注释符 random.seed 1234567890 #随机数种子
simulation.cycles 30 #这里设置了模拟的周期为30,类似java里给变量赋值 语法就是aa.bb cc ,把aa的bb赋cc的值 很容易理解 control.shf Shuffle #shuffle就是洗牌的意思,control类通常用来修改或者跟踪仿真过程的,这里洗牌的意思就是在每个周期,把节点打乱顺序 network.size 50000 #设置网络的大小为50000 protocol.lnk IdleProtocol #这里开始,就要注意下了,出现了语法, 定义了一个叫做lnk的协议,这个协议的值为 IdleProtocol,这似乎是一个很常见的协议,目前我的理解就 #是他可以为提供其他协议提供邻居的信息 protocol.avg example.aggregation.AverageFunction # 这里同样,定义了叫做avg的协议,值是后面的一长串,后面协议的功能一会会提到,主要就是求平均数
protocol.avg.linkable lnk # 注意下,这行的意思是说avg(在上一行定义的)里有一个属性是linkable,为这个属性赋值,值为之前定义的lnk,之前 #就是因为有的地方是自定义的名称,有的是定义好的属性,所以分不清,具体可以多看看源代码 init.rnd WireKOut #这里定义了一个叫rnd的初始器,目前我理解的作用是定义网络拓扑结构,下面的k=20,意思是以20的出度和其他节点连接
init.rnd.protocol lnk #rnd的protocol属性设为lnk
init.rnd.k 20 init.peak example.aggregation.PeakDistributionInitializer#这里定义的也是有关设置初始化的,但是不是拓扑结构,是分布,我理解的就是50000个节点,怎么给他们赋初值
init.peak.value 10000 #这种peak赋初值的方法是这么做的,第一个节点的值设为value,这里也就是10000,其他全是0
init.peak.protocol avg #同样需要为peak的protocol属性设值,这里要用avg而不用lnk,因为avg的protocol属性已经为lnk了 init.lin LinearDistribution #这是和peak相似功能的另一种初始化方法,名字就能看出来,是线性增长的方法,可以为他设最小和最大值
init.lin.protocol avg
init.lin.max
init.lin.min # you can change this to select the peak initializer instead
include.init rnd peak #这里说下,include后面出现的才是真正会使用的,这里我把原来的lnk改为peak,因为peak更好理解一点,所 #以这次实验,跟lin就无关了,如果改为include.init rnd lin 同样就用不到peak了 control.avgo example.aggregation.AverageObserver #这里最后设值了一个control量,用来监测仿真过程,下面会详细分析
control.avgo.protocol avg
代码部分到此,接着我把实验结果贴出来,再仔细分析
F:\peersim-1.0.5>java -cp peersim-1.0.5.jar;jep-2.3.0.jar;djep-1.0.0.jar peersim.Simulator example/config-example1.txt
Simulator: loading configuration
ConfigProperties: File example/config-example1.txt loaded.
Simulator: starting experiment 0 invoking peersim.cdsim.CDSimulator
Random seed: 1234567890
CDSimulator: resetting
Network: no node defined, using GeneralNode
CDSimulator: running initializers
- Running initializer init.rnd: class peersim.dynamics.WireKOut
- Running initializer init.peak: class example.aggregation.PeakDistributionInitializer
CDSimulator: loaded controls [control.avgo, control.shf]
CDSimulator: starting simulation
control.avgo: 0 0.0 10000.0 50000 0.2 2000.0 49999 1
CDSimulator: cycle 0 done
control.avgo: 1 0.0 5000.0 50000 0.2 687.4737494749895 49996 1
CDSimulator: cycle 1 done
control.avgo: 2 0.0 2500.0 50000 0.2 245.57038015760315 49980 1
CDSimulator: cycle 2 done
control.avgo: 3 0.0 1250.0 50000 0.2 83.07127865884954 49918 1
CDSimulator: cycle 3 done
control.avgo: 4 0.0 625.0 50000 0.2 27.385730697893184 49571 1
CDSimulator: cycle 4 done
control.avgo: 5 0.0 156.25 50000 0.2 7.57358497068821 47829 5
CDSimulator: cycle 5 done
control.avgo: 6 0.0 78.125 50000 0.2 2.2637719903529367 39984 2
CDSimulator: cycle 6 done
control.avgo: 7 0.0 29.363781213760376 50000 0.2 0.6944917092712494 18436 2
CDSimulator: cycle 7 done
control.avgo: 8 0.0 14.692321419715881 50000 0.2 0.22599995660240516 1676 1
CDSimulator: cycle 8 done
control.avgo: 9 0.0 7.773749530315399 50000 0.19999999999999996 0.07499273060350721 8 2
CDSimulator: cycle 9 done
control.avgo: 10 0.007466878741979599 3.9366912096738815 50000 0.19999999999999699 0.023950746235829403 1 1
CDSimulator: cycle 10 done
control.avgo: 11 0.037196914490778 2.003569261432858 50000 0.19999999999999693 0.007786713762873151 1 1
CDSimulator: cycle 11 done
control.avgo: 12 0.07241240396638204 1.439594765546559 50000 0.20000000000000212 0.002526494751788285 1 1
CDSimulator: cycle 12 done
control.avgo: 13 0.11444778778013642 0.8058056706961025 50000 0.19999999999999968 8.047749060418319E-4 1 1
CDSimulator: cycle 13 done
control.avgo: 14 0.14527491199664566 0.5412341546913619 50000 0.19999999999999857 2.5669976815967627E-4 1 1
CDSimulator: cycle 14 done
control.avgo: 15 0.16625072097394172 0.3086751814077813 50000 0.1999999999999984 8.071849333870349E-5 1 1
CDSimulator: cycle 15 done
control.avgo: 16 0.17188874045468727 0.25586305250877606 50000 0.19999999999999915 2.56414324360324E-5 1 1
CDSimulator: cycle 16 done
control.avgo: 17 0.18126059597579963 0.2284452071697809 50000 0.19999999999999926 8.156374000530416E-6 1 2
CDSimulator: cycle 17 done
control.avgo: 18 0.1908732136140849 0.2164359304896662 50000 0.20000000000000073 2.596046179086563E-6 1 2
CDSimulator: cycle 18 done
control.avgo: 19 0.19463901353170004 0.20867151463200723 50000 0.20000000000000132 8.247630624269391E-7 1 1
CDSimulator: cycle 19 done
control.avgo: 20 0.19743621150008228 0.20414677686379626 50000 0.19999999999999932 2.598124738924983E-7 1 1
CDSimulator: cycle 20 done
control.avgo: 21 0.19853546091585267 0.20213994106099414 50000 0.20000000000000218 8.305109997981584E-8 2 1
CDSimulator: cycle 21 done
control.avgo: 22 0.19914334355323826 0.20111512260564823 50000 0.19999999999999982 2.6420408323917597E-8 1 1
CDSimulator: cycle 22 done
control.avgo: 23 0.1994687670844077 0.20059480913650848 50000 0.20000000000000076 8.351299478222964E-9 2 1
CDSimulator: cycle 23 done
control.avgo: 24 0.19973746582822932 0.20030291389208998 50000 0.19999999999999854 2.676425576105711E-9 1 2
CDSimulator: cycle 24 done
control.avgo: 25 0.19983215529336568 0.20018999494961187 50000 0.19999999999999687 8.676425051288862E-10 1 1
CDSimulator: cycle 25 done
control.avgo: 26 0.19989827974265328 0.20010713659190948 50000 0.19999999999999804 2.7427770854287373E-10 1 1
CDSimulator: cycle 26 done
control.avgo: 27 0.19992737138288125 0.2000588315827033 50000 0.1999999999999992 8.762195519908992E-11 1 1
CDSimulator: cycle 27 done
control.avgo: 28 0.1999626822953865 0.200032897978195 50000 0.19999999999999915 2.7973829010656408E-11 2 1
CDSimulator: cycle 28 done
control.avgo: 29 0.19997940109815665 0.20001754407497246 50000 0.2000000000000003 8.765247306483662E-12 1 2
CDSimulator: cycle 29 done
这就是之前配置文件的实验结果,当时我第一反应是这每一列是对应的什么东西?在哪里定义的?可惜在网上没有找到,所以就自己一点点开始找。
开始我在AverageObserver文件里找(所有这些文件都可以在peer的src文件夹里找到),里面并没有直接定义这些结果的表示,不过已经有了
System.out.println(name + ": " + time + " " + is);这行,至少我明白了第一列的control.avgo对于的是name属性,0-29的序列对于的是time(为什么是time我还没仔细看),后面的几列对应的is,is就是IncrementalStats类的实例,
接着我又去这个 IncrementalStats文件里找,发现了这个方法
public String toString() {
return min+" "+max+" "+n+" "+sum/n+" "+getVar()+" "+
countmin+" "+countmax;
}
这下每列对于的什么就很清楚了,分别是网络中的最小值,最大值,网络节点数,平均数,方法和最小最大值记数。
接着我开始分析数据内容,主要关注第3和第4列,也就是最小值最大值,开始从0和10000开始,正好对于之前我设置的peak的初始化器,接着通过求平均数的方法,最大值变为(0+10000)/2=5000,一次类推,每个周期的最大值一直变为一半。
到这里我大概明白了实验的功能,但是流程还不清楚,我回去看AverageObserver文件,里面核心是这个函数
public boolean execute() {
long time = peersim.core.CommonState.getTime();
IncrementalStats is = new IncrementalStats();
for (int i = 0; i < Network.size(); i++) {
SingleValue protocol = (SingleValue) Network.get(i)
.getProtocol(pid);
is.add(protocol.getValue());
}
/* Printing statistics */
System.out.println(name + ": " + time + " " + is);
/* Terminate if accuracy target is reached */
return (is.getStD() <= accuracy);
}
其中is我已经明白了结构,但是这个add()函数到底传进了去什么值,在singleValueHolder里可以查到这个getValue的方法,对于到他的子类example.aggregation.AverageFunction里的方法
public void nextCycle(Node node, int protocolID) {
int linkableID = FastConfig.getLinkable(protocolID);
Linkable linkable = (Linkable) node.getProtocol(linkableID);
if (linkable.degree() > 0) {
Node peer = linkable.getNeighbor(CommonState.r.nextInt(linkable
.degree()));
// Failure handling
if (!peer.isUp())
return;
AverageFunction neighbor = (AverageFunction) peer
.getProtocol(protocolID);
double mean = (this.value + neighbor.value) / 2;
this.value = mean;
neighbor.value = mean;
}
}
里面的value就是本节点和邻居节点的平均值,所以最后传进is的正是这个平均值。
而is里通过这个方法求出了最终的展示的结果
public final void add( double item ) { add(item,1); }
// --------------------------------------------------------------------
/** Updates the statistics assuming element <code>item</code> is added
* <code>k</code> times.*/
public void add( double item, int k ) {
if( item < min )
{
min = item;
countmin = 0;
}
if( item == min ) countmin+=k;
if( item > max )
{
max = item;
countmax = 0;
}
if(item == max) countmax+=k;
n+=k;
if( k == 1 )
{
sum += item;
sqrsum += item*item;
}
else
{
sum += item*k;
sqrsum += item*item*k;
}
}
到此为止,配置文件以及结果的含义,整个流程大概就明白了,还有一些关于配置文件里ID的部分,看看上面提的文件里的构造函数就能明白了。
本人刚刚接触peersim,写这个只是为了以后不记得的时候能回顾一下,如果对大家有帮助最好了~