Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but you can also compare across forks.

base fork: panisson/pymobility
base: ca45b856d6
...
head fork: panisson/pymobility
compare: 304415a910
  • 3 commits
  • 3 files changed
  • 0 commit comments
  • 1 contributor
135 src/pymobility/models/contact.py
View
@@ -27,34 +27,131 @@
'''
import numpy as np
-def random_contact(nr_nodes, avg_contacts=1.):
+def dynamic_gnp(n, p):
'''
- Random Contact model.
- This model produces a list of random node pairs that were in contact at each time step.
- The average number of contacts generated in each time step is defined by the *avg_contacts* parameter,
- and is distributed accordingly to an exponential distribution with average *avg_contacts*.
+ Implementation of the Dynamic G(n,p) graph as discussed in the following paper:
+ Andrea E. F. Clementi, Francesco Pasquale, Angelo Monti, and Riccardo Silvestri. 2007.
+ Communication in dynamic radio networks. In Proceedings of the twenty-sixth annual
+ ACM symposium on Principles of distributed computing (PODC '07). ACM, New York, NY, USA, 205-214.
+ At each time slot t of the execution of the protocol, a (new) graph G(t) is selected
+ according to the well-known random graph model G(n,p) where n is the number of nodes and p is the
+ edge probability.
Required arguments:
- *nr_nodes*:
- Integer, the number of nodes.
-
- *avg_contacts*:
- Double, the average number of contacts produced in each time step.
+ *n*:
+ The number of vertices in the graph.
+
+ *p*
+ The probability for drawing an edge between two arbitrary vertices (G(n,p) graph)
+
+ '''
+ while True:
+ m = np.random.rand(n, n)
+ c = np.where(m < p)
+ yield [(i,j) for i,j in zip(c[0], c[1]) if i < j]
+
+def dynamic_gnm(n, m):
+ '''
+ Implementation of the Dynamic G(n,m) graph as discussed in the following paper:
+
+ Andrea E. F. Clementi, Francesco Pasquale, Angelo Monti, and Riccardo Silvestri. 2007.
+ Communication in dynamic radio networks. In Proceedings of the twenty-sixth annual
+ ACM symposium on Principles of distributed computing (PODC '07). ACM, New York, NY, USA, 205-214.
+
+ At each time slot t of the execution of the protocol, a (new) graph G(t) is selected
+ according to the well-known random graph model G(n,m) where n is the number of nodes and m is the
+ number of edges.
+
+ Required arguments:
+
+ *n*:
+ The number of vertices in the graph.
+
+ *m*:
+ The number of edges in the graph (for G(n,m) graphs).
+
'''
- from pymobility.models.mobility import E
- a = np.array(range(nr_nodes))
while True:
- n = int(E(avg_contacts, np.zeros(1)))
contacts = []
- while len(contacts) < n:
- i = np.random.randint(nr_nodes)
- j = np.random.randint(nr_nodes)
- if i == j: continue
- if (a[i], a[j]) in contacts: continue
- contacts.append((a[i], a[j]))
+ while len(contacts) < m:
+ i = np.random.randint(n)
+ j = np.random.randint(n)
+ if i == j or (i, j) in contacts: continue
+ contacts.append((i, j))
yield contacts
+def edge_markovian(n, p, q, g=0):
+ '''
+ Implementation of the edge-Markovian dynamic graph as discussed in the following paper:
+
+ Andrea E.F. Clementi, Claudio Macci, Angelo Monti, Francesco Pasquale, and Riccardo Silvestri. 2008.
+ Flooding time in edge-Markovian dynamic graphs. In Proceedings of the
+ twenty-seventh ACM symposium on Principles of distributed computing (PODC '08).
+ ACM, New York, NY, USA, 213-222.
+
+ Starting from an arbitrary initial edge probability distribu-
+ tion, at every time step, every edge changes its state (exist-
+ ing or not) according to a two-state Markovian process with
+ probabilities p (edge birth-rate) and q (edge death-rate). If
+ an edge exists at time t then, at time t + 1, it dies with prob-
+ ability q. If instead the edge does not exist at time t, then
+ it will come into existence at time t + 1 with probability p.
+
+ Required arguments:
+
+ *n*:
+ The number of vertices in the graph.
+
+ *p*
+ If the edge does not exist at time t then it will come into existence at time
+ t + 1 with probability p.
+
+ *p*
+ If an edge exists at time t then, at time t + 1, it dies with probability q.
+
+ *g*:
+ an arbitrary initial probability distribution over the set [n] yielding E0.
+
+
+ '''
+ # adjacency matrix
+ a = np.zeros((n,n))
+
+ # initial set of edges
+ a[np.where(np.random.rand(n, n) < g)] = 1
+
+ while True:
+ m = np.random.rand(n, n)
+ up = np.where(np.logical_and(a == 0, m < p))
+ down = np.where(np.logical_and(a > 0, m < q))
+ a[up] = 1.
+ a[down] = 0.
+
+ c = np.nonzero(a)
+ yield [(i,j) for i,j in zip(c[0], c[1]) if i < j]
+
+def continuous_time_edge_markovian(n, lmbd):
+ '''
+ Implementation of the continuous-time edge-Markovian dynamic graph as discussed in the following paper:
+
+ Augustin Chaintreau, Abderrahmen Mtibaa, Laurent Massoulie, and Christophe Diot. 2007.
+ The diameter of opportunistic mobile networks. In Proceedings of the
+ 2007 ACM CoNEXT conference (CoNEXT '07). ACM, New York, NY, USA, , Article 12 , 12 pages.
+
+ We assume that, for any pairs of nodes (u, v), the times of
+ contact are separated by exponential random variables.
+ '''
+ from pymobility.models.mobility import E
+ a = np.zeros((n,n))
+ a = E(lmbd, a)
+
+ while True:
+ a -= 1.
+ c = np.where(a <= 0.)
+ yield [(i,j) for i,j in zip(c[0], c[1]) if i < j]
+ a[c] = E(lmbd, c[0])
+
def mobility_contact(mobility_model, contact_range=1.0):
'''
Contact model based on a mobility model.
427 src/pymobility/models/mobility.py
View
@@ -87,197 +87,10 @@ def random_waypoint(nr_nodes, dimensions, velocity=(0.1, 1.), wt_max=None):
sintheta[arrived] = np.sin(theta[arrived])
yield np.dstack((x,y))[0]
-
-# if i%100 == 0:
-# print np.average(velocity)
-
-def random_walk(nr_nodes, dimensions, velocity=1., distance=1., border_policy='reflect'):
- '''
- Random Walk mobility model.
- This model is based in the Stochastic Walk, but both the flight length and node velocity distributions are in fact constants,
- set to the *distance* and *velocity* parameters. The waiting time is set to None.
-
- Required arguments:
-
- *nr_nodes*:
- Integer, the number of nodes.
-
- *dimensions*:
- Tuple of Integers, the x and y dimensions of the simulation area.
-
- keyword arguments:
-
- *velocity*:
- Double, the value for the constant node velocity. Default is 1.0
-
- *distance*:
- Double, the value for the constant distance traveled in each step. Default is 1.0
-
- *border_policy*:
- String, either 'reflect' or 'wrap'. The policy that is used when the node arrives to the border.
- If 'reflect', the node reflects off the border.
- If 'wrap', the node reappears at the opposite edge (as in a torus-shaped area).
- '''
- if velocity>distance:
- # In this implementation, each step is 1 second,
- # it is not possible to have a velocity larger than the distance
- raise Exception('Velocity must be <= Distance')
-
- fl = np.zeros(nr_nodes)+distance
- vel = np.zeros(nr_nodes)+velocity
-
- FL_DISTR = lambda SAMPLES: np.array(fl[:len(SAMPLES)])
- VELOCITY_DISTR = lambda FD: np.array(vel[:len(FD)])
-
- return stochastic_walk(nr_nodes, dimensions, FL_DISTR, VELOCITY_DISTR, border_policy=border_policy)
-
-def truncated_levy_walk(nr_nodes, dimensions, FL_EXP=-2.6, FL_MAX=50., WT_EXP=-1.8, WT_MAX=100., border_policy='reflect'):
- '''
- Truncated Levy Walk mobility model, based on the following paper:
- Injong Rhee, Minsu Shin, Seongik Hong, Kyunghan Lee, and Song Chong. On the Levy-Walk Nature of Human Mobility.
- In 2008 IEEE INFOCOM - Proceedings of the 27th Conference on Computer Communications, pages 924-932. April 2008.
-
- The implementation is a special case of the more generic Stochastic Walk,
- in which both the flight length and waiting time distributions are truncated power laws,
- with exponents set to FL_EXP and WT_EXP and truncated at FL_MAX and WT_MAX.
- The node velocity is a function of the flight length.
-
- Required arguments:
-
- *nr_nodes*:
- Integer, the number of nodes.
-
- *dimensions*:
- Tuple of Integers, the x and y dimensions of the simulation area.
-
- keyword arguments:
-
- *FL_EXP*:
- Double, the exponent of the flight length distribution. Default is -2.6
-
- *FL_MAX*:
- Double, the maximum value of the flight length distribution. Default is 50
-
- *WT_EXP*:
- Double, the exponent of the waiting time distribution. Default is -1.8
-
- *WT_MAX*:
- Double, the maximum value of the waiting time distribution. Default is 100
-
- *border_policy*:
- String, either 'reflect' or 'wrap'. The policy that is used when the node arrives to the border.
- If 'reflect', the node reflects off the border.
- If 'wrap', the node reappears at the opposite edge (as in a torus-shaped area).
- '''
-
- FL_DISTR = lambda SAMPLES: P(FL_EXP, 1., FL_MAX, SAMPLES)
- if WT_EXP and WT_MAX:
- WT_DISTR = lambda SAMPLES: P(WT_EXP, 1., WT_MAX, SAMPLES)
- else:
- WT_DISTR = None
- VELOCITY_DISTR = lambda FD: np.sqrt(FD)/10.
-
- return stochastic_walk(nr_nodes, dimensions, FL_DISTR, VELOCITY_DISTR, WT_DISTR, border_policy=border_policy)
-
-def heterogeneous_truncated_levy_walk(nr_nodes, dimensions, WT_EXP=-1.8, WT_MAX=100., FL_EXP=-2.6, FL_MAX=50., border_policy='reflect'):
- '''
- This is a variant of the Truncated Levy Walk mobility model.
- This model is based in the Stochastic Walk.
- The waiting time distribution is a truncated power law with exponent set to WT_EXP and truncated WT_MAX.
- The flight length is a uniform distribution, different for each node. These uniform distributions are
- created by taking both min and max values from a power law with exponent set to FL_EXP and truncated FL_MAX.
- The node velocity is a function of the flight length.
-
- Required arguments:
-
- *nr_nodes*:
- Integer, the number of nodes.
-
- *dimensions*:
- Tuple of Integers, the x and y dimensions of the simulation area.
-
- keyword arguments:
-
- *WT_EXP*:
- Double, the exponent of the waiting time distribution. Default is -1.8
-
- *WT_MAX*:
- Double, the maximum value of the waiting time distribution. Default is 100
-
- *FL_EXP*:
- Double, the exponent of the flight length distribution. Default is -2.6
-
- *FL_MAX*:
- Double, the maximum value of the flight length distribution. Default is 50
-
- *border_policy*:
- String, either 'reflect' or 'wrap'. The policy that is used when the node arrives to the border.
- If 'reflect', the node reflects off the border.
- If 'wrap', the node reappears at the opposite edge (as in a torus-shaped area).
- '''
-
- NODES = np.arange(nr_nodes)
- FL_MAX = P(-1.8, 10., FL_MAX, NODES)
- FL_MIN = FL_MAX/10.
-
- FL_DISTR = lambda SAMPLES: rand(len(SAMPLES)) * (FL_MAX[SAMPLES] - FL_MIN[SAMPLES]) + FL_MIN[SAMPLES]
- WT_DISTR = lambda SAMPLES: P(WT_EXP, 1., WT_MAX, SAMPLES)
- VELOCITY_DISTR = lambda FD: np.sqrt(FD)/10.
-
- return stochastic_walk(nr_nodes, dimensions, FL_DISTR, VELOCITY_DISTR, WT_DISTR, border_policy=border_policy)
-
-def random_direction(nr_nodes, dimensions, wt_max=None, velocity=(0.1, 1.), border_policy='reflect'):
- '''
- Random Direction mobility model.
- This model is based in the Stochastic Walk. The flight length is chosen from a uniform distribution,
- with minimum 0 and maximum set to the maximum dimension value.
- The velocity is also chosen from a uniform distribution, with boundaries set by the *velocity* parameter.
- If wt_max is set, the waiting time is chosen from a uniform distribution with values between 0 and wt_max.
- If wt_max is not set, waiting time is set to None.
-
- Required arguments:
-
- *nr_nodes*:
- Integer, the number of nodes.
-
- *dimensions*:
- Tuple of Integers, the x and y dimensions of the simulation area.
-
- keyword arguments:
-
- *wt_max*:
- Double, maximum value for the waiting time distribution.
- If wt_max is set, the waiting time is chosen from a uniform distribution with values between 0 and wt_max.
- If wt_max is not set, the waiting time is set to None.
- Default is None.
-
- *velocity*:
- Tuple of Doubles, the minimum and maximum values for node velocity.
-
- *border_policy*:
- String, either 'reflect' or 'wrap'. The policy that is used when the node arrives to the border.
- If 'reflect', the node reflects off the border.
- If 'wrap', the node reappears at the opposite edge (as in a torus-shaped area).
- '''
-
- MIN_V, MAX_V = velocity
- FL_MAX = max(dimensions)
-
- FL_DISTR = lambda SAMPLES: U(0, FL_MAX, SAMPLES)
- if wt_max:
- WT_DISTR = lambda SAMPLES: U(0, wt_max, SAMPLES)
- else:
- WT_DISTR = None
- VELOCITY_DISTR = lambda FD: U(MIN_V, MAX_V, FD)
-
- return stochastic_walk(nr_nodes, dimensions, FL_DISTR, VELOCITY_DISTR, WT_DISTR, border_policy=border_policy)
class StochasticWalk(object):
- def __init__(self):
- self.collect_fl_stats = False
- self.collect_wt_stats = False
- def __call__(self, nr_nodes, dimensions, FL_DISTR, VELOCITY_DISTR, WT_DISTR=None, border_policy='reflect'):
+ def __init__(self, nr_nodes, dimensions, FL_DISTR, VELOCITY_DISTR, WT_DISTR=None, border_policy='reflect'):
'''
Base implementation for models with direction uniformly chosen from [0,pi]:
random_direction, random_walk, truncated_levy_walk
@@ -316,6 +129,16 @@ def __call__(self, nr_nodes, dimensions, FL_DISTR, VELOCITY_DISTR, WT_DISTR=None
If 'reflect', the node reflects off the border.
If 'wrap', the node reappears at the opposite edge (as in a torus-shaped area).
'''
+ self.collect_fl_stats = False
+ self.collect_wt_stats = False
+ self.border_policy = border_policy
+ self.dimensions = dimensions
+ self.nr_nodes = nr_nodes
+ self.FL_DISTR = FL_DISTR
+ self.VELOCITY_DISTR = VELOCITY_DISTR
+ self.WT_DISTR = WT_DISTR
+
+ def __iter__(self):
def reflect(xy):
# node bounces on the margins
b = np.where(xy[:,0]<0)[0]
@@ -345,21 +168,21 @@ def wrap(xy):
b = np.where(xy[:,1]>MAX_Y)[0]
if b.size > 0: xy[b,1] -= MAX_Y
- if border_policy == 'reflect':
+ if self.border_policy == 'reflect':
borderp = reflect
- elif border_policy == 'wrap':
+ elif self.border_policy == 'wrap':
borderp = wrap
else:
- borderp = border_policy
+ borderp = self.border_policy
- MAX_X, MAX_Y = dimensions
- NODES = np.arange(nr_nodes)
+ MAX_X, MAX_Y = self.dimensions
+ NODES = np.arange(self.nr_nodes)
xy = U(0, MAX_X, np.dstack((NODES,NODES))[0])
- fl = FL_DISTR(NODES)
- velocity = VELOCITY_DISTR(fl)
+ fl = self.FL_DISTR(NODES)
+ velocity = self.VELOCITY_DISTR(fl)
theta = U(0, 2*np.pi, NODES)
cosintheta = np.dstack((np.cos(theta), np.sin(theta)))[0] * np.dstack((velocity,velocity))[0]
- wt = np.zeros(nr_nodes)
+ wt = np.zeros(self.nr_nodes)
if self.collect_fl_stats: self.fl_stats = list(fl)
if self.collect_wt_stats: self.wt_stats = list(wt)
@@ -378,9 +201,9 @@ def wrap(xy):
# apply border policy
borderp(xy)
- if WT_DISTR:
+ if self.WT_DISTR:
velocity[arrived] = 0.
- wt[arrived] = WT_DISTR(arrived)
+ wt[arrived] = self.WT_DISTR(arrived)
if self.collect_wt_stats: self.wt_stats.extend(wt[arrived])
# update info for paused nodes
wt[np.where(velocity==0.)[0]] -= 1.
@@ -389,15 +212,217 @@ def wrap(xy):
# update info for moving nodes
if arrived.size > 0:
theta = U(0, 2*np.pi, arrived)
- fl[arrived] = FL_DISTR(arrived)
+ fl[arrived] = self.FL_DISTR(arrived)
if self.collect_fl_stats: self.fl_stats.extend(fl[arrived])
- velocity[arrived] = VELOCITY_DISTR(fl[arrived])
+ velocity[arrived] = self.VELOCITY_DISTR(fl[arrived])
v = velocity[arrived]
cosintheta[arrived] = np.dstack((v * np.cos(theta), v * np.sin(theta)))[0]
yield xy
+
+class RandomWalk(StochasticWalk):
+
+ def __init__(self, nr_nodes, dimensions, velocity=1., distance=1., border_policy='reflect'):
+ '''
+ Random Walk mobility model.
+ This model is based in the Stochastic Walk, but both the flight length and node velocity distributions are in fact constants,
+ set to the *distance* and *velocity* parameters. The waiting time is set to None.
+
+ Required arguments:
+
+ *nr_nodes*:
+ Integer, the number of nodes.
+
+ *dimensions*:
+ Tuple of Integers, the x and y dimensions of the simulation area.
+
+ keyword arguments:
+
+ *velocity*:
+ Double, the value for the constant node velocity. Default is 1.0
+
+ *distance*:
+ Double, the value for the constant distance traveled in each step. Default is 1.0
+
+ *border_policy*:
+ String, either 'reflect' or 'wrap'. The policy that is used when the node arrives to the border.
+ If 'reflect', the node reflects off the border.
+ If 'wrap', the node reappears at the opposite edge (as in a torus-shaped area).
+ '''
+ if velocity>distance:
+ # In this implementation, each step is 1 second,
+ # it is not possible to have a velocity larger than the distance
+ raise Exception('Velocity must be <= Distance')
+
+ fl = np.zeros(nr_nodes)+distance
+ vel = np.zeros(nr_nodes)+velocity
+
+ FL_DISTR = lambda SAMPLES: np.array(fl[:len(SAMPLES)])
+ VELOCITY_DISTR = lambda FD: np.array(vel[:len(FD)])
+
+ StochasticWalk.__init__(self, nr_nodes, dimensions, FL_DISTR, VELOCITY_DISTR,border_policy=border_policy)
+
+class RandomDirection(StochasticWalk):
+
+ def __init__(self, nr_nodes, dimensions, wt_max=None, velocity=(0.1, 1.), border_policy='reflect'):
+ '''
+ Random Direction mobility model.
+ This model is based in the Stochastic Walk. The flight length is chosen from a uniform distribution,
+ with minimum 0 and maximum set to the maximum dimension value.
+ The velocity is also chosen from a uniform distribution, with boundaries set by the *velocity* parameter.
+ If wt_max is set, the waiting time is chosen from a uniform distribution with values between 0 and wt_max.
+ If wt_max is not set, waiting time is set to None.
+
+ Required arguments:
+
+ *nr_nodes*:
+ Integer, the number of nodes.
+
+ *dimensions*:
+ Tuple of Integers, the x and y dimensions of the simulation area.
+
+ keyword arguments:
+
+ *wt_max*:
+ Double, maximum value for the waiting time distribution.
+ If wt_max is set, the waiting time is chosen from a uniform distribution with values between 0 and wt_max.
+ If wt_max is not set, the waiting time is set to None.
+ Default is None.
+
+ *velocity*:
+ Tuple of Doubles, the minimum and maximum values for node velocity.
+
+ *border_policy*:
+ String, either 'reflect' or 'wrap'. The policy that is used when the node arrives to the border.
+ If 'reflect', the node reflects off the border.
+ If 'wrap', the node reappears at the opposite edge (as in a torus-shaped area).
+ '''
-stochastic_walk = StochasticWalk()
+ MIN_V, MAX_V = velocity
+ FL_MAX = max(dimensions)
+
+ FL_DISTR = lambda SAMPLES: U(0, FL_MAX, SAMPLES)
+ if wt_max:
+ WT_DISTR = lambda SAMPLES: U(0, wt_max, SAMPLES)
+ else:
+ WT_DISTR = None
+ VELOCITY_DISTR = lambda FD: U(MIN_V, MAX_V, FD)
+
+ StochasticWalk.__init__(self, nr_nodes, dimensions, FL_DISTR, VELOCITY_DISTR, WT_DISTR=WT_DISTR, border_policy=border_policy)
+
+class TruncatedLevyWalk(StochasticWalk):
+
+ def __init__(self, nr_nodes, dimensions, FL_EXP=-2.6, FL_MAX=50., WT_EXP=-1.8, WT_MAX=100., border_policy='reflect'):
+ '''
+ Truncated Levy Walk mobility model, based on the following paper:
+ Injong Rhee, Minsu Shin, Seongik Hong, Kyunghan Lee, and Song Chong. On the Levy-Walk Nature of Human Mobility.
+ In 2008 IEEE INFOCOM - Proceedings of the 27th Conference on Computer Communications, pages 924-932. April 2008.
+
+ The implementation is a special case of the more generic Stochastic Walk,
+ in which both the flight length and waiting time distributions are truncated power laws,
+ with exponents set to FL_EXP and WT_EXP and truncated at FL_MAX and WT_MAX.
+ The node velocity is a function of the flight length.
+
+ Required arguments:
+
+ *nr_nodes*:
+ Integer, the number of nodes.
+
+ *dimensions*:
+ Tuple of Integers, the x and y dimensions of the simulation area.
+
+ keyword arguments:
+
+ *FL_EXP*:
+ Double, the exponent of the flight length distribution. Default is -2.6
+
+ *FL_MAX*:
+ Double, the maximum value of the flight length distribution. Default is 50
+
+ *WT_EXP*:
+ Double, the exponent of the waiting time distribution. Default is -1.8
+
+ *WT_MAX*:
+ Double, the maximum value of the waiting time distribution. Default is 100
+
+ *border_policy*:
+ String, either 'reflect' or 'wrap'. The policy that is used when the node arrives to the border.
+ If 'reflect', the node reflects off the border.
+ If 'wrap', the node reappears at the opposite edge (as in a torus-shaped area).
+ '''
+
+ FL_DISTR = lambda SAMPLES: P(FL_EXP, 1., FL_MAX, SAMPLES)
+ if WT_EXP and WT_MAX:
+ WT_DISTR = lambda SAMPLES: P(WT_EXP, 1., WT_MAX, SAMPLES)
+ else:
+ WT_DISTR = None
+ VELOCITY_DISTR = lambda FD: np.sqrt(FD)/10.
+
+ StochasticWalk.__init__(self, nr_nodes, dimensions, FL_DISTR, VELOCITY_DISTR, WT_DISTR=WT_DISTR, border_policy=border_policy)
+
+class HeterogeneousTruncatedLevyWalk(StochasticWalk):
+
+ def __init__(self, nr_nodes, dimensions, WT_EXP=-1.8, WT_MAX=100., FL_EXP=-2.6, FL_MAX=50., border_policy='reflect'):
+ '''
+ This is a variant of the Truncated Levy Walk mobility model.
+ This model is based in the Stochastic Walk.
+ The waiting time distribution is a truncated power law with exponent set to WT_EXP and truncated WT_MAX.
+ The flight length is a uniform distribution, different for each node. These uniform distributions are
+ created by taking both min and max values from a power law with exponent set to FL_EXP and truncated FL_MAX.
+ The node velocity is a function of the flight length.
+
+ Required arguments:
+
+ *nr_nodes*:
+ Integer, the number of nodes.
+
+ *dimensions*:
+ Tuple of Integers, the x and y dimensions of the simulation area.
+
+ keyword arguments:
+
+ *WT_EXP*:
+ Double, the exponent of the waiting time distribution. Default is -1.8
+
+ *WT_MAX*:
+ Double, the maximum value of the waiting time distribution. Default is 100
+
+ *FL_EXP*:
+ Double, the exponent of the flight length distribution. Default is -2.6
+
+ *FL_MAX*:
+ Double, the maximum value of the flight length distribution. Default is 50
+
+ *border_policy*:
+ String, either 'reflect' or 'wrap'. The policy that is used when the node arrives to the border.
+ If 'reflect', the node reflects off the border.
+ If 'wrap', the node reappears at the opposite edge (as in a torus-shaped area).
+ '''
+
+ NODES = np.arange(nr_nodes)
+ FL_MAX = P(-1.8, 10., FL_MAX, NODES)
+ FL_MIN = FL_MAX/10.
+
+ FL_DISTR = lambda SAMPLES: rand(len(SAMPLES)) * (FL_MAX[SAMPLES] - FL_MIN[SAMPLES]) + FL_MIN[SAMPLES]
+ WT_DISTR = lambda SAMPLES: P(WT_EXP, 1., WT_MAX, SAMPLES)
+ VELOCITY_DISTR = lambda FD: np.sqrt(FD)/10.
+
+ StochasticWalk.__init__(self, nr_nodes, dimensions, FL_DISTR, VELOCITY_DISTR, WT_DISTR=WT_DISTR, border_policy=border_policy)
+
+def stochastic_walk(*args, **kwargs):
+ return iter(StochasticWalk(*args, **kwargs))
+
+def random_walk(*args, **kwargs):
+ return iter(RandomWalk(*args, **kwargs))
+
+def random_direction(*args, **kwargs):
+ return iter(RandomDirection(*args, **kwargs))
+
+def truncated_levy_walk(*args, **kwargs):
+ return iter(TruncatedLevyWalk(*args, **kwargs))
+
+def heterogeneous_truncated_levy_walk(*args, **kwargs):
+ return iter(HeterogeneousTruncatedLevyWalk(*args, **kwargs))
def gauss_markov(nr_nodes, dimensions, velocity_mean=1., alpha=1., variance=1.):
'''
55 src/pymobility/tests.py
View
@@ -7,6 +7,7 @@
# This program was written by André Panisson <panisson@gmail.com>
#
import unittest
+from pymobility.models import contact
from pymobility.models.contact import modelB, model_het
import numpy as np
from pymobility.models.mobility import random_waypoint, random_walk,\
@@ -95,3 +96,57 @@ def test_model_het(self):
if t==10000:
assert contacts == [(0, 36), (1, 21), (2, 4), (3, 92), (4, 2), (5, 70), (5, 87), (6, 46), (7, 53), (8, 80), (8, 52), (9, 15), (10, 27), (11, 23), (12, 90), (13, 81), (14, 34), (15, 9), (18, 35), (19, 75), (20, 98), (21, 1), (22, 78), (23, 11), (24, 58), (25, 26), (26, 25), (27, 10), (28, 31), (29, 95), (30, 50), (31, 28), (32, 79), (33, 68), (34, 14), (35, 18), (36, 0), (37, 44), (38, 47), (39, 55), (40, 74), (41, 63), (42, 73), (43, 93), (44, 37), (45, 67), (46, 6), (47, 38), (48, 97), (49, 96), (50, 30), (51, 66), (52, 8), (52, 80), (53, 7), (54, 61), (55, 39), (57, 82), (58, 24), (60, 83), (61, 54), (62, 91), (63, 41), (65, 89), (66, 51), (67, 45), (68, 33), (70, 5), (70, 87), (73, 42), (74, 40), (75, 19), (76, 99), (77, 94), (78, 22), (79, 32), (80, 8), (80, 52), (81, 13), (82, 57), (83, 60), (87, 5), (87, 70), (89, 65), (90, 12), (91, 62), (92, 3), (93, 43), (94, 77), (95, 29), (96, 49), (97, 48), (98, 20), (99, 76)]
break
+
+ def test_dynamic_gnp(self):
+ n = 10
+ dgnp = contact.dynamic_gnp(n, 1.)
+ for i in range(5):
+ contacts = next(dgnp)
+ self.assertEqual(len(contacts), (n*(n-1))/2)
+ for i,j in contacts:
+ self.assertNotEqual(i,j)
+
+ def test_dynamic_gnm(self):
+ n = 10
+ m = 5
+ dgnm = contact.dynamic_gnm(n, m)
+ for i in range(5):
+ contacts = next(dgnm)
+ self.assertEqual(len(contacts), m)
+ for i,j in contacts:
+ self.assertNotEqual(i,j)
+
+ def test_edge_markovian_empty(self):
+ n = 10
+ p = 0.
+ q = 1.
+ g = 0.
+ em = contact.edge_markovian(n, p, q, g)
+ for i in range(5):
+ contacts = next(em)
+ self.assertEqual(len(contacts), 0)
+ for i,j in contacts:
+ self.assertNotEqual(i,j)
+
+ def test_edge_markovian_alternating(self):
+ n = 10
+ p = 1.
+ q = 1.
+ g = 0.
+ em = contact.edge_markovian(n, p, q, g)
+ for i in range(5):
+ contacts = next(em)
+ if i%2 == 0:
+ self.assertEqual(len(contacts), (n*(n-1))/2)
+ else:
+ self.assertEqual(len(contacts), 0)
+ for i,j in contacts:
+ self.assertNotEqual(i,j)
+
+ def test_continuous_time_edge_markovian(self):
+ n = 10
+ lmbd = 50.
+ model = contact.continuous_time_edge_markovian(n, lmbd)
+ for i in range(50):
+ contacts = next(model)
+

No commit comments for this range

Something went wrong with that request. Please try again.