ContactCenters
V. 0.9.9.

umontreal.iro.lecuyer.contactcenters
Class PeriodChangeEvent

java.lang.Object
  extended by umontreal.iro.lecuyer.simevents.Event
      extended by umontreal.iro.lecuyer.contactcenters.PeriodChangeEvent
All Implemented Interfaces:
Comparable<Event>, Initializable, Named, ToggleElement

public class PeriodChangeEvent
extends Event
implements Initializable, Named, ToggleElement

Defines a simulation event that occurs upon period changes and supporting fixed-sized or variable-sized periods. Because this event must cover the complete simulation horizon (day, week, etc.), not only the times at which the contact center is opened, three types of periods need to be defined.

The P periods during which the contact center is opened are denoted main periods, or simply periods. Main period p, where p = 1,…, P, corresponds to simulation time interval [tp-1, tp[, where t0 < ... < tP. During the preliminary period [0, t0), the contact center is closed. Sometimes, arrivals start at time t0 - τ for a queue to build up before agents enter into service. During the wrap-up period [tP, T], no more arrival occurs, but ongoing services are terminated. Note that preliminary and wrap-up periods are more useful when a simulation replication corresponds to a day.

Before starting the simulation, the period-change event should be initialized by calling init(), which resets the current period index. The event needs to be started by using start(); this schedules it at the beginning of the first main period. This also schedules auxiliary event managing period changes at the other periods. It is recommended to start the period-change event before scheduling any other event to ensure that period changes have priority over other events. When the period change occurs, it is notified to any registered PeriodChangeListener implementation. When returning from Sim.start or just before calling Sim.stop, it is recommended to call the stop() method of this object, since the end of the wrap-up period is not scheduled as an event. This notifies all registered listeners about the end of the simulation, and disables any remaining auxiliary event. This can be useful for some statistical collectors.

Note: the PeriodChangeListener implementations are notified in the order of the list returned by getPeriodChangeListeners(), and a period-change listener modifying the list of listeners by using addPeriodChangeListener(PeriodChangeListener) or removePeriodChangeListener(PeriodChangeListener) could result in unpredictable behavior.


Field Summary
static double PRIORITY
          Default priority of period-change events.
 
Fields inherited from class umontreal.iro.lecuyer.simevents.Event
eventTime, priority, sim
 
Constructor Summary
PeriodChangeEvent(double... endingTimes)
          Constructs a new period-change event with variable-sized periods, using the default simulator.
PeriodChangeEvent(double periodDuration, int numPeriods, double startingTime)
          Constructs a new period-change event with fixed-sized main periods of duration periodDuration, a total of P + 2 = numPeriods periods, with the first main period beginning at time t0 = startingTime, and using the default simulator.
PeriodChangeEvent(Simulator sim, double... endingTimes)
          Equivalent to PeriodChangeEvent(double[]), with a user-defined simulator sim.
PeriodChangeEvent(Simulator sim, double periodDuration, int numPeriods, double startingTime)
          Equivalent to PeriodChangeEvent(double,int,double), with a user-defined simulator sim.
 
Method Summary
 void actions()
           
 void addPeriodChangeListener(PeriodChangeListener l)
          Registers the period-change listener l to be notified when a period change occurs.
 boolean cancel()
           
 void clearPeriodChangeListeners()
          Removes all the period change listeners from this event.
 int getCurrentMainPeriod()
          Returns the current main period for this period-change event.
 int getCurrentPeriod()
          Returns the index of the current simulation period.
 int getMainPeriod(int period)
          Returns the main period index corresponding to period period.
 String getName()
          Returns the name associated with this object.
 int getNumMainPeriods()
          Returns P, the number of main periods used by this period change event, i.e., getNumPeriods() - 2.
 int getNumPeriods()
          Returns P + 2, the number of periods supported by this period change event.
 int getPeriod(double simTime)
          Computes the period index corresponding to the simulation time simTime.
 List<PeriodChangeListener> getPeriodChangeListeners()
          Returns an unmodifiable list containing the period-change listeners currently registered with this event.
 double getPeriodDuration(int period)
          Returns the duration of the period period.
 double getPeriodEndingTime(int period)
          Returns the simulation time at which the period period ends.
 double getPeriodStartingTime(int period)
          Returns the simulation time at which the period period starts.
 void init()
          Equivalent to init (simulator().time()).
 void init(double initTime)
          Inits this period-change event at initial time initTime.
 void initAndNotify()
          Equivalent to initAndNotify (simulator().time()).
 void initAndNotify(double initTime)
          Calls init() and notifies the period-change listeners if the period changed due to the initialization.
 boolean isLockedPeriod()
          Returns true if the current period was changed using setCurrentPeriod(int) from the last call to init().
 boolean isMainPeriod(int period)
          Determines if the period index period corresponds to a main period.
 boolean isPeriodStartingTime(double time)
          Determines if the time time corresponds to the beginning of a period.
 boolean isPreliminaryPeriod(int period)
          Determines if the period index period corresponds to the preliminary period.
 boolean isStarted()
          Determines if the element is enabled or disabled.
 boolean isWrapupPeriod(int period)
          Determines if the period index period corresponds to the wrap-up period.
 void removePeriodChangeListener(PeriodChangeListener l)
          Removes the period-change listener l from this period-change event.
 void setCurrentPeriod(int p)
          Sets the current period to p and disables all period changes initiated by this event.
 void setEndingTimes(double... endingTimes)
          Changes the ending times of periods to endingTimes.
 void setFixedPeriods(double periodDuration, double startingTime)
          Sets this period-change event to fixed-length periods of duration periodDuration, and with main period starting at t0 = startingTime.
 void setName(String name)
          Sets the name of this object to name.
 void start()
          Starts the period-change event by scheduling it.
 void stop()
          This method should be called when the simulation ends.
 String toString()
           
 boolean wasStopped()
          Determines if this period-change event was stopped since the last call to init().
 
Methods inherited from class umontreal.iro.lecuyer.simevents.Event
cancel, compareTo, getRa, priority, reschedule, schedule, scheduleAfter, scheduleBefore, scheduleNext, setPriority, setRa, setSimulator, setTime, simulator, time
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

PRIORITY

public static final double PRIORITY
Default priority of period-change events. This priority index is set to 0.1, because the period-change event should execute before any other event at the same time.

See Also:
Constant Field Values
Constructor Detail

PeriodChangeEvent

public PeriodChangeEvent(double periodDuration,
                         int numPeriods,
                         double startingTime)
Constructs a new period-change event with fixed-sized main periods of duration periodDuration, a total of P + 2 = numPeriods periods, with the first main period beginning at time t0 = startingTime, and using the default simulator. For the event to be used, there must be at least two periods (preliminary and wrap-up). With a total of numPeriods periods, the event defines numPeriods - 2 main periods, a preliminary, and a wrap-up periods, even if the given starting time is 0.

Note that this constructor calls the setFixedPeriods(double,double) method.

Parameters:
periodDuration - the length of each period, in simulation time units.
numPeriods - the total number of periods P + 2.
startingTime - the beginning of the first period.
Throws:
IllegalArgumentException - if the number of periods is smaller than 2 or the period duration or starting time is smaller than 0.

PeriodChangeEvent

public PeriodChangeEvent(Simulator sim,
                         double periodDuration,
                         int numPeriods,
                         double startingTime)
Equivalent to PeriodChangeEvent(double,int,double), with a user-defined simulator sim.

Parameters:
sim - the simulator attached to the new event.
periodDuration - the length of each period, in simulation time units.
numPeriods - the total number of periods P + 2.
startingTime - the beginning of the first period.
Throws:
IllegalArgumentException - if sim is null, if the number of periods is smaller than 2, or the period duration or starting time is smaller than 0.

PeriodChangeEvent

public PeriodChangeEvent(double... endingTimes)
Constructs a new period-change event with variable-sized periods, using the default simulator. The object will support endingTimes.length + 1 periods where tp = endTimes[p]. The ending times in the array must be non-decreasing, otherwise an IllegalArgumentException is thrown.

This constructor accepts a variable number of arguments, i.e., one can use new PeriodChangeEvent (t1, t2, t3, t4, t5), where tN are ending times. One can also pass a regular array.

Note that this constructor calls the setEndingTimes(double[]) method.

Parameters:
endingTimes - the ending times of periods.
Throws:
IllegalArgumentException - if one ending time is negative or the ending times are not non-decreasing.

PeriodChangeEvent

public PeriodChangeEvent(Simulator sim,
                         double... endingTimes)
Equivalent to PeriodChangeEvent(double[]), with a user-defined simulator sim.

Parameters:
sim - the simulator attached to this event.
endingTimes - the ending times of periods.
Throws:
IllegalArgumentException - if sim is null, or if one ending time is negative or the ending times are not non-decreasing.
Method Detail

getName

public String getName()
Description copied from interface: Named
Returns the name associated with this object. If no name was set, this must return an empty string, not null.

Specified by:
getName in interface Named
Returns:
the name of this object.

setName

public void setName(String name)
Description copied from interface: Named
Sets the name of this object to name. The given name cannot be null and the implementation can throw an UnsupportedOperationException if the name is read-only.

Specified by:
setName in interface Named
Parameters:
name - the new name of the object.

setFixedPeriods

public final void setFixedPeriods(double periodDuration,
                                  double startingTime)
Sets this period-change event to fixed-length periods of duration periodDuration, and with main period starting at t0 = startingTime. It should not be used during a simulation replication. It is not allowed to modify the number of periods as many other objects depend on this parameter.

Parameters:
periodDuration - the length of each main period.
startingTime - the starting time of the first main period.
Throws:
IllegalArgumentException - if one argument is negative.

setEndingTimes

public final void setEndingTimes(double... endingTimes)
Changes the ending times of periods to endingTimes. This should not be used during a simulation replication, otherwise the period-change event will be cancelled and no more period change will be notified to listeners. It is also not allowed to change the number of periods, because many objects can depend on this number.

Parameters:
endingTimes - the new period ending times.
Throws:
IllegalArgumentException - if one ending time is negative, the ending times are not non-decreasing, or one tries to change the number of periods.

addPeriodChangeListener

public void addPeriodChangeListener(PeriodChangeListener l)
Registers the period-change listener l to be notified when a period change occurs.

Parameters:
l - the listener to be registered.
Throws:
NullPointerException - if l is null.

removePeriodChangeListener

public void removePeriodChangeListener(PeriodChangeListener l)
Removes the period-change listener l from this period-change event.

Parameters:
l - the period change listener being removed.

clearPeriodChangeListeners

public void clearPeriodChangeListeners()
Removes all the period change listeners from this event.


getPeriodChangeListeners

public List<PeriodChangeListener> getPeriodChangeListeners()
Returns an unmodifiable list containing the period-change listeners currently registered with this event.

Returns:
the list of period-change listeners.

init

public void init()
Equivalent to init (simulator().time()).

Specified by:
init in interface Initializable

init

public void init(double initTime)
Inits this period-change event at initial time initTime. This initializes the event for a new simulation replication, which resets the current period index. When start() is called, no period changes will be scheduled before initTime.

Parameters:
initTime - the initialization time.

initAndNotify

public void initAndNotify()
Equivalent to initAndNotify (simulator().time()).


initAndNotify

public void initAndNotify(double initTime)
Calls init() and notifies the period-change listeners if the period changed due to the initialization. This can be useful to force period-change listeners to restore parameters.


start

public void start()
Starts the period-change event by scheduling it.

Specified by:
start in interface ToggleElement

stop

public void stop()
This method should be called when the simulation ends. It calls the PeriodChangeListener.stop(PeriodChangeEvent) method of all registered PeriodChangeListener implementations.

Specified by:
stop in interface ToggleElement

wasStopped

public boolean wasStopped()
Determines if this period-change event was stopped since the last call to init().

Returns:
true if and only if the period-change event was stopped.

isStarted

public boolean isStarted()
Description copied from interface: ToggleElement
Determines if the element is enabled or disabled. Returns true if the element is enabled, false otherwise.

Specified by:
isStarted in interface ToggleElement
Returns:
the current state of the element.

cancel

public boolean cancel()
Overrides:
cancel in class Event

getCurrentPeriod

public int getCurrentPeriod()
Returns the index of the current simulation period.

Returns:
the index of the current period.

setCurrentPeriod

public void setCurrentPeriod(int p)
Sets the current period to p and disables all period changes initiated by this event. When the period is arbitrarily set by this method, the period-change event is cancelled and cannot be used to change period until the next call to init(), or initAndNotify(). However, this method can be used multiple times without calling init(). Each time this method changes the current period, registered period-change listeners are notified.

Parameters:
p - the new period index.
Throws:
IllegalArgumentException - if the period index is negative or greater than or equal to getNumPeriods().

isLockedPeriod

public boolean isLockedPeriod()
Returns true if the current period was changed using setCurrentPeriod(int) from the last call to init(). When the period is locked, only calls to setCurrentPeriod(int) can change the period index. If the period is not locked, this returns false.

Returns:
the period locking indicator.

getCurrentMainPeriod

public int getCurrentMainPeriod()
Returns the current main period for this period-change event. This is equivalent to getMainPeriod (getCurrentPeriod()).

Returns:
the index of the current main period.

isPreliminaryPeriod

public boolean isPreliminaryPeriod(int period)
Determines if the period index period corresponds to the preliminary period. This method returns true if and only if period is equal to 0.

Parameters:
period - the tested period index.
Returns:
true if and only if the period index corresponds to the preliminary period.

isMainPeriod

public boolean isMainPeriod(int period)
Determines if the period index period corresponds to a main period. The method returns true if and only if period is greater than 0 and smaller than or equal to getNumPeriods() - 2.

Parameters:
period - the tested period index.
Returns:
true if period corresponds to a main period.

isWrapupPeriod

public boolean isWrapupPeriod(int period)
Determines if the period index period corresponds to the wrap-up period. This method returns true if and only if period is equal to getNumPeriods() - 1.

Parameters:
period - the tested period index.
Returns:
true if and only if the period index corresponds to the wrap-up period.

getMainPeriod

public int getMainPeriod(int period)
Returns the main period index corresponding to period period. This returns the result of period - 1 for main periods. If the period is the preliminary period, this returns 0, the index of the first main period. If the period is the wrap-up period, this returns the index of the last main period.

Parameters:
period - the period index to be processed.
Returns:
the main period index.

getPeriod

public int getPeriod(double simTime)
Computes the period index corresponding to the simulation time simTime.

Parameters:
simTime - the simulation time.
Returns:
the corresponding period index.

isPeriodStartingTime

public boolean isPeriodStartingTime(double time)
Determines if the time time corresponds to the beginning of a period. This class cannot force period-change events to have priority over simulation events happening at the time of a period change, but the period change should usually be processed before any other event happening at the same time. Otherwise, parameters may have inconsistent values. This method can be used to help reschedule offending events manually if they cannot be scheduled after start() is called. One can use getPeriod(double) to obtain the period corresponding to the given simulation time if needed.

Parameters:
time - the simulation time to test.
Returns:
true if the given time corresponds to the time of a (future) period change, false otherwise.

getPeriodStartingTime

public double getPeriodStartingTime(int period)
Returns the simulation time at which the period period starts.

Parameters:
period - the index of the queried period.
Returns:
the simulation time at which the period begins.
Throws:
IllegalArgumentException - if the period index is invalid.

getPeriodEndingTime

public double getPeriodEndingTime(int period)
Returns the simulation time at which the period period ends. If the index of the last period is given, this returns the time at which stop() was called. If it was not called yet, this returns the current simulation time if the current period is the last one or Double.NaN otherwise.

Parameters:
period - the queried period.
Returns:
the simulation time of the beginning of the period.
Throws:
IllegalArgumentException - if the period index is invalid.

getPeriodDuration

public double getPeriodDuration(int period)
Returns the duration of the period period. This corresponds to getPeriodEndingTime(int) minus getPeriodStartingTime(int).

Parameters:
period - the period of interest.
Returns:
the duration of the period.
Throws:
IllegalArgumentException - if the period index is invalid.

getNumPeriods

public int getNumPeriods()
Returns P + 2, the number of periods supported by this period change event.

Returns:
the number of periods.

getNumMainPeriods

public int getNumMainPeriods()
Returns P, the number of main periods used by this period change event, i.e., getNumPeriods() - 2.

Returns:
the number of main periods.

actions

public void actions()
Specified by:
actions in class Event

toString

public String toString()
Overrides:
toString in class Object

ContactCenters
V. 0.9.9.

To submit a bug or ask questions, send an e-mail to Richard Simard.