Overview | Package | Class | Tree | Deprecated | Index | Help
| ContactCenters V. 0.9.9.
PREV CLASS NEXT CLASS | FRAMES NO FRAMES
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD

## umontreal.iro.lecuyer.contactcenters.dialer
Class AgentsMoveDialerPolicy

    java.lang.Object
      umontreal.iro.lecuyer.contactcenters.dialer.AgentsMoveDialerPolicy

All Implemented Interfaces:
  DialerPolicy

    public class AgentsMoveDialerPolicy

extends Object
implements DialerPolicy

Represents a dialer policy that dynamically moves agents from inbound to outbound groups to balance performance. This policy is inspired from a real dialer called SER's SmartAgent Manager. This dialer manages a subset of the I agent groups of the contact center by separating them into two categories: inbound agent groups and outbound agent groups. The inbound groups are assumed to serve inbound contacts only while the outbound groups process outbound contacts only. An inbound agent is an agent belonging to an inbound group while any outbound agent belongs to an outbound group. Consequently, an inbound agent is made outbound by removing it from its original inbound group, and adding it into an outbound group. A similar process is used to turn an outbound agent into an inbound one. This dialer policy performs such transfers in order to balance performance.

Note that this dialer policy does not impose outbound contacts to be routed to outbound agents, and inbound contacts to be sent to inbound agents. The routing policy must be configured separately to be consistent with the inbound and outbound agent groups managed by the dialer.

This policy required two different aspects to be specified: how contacts are dialed, and how agents are moved across groups. We will now describe these two aspects in more details.

#### The dialing process.

Two algorithms are available for dialing: one simple method using no routing information, and one more elaborate method using the information. With the first and fastest method, the policy does not control the distribution of the dialed calls, which can result in many mismatches if agents can only serve a restricted subset of the calls. With the second method, the number of dialed calls of each type depends on the agents available to serve them. Both methods use a dialer list L to obtain calls to dial.

The first method works as follows. When the dialer is triggered, i.e., when it is requested to dial numbers, this policy computes the number of outbound agents managed by the dialer given by

N = [i](t){i is an outbound agent group managed by the dialer}.

The number of calls to dial is then obtained using n = round(κN) + c - a where κ∈, c∈, and round(⋅) rounds its argument to the nearest integer. The dialer schedules an action event for each call waiting a dial delay. If the number of action events is taken into account (the default), the constant a is the number of action events currently scheduled by the dialer. Otherwise, a = 0. An action event occurs when a call made by the dialer reaches a person or fails. The n calls to be dialed are extracted from the dialer list L.

The dialing method using routing information works as follows. For each managed agent group, the dialer determines a number of calls to dial using the number of free agents. It then sums up the number of calls mk for each type, and constructs a dialer list L2 containing at most mk calls of type k. The calls are extracted from the dialer list L. The contents of the dialer list might be affected by limits imposed on the number of calls of each type.

The values of mk are computed as follows. First, mk = 0 for each value of k. Then, for each managed outbound agent group i, the dialer obtains ni = round(κ[i](t)) + c. Let Ki be the number of different types of calls agents in group i can serve, and bk, i = 1 if and only if agents in group i can serve calls of type k. If Ki > 0, for each value of k, the value round(bk, ini/Ki) is added to mk. Usually, Ki = 1 with this model, i.e., agents in each group i can serve a single outbound call type.

After each agent group is processed, if the dialer takes the number of action events into account, the number of action events concerning calls of type k is subtracted to each value of mk, for each call type k.

#### Management of agents.

This dialer regroups agent groups into virtual groups containing inbound and outbound agent groups. Let J be the total number of virtual agent groups, and Vj(t) = Ij(t) + Oj(t) the number of agents in virtual group j at simulation time t, where Ij(t) is the total number of inbound agents in virtual group j, and Oj(t) is the total number of outbound agents in virtual group j at time t. This dialer policy never changes the virtual group of an agent; it only transfers agents to groups within the same virtual group.

Note that an agent group can only be in a single virtual group, for a single dialer.

Any external change to an agent group managed by this dialer policy is handled the same way as if the dialer never transferred agents from groups to groups. This requires the dialer to keep track of the number of agents transferred into or out of each managed group. The changes are performed as follows. If the number of agents is increased, agents are added to the concerned group. However, if the number of agents is reduced, the dialer first removes outbound agents, then inbound agents if the affected virtual group does not contain any more outbound agents. The order in which the agent groups are selected to remove agents from is random to avoid an agent group having priority over other groups. The only constraint on the order is the priority of outbound agents over inbound agents. When the dialer is stopped, every outbound agent becomes inbound, but busy outbound agents terminate their on-going services before they become inbound.

Two flags are available for this dialer policy: inbound-to-outbound flag, and outbound-to-inbound flag. These flags trigger procedures that can be considered as background processes, although they are implemented with simulation events. When the inbound-to-outbound flag is turned ON, the policy starts the following procedure for each virtual agent group j, each time the dialer is required to take a decision.

1. If the procedure is already running for virtual group j, stop.
2. Let τ be the delay between the last time an inbound agent in virtual group j became outbound, and the current simulation time. If τ < [j], wait for [j] - τ.
3. Generate a random permutation of the inbound agent groups in the virtual group j.
4. For each inbound agent group i in the virtual group j, do the following. Agent groups are processed in the order given by the random permutation of the previous step. While [i](t) > 0,
   1. Select an agent A in group i with the following characteristics:
      - The agent is in group i (idle or busy) for a minimal time [j],
      - The idle time of the agent is greater than or equal to tj,
      - The number of idle inbound agents in virtual group j is greater than or equal to mj,
      - The number of outbound idle agents in virtual group j is smaller than Mj.
   2. If no agent was selected at previous step, skip to next agent group.
   3. Remove agent A from group i, select outbound agent group o with probability pj, o, and add the agent A to group o.
   4. Wait for a delay [j].

When the flag is turned OFF, every process moving inbound agents to outbound groups is stopped.

On the other hand, when the outbound-to-inbound flag is turned ON, the policy starts the following procedure for each virtual agent group j, each time the dialer is required to take a decision.

1. If the procedure is already running for group j, stop.
2. Let τ be delay between the last time an outbound agent in virtual group j became inbound, and the current simulation time. If τ < [j], wait for [j] - τ.
3. Generate a random permutation of outbound agent groups.
4. For each outbound agent group o in virtual group j, do the following. Agent groups are processed in the order given by the random permutation generated at the previous step. While [o](t) > 0,
   1. Select an agent A in group o with the following characteristic:
      - The agent is in group o (idle or busy) for a minimal time [j].
   2. If no agent was selected at previous step, skip to next agent group.
   3. Remove agent A from group o, select inbound agent group with probability pj, i, and add agent A to group i.
   4. Wait for a delay [j].

When the flag is turned OFF, every process moving outbound agents to inbound groups is stopped.

Nested Class Summary
`static class` | `AgentsMoveDialerPolicy.AgentGroupInfo` Represents a virtual agent group j for the `AgentsMoveDialerPolicy`.

Constructor Summary
`AgentsMoveDialerPolicy(DialerList list, AgentsMoveDialerPolicy.AgentGroupInfo[] groupInfo, double kappa, int c)` Constructs a new dialer policy using the dialer list `list`, and agent group information `groupInfo`.

Method Summary
`void` | `dialerStarted(Dialer dialer)` This method is called when the dialer using this policy is started.
`void` | `dialerStopped(Dialer dialer)` Calls `init(Dialer)`.
`AgentsMoveDialerPolicy.AgentGroupInfo[]` | `getAgentGroupInfo()` Returns an array containing the references to the virtual agent groups managed by this dialer policy.
`DialerList` | `getDialerList(Dialer dialer)` Returns the dialer list associated with this policy.
`int` | `getNumDials(Dialer dialer)` This method returns the number of free agents in all outbound groups connected to this dialer.
`void` | `init(Dialer dialer)` Makes every agent inbound when the dialer stops.
`boolean` | `isInboundToOutboundStarted()` Determines if the inbound-to-outbound flag is turned ON.
`boolean` | `isOutboundToInboundStarted()` Determines if the outbound-to-inbound flag is turned ON.
`void` | `setDialerList(DialerList list)` Sets the dialer list of this policy to `list`.
`void` | `setRouter(Router router)`
`void` | `startInboundToOutbound()` Turns the inbound-to-outbound flag on.
`void` | `startOutboundToInbound()` Turns the outbound-to-inbound flag on.
`void` | `stopInboundToOutbound()` Turns the inbound-to-outbound flag off.
`void` | `stopOutboundToInbound()` Turns the outbound-to-inbound flag off.

Methods inherited from class java.lang.Object
`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

Constructor Detail

### AgentsMoveDialerPolicy

    public AgentsMoveDialerPolicy(DialerList list,
                                  AgentsMoveDialerPolicy.AgentGroupInfo[] groupInfo,
                                  double kappa,
                                  int c)

  Constructs a new dialer policy using the dialer list `list`, and agent group information `groupInfo`. Each `AgentsMoveDialerPolicy.AgentGroupInfo` object results in a virtual group of agents for the dialer.

  Parameters:
    `list` - the dialer list.
    `groupInfo` - the agent group information.

Method Detail

### getAgentGroupInfo

    public AgentsMoveDialerPolicy.AgentGroupInfo[] getAgentGroupInfo()

  Returns an array containing the references to the virtual agent groups managed by this dialer policy.

  Returns:
    the virtual agent groups for this policy.

### dialerStarted

    public void dialerStarted(Dialer dialer)

  Description copied from interface: `DialerPolicy`
  This method is called when the dialer using this policy is started.

  Specified by:
    `dialerStarted` in interface `DialerPolicy`
  Parameters:
    `dialer` - the started dialer.

### dialerStopped

    public void dialerStopped(Dialer dialer)

  Calls `init(Dialer)`.

  Specified by:
    `dialerStopped` in interface `DialerPolicy`
  Parameters:
    `dialer` - the stopped dialer.

### getDialerList

    public DialerList getDialerList(Dialer dialer)

  Returns the dialer list associated with this policy.

  Specified by:
    `getDialerList` in interface `DialerPolicy`
  Parameters:
    `dialer` - the dialer for which the dialer list is required.
  Returns:
    the associated dialer list.

### setDialerList

    public void setDialerList(DialerList list)

  Sets the dialer list of this policy to `list`.

  Parameters:
    `list` - the new dialer list.

### getNumDials

    public int getNumDials(Dialer dialer)

  This method returns the number of free agents in all outbound groups connected to this dialer.

  Specified by:
    `getNumDials` in interface `DialerPolicy`
  Parameters:
    `dialer` - the triggered dialer.
  Returns:
    the number of calls the dialer should try to make.

### setRouter

    public void setRouter(Router router)

### init

    public void init(Dialer dialer)

  Makes every agent inbound when the dialer stops.

  Specified by:
    `init` in interface `DialerPolicy`
  Parameters:
    `dialer` - the dialer which initialized this policy.

### isInboundToOutboundStarted

    public boolean isInboundToOutboundStarted()

  Determines if the inbound-to-outbound flag is turned ON.

  Returns:
    the status of the inbound-to-outbound flag.

### startInboundToOutbound

    public void startInboundToOutbound()

  Turns the inbound-to-outbound flag on.

### stopInboundToOutbound

    public void stopInboundToOutbound()

  Turns the inbound-to-outbound flag off.

### isOutboundToInboundStarted

    public boolean isOutboundToInboundStarted()

  Determines if the outbound-to-inbound flag is turned ON.

  Returns:
    the status of the outbound-to-inbound flag.

### startOutboundToInbound

    public void startOutboundToInbound()

  Turns the outbound-to-inbound flag on.

### stopOutboundToInbound

    public void stopOutboundToInbound()

  Turns the outbound-to-inbound flag off.

Overview | Package | Class | Tree | Deprecated | Index | Help
| ContactCenters V. 0.9.9.
PREV CLASS NEXT CLASS | FRAMES NO FRAMES
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD

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