the-one-code-4

[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
2
3
4
5
/** coordinates of the path  所有的点的list*/
private List<Coord> coords;
/** speeds in the path legs 不同是速度的list*/
private List<Double> speeds;
private int nextWpIndex;

其它方法

  • 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/** Value for infinite distance  */
private static final Double INFINITY = Double.MAX_VALUE;
/** Initial size of the priority queue */
private static final int PQ_INIT_SIZE = 11;

/** Map of node distances from the source node */
private DistanceMap distances;
/** Set of already visited nodes (where the shortest path is known) */
private Set<MapNode> visited;
/** Priority queue of unvisited nodes discovered so far */
private Queue<MapNode> unvisited;
/** Map of previous nodes on the shortest path(s) */
private Map<MapNode, MapNode> prevNodes;

private int [] okMapNodes;//可以访问的map node

其它方法

  • initWith(): 根据node 来初始化一个新的搜索过程,注意其中的visited 使用的是HashSet
  • getShortestPath(): 查找一个两点之间的最短路径,具体实现方法也就是Dijkstra算法,只不过当查找到目的结点之后,就不会再继续查找
  • relax(node): 更新当前结点的周围结点(能到达的结点),只更新那些ok 且没有被visited的结点
  • setDistance: 也就是设置相应结点所在的距离

整体而言,实际上就是通过getShortestPath()实现了Dijkstra算法,有一些细节方面的修改。

MapNode

也就是在一个仿真map 中的一个结点,其主要记录了这样几个内容: 其坐标(Coord),该结点的相应邻居(Vector),该节点的类型(int type)

类型标注方式:type是通过标识具体某一bit 来表示其是否含有某种特性。

MapRoute

一个包含了多个map nodes 的路由协议,可以有多个不同的route 类型。

主要变量

1
2
3
4
private List<MapNode> stops;
private int type; // type of the route
private int index; // index of the previous returned map node
private boolean comingBack;

也就是,整个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
2
3
4
5
6
7
8
9
10
11
12
/** the Dijkstra shortest path finder */
private DijkstraPathFinder pathFinder;

/** Prototype's reference to all routes read for the group */
private List<MapRoute> allRoutes = null;
/** next route's index to give by prototype */
private Integer nextRouteIndex = null;
/** Index of the first stop for a group of nodes (or -1 for random) */
private int firstStopIndex = -1;

/** Route of the movement model's instance */
private MapRoute route;

主要方法

  • getPath(): 重载函数,也就是需要通过map route 来找到当前route 的下一个stop,并且通过Dijkstra算法去根据当前的节点和目的节点找到最短路径,并在path中加上该路径
  • getInitialLocation(): 返回当前MapRoute 的第一个stop
  • getLastLocation():返回当前MapRoute 的path 的最终节点。

BusControlSystem

一个对于公交车和乘客的控制系统类,可以有多个BusControlSystem,但是一辆公交车只能是一类。

变量声明

1
2
3
4
5
6
7
8
9
10
11
12
13
public static final String BUS_CONTROL_SYSTEM_NR = "busControlSystemNr";
//相应的hashmap ,映射int -> system
private static HashMap<Integer, BusControlSystem> systems;
//同样,也会映射到BusMovement 和 BusTravellerMovement
private HashMap<Integer, BusMovement> busses;
private HashMap<Integer, BusTravellerMovement> travellers;
private List<Coord> busStops;//公交站台的位置

private SimMap simMap;

static { DTNSim.registerForReset(BusControlSystem.class.getCanonicalName());
reset();
}

主要方法

  • 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private int state;
private Path nextPath;// path
private Coord location;
private Coord latestBusStop;
private BusControlSystem controlSystem;//控制system
private int id;
private ContinueBusTripDecider cbtd;//是否要继续trip
private double[] probabilities;
private double probTakeOtherBus;
private DijkstraPathFinder pathFinder;//寻找最近路径

private Coord startBusStop;
private Coord endBusStop;

private boolean takeBus;

private static int nextID = 0;

主要方法

  • 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
2
3
4
5
6
private EveningActivityMovement[] eveningActivityNodes;
private int eveningActivityNodesInBuffer;
private Path path;// 路径
private Coord location;//起点
private Coord destination;//目的地
private double waitTimeAtEnd;//等待时间

主要方法

  • addNode(): 向其中添加一个相应结点
  • allMemberPresent(): 检查是否这个group 中的所有节点都能找到一条路径到这个meeting point

EveningActivityControlSystem

这个类控制了在晚上去见朋友的人的行动。

主要变量包括:

1
2
3
4
5
6
7
private HashMap<Integer, EveningActivityMovement> eveningActivityNodes;
private List<Coord> meetingSpots;//见面地点
private EveningTrip[] nextTrips;//下一个目的地

private Random rng;

private static HashMap<Integer, EveningActivityControlSystem> controlSystems;

主要方法

  • addEveningActivityNode(): 注册一个(新加入一个)相应结点
  • setMeetingSpots():从meeting locations中选择一些并进行设置
  • getEveningInstruction(): 也就是针对某一个相应的人,给出了它的起始地址和目的地址包括相应的路径,也就是instruction
  • getMeetingSpotForID(): 通过给定的id,去找到相应的meeting spot
  • getEveningActivityControlSystem(): 返回一个EveningActivityControlSystem,根据id进行查找

EveningActivityMovement

继承自MapBasedMovement,并且实现了SwitchableMovement的接口。 这是一个类用来描述people 购物或者做一些其它活动。

新增变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private static int nrOfMeetingSpots = 10;
//meeting spots 的个数
private int mode;
private boolean ready;
private DijkstraPathFinder pathFinder;//path

private Coord lastWaypoint;
private Coord startAtLocation;

private EveningActivityControlSystem scs;//控制系统
private EveningTrip trip;//to and from

private boolean readyToShop;

private int id;

private static int nextID = 0;

private int minGroupSize;
private int maxGroupSize;

可以通过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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/** mapping of external id to movement model */
private static Map<String, ExternalMovement> idMapping;
/** initial locations for nodes */
private static List<Tuple<String, Coord>> initLocations;
/** time of the very first location data */
private static double initTime;
/** sampling interval (seconds) of the location data */
private static double samplingInterval;// 采样间隔
/** last read time stamp after preloading */
private static double lastPreloadTime;
/** how many time intervals to load on every preload run */
private static double nrofPreload = 10;
/** minimum number intervals that should be preloaded ahead of sim time */
private static final double MIN_AHEAD_INTERVALS = 2;

/** the very first location of the node */
private Coord intialLocation;
/** queue of path-start-time, path tuples */
private Queue<Tuple<Double, Path>> pathQueue;

/** when was the path currently under construction started */
private double latestPathStartTime;
/** the last location of path waypoint */
private Coord latestLocation;
/** the path currently under construction */
private Path latestPath;

/** is this node active */
private boolean isActive;

主要方法

  • checkPathNeed(): 检查是否有更多的path需要被预加载或者重新加载
  • addLocation():添加一个新的location ,其需要根据这个model 移动的相应特征来进行,所以还需要一个time 来进行判断, time 表示那个节点应该在何时到那里
  • nextPathAvailable(): 返回下一条路径能够获取的仿真时间点
  • getPath():首先需要检测是否需要preload,然后得到latestPath。
  • readMorePaths(): 为下一次time instance读相应的paths,返回的是相应的time

ExternalPathMovementReader

用来读取相应的path format 的一个reader,用了两个trace file,一个是path ,另一个是来设定某一节点被激活的时间点,两个文件格式为:

1
2
3
4
5
* <p>The first line should be:</>
* <code>maxID minTime maxTime minX maxX minY maxY</code>
*
* <p>Activity trace file format is:</p>
* <code>id activeStart activeEnd\n</code>

其中包括了两个类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* Represents a point on the path.
*/
public class Entry {
public double time;
public double x;
public double y;
}

/**
* Describes a node's activity time
*/
public class ActiveTime {
public double start;
public double end;
}

分别表示了point 和 一个node 激活的时间,包括开始和结束的时间点。

ExternalPathMovement

继承自MovementModel,并且依据path format来进行相应的追踪。其添加了三个主要的变量:

1
2
3
4
// Node's paths
private List<List<ExternalPathMovementReader.Entry>> paths;//记录了相应的所有的path(time , x , y)
private int curPath=0;
private List<ExternalPathMovementReader.ActiveTime> active;//(start,end)

getPath()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
@Override
public Path getPath() {
// Make sure to not give out paths when the node is not active
if (!this.isActive()) {
return null;
}

// Check whether we're moving or waiting for the next path to start
double t = SimClock.getTime();
if (t < this.paths.get(this.curPath).get(0).time) {
return null;
}

// Get the path
List<ExternalPathMovementReader.Entry> path =
this.paths.get(this.curPath);
this.curPath++;

// Drop the node to the the beginning of the new path in case the
// previous path ended somewhere else.
Coord curPos = super.getHost().getLocation();
ExternalPathMovementReader.Entry pathStart = path.get(0);
if (curPos.getX() != pathStart.x ||
curPos.getY() != pathStart.y) {
Coord c = new Coord(pathStart.x, pathStart.y);
super.getHost().setLocation(c);
}

// If this is a stationary path, return only the fist point
if (path.size() == 1) {
Path p = new Path(0);
ExternalPathMovementReader.Entry e = path.get(0);
Coord c = new Coord(e.x, e.y);
p.addWaypoint(c);
return p;
}

// Build and return the whole path at once
Path p = new Path();
for (int i=1; i < path.size(); i++) {
ExternalPathMovementReader.Entry e = path.get(i);
ExternalPathMovementReader.Entry e2 = path.get(i-1);
Coord c = new Coord(e.x, e.y);
double dt = e.time - e2.time;
double ds = Math.sqrt( (e.x - e2.x) * (e.x - e2.x) +
(e.y - e2.y) * (e.y - e2.y));
double v = ds/dt;
p.addWaypoint(c, v);
}

return p;
}

重载函数,首先需要判断当前整个movement必须要是acitve 的状态,然后根据paths来get到当前适合的路径,然后去检测当前的path的size,根据相应的计算来得到最终需要的c,v,即相应的Coord,然后将其添加到p中并返回。

GridLocation

同样的,其继承自MovementModel,并且其是用一个grid的方式来设置node,其新增变量包括:

1
2
3
4
5
6
7
private double startCoords[];
private int rows;
private int cols;
private double spacing;
private double offset;
private int nodeCount;
private Coord loc;//坐标点

主要方法

  • getInitialLocation(): 返回了当前movement model 的初始节点位置(location)
  • getPath(): 将loc 加入其中,因为其处于grid之中,没有改变。

HomeActivityMovement

这个类继承自MapBasedMovement 并且实现了SwitchableMovement的相应接口,它是一个用来模拟在家的行动的类。

1
2
3
4
5
6
7
8
9
10
11
12
private int mode;
private DijkstraPathFinder pathFinder;

private int distance;

private Coord lastWaypoint;
private Coord homeLocation;//固定的位置

private List<Coord> allHomes;//所有的家庭住址的点

private int timeDiffSTD;
private int timeDifference;

getPath()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public Path getPath() {
if (mode == WALKING_HOME_MODE) {
// Try to find home
SimMap map = super.getMap();
if (map == null) {
return null;
}
MapNode thisNode = map.getNodeByCoord(lastWaypoint);
MapNode destinationNode = map.getNodeByCoord(homeLocation);
List<MapNode> nodes = pathFinder.getShortestPath(thisNode,
destinationNode);
Path path = new Path(generateSpeed());
for (MapNode node : nodes) {
path.addWaypoint(node.getLocation());
}
lastWaypoint = homeLocation.clone();
mode = AT_HOME_MODE;

double newX = lastWaypoint.getX() + (rng.nextDouble() - 0.5) *
distance;
if (newX > getMaxX()) {
newX = getMaxX();
} else if (newX < 0) {
newX = 0;
}
double newY = lastWaypoint.getY() + (rng.nextDouble() - 0.5) *
distance;
if (newY > getMaxY()) {
newY = getMaxY();
} else if (newY < 0) {
newY = 0;
}
Coord c = new Coord(newX, newY);
path.addWaypoint(c);
return path;
} else {
Path path = new Path(1);
path.addWaypoint(lastWaypoint.clone());
mode = READY_MODE;
return path;
}

}

重载函数的实现,根据mode不同,有不同的方式,如果是WALKING_HOME_MODE,那么需要找到回家的一条路,故而需要通过thisNode 和 destinationNode来找到一条路,并且在到达之后,需要将mode 改写为AT_HOME_MODE,否则就不需要做什么,只需要将当前的lastWaypoint加入其中即可。

LinearFormation

一个静止的”movement” model ,所有的node 都不需要移动,除了在具体某一条线上。 主要的变量有:

1
2
3
4
5
6
7
/* values for the prototype */
private Coord startLoc; /** The start location of the line */
private Coord endLoc; /** The start location of the line */
private int nodeCount; /** how many nodes in this formation */
private int lastIndex; /** index of the previous node */
/* values for the per-node models */
private Coord loc;

主要方法

  • calculateInitLocation(): 计算并返回当前结点的location
  • getPath(): 由于不需要移动,所以直接为当前loc

LinearMovement

继承自Movement,所有的nodes只是在一条线上进行移动

新增变量:

1
2
3
4
5
6
7
8
9
10
11
/* values for the prototype */
private Coord startLoc; /** The start location of the line */
private Coord endLoc; /** The start location of the line */
private int initLocType;
private int targetType;
private int nodeCount; /** how many nodes in this formation */
private int lastIndex; /** index of the previous node */

/* values for the per-node models */
private Path nextPath;
private Coord initLoc;

包括了开始的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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private static int nrOfOffices = 50;//office的数目

private int mode;//相应的模式
private int workDayLength;//工作时长
private int startedWorkingTime;//开始时间
private boolean ready;;
private DijkstraPathFinder pathFinder;//找到最短路径来到达

private ParetoRNG paretoRNG;

private int distance;
private double officeWaitTimeParetoCoeff;
private double officeMinWaitTime;
private double officeMaxWaitTime;

private List<Coord> allOffices;

private Coord lastWaypoint;
private Coord officeLocation;
private Coord deskLocation;

private boolean sittingAtDesk;

主要方法

构造函数同样是两种,包括了利用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。 其主要增加了两个变量: DijkstraPathFinderPointsOfInterest

主要方法

  • getPath(): 重载函数,也就是直接利用pathFinder 来找到最短路径,并将其所有的node 加入到返回的path中。

StationaryMovement

一个非常简单的不动的节点,包括用来模拟基站等。

WorkingDayMovement

继承自ExtendedMovementModel,这个模型利用了其它好几个模型的实现,来模拟一个整个的一天的活动。 描绘的行动方式如下: 人早上起床,然后去上班,在晚上去聚会或者购物,最后回家睡觉。

1
2
3
4
5
6
7
private BusTravellerMovement busTravellerMM;
private OfficeActivityMovement workerMM;
private HomeActivityMovement homeMM;
private EveningActivityMovement eveningActivityMovement;
private CarMovement carMM;

private TransportMovement movementUsedForTransfers;

可以看到,其具体包括了这些运动模型。