|
ContactCenters V. 0.9.9. |
||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectjava.util.AbstractCollection<EndServiceEvent>
umontreal.iro.lecuyer.contactcenters.server.AgentGroup
public class AgentGroup
Represents a group i of agents capable of serving some types of contacts. An instance of this class keeps counters for the number of agents in a group, and provides logic to manage the service of contacts. It also defines a list of observers being notified when the agent group changes.
An agent group contains
Ni(t)∈ members at simulation time t. Among
these agents,
[i](t) are idle and
[i](t) are busy. Since agents
terminate their service before they leave, we can have
Ni(t) <
[i](t),
in which case
[i](t) =
[i](t) - Ni(t) ghost agents need to
disappear after they finish their work. As a result, the true number of
agents in a group i at time t is given by
Ni(t) +
[i](t). New
contacts are not accepted by the group when
Ni(t)≤
[i](t). Since
[i](t) includes the ghost agents, we have
Some idle agents may be unavailable to serve contacts at some times during
their shift. They can be taking unplanned breaks, going to the bathroom, etc.
These details can be modeled in the simulation if the appropriate information
is available. But in practice they are often approximated by various models
such as an efficiency factor
εi∈[0, 1], which corresponds to the
fraction of agents being effectively busy or available to serve contacts. If
[i](t) = 0, the number of free agents
[i](t) available to serve
contacts is given by
[i](t) = round(εiNi(t)) where
round(⋅) rounds its argument to the nearest integer. If
[i](t) > 0, the number of busy members of the group,
[i](t) -
[i](t), needs to be subtracted to get
[i](t). This
yields:
The service of a contact, started by the serve(Contact)
method, is divided in
two steps. After communicating with a customer (first step), an agent can
perform after-contact work (second step), e.g., update an account, take some
notes, etc.
After the first step, the contact may exit the system, or be
transferred to another agent. However, the agent becomes free only after the
second step (if any) is over. The end of these steps is scheduled using a
simulation event EndServiceEvent
that contains additional information
about the service. Service can be terminated automatically through the event
or manually through the endContact(EndServiceEvent,int)
and
endService(EndServiceEvent,int)
methods of
this class. Special indicators called the end-contact type and
end-service type tell us which type of termination has occurred for
each step.
By default, the two steps of the service are terminated automatically
after durations obtained using
the Contact.getDefaultContactTime()
and
Contact.getDefaultAfterContactTime()
methods of the
concerned contact, respectively.
These default times can be set to infinity if services
need to be terminated manually, conditional on some event.
The way times are obtained can also be changed
by setting value generators
using setContactTimeGenerator(int,ValueGenerator)
,
and setAfterContactTimeGenerator(int,ValueGenerator)
,
or by overriding getContactTime(EndServiceEvent)
and getAfterContactTime(EndServiceEvent)
.
Registered agent-group listeners can be notified when Ni(t) changes, when a service starts, and when it ends.
Note: the AgentGroupListener
implementations are notified in the
order of the list returned by getAgentGroupListeners()
, and an
agent-group listener modifying the list of listeners by using
addAgentGroupListener(AgentGroupListener)
or removeAgentGroupListener(AgentGroupListener)
could
result in unpredictable behavior.
An agent group can also be viewed as a collection
of end-service events.
For this reason, this class implements
the Collection
interface.
The collection contains end-service events
corresponding to in-progress services.
Its size thus always corresponds to the
number of busy agents.
Field Summary | |
---|---|
protected int |
ecTypeRet
The end-contact type associated with the contact time returned by getContactTime(EndServiceEvent) . |
protected int |
esTypeRet
The end-service type associated with the after-contact time returned by getAfterContactTime(EndServiceEvent) . |
Constructor Summary | |
---|---|
AgentGroup(int n)
Constructs a new agent group with n available agents. |
|
AgentGroup(PeriodChangeEvent pce,
int[] ns)
Constructs a new agent group with the period-change event pce, and ns[p] agents in the period p. |
Method Summary | |
---|---|
void |
addAgentGroupListener(AgentGroupListener listener)
Adds the agent-group listener listener to this object. |
void |
changePeriod(PeriodChangeEvent pce1)
Switches to the next period defined by pce. |
void |
clearAgentGroupListeners()
Removes all the agent-group listeners registered with this agent group. |
boolean |
contains(Object o)
|
boolean |
endContact(EndServiceEvent es,
int ecType)
Aborts the communication with a contact identified by the end-service event es, overriding the event's end-contact type with ecType. |
boolean |
endService(EndServiceEvent es,
int esType)
Aborts the service of a contact identified by the end-service event es, overriding the event's end-service type with esType. |
Iterator<EndServiceEvent> |
endServiceEventsIterator()
Constructs and returns an iterator for the end-service events. |
protected double |
getAfterContactTime(EndServiceEvent es)
Generates and returns the after-contact time for the service represented by es. |
ValueGenerator |
getAfterContactTimeGenerator(int esType)
Returns the value generator used to generate after-contact times for end-service type esType. |
List<AgentGroupListener> |
getAgentGroupListeners()
Returns an unmodifiable list containing all the agent-group listeners registered with this agent group. |
int[] |
getAllNumAgents()
Returns the array containing the number of agents for each period. |
Map<Object,Object> |
getAttributes()
Returns the map containing the attributes for this agent group. |
protected double |
getContactTime(EndServiceEvent es)
Generates and returns the contact time for the service represented by es. |
ValueGenerator |
getContactTimeGenerator(int ecType)
Returns the value generator used to generate contact times for end-contact type ecType. |
double |
getEfficiency()
Returns εi, the fraction of free and busy agents available to serve contacts over the total number of agents. |
Set<EndServiceEvent> |
getEndServiceEvents()
Returns a reference to a set containing all the end-service events for this agent group. |
int |
getId()
Returns the identifier associated with this agent group. |
String |
getName()
Returns the name associated with this object. |
int |
getNumAgents()
Returns the total number of agents in the agent group. |
int |
getNumAgents(int p)
Returns the number of agents in period p. |
int |
getNumBusyAgents()
Returns ![]() |
int |
getNumBusyAgents(int k)
Returns the number of busy agents serving contacts of type k. |
int |
getNumFreeAgents()
Returns ![]() |
int |
getNumGhostAgents()
Returns ![]() |
int |
getNumIdleAgents()
Returns ![]() |
PeriodChangeEvent |
getPeriodChangeEvent()
Returns the period-change event associated with this agent group. |
void |
init()
Initializes the agent group for a new simulation replication. |
boolean |
isKeepingEndServiceEvents()
Determines if this object keeps track of the end-service events for contacts in service by an agent. |
Iterator<EndServiceEvent> |
iterator()
|
protected void |
notifyBeginService(EndServiceEvent es)
Notifies every registered listener that a service, represented by es, was started by this agent group. |
protected void |
notifyChange()
Notifies every registered listener that the number of agents of this group has changed. |
protected void |
notifyEndContact(EndServiceEvent es,
boolean aborted)
Notifies every registered listener that the communication part of the service represented by es has ended. |
protected void |
notifyEndService(EndServiceEvent es,
boolean aborted)
Notifies every registered listener that the service represented by es is finished. |
protected void |
notifyInit()
Notifies every registered listener that this agent group has been initialized. |
void |
removeAgentGroupListener(AgentGroupListener listener)
Removes the agent-group listener listener from this object. |
void |
restore(AgentGroupState state)
Restores the state of this agent group by using the restore method of
state. |
AgentGroupState |
save()
Constructs a new AgentGroupState instance holding the state of
this agent group. |
EndServiceEvent |
serve(Contact contact)
Begins the service of the contact contact and returns the constructed end-service event. |
EndServiceEvent |
serve(Contact contact,
double contactTime,
int ecType)
This is similar to serve(Contact) , except that the specified
contact time and end-contact type are used instead of generated ones. |
EndServiceEvent |
serve(Contact contact,
double contactTime,
int ecType,
double afterContactTime,
int esType)
This is similar to serve(Contact) except that the contact and
after-contact times are specified explicitly. |
EndServiceEvent |
serve(EndServiceEvent oldEndServiceEvent)
Starts the service of a contact based on information stored in the old end-service event oldEndServiceEvent. |
void |
setAfterContactTimeGenerator(int esType,
ValueGenerator acgen)
Sets the after-contact time generator for end-service type esType to acgen. |
void |
setContactTimeGenerator(int ecType,
ValueGenerator cgen)
Sets the contact time generator for end-contact type ecType to cgen. |
void |
setEfficiency(double eff)
Changes the agents' efficiency to eff. |
void |
setId(int id)
Sets the identifier of this agent group to id. |
void |
setKeepingEndServiceEvents(boolean keepEsev)
Sets the keep end-service-event indicator to keepEsev. |
void |
setName(String name)
Sets the name of this object to name. |
void |
setNumAgents(int n)
Changes the number of agents of this group to n. |
void |
setNumAgents(int[] allNumAgents)
Sets the vector giving the number of agent for each period to allNumAgents. |
void |
setNumAgents(int p,
int n)
Sets the number of agents in period p to n. |
int |
size()
|
void |
stop(PeriodChangeEvent pce1)
This method is called after the period-change event is stopped by PeriodChangeEvent.stop() . |
String |
toString()
|
Methods inherited from class java.util.AbstractCollection |
---|
add, addAll, clear, containsAll, isEmpty, remove, removeAll, retainAll, toArray, toArray |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
Methods inherited from interface java.util.Collection |
---|
equals, hashCode |
Field Detail |
---|
protected int ecTypeRet
getContactTime(EndServiceEvent)
.
protected int esTypeRet
getAfterContactTime(EndServiceEvent)
.
Constructor Detail |
---|
public AgentGroup(int n)
n
- the number of agents in the group.public AgentGroup(PeriodChangeEvent pce, int[] ns)
pce
- the period-change event defining the simulation periods.ns
- the number of agents in the group for each period.
IllegalArgumentException
- if there is not a number of agent for each period.Method Detail |
---|
public String getName()
Named
getName
in interface Named
public void setName(String name)
Named
UnsupportedOperationException
if the name is read-only.
setName
in interface Named
name
- the new name of the object.public PeriodChangeEvent getPeriodChangeEvent()
public double getEfficiency()
public void setEfficiency(double eff)
setNumAgents(int)
to update the number of free agents according to the
new efficiency factor. If there is no busy agent, the number of free
agents is given by getNumAgents()
*eff, rounded to the
nearest integer. The efficiency factor must be in [0, 1], otherwise an
exception is thrown.
eff
- the new efficiency.
IllegalArgumentException
- if the efficiency factor is smaller than 0 or greater than
1.public ValueGenerator getContactTimeGenerator(int ecType)
ecType
- the queried end-contact type.
public ValueGenerator getAfterContactTimeGenerator(int esType)
esType
- the queried end-service type.
public void setContactTimeGenerator(int ecType, ValueGenerator cgen)
ecType
- the affected end-contact type.cgen
- the new contact time generator associated with this end-contact
type.
IllegalArgumentException
- if the end-contact type is negative.public void setAfterContactTimeGenerator(int esType, ValueGenerator acgen)
esType
- the affected end-service type.acgen
- the new after-contact time generator associated with this
end-service type.
IllegalArgumentException
- if the end-service type is negative.public void init()
init
in interface Initializable
public boolean isKeepingEndServiceEvents()
public void setKeepingEndServiceEvents(boolean keepEsev)
keepEsev
- the new value of the indicator.isKeepingEndServiceEvents()
public Iterator<EndServiceEvent> endServiceEventsIterator()
isKeepingEndServiceEvents()
returns true, the iterator
is constructed from the set returned by getEndServiceEvents()
.
Otherwise, an illegal state exception is thrown.
public Iterator<EndServiceEvent> iterator()
iterator
in interface Iterable<EndServiceEvent>
iterator
in interface Collection<EndServiceEvent>
iterator
in class AbstractCollection<EndServiceEvent>
public int size()
size
in interface Collection<EndServiceEvent>
size
in class AbstractCollection<EndServiceEvent>
public boolean contains(Object o)
contains
in interface Collection<EndServiceEvent>
contains
in class AbstractCollection<EndServiceEvent>
public Set<EndServiceEvent> getEndServiceEvents()
IllegalStateException
.
IllegalStateException
- if the agent group does not keep end-service events.public EndServiceEvent serve(Contact contact)
IllegalStateException
is thrown. Otherwise, a contact
time is obtained using getContactTime(EndServiceEvent)
.
The end-service event is then constructed and scheduled
if the contact time is not infinite. If an
infinite contact time is generated, one must manually abort the
communication using endContact(EndServiceEvent,int)
or schedule the end-service event.
When the communication is over, the same rules are applied for generating
the after-contact time using getAfterContactTime(EndServiceEvent)
. When the
after-contact time is finite, the end-service event is scheduled a second
time for the service termination.
contact
- the contact to be served.
IllegalStateException
- if no free agent is available.public EndServiceEvent serve(Contact contact, double contactTime, int ecType)
serve(Contact)
, except that the specified
contact time and end-contact type are used instead of generated ones. The
after-contact time is generated as in serve(Contact)
. The main
purpose of this method is for recreating an end-service event based on
saved state information.
contact
- the contact being served.contactTime
- the communication time of the contact with the agent.ecType
- the end-contact type.
IllegalStateException
- if no free agent is available.public EndServiceEvent serve(Contact contact, double contactTime, int ecType, double afterContactTime, int esType)
serve(Contact)
except that the contact and
after-contact times are specified explicitly. The main purpose of this
method is for recreating an end-service event based on saved state
information.
contact
- the contact being served.contactTime
- the contact time.ecType
- the end-contact type.afterContactTime
- the after-contact time.esType
- the end-service type.
IllegalStateException
- if no free agent is available.public EndServiceEvent serve(EndServiceEvent oldEndServiceEvent)
EndServiceEvent.contactDone()
returns true, the method
uses the effective end-contact time and end-contact type, and the
scheduled end-service time and end-service type to start the service.
Otherwise, it uses the scheduled end-contact time and end-contact type
only.
oldEndServiceEvent
- the old end-service event.
public AgentGroupState save()
AgentGroupState
instance holding the state of
this agent group. The method isKeepingEndServiceEvents()
must
return true for this method to be called, because the state
includes every contact served by agents in this group.
public void restore(AgentGroupState state)
restore
method of
state.
state
- the saved state of this agent group.protected double getContactTime(EndServiceEvent es)
ecTypeRet
if
the default value of 0 is not appropriate.
By default, a MinValueGenerator
is used. For each end-contact type
c with an associated value generator, a contact time Cc is generated.
The scheduled contact time is
Cc* = {Cc}, and the end-contact
type is c*.
es
- the end-service event.
protected double getAfterContactTime(EndServiceEvent es)
esTypeRet
if
the default value of 0 is not appropriate.
By default, a MinValueGenerator
is used. For each end-service type
c with an associated value generator, an after-contact time Cc is
generated. The scheduled after-contact time is
Cc* = {Cc},
and the end-service type is c*.
es
- the end-service event.
public boolean endContact(EndServiceEvent es, int ecType)
endService(EndServiceEvent,int)
after this method to completely abort the service.
es
- the end-service event representing the service to be aborted.ecType
- the type of communication termination.
public boolean endService(EndServiceEvent es, int esType)
endContact(EndServiceEvent,int)
to abort the communication.
es
- the end-service event representing the after-contact work to be
aborted.esType
- the type of service termination.
public int getNumAgents()
public void setNumAgents(int n)
n
- the total number of agents.
IllegalArgumentException
- if the given number of agents is negative.public int[] getAllNumAgents()
IllegalStateException
- if the per-period numbers of agents are not available.public int getNumAgents(int p)
p
- the period index.
IllegalStateException
- if the per-period numbers of agents are not available.
ArrayIndexOutOfBoundsException
- if the period index is negative or greater than or equal to
the number of periods.public void setNumAgents(int p, int n)
p
- the period index.n
- the new number of agents.
IllegalStateException
- if the per-period numbers of agents are not available.
ArrayIndexOutOfBoundsException
- if the period index is negative or greater than or equal to
the number of periods.public void setNumAgents(int[] allNumAgents)
allNumAgents
- the new vector of agents.public int getNumGhostAgents()
public int getNumIdleAgents()
getNumFreeAgents()
. If
getEfficiency()
returns 1, this returns the same value as
getNumFreeAgents()
.
public int getNumFreeAgents()
public int getNumBusyAgents()
getNumAgents()
and
getNumGhostAgents()
.
public int getNumBusyAgents(int k)
k
- the contact type index.
public int getId()
public void setId(int id)
IllegalStateException
is
thrown.
id
- the new identifier associated with the agent group.
IllegalStateException
- if the identifier was already set.public void addAgentGroupListener(AgentGroupListener listener)
listener
- the agent-group listener being added.
NullPointerException
- if listener is null.public void removeAgentGroupListener(AgentGroupListener listener)
listener
- the agent-group listener being removed.public void clearAgentGroupListeners()
public List<AgentGroupListener> getAgentGroupListeners()
protected void notifyInit()
protected void notifyChange()
protected void notifyBeginService(EndServiceEvent es)
es
- the end-service event representing the service.protected void notifyEndContact(EndServiceEvent es, boolean aborted)
es
- the end-service event.aborted
- determines if the service was aborted or terminated
normally.protected void notifyEndService(EndServiceEvent es, boolean aborted)
es
- the end-service vent representing the ended service.aborted
- determines if the after-contact work was
aborted or terminated normally.public Map<Object,Object> getAttributes()
public void changePeriod(PeriodChangeEvent pce1)
PeriodChangeListener
PeriodChangeEvent.getCurrentPeriod()
returns the index
of the new period.
changePeriod
in interface PeriodChangeListener
pce1
- the source period-change event.public void stop(PeriodChangeEvent pce1)
PeriodChangeListener
PeriodChangeEvent.stop()
.
stop
in interface PeriodChangeListener
pce1
- the period-change event being stopped.public String toString()
toString
in class AbstractCollection<EndServiceEvent>
|
ContactCenters V. 0.9.9. |
||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |