def __init__(self, area, nodes_number, standard_deviation=0.2): """ *Parameters*: - **area**: an object representing the simulation area; - **nodes_number** (`int`): a number of nodes to place over the simulation area; - **standard_deviation** (`float`): a value of the standard deviation (default: `0.2`). *Raises*: - **ValueError**: raised when the number of nodes is less or equal to 0, or when the given value of the *area* parameter is `None`. """ if area is None: raise ValueError('Parameter "area": a simulation area object' ' expected but "None" value given!') super(Normal, self).__init__(Normal.__name__) self.__area = area check_argument_type(Normal.__name__, "nodes_number", int, nodes_number, self.logger) if nodes_number <= 0: raise ValueError( 'Parameter "nodes_number": the number of nodes' " cannot be less or equal to zero but %d given!" % int(nodes_number) ) self.__nodes_number = int(nodes_number) check_argument_type(Normal.__name__, "standard_deviation", float, standard_deviation, self.logger) self.__standard_deviation = float(standard_deviation)
def __init__(self, speed): """ *Parameters*: - **speed** (`float`): a value of the node speed. *Example*: .. testsetup:: from sim2net.speed.constant import Constant .. doctest:: >>> speed = Constant(5.0) >>> speed.current 5.0 >>> speed.get_new() 5.0 >>> speed = Constant(-5.0) >>> speed.current 5.0 >>> speed.get_new() 5.0 """ super(Constant, self).__init__(Constant.__name__) check_argument_type(Constant.__name__, 'speed', float, speed, self.logger) self.__current_speed = fabs(float(speed))
def __init__(self, width, height): """ *Parameters*: - **width** (`float`): a width of the rectangular simulation area (along the horizontal x-axis), - **height** (`float`): a height of the rectangular simulation area (along the vertical y-axis). *Raises*: - **ValueError**: raised when a given value of either **width** or **height** parameter is equal to or less than 0. """ super(Rectangle, self).__init__(Rectangle.__name__) check_argument_type(Rectangle.__name__, 'width', float, width, self.logger) if width <= 0: raise ValueError('Parameter "width": the width of a simulation' ' area cannot be equal to or less than 0, but' ' %d given!' % float(width)) self.__width = float(width) check_argument_type(Rectangle.__name__, 'height', float, height, self.logger) if height <= 0: raise ValueError('Parameter "height": the height of a simulation' ' area cannot be equal to or less than 0, but' ' %d given!' % float(height)) self.__height = float(height)
def __init__(self, area, nodes_number, transmission_range): """ *Parameters*: - **area**: an object representing the simulation area; - **nodes_number** (`int`): a number of nodes to place within the simulation area; - **transmission_range** (`float`): a value of the transmission (or communication) radius of nodes, that is, the distance from a transmitter at which the signal strength remains above the minimum usable level. *Raises*: - **ValueError**: raised when: the given number of nodes or transmission range is less or equal to 0, or when the given value of the *area* parameter is `None`. """ if area is None: raise ValueError('Parameter "area": a simulation area object' ' expected but "None" value given!') super(Grid, self).__init__(Grid.__name__) self.__area = area check_argument_type(Grid.__name__, 'nodes_number', int, nodes_number, self.logger) if nodes_number <= 0: raise ValueError('Parameter "nodes_number": the number of nodes' ' cannot be less or equal to zero but %d given!' % int(nodes_number)) self.__nodes_number = int(nodes_number) check_argument_type(Grid.__name__, 'transmission_range', float, transmission_range, self.logger) if transmission_range <= 0.0: raise ValueError('Parameter "transmission_range": a value of the' ' transmission range cannot be less or equal to' ' 0 but %f given!' % float(transmission_range)) self.__transmission_range = float(transmission_range)
def __init__(self, area, nodes_number, standard_deviation=0.2): """ *Parameters*: - **area**: an object representing the simulation area; - **nodes_number** (`int`): a number of nodes to place over the simulation area; - **standard_deviation** (`float`): a value of the standard deviation (default: `0.2`). *Raises*: - **ValueError**: raised when the number of nodes is less or equal to 0, or when the given value of the *area* parameter is `None`. """ if area is None: raise ValueError('Parameter "area": a simulation area object' ' expected but "None" value given!') super(Normal, self).__init__(Normal.__name__) self.__area = area check_argument_type(Normal.__name__, 'nodes_number', int, nodes_number, self.logger) if nodes_number <= 0: raise ValueError('Parameter "nodes_number": the number of nodes' ' cannot be less or equal to zero but %d given!' % int(nodes_number)) self.__nodes_number = int(nodes_number) check_argument_type(Normal.__name__, 'standard_deviation', float, standard_deviation, self.logger) self.__standard_deviation = float(standard_deviation)
def __init__(self, area, time, initial_coordinates, pause_time=0.0): """ *Parameters*: - **area**: an object representing the simulation area; - **time**: a simulation time object of the :class:`sim2net._time.Time` class; - **initial_coordinates** (`list`): initial coordinates of all nodes; each element of this parameter should be a tuple of two coordinates: horizontal and vertical (respectively) of type `float`; - **pause_time** (`float`): a maximum value of the pause time in the *simulation time* units (default: `0.0`, see also: :mod:`sim2net._time`). *Raises*: - **ValueError**: raised when the given value of the *area*, *time* or *initial_coordinates* parameter is `None` or when the given value of the *pause_time* parameter is less that zero. (At the beginning, nodes' destination points are set to be equal to its initial coordinates passed by the *initial_coordinates* parameter.) """ if area is None: raise ValueError('Parameter "area": a simulation area object' \ ' expected but "None" value given!') if time is None: raise ValueError('Parameter "time": a time abstraction object' \ ' expected but "None" value given!') if initial_coordinates is None: raise ValueError('Parameter "initial_coordinates": identifiers' \ ' of nodes expected but "None" value given!') Mobility.__init__(self, RandomDirection.__name__) self._area = area self._time = time self._destinations = dict() check_argument_type(RandomDirection.__name__, 'initial_coordinates', list, initial_coordinates, self.logger) check_argument_type(RandomDirection.__name__, 'pause_time', float, pause_time, self.logger) if pause_time < 0.0: raise ValueError('Parameter "pause_time": a value of the pause' \ ' time cannot be less that zero but %f given!' \ % float(pause_time)) self._pause_time = float(pause_time) # { node id: # { 'destination': (horizontal coordinate, vertical coordinate), # 'pause time' : time } } for node_id in range(0, len(initial_coordinates)): self._destinations[node_id] = dict() self._destinations[node_id]['destination'] = \ initial_coordinates[node_id] self._destinations[node_id]['pause time'] = None self.logger.debug('Destination points has been initialized for %d' \ ' nodes' % len(self._destinations))
def __init__(self, area, time, initial_coordinates, pause_time=0.0): """ *Parameters*: - **area**: an object representing the simulation area; - **time**: a simulation time object of the :class:`sim2net._time.Time` class; - **initial_coordinates** (`list`): initial coordinates of all nodes; each element of this parameter should be a tuple of two coordinates: horizontal and vertical (respectively) of type `float`; - **pause_time** (`float`): a maximum value of the pause time in the *simulation time* units (default: `0.0`, see also: :mod:`sim2net._time`). *Raises*: - **ValueError**: raised when the given value of the *area*, *time* or *initial_coordinates* parameter is `None` or when the given value of the *pause_time* parameter is less that zero. (At the beginning, nodes' destination points are set to be equal to its initial coordinates passed by the *initial_coordinates* parameter.) """ if area is None: raise ValueError('Parameter "area": a simulation area object' \ ' expected but "None" value given!') if time is None: raise ValueError('Parameter "time": a time abstraction object' \ ' expected but "None" value given!') if initial_coordinates is None: raise ValueError('Parameter "initial_coordinates": identifiers' \ ' of nodes expected but "None" value given!') super(RandomWaypoint, self).__init__(RandomWaypoint.__name__) self._area = area self._time = time self._destinations = dict() check_argument_type(RandomWaypoint.__name__, 'initial_coordinates', list, initial_coordinates, self.logger) check_argument_type(RandomWaypoint.__name__, 'pause_time', float, pause_time, self.logger) if pause_time < 0.0: raise ValueError('Parameter "pause_time": a value of the pause' \ ' time cannot be less that zero but %f given!' \ % float(pause_time)) self._pause_time = float(pause_time) # { node id: # { 'destination': (horizontal coordinate, vertical coordinate), # 'pause time' : time } } for node_id in range(0, len(initial_coordinates)): self._destinations[node_id] = dict() self._destinations[node_id]['destination'] = \ initial_coordinates[node_id] self._destinations[node_id]['pause time'] = None self.logger.debug('Destination points has been initialized for %d' \ ' nodes' % len(self._destinations))
def __init__(self, prhk=None): """ *Parameters*: - **prhk** (`tuple`): a `tuple` that contains four model parameters: :math:`0\\leqslant p,r,h,k\\leqslant 1`, respectively (each of type `float`). The parameters default to the following values: * :math:`p=0.00001333`, * :math:`r=0.00601795`, * :math:`h=0.55494900`, * :math:`k=0.99999900`; (which leads to error rate equal to :math:`0.098\\%` and the mean packet loss rate equal to :math:`0.1\\%` ([HH08]_)). *Raises*: - **ValueError**: raised when the given value any model parameter is less than zero or greater that one. (At the beginning the model is in the ``G`` state.) """ super(GilbertElliott, self).__init__(PacketLoss.__name__) if prhk is None: p = float(GilbertElliott.__DEFAULT_P) r = float(GilbertElliott.__DEFAULT_R) b = float(1.0 - GilbertElliott.__DEFAULT_H) g = float(1.0 - GilbertElliott.__DEFAULT_K) else: for param in range(4): check_argument_type( GilbertElliott.__name__, "prhk[" + str(param) + "]", float, prhk[param], self.logger ) if prhk[param] < 0.0 or prhk[param] > 1.0: raise ValueError( 'Parameter "prhk[%d]": a value of the' " model parameter cannot be less than" " zero and greater than one but %f given!" % (param, float(prhk[param])) ) p = float(prhk[0]) r = float(prhk[1]) b = float(1.0 - prhk[2]) g = float(1.0 - prhk[3]) # ( current state: 'G' or 'B', # transition probability, # current packet error rate ) self.__state_g = ("G", p, g) self.__state_b = ("B", r, b) self.__current_state = self.__state_g
def __init__(self, prhk=None): """ *Parameters*: - **prhk** (`tuple`): a `tuple` that contains four model parameters: :math:`0\\leqslant p,r,h,k\\leqslant 1`, respectively (each of type `float`). The parameters default to the following values: * :math:`p=0.00001333`, * :math:`r=0.00601795`, * :math:`h=0.55494900`, * :math:`k=0.99999900`; (which leads to error rate equal to :math:`0.098\\%` and the mean packet loss rate equal to :math:`0.1\\%` ([HH08]_)). *Raises*: - **ValueError**: raised when the given value any model parameter is less than zero or greater that one. (At the beginning the model is in the ``G`` state.) """ super(GilbertElliott, self).__init__(PacketLoss.__name__) if prhk is None: p = float(GilbertElliott.__DEFAULT_P) r = float(GilbertElliott.__DEFAULT_R) b = float(1.0 - GilbertElliott.__DEFAULT_H) g = float(1.0 - GilbertElliott.__DEFAULT_K) else: for param in range(4): check_argument_type(GilbertElliott.__name__, 'prhk[' + str(param) + ']', float, prhk[param], self.logger) if prhk[param] < 0.0 or prhk[param] > 1.0: raise ValueError('Parameter "prhk[%d]": a value of the' \ ' model parameter cannot be less than' \ ' zero and greater than one but %f given!' % (param, float(prhk[param]))) p = float(prhk[0]) r = float(prhk[1]) b = float(1.0 - prhk[2]) g = float(1.0 - prhk[3]) # ( current state: 'G' or 'B', # transition probability, # current packet error rate ) self.__state_g = ('G', p, g) self.__state_b = ('B', r, b) self.__current_state = self.__state_g
def __init__(self, mean=0.0, standard_deviation=0.2): """ (Defaults to **standard normal distribution**.) *Parameters*: - **mean** (`float`): a value of the expectation (default: `0.0`); - **standard_deviation** (`float`): a value of the standard deviation (default: `0.2`). """ super(Normal, self).__init__(Normal.__name__) check_argument_type(Normal.__name__, 'mean', float, mean, self.logger) self.__mean = float(mean) check_argument_type(Normal.__name__, 'standard_deviation', float, standard_deviation, self.logger) self.__standard_deviation = float(standard_deviation) self.__current_speed = None self.get_new()
def __init__(self, minimal_speed, maximal_speed): """ *Parameters*: - **minimal_speed** (`float`): a value of a node's minimal speed; - **maximal_speed** (`float`): a value of a node's maximal speed. """ super(Uniform, self).__init__(Uniform.__name__) check_argument_type(Uniform.__name__, 'minimal_speed', float, minimal_speed, self.logger) self.__minimal_speed = float(minimal_speed) check_argument_type(Uniform.__name__, 'maximal_speed', float, maximal_speed, self.logger) self.__maximal_speed = float(maximal_speed) if self.__minimal_speed == self.__maximal_speed: self.__current_speed = float(self.__minimal_speed) else: self.__current_speed = None self.get_new()
def __init__(self, time, packet_loss, node_id, maximum_transmission_time): """ *Parameters*: - **time**: a simulation time object of the :class:`sim2net._time.Time` class; - **packet_loss**: an object representing the packet loss model (see :mod:`sim2net.packet_loss`); - **node_id** (`int`): an identifier of the node; - **maximum_transmission_time** (`float`): maximum message transmission time between neighboring nodes in the *simulation time* units (see: :mod:`sim2net._time`). *Raises*: - **ValueError**: raised when the given value of the *time* or *packet_loss* parameter is `None`; or when the given value of the *node_id* or *maximum_transmission_time* parameter is less than zero. """ if time is None: raise ValueError('Parameter "time": a time abstraction object' ' expected but "None" value given!') if packet_loss is None: raise ValueError('Parameter "packet_loss": an object' ' representing a packet loss model expected' ' but "None" value given!') self.__logger = logger.get_logger(Channel.__name__) assert self.__logger is not None, \ 'A logger object expected but "None" value got!' check_argument_type(Channel.__name__, 'node_id', int, node_id, self.__logger) if node_id < 0: raise ValueError('Parameter "node_id": a value of the identifier' ' cannot be less that zero but %d given!' % int(node_id)) check_argument_type(Channel.__name__, 'maximum_transmission_time', float, maximum_transmission_time, self.__logger) if maximum_transmission_time < 0.0: raise ValueError('Parameter "maximum_transmission_time": a value' ' of the maximum message transmission time' ' cannot be less that zero but %f given!' % float(maximum_transmission_time)) super(Channel, self).__init__(time, packet_loss, node_id, maximum_transmission_time)
def __init__(self, transmission_range): """ *Parameters*: - **transmission_range** (`float`): a value of the transmission (or communication) radius of nodes, that is, the distance from a transmitter at which the signal strength remains above the minimum usable level. *Raises*: - **ValueError**: raised when the given transmission range is less or equal to 0. """ super(PathLoss, self).__init__(PathLoss.__name__) check_argument_type(PathLoss.__name__, 'transmission_range', float, transmission_range, self.logger) if transmission_range <= 0.0: raise ValueError('Parameter "transmission_range": a value of the' \ ' transmission range cannot be less or equal to' \ ' 0 but %f given!' % float(transmission_range)) self.__transmission_range = float(transmission_range)
def __init__(self, area, nodes_number): """ *Parameters*: - **area**: an object representing the simulation area; - **nodes_number** (`int`): a number of nodes to place over the simulation area. *Raises*: - **ValueError**: raised when the number of nodes is less or equal to 0, or when the given value of the *area* parameter is `None`. """ if area is None: raise ValueError('Parameter "area": a simulation area object' ' expected but "None" value given!') super(Uniform, self).__init__(Uniform.__name__) self.__area = area check_argument_type(Uniform.__name__, 'nodes_number', int, nodes_number, self.logger) if nodes_number <= 0: raise ValueError('Parameter "nodes_number": the number of nodes' ' cannot be less or equal to zero but %d given!' % int(nodes_number)) self.__nodes_number = int(nodes_number)
def setup(self, simulation_frequency=1): """ Initializes time abstractions for simulations. *Parameters*: - **simulation_frequency** (`int`): a value of the simulation frequency (greater than 0). *Raises*: - **ValueError**: raised when a given value of the simulation frequency is less or equal to 0. *Examples*: .. testsetup:: from sim2net._time import Time .. doctest:: >>> clock = Time() >>> clock.setup() >>> clock.tick() (0, 0.0) >>> clock.tick() (1, 1.0) >>> clock.tick() (2, 2.0) >>> clock.simulation_period 1.0 >>> clock = Time() >>> clock.setup(4) >>> clock.tick() (0, 0.0) >>> clock.tick() (1, 0.25) >>> clock.tick() (2, 0.5) >>> clock.tick() (3, 0.75) >>> clock.tick() (4, 1.0) >>> clock.simulation_period 0.25 """ self.__logger = logger.get_logger(Time.__name__) assert self.__logger is not None, \ 'A logger object expected but "None" value got!' self.__simulation_step = int(-1) self.__simulation_time = float(-1.0) check_argument_type(Time.__name__, 'simulation_frequency', int, simulation_frequency, self.__logger) if simulation_frequency <= 0: raise ValueError('Parameter "simulation_frequency": a value of' \ ' the simulation frequency parameter cannot be' \ ' less or equal to zero, but %d given!' % int(simulation_frequency)) self.__simulation_frequency = float(simulation_frequency) self.__simulation_period = 1.0 / self.__simulation_frequency self.__logger.debug('The simulation time has been initialized with' \ ' the simulation frequency set to %d and the' \ ' simulation period equal to %f' % (self.__simulation_frequency, self.__simulation_period))
def __init__(self, area, time, initial_coordinates, initial_speed, **kwargs): """ *Parameters*: - **area**: an object representing the simulation area; - **time**: a simulation time object of the :class:`sim2net._time.Time` class; - **initial_coordinates** (`list`): initial coordinates of all nodes; each element of this parameter should be a tuple of two coordinates: horizontal and vertical (respectively) of type `float`; - **initial_speed** (`float`): a value of the initial speed that is assigned to each node at the beginning of the simulation; - **kwargs** (`dict`): a dictionary of (optional) keyword parameters related to the Gauss-Markov mobility model; the following parameters are accepted: **alpha** (`float`) The tuning parameter :math:`0\\leqslant\\alpha\\leqslant 1` used to vary the randomness of movements (default: `0.75`). **direction_deviation** (`float`) Constant representing the standard deviation of direction random variable :math:`d_x` (it defaults to :math:`\\frac{\\pi}{2}`). **direction_margin** (`float`) Constant used to change direction mean :math:`\\overline{d}` to ensure that nodes do not remain near a border of the simulation area for a long period of time (it defaults to `0.15`, or `15%` of the simulation area width/height, and cannot be less than zero and greater than one; see: :meth:`_GaussMarkov__velocity_recalculation`). **direction_mean** (`float`) Constant representing mean value :math:`\\overline{d}` of direction (it defaults to :math:`\\frac{\\pi}{6}`). The same value is used as mean of direction random variable :math:`d_x`. **recalculation_interval** (`int`) Velocity (i.e. speed and direction) recalculation time interval (it defaults to the *simulation frequency*; see: :mod:`sim2net._time`). It determines how often, counting in simulation steps, new values of velocity are recalculated. *Raises*: - **ValueError**: raised when the given value of the *area*, *time*, *initial_coordinates* or *initial_speed* parameter is `None`; or when the given value of the keyword parameter *alpha* is less than zero or greater that one; or when the given value of the (optional) keyword parameter *direction_margin* is less than zero or greater than one. *Example*: .. doctest:: :options: +SKIP >>> gm = GaussMarkov(area, time, coordinates, 10.0, alpha=0.35) """ if area is None: raise ValueError('Parameter "area": a simulation area object' \ ' expected but "None" value given!') if time is None: raise ValueError('Parameter "time": a time abstraction object' \ ' expected but "None" value given!') if initial_coordinates is None: raise ValueError('Parameter "initial_coordinates": identifiers' \ ' of nodes expected but "None" value given!') if initial_speed is None: raise ValueError('Parameter "initial_speed": a value of the' \ ' initial speed of nodes expected but "None"' \ ' value given!') Mobility.__init__(self, GaussMarkov.__name__) self.__area = area self.__time = time check_argument_type(GaussMarkov.__name__, 'initial_coordinates', list, initial_coordinates, self.logger) check_argument_type(GaussMarkov.__name__, 'initial_speed', float, initial_speed, self.logger) if 'alpha' in kwargs: check_argument_type(GaussMarkov.__name__, 'alpha', float, kwargs['alpha'], self.logger) if kwargs['alpha'] < 0.0 or kwargs['alpha'] > 1.0: raise ValueError('Keyword parameter "alpha": a value of the' \ ' "alpha" parameter cannot be less than' \ ' zero and greater than one but %f given!' \ % float(kwargs['alpha'])) if 'direction_deviation' in kwargs: check_argument_type(GaussMarkov.__name__, 'direction_deviation', float, kwargs['direction_deviation'], self.logger) if 'direction_margin' in kwargs: check_argument_type(GaussMarkov.__name__, 'direction_margin', float, kwargs['direction_margin'], self.logger) if kwargs['direction_margin'] < 0.0 \ or kwargs['direction_margin'] > 1.0: raise ValueError('Keyword parameter "direction_margin": a' \ ' value of the direction margin cannot be' \ ' less than zero and greater than one but' \ ' %f given!' \ % float(kwargs['direction_margin'])) if 'direction_mean' in kwargs: check_argument_type(GaussMarkov.__name__, 'direction_mean', float, kwargs['direction_mean'], self.logger) if 'recalculation_interval' in kwargs: check_argument_type(GaussMarkov.__name__, 'recalculation_interval', int, kwargs['recalculation_interval'], self.logger) self.__alpha = float(kwargs.get('alpha', GaussMarkov.__DEFAULT_ALPHA)) self.__direction_deviation = \ float(kwargs.get('direction_deviation', GaussMarkov.__DEFAULT_DIRECTION_DEVIATION)) self.__direction_margin = \ float(kwargs.get('direction_margin', GaussMarkov.__DEFAULT_DIRECTION_MARGIN)) self.__direction_mean = \ float(kwargs.get('direction_mean', GaussMarkov.__DEFAULT_DIRECTION_MEAN)) self.__recalculation_interval = \ int(kwargs.get('recalculation_interval', self.__time.simulation_frequency)) # 1.0 - alpha: self.__gauss_markov_factor_one = 1.0 - self.__alpha # sqrt((1.0 - alpha^2)): self.__gauss_markov_factor_two = sqrt(1.0 - (pow(self.__alpha, 2.0))) # area width * direction margin: self.__width_left = self.__area.width * self.__direction_margin # area width - (area width * direction margin): self.__width_right = self.__area.width - self.__width_left # area height * direction margin: self.__height_bottom = self.__area.height * self.__direction_margin # area height - (area height * direction margin): self.__height_top = self.__area.height - self.__height_bottom # { node id: # { 'speed': current speed), # 'direction': current direction } } self.__velocities = dict() for node_id in range(0, len(initial_coordinates)): self.__velocities[node_id] = dict() self.__velocities[node_id]['speed'] = float(initial_speed) self.__velocities[node_id]['direction'] = \ self.__get_new_direction() self.logger.debug('Speed and direction values has been initialized' \ ' for %d nodes' % len(self.__velocities))
def __init__(self, time, nodes_number, crash_probability, maximum_crash_number, total_simulation_steps, transient_steps=0): """ *Parameters*: - **time**: a simulation time object of the :class:`sim2net._time.Time` class; - **nodes_number** (`int`): the total number of nodes in the simulated network; - **crash_probability** (`float`): the probability that a single process will crash during the total simulation time; - **maximum_crash_number** (`int`): the maximum number of faulty processes; - **total_simulation_steps** (`int`): the total number of simulation steps; - **transient_steps** (`int`): a number of steps at the beginning of the simulation during which no crashes occur (default: `0`). *Raises*: - **ValueError**: raised when the given value of the *time* object is `None`; or when the given number of nodes is less than or equal to zero; or when the given crash probability is less than zero or grater than one; or when the given value of the maximum number of faulty processes or the given value of the total simulation steps is less than zero; or when the number of steps in the transient period is less than zero or greater than the given value of the total simulation steps. """ super(Crash, self).__init__(Crash.__name__) if time is None: raise ValueError('Parameter "time": a time abstraction object' ' expected but "None" value given!') check_argument_type(Crash.__name__, 'nodes_number', int, nodes_number, self.logger) if nodes_number <= 0: raise ValueError('Parameter "nodes_number": the number of nodes' ' cannot be less or equal to zero but %d given!' % int(nodes_number)) check_argument_type(Crash.__name__, 'crash_probability', float, crash_probability, self.logger) if crash_probability < 0.0 or crash_probability > 1.0: raise ValueError('Parameter "crash_probability": a value of the' ' crash probability parameter cannot be less' ' than zero and greater than one but %f given!' % float(crash_probability)) check_argument_type(Crash.__name__, 'maximum_crash_number', int, maximum_crash_number, self.logger) if maximum_crash_number < 0: raise ValueError('Parameter "maximum_crash_number": a value of' ' the maximum number of crashes cannot be less' ' than zero but %d given!' % int(maximum_crash_number)) check_argument_type(Crash.__name__, 'total_simulation_steps', int, total_simulation_steps, self.logger) if total_simulation_steps < 0: raise ValueError('Parameter "total_simulation_steps": a value of' ' the total number of simulation steps cannot be' ' less than zero but %d given!' % int(total_simulation_steps)) check_argument_type(Crash.__name__, 'transient_steps', int, transient_steps, self.logger) if transient_steps < 0 or transient_steps > total_simulation_steps: raise ValueError('Parameter "transient_steps": a number of the' ' transient steps cannot be less than zero or' ' greater than the total number of simulation' ' steps but %d given!' % int(transient_steps)) self.__time = time self.__crashed = \ self.__crashes(int(nodes_number), float(crash_probability), int(maximum_crash_number), int(total_simulation_steps), int(transient_steps))
def __init__(self, area, time, initial_coordinates, pause_time=0.0, area_factor=0.25): """ *Parameters*: - **area**: an object representing the simulation area; - **time**: a simulation time object of the :class:`sim2net._time.Time` class; - **initial_coordinates** (`list`): initial coordinates of all nodes; each element of this parameter should be a tuple of two coordinates: horizontal and vertical (respectively) of type `float`; - **pause_time** (`float`): a maximum value of the pause time in the *simulation time* units (default: `0.0`, see also: :mod:`sim2net._time`); - **area_factor** (`float`): a factor used to determine the width and height of the free roam area around the reference point (default: `0.25`). *Raises*: - **ValueError**: raised when the given value of the *area*, *time* or *initial_coordinates* parameter is `None`; or when the given value of the *pause_time* parameter is less that zero; or when the given value of the *area_factor* parameter is less than zero or greater than one. (At the beginning, nodes' destination points are set to be equal to its initial coordinates passed by the *initial_coordinates* parameter.) """ if area is None: raise ValueError('Parameter "area": a simulation area object' \ ' expected but "None" value given!') if time is None: raise ValueError('Parameter "time": a time abstraction object' \ ' expected but "None" value given!') if initial_coordinates is None: raise ValueError('Parameter "initial_coordinates": identifiers' \ ' of nodes expected but "None" value given!') Mobility.__init__(self, NomadicCommunity.__name__) check_argument_type(RandomWaypoint.__name__, 'initial_coordinates', list, initial_coordinates, self.logger) check_argument_type(RandomWaypoint.__name__, 'pause_time', float, pause_time, self.logger) if pause_time < 0.0: raise ValueError('Parameter "pause_time": a value of the pause' \ ' time cannot be less that zero but %f given!' \ % float(pause_time)) self._pause_time = float(pause_time) check_argument_type(RandomWaypoint.__name__, 'area_factor', float, area_factor, self.logger) if area_factor < 0.0 or area_factor > 1.0: raise ValueError('Parameter "area_factor": a value of the factor' \ ' used to compute the free roam area of nodes' \ ' cannot be less than zero or greater than one' \ ' but %f given!' % float(area_factor)) self.__area_factor = float(area_factor) self._area = area self._time = time self.__reference_point = \ (self.random_generator.uniform(self._area.ORIGIN[0], self._area.width), self.random_generator.uniform(self._area.ORIGIN[1], self._area.height)) self.__relocation_time = None # { node id: # { 'destination': (horizontal coordinate, vertical coordinate), # 'pause time' : time } } # 'on site' : True/False } } self._destinations = dict() for node_id in range(0, len(initial_coordinates)): self._destinations[node_id] = dict() self._destinations[node_id]['destination'] = \ initial_coordinates[node_id] self._destinations[node_id]['pause time'] = None self._destinations[node_id]['on site'] = False self.logger.debug('Destination points has been initialized for %d' \ ' nodes with the initial reference point at (%f,' \ ' %f)' % (len(self._destinations), self.__reference_point[0], self.__reference_point[1]))
def __init__(self, area, time, initial_coordinates, initial_speed, **kwargs): """ *Parameters*: - **area**: an object representing the simulation area; - **time**: a simulation time object of the :class:`sim2net._time.Time` class; - **initial_coordinates** (`list`): initial coordinates of all nodes; each element of this parameter should be a tuple of two coordinates: horizontal and vertical (respectively) of type `float`; - **initial_speed** (`float`): a value of the initial speed that is assigned to each node at the beginning of the simulation; - **kwargs** (`dict`): a dictionary of (optional) keyword parameters related to the Gauss-Markov mobility model; the following parameters are accepted: **alpha** (`float`) The tuning parameter :math:`0\\leqslant\\alpha\\leqslant 1` used to vary the randomness of movements (default: `0.75`). **direction_deviation** (`float`) Constant representing the standard deviation of direction random variable :math:`d_x` (it defaults to :math:`\\frac{\\pi}{2}`). **direction_margin** (`float`) Constant used to change direction mean :math:`\\overline{d}` to ensure that nodes do not remain near a border of the simulation area for a long period of time (it defaults to `0.15`, or `15%` of the simulation area width/height, and cannot be less than zero and greater than one; see: :meth:`_GaussMarkov__velocity_recalculation`). **direction_mean** (`float`) Constant representing mean value :math:`\\overline{d}` of direction (it defaults to :math:`\\frac{\\pi}{6}`). The same value is used as mean of direction random variable :math:`d_x`. **recalculation_interval** (`int`) Velocity (i.e. speed and direction) recalculation time interval (it defaults to the *simulation frequency*; see: :mod:`sim2net._time`). It determines how often, counting in simulation steps, new values of velocity are recalculated. *Raises*: - **ValueError**: raised when the given value of the *area*, *time*, *initial_coordinates* or *initial_speed* parameter is `None`; or when the given value of the keyword parameter *alpha* is less than zero or greater that one; or when the given value of the (optional) keyword parameter *direction_margin* is less than zero or greater than one. *Example*: .. doctest:: :options: +SKIP >>> gm = GaussMarkov(area, time, coordinates, 10.0, alpha=0.35) """ if area is None: raise ValueError('Parameter "area": a simulation area object' ' expected but "None" value given!') if time is None: raise ValueError('Parameter "time": a time abstraction object' ' expected but "None" value given!') if initial_coordinates is None: raise ValueError( 'Parameter "initial_coordinates": identifiers' ' of nodes expected but "None" value given!' ) if initial_speed is None: raise ValueError( 'Parameter "initial_speed": a value of the' ' initial speed of nodes expected but "None"' " value given!" ) Mobility.__init__(self, GaussMarkov.__name__) self.__area = area self.__time = time check_argument_type(GaussMarkov.__name__, "initial_coordinates", list, initial_coordinates, self.logger) check_argument_type(GaussMarkov.__name__, "initial_speed", float, initial_speed, self.logger) if "alpha" in kwargs: check_argument_type(GaussMarkov.__name__, "alpha", float, kwargs["alpha"], self.logger) if kwargs["alpha"] < 0.0 or kwargs["alpha"] > 1.0: raise ValueError( 'Keyword parameter "alpha": a value of the' ' "alpha" parameter cannot be less than' " zero and greater than one but %f given!" % float(kwargs["alpha"]) ) if "direction_deviation" in kwargs: check_argument_type( GaussMarkov.__name__, "direction_deviation", float, kwargs["direction_deviation"], self.logger ) if "direction_margin" in kwargs: check_argument_type( GaussMarkov.__name__, "direction_margin", float, kwargs["direction_margin"], self.logger ) if kwargs["direction_margin"] < 0.0 or kwargs["direction_margin"] > 1.0: raise ValueError( 'Keyword parameter "direction_margin": a' " value of the direction margin cannot be" " less than zero and greater than one but" " %f given!" % float(kwargs["direction_margin"]) ) if "direction_mean" in kwargs: check_argument_type(GaussMarkov.__name__, "direction_mean", float, kwargs["direction_mean"], self.logger) if "recalculation_interval" in kwargs: check_argument_type( GaussMarkov.__name__, "recalculation_interval", int, kwargs["recalculation_interval"], self.logger ) self.__alpha = float(kwargs.get("alpha", GaussMarkov.__DEFAULT_ALPHA)) self.__direction_deviation = float(kwargs.get("direction_deviation", GaussMarkov.__DEFAULT_DIRECTION_DEVIATION)) self.__direction_margin = float(kwargs.get("direction_margin", GaussMarkov.__DEFAULT_DIRECTION_MARGIN)) self.__direction_mean = float(kwargs.get("direction_mean", GaussMarkov.__DEFAULT_DIRECTION_MEAN)) self.__recalculation_interval = int(kwargs.get("recalculation_interval", self.__time.simulation_frequency)) # 1.0 - alpha: self.__gauss_markov_factor_one = 1.0 - self.__alpha # sqrt((1.0 - alpha^2)): self.__gauss_markov_factor_two = sqrt(1.0 - (pow(self.__alpha, 2.0))) # area width * direction margin: self.__width_left = self.__area.width * self.__direction_margin # area width - (area width * direction margin): self.__width_right = self.__area.width - self.__width_left # area height * direction margin: self.__height_bottom = self.__area.height * self.__direction_margin # area height - (area height * direction margin): self.__height_top = self.__area.height - self.__height_bottom # { node id: # { 'speed': current speed), # 'direction': current direction } } self.__velocities = dict() for node_id in range(0, len(initial_coordinates)): self.__velocities[node_id] = dict() self.__velocities[node_id]["speed"] = float(initial_speed) self.__velocities[node_id]["direction"] = self.__get_new_direction() self.logger.debug("Speed and direction values has been initialized" " for %d nodes" % len(self.__velocities))