[TOC]
ONE程序代码简析
Movement
MovementModel
这是一个抽象类,是所有movement model 的超类,所有它的相关子类的需要有相应的setting 的参数。 具体而言,对于每一个其子类,都需要实现replicate()
方法,如果需要创建一个新的movement model ,至少需要重载getInitialLocation() 和 getPath()方法。
变量声明
有多个需要从setting
中读取的值,包括speed, waitTime
等,然后对于一个movement model,其对应了相应的DTNHost,除此之外,还包括了一个相应的ActivenessHandler
类,用于说明当前某个属于特定group 的node 是否还是active,最后还有一个ModuleCommunicationBus
,用来表示通信的总线。
其它方法
- checkMinAndMaxSetting: 用来检测当前的最小值和最大值是否满足范围要求(不能小于0 ,且max > min)
- MovementModel(Settings settings)用来从
settings
中读取相应的内容 - 然后后面的一个MovementModel是用于copy
- generateSpeed 是通过这样一个公式来生成一个速度: $(S_{max} - S_{min}) \times rng + S_{min}$
- generateWaitTime 同样是为了生成相应的等待时间
- reset() 是为了重新生成一个rng
SwitchableMovement
这是一个基础的接口,哪些需要使用ExtendedMovementModels 的 Movement models 需要实现该接口,其具有的方法包括:
- setLocation(Coord): 设定当前的model 所在结点位置
- getLastLocation():得到最近这个movement model 所在的位置
- isReady(): 检查当前的movement model 已经完成了它相应的任务,并且可以调到下一个movement model 上。
Path.java
这是一条基于多点之间的路径,movement models 必须要使用到它。其只有三个基本参数:
1 | /** coordinates of the path 所有的点的list*/ |
其它方法
- setSpeed() : 在所有的path的速度集合中添加该速度
- addWaypoint(): 在所有的coords中添加一个坐标 ,或者有添加速度和坐标
- getNextWaypoint():通过coords去找到下一个坐标点
- hasNext():表示存在下一个坐标点(当前路径)
- getSpeed(): 用nextWpIndex 去找到当前需要的那个speed
MapBasedMovement
继承了MovementModel
,并且实现了SwitchableMovement
的接口,其主要是一个基础的基于map 的movement model ,并且能够基于仿真地图给出相应的path。
其它方法
- readOkMapNodeTypes: 在setting 中读取可行的map 类型 (
private int [] okMapNodeTypes
) - getInitialLocation(): 返回一个随机的处于两个相应的mapnodes 之间的坐标(重载函数)
- getPath(): 通过构建相应的path,主要是通过查找neighbors 和通过okmaps 来找到可以到达的路径
- selectRandomOkNode(): 选择并返回一个ok 的随机点(在所有的nodes当中)
- readMap():读一个sim map ,通过setting来进行读取,而且当获取一个sim map 之后,会利用cachedMap 进行缓存
- checkMapConnectedness() 检查所有的可从其它的map nodes到达的nodes
- checkCoordValidity() : 检查当前的某个结点是否能够满足给定的范围
- checkCache(): 检查map cache和需要的某个map 是否相同
DijkstraPathFinder
实现DijkstraPathFinder算法
其中包含了两个基础的类:
DistanceMap
,即通过mapnode -> double 的一个hashtable , 通过get方法去得到相应mapnode 对应的distance
DistanceComparator
, 即通过两个map node 的相应distane 来进行判断,只有一个方法,即compare犯法,判断两者之间的距离大小。
变量
1 | /** Value for infinite distance */ |
其它方法
- initWith(): 根据node 来初始化一个新的搜索过程,注意其中的visited 使用的是HashSet
- getShortestPath(): 查找一个两点之间的最短路径,具体实现方法也就是Dijkstra算法,只不过当查找到目的结点之后,就不会再继续查找
- relax(node): 更新当前结点的周围结点(能到达的结点),只更新那些ok 且没有被visited的结点
- setDistance: 也就是设置相应结点所在的距离
整体而言,实际上就是通过getShortestPath()
实现了Dijkstra算法,有一些细节方面的修改。
MapNode
也就是在一个仿真map 中的一个结点,其主要记录了这样几个内容: 其坐标(Coord),该结点的相应邻居(Vector
类型标注方式:type是通过标识具体某一bit 来表示其是否含有某种特性。
MapRoute
一个包含了多个map nodes 的路由协议,可以有多个不同的route 类型。
主要变量
1 | private List<MapNode> stops; |
也就是,整个map route 包含了相应的 map node 的所有站点,以及对应的route 的类型,利用index 指示了前一个返回的map node
其它方法
- nextStop(): 也就是根据index 来找到当前 map route 的下一个stop
- readRoutes():通过setting 在相应的配置文件中进行读取,得到相应的map route ,具体是通过fileName来进行读取的。
MapRouterMovement
基于MapBasedMovement 实现的子类,并且实现了相应的SwitchableMovement的接口。其具体是一个map based 的movement ,但是其相应路径是提前决定的。
变量声明
1 | /** the Dijkstra shortest path finder */ |
主要方法
- getPath(): 重载函数,也就是需要通过map route 来找到当前route 的下一个stop,并且通过Dijkstra算法去根据当前的节点和目的节点找到最短路径,并在path中加上该路径
- getInitialLocation(): 返回当前MapRoute 的第一个stop
- getLastLocation():返回当前MapRoute 的path 的最终节点。
BusControlSystem
一个对于公交车和乘客的控制系统类,可以有多个BusControlSystem,但是一辆公交车只能是一类。
变量声明
1 | public static final String BUS_CONTROL_SYSTEM_NR = "busControlSystemNr"; |
主要方法
- busHashStopped(): 被使用当前系统的bus进行调用,它调用了每个passengers 的enterBus(),来使得所有的乘客能够上车
- getBusControlSystem(): 通过一个相应的system ID 来获得相应的内容
- registerBus(): 为当前的system 注册一个新的bus
- registerTraveller():同理
BusMovement
继承自MapRouteMovement 的子类,这个类控制了busses的movement,模拟公交车控制系统的方式,也就是每次到达一个结点之后,会进行相应的registered(记录)
主要包括了一个BusControlSystem
以及相应的id 和 记录的所有的stops。
主要方法
- getPath() : 重载函数,除了之前实现的功能外,还利用system 中的busHasStopped函数来使得passengers 能够上车。
BusTravellerMovement
继承自MapBasedMovement ,并且实现了SwitchableMovement 和 TransportMovement 的相应接口,这个类主要是控制bus travellers 的一个相应接口,每一个bus traveller 属于一个control system, 其有一个出发点和一个目的地。
还包括了一个类ContinueBusTripDecider
,也就是为了帮助node 来判断是否应该继续这一段trip,保持nodes 的相应状态。其中最重要的一个函数就是continueTrip()
这个函数,用来判断是否需要继续。
变量声明
1 | private int state; |
主要方法
- getInitialLocation(): 重载函数,获得初始节点位置
- getPath(): 重载函数,主要需要查看当前状态,是否是在bus上,然后再去查找path。
- enterBus():上车,主要是判断是否是需要上的车,通过continueTrip去进行相应的判断
- getClosestCoordination(),利用这个函数来从list中找到最近的那个点的坐标
- setNextRoute(): 根据相应的设置来设定traveller的下一个route,因此来判断其是否需要上车
CarMovement
代表了car 的运动的子模型,其只有三个新的变量,包括了一个起始地址和目的地址,以及一个DijkstraPathFinder
来查找最短路径。
相关方法
- getPath(): 重载函数,具体实现很简单,就是通过to 和 from 两个节点,然后直接查找到相应路径,并把其中所有节点加入即可。
RandomWaypoint
这个model 创建了一种曲折的路径(因为随机的选择)。其基于MovementModel,然后只新增了一个节点: lastWaypoint
实现方法
- getInitialLocation(): 返回一个随机产生的可能的节点
- getPath(): 这个path 是通过随机方式来得到的,主要是通过randomCoord()
- randomCoord(): 通过
rng.nextDouble() * getMaxX(), rng.nextDouble() * getMaxY()
来实现
ClusterMovement
继承自RandomWayPoint,需要定义整个cluster 的范围和其中心。
主要方法
- randomCoord(): 重载函数,通过rng 和设定的相应范围,包括整个cluster 的中心来得到其具体的坐标点。
- getMaxX, getMaxY : 得到范围中x,y 的最大值
EveningTrip
压缩了购物的trip 的信息到四点:1. 起始地点 2. 目的地 3. 具体路径 4. 所有在group中的节点。
具体变量如下:
1 | private EveningActivityMovement[] eveningActivityNodes; |
主要方法
- addNode(): 向其中添加一个相应结点
- allMemberPresent(): 检查是否这个group 中的所有节点都能找到一条路径到这个meeting point
EveningActivityControlSystem
这个类控制了在晚上去见朋友的人的行动。
主要变量包括:
1 | private HashMap<Integer, EveningActivityMovement> eveningActivityNodes; |
主要方法
- addEveningActivityNode(): 注册一个(新加入一个)相应结点
- setMeetingSpots():从meeting locations中选择一些并进行设置
- getEveningInstruction(): 也就是针对某一个相应的人,给出了它的起始地址和目的地址包括相应的路径,也就是instruction
- getMeetingSpotForID(): 通过给定的id,去找到相应的meeting spot
- getEveningActivityControlSystem(): 返回一个EveningActivityControlSystem,根据id进行查找
EveningActivityMovement
继承自MapBasedMovement,并且实现了SwitchableMovement的接口。 这是一个类用来描述people 购物或者做一些其它活动。
新增变量
1 | private static int nrOfMeetingSpots = 10; |
可以通过setting 进行初始化的相应操作,或者进行copy construct。
主要方法
- getInitialLocation(): 得到初始化的location(coord)
- getPath(): 重载函数,需要根据不同的mode 来进行选择,包括walking 和处于evening_activity的处境。 如果在walking ,那么就需要通过pathFinder来找到路径,而如果已经满足,那么直接返回trip 的相应路径
- getShoppingLocationAndGetReady(): 设置可以开始一段trip 的开始节点
ExtendedMovementModel
一个抽象类,继承自这个类的子类可以使用其它实现了SwitchableMovement interface 的 movement model。
主要方法
- setCurrentMovementModel(): 设置当前的movement model ,即在下一次getPath() 调用之前需要设置的。
- getPath(): 重载函数,需要调用newOrders()函数
- newOrders():一个需要根据不同类实现的函数,需要根据当前的movementModel来进行分析,其必须要ready
ExternalMovement
继承自MovementModel 的一个子类,其使用了node location 的其它的数据来进行移动
新增变量:
1 | /** mapping of external id to movement model */ |
主要方法
- checkPathNeed(): 检查是否有更多的path需要被预加载或者重新加载
- addLocation():添加一个新的location ,其需要根据这个model 移动的相应特征来进行,所以还需要一个time 来进行判断, time 表示那个节点应该在何时到那里
- nextPathAvailable(): 返回下一条路径能够获取的仿真时间点
- getPath():首先需要检测是否需要preload,然后得到latestPath。
- readMorePaths(): 为下一次time instance读相应的paths,返回的是相应的time
ExternalPathMovementReader
用来读取相应的path format 的一个reader,用了两个trace file,一个是path ,另一个是来设定某一节点被激活的时间点,两个文件格式为:
1 | * <p>The first line should be:</> |
其中包括了两个类:
1 | /** |
分别表示了point 和 一个node 激活的时间,包括开始和结束的时间点。
ExternalPathMovement
继承自MovementModel,并且依据path format来进行相应的追踪。其添加了三个主要的变量:
1 | // Node's paths |
getPath()
1 |
|
重载函数,首先需要判断当前整个movement必须要是acitve 的状态,然后根据paths来get到当前适合的路径,然后去检测当前的path的size,根据相应的计算来得到最终需要的c,v,即相应的Coord,然后将其添加到p中并返回。
GridLocation
同样的,其继承自MovementModel,并且其是用一个grid的方式来设置node,其新增变量包括:
1 | private double startCoords[]; |
主要方法
- getInitialLocation(): 返回了当前movement model 的初始节点位置(location)
- getPath(): 将loc 加入其中,因为其处于grid之中,没有改变。
HomeActivityMovement
这个类继承自MapBasedMovement 并且实现了SwitchableMovement的相应接口,它是一个用来模拟在家的行动的类。
1 | private int mode; |
getPath()
1 | public Path getPath() { |
重载函数的实现,根据mode不同,有不同的方式,如果是WALKING_HOME_MODE,那么需要找到回家的一条路,故而需要通过thisNode 和 destinationNode来找到一条路,并且在到达之后,需要将mode 改写为AT_HOME_MODE,否则就不需要做什么,只需要将当前的lastWaypoint加入其中即可。
LinearFormation
一个静止的”movement” model ,所有的node 都不需要移动,除了在具体某一条线上。 主要的变量有:
1 | /* values for the prototype */ |
主要方法
- calculateInitLocation(): 计算并返回当前结点的location
- getPath(): 由于不需要移动,所以直接为当前loc
LinearMovement
继承自Movement,所有的nodes只是在一条线上进行移动
新增变量:
1 | /* values for the prototype */ |
包括了开始的location 和 结束的location,以及初始的location的类型,以及目标类型,同样的记录了相应的path
RandomDirection
继承自Movement Model,并且node 会在一个随机的地点开始,并且随机挑选一个方向并按照此运动到某一边界,然后需要停止并重新选择一个方向。只新增了一个变量: lastWaypoint
。
主要方法
- getPath(): 每一次就随机选择一个方向(也就是随机选择一个结点来进行运动),然后移动到该处。 作为next 的节点
- getRandomWaypoint():随机挑选下一个way point,主要是需要先判断其是否在某一个边界上,然后再进行随机计算。
- getBottomParams(),返回的是一个根据当前的direction,所到达某一边界的位置,同理,left,top,和right
ParetoRNG
一个随机数的生成器,根据相应的数据进行相应的生成Pareto distributed double value
OfficeActivityMovement
继承了MapBasedMovement,并且实现了SwitchableMovement的相应接口,描述的是一个office的movement,如果其没在office 中,那么找到一条最短路径进入office。一个结点只能为一个office 工作。
新增变量
1 | private static int nrOfOffices = 50;//office的数目 |
主要方法
构造函数同样是两种,包括了利用setting 和使用 copy constructor来进行相应的创建和部署。
- getRandomCoorinateInsideOffice(): 获得一个随机的地址,主要是利用的是rng来进行计算并得到,但是其范围需要在office 范围内
- getInitialLocation(): 一个初始化结点,重载操作
- getPath(): 根据mode 的不同,会有不同的方式来进行相应的操作,包括
WALKING_TO_OFFICE_MODE
,这种模式下,需要利用pathFinder找到相应的最短路径,然后到达,并修改其模式,否则的话,就直接对其path 进行相应的固定,只有一个c(coordinator)来进行控制 - generateWaitTime(): 一个重载函数,通过当前时间和每天需要工作的时间,来进行相应的计算。
RandomWalk
继承自MovementModel 并且实现了SwitchableMovement来实现Random Walk的相应movement model。
主要方法:
- getInitialLocation(): 返回一个随机的可能的值,针对一个可能的host而言
- getPath(): 重载函数,随机生成一个在相应范围之内的数据,然后加入到路径当中。
PointsOfInterest
兴趣点数据的处理程序,也就是一种相应的points 的相关类型
其主要方法有:
- selectDestination(): 选择一个随机的目的地,从所有的POI或者所有的mapnodes中进行选择,通过其不同的可能性来进行选择。
- readPois():也就是从setting中读取POI selections 和它们各自的可能性并将其保存到相应的poiLists 和 poiProbs之中。
ShortestPathMapBasedMovement
继承自MapBasedMovement并且实现了相应的SwitchableMovement。 其主要增加了两个变量: DijkstraPathFinder
和PointsOfInterest
主要方法
- getPath(): 重载函数,也就是直接利用pathFinder 来找到最短路径,并将其所有的node 加入到返回的path中。
StationaryMovement
一个非常简单的不动的节点,包括用来模拟基站等。
WorkingDayMovement
继承自ExtendedMovementModel,这个模型利用了其它好几个模型的实现,来模拟一个整个的一天的活动。 描绘的行动方式如下: 人早上起床,然后去上班,在晚上去聚会或者购物,最后回家睡觉。
1 | private BusTravellerMovement busTravellerMM; |
可以看到,其具体包括了这些运动模型。