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.router
Class AgentsPrefRouterWithDelays

    java.lang.Object
      umontreal.iro.lecuyer.contactcenters.router.Router
          umontreal.iro.lecuyer.contactcenters.router.AgentsPrefRouter
              umontreal.iro.lecuyer.contactcenters.router.AgentsPrefRouterWithDelays

All Implemented Interfaces:
  NewContactListener

    public class AgentsPrefRouterWithDelays

extends AgentsPrefRouter

Extends the agents' preference-based router to support delays for routing, and allow priority to change with waiting time. Often, a contact has to wait for some time before it can overflow to groups of backup agents. Delays are used to favor the usage of primary agents as opposed to backup agents which are kept for customers which have waited long enough. The priority of a waiting contact may also change if it is waiting long enough. This router allows the user to input such delays, and to set up several different matrices of ranks for priority to be a piecewise-constant function of the waiting time.

#### Data structures.

This router uses the same structures as the agents' preference-based router without delays, with an additional I×K matrix of delays, and optional extra group-to-type matrices of ranks associated with minimal waiting times. Each delay d (i, k) is a finite positive number indicating the minimal time a contact of type k must wait to be accepted for service by an agent in group i.

Each extra matrix of ranks defines a function [j](i, k) which associates a matrix of ranks with the minimal waiting time wj. Let w0 = 0 and [0](i, k) = (i, k). So if no extra matrix of ranks is given, we have only [0](i, k), the default matrix of ranks used by the agents' preference-based routing policy without delays.

Note that fixing d (i, k) = 0 for all i and k, and omitting extra matrices of ranks reverts to the original agents' preference-based routing without delays.

#### Basic routing scheme.

We now describe more specifically how the routing with delays works. Let dk, 1, dk, 2,… be the delays d (⋅, k) sorted in increasing order, with duplicates eliminated, and dk, 0 = 0. When a contact of type k arrives, it can be served only by agents whose group i satisfies d (i, k) = 0 in addition to the conditions imposed by the agents' preference-based routing policy. If a contact is queued as no free agent is available to serve it, an event is scheduled to try routing the contact again after a delay dk, 1. During this so-called rerouting, the delay condition becomes W≥d (i, k), where W is the time the contact has waited in queue so far. If this second agent selection fails, a third trial happens after a delay dk, 2 - dk, 1. More generally, reroutings happen for each delay dk, j, for j = 1, 2,…, unless the contact is accepted by an agent, or abandons. Consequently, as its waiting time increases, the contact can be accepted by a wider range of agents.

Contact selection is done in a similar way as with the agents' preference-based routing policy, except that delays d (i, k), and extra matrices of ranks [j](i, k) are taken into account while determining the rank for a pair (i, k). More specifically, let Wk be the longest waiting time among all queued contacts of type k. First, the rank of a queued contact of type k is infinite (so the call cannot leave the queue) if its waiting time Wk is smaller than the delay d (i, k). On the other hand, if Wk≥d (i, k), the rank is given by [j'](i, k) where j' = {j : Wk≥wj} is the index of the matrix of ranks applying to the queued contact. If j' > 0, we check the other queued contacts of type k to determine if another queued contact has a smaller rank, i.e., an higher priority. For each scanned queued contact, we check the delay condition and stop scanning as soon as Wk < d (i, k) or j' = 0.

The default behavior of this policy can be altered by two switches: overflow transfer, and longest waiting time modes. When overflow transfer is turned ON, a contact gaining access to some agent groups after waiting some delay also loses access to the original agent groups. When longest waiting time is turned OFF, the contact selection gives priority to pairs (i, k) with small delays d (i, k).

#### Overflow transfer mode.

In this mode, turned off by default, the delay condition for the jth rerouting (j + 1th agent selection) becomes dk, j≤q < dk, j+1, j starting with 0, while the original condition is dk, j≤q. With this variant, when a contact has waited sufficient long to overflow to a new set of agent groups, it cannot be served by the original agent groups. Overflow can then be considered as a transfer in a new section of the contact center.

#### Longest waiting time mode.

In this mode, turned on by default, contact selection is performed in a single pass, in a way similar to the contact selection of the policy without delays. However, the delay condition is enforced to restrict contact-to-agent assignment.

If this option is disabled, contact selection is performed using the following multiple-passes process. When an agent in group i becomes free, it first searches for a contact whose type k satisfies d (i, k) = 0. Then, it searches for contacts for which d (i, k)≤dk, 1, for contacts for which d (i, k)≤dk, 2, etc., in that order. This gives higher priority to contacts with small minimal delay, because they can be served by a more restricted set of agents.

The latter behavior of this router is especially appropriate if delays are functions of the distance between the contact and the agent. For local contacts, d (i, k) is small, while it is large for remote contacts. The router then always gives priority to local assignments. However, it is often simpler and more intuitive to use the single-pass contact selection.

Field Summary

Fields inherited from class umontreal.iro.lecuyer.contactcenters.router.AgentsPrefRouter
`bestAgent, bestGroup, bestQueue, bestQueuedContact, ranksGT, ranksTG, weightsGT, weightsTG`

Fields inherited from class umontreal.iro.lecuyer.contactcenters.router.Router
`BLOCKTYPE_CANTQUEUE, BLOCKTYPE_NOLINE, BLOCKTYPE_QUEUEFULL, DEQUEUETYPE_BEGINSERVICE, DEQUEUETYPE_FANTOM, DEQUEUETYPE_NOAGENT, DEQUEUETYPE_TRANSFER, dqTypeRet`

Constructor Summary
`AgentsPrefRouterWithDelays(double[][] ranksGT, double[][] delaysGT)` Constructs a new agents' preference-based router with matrix of ranks `ranksGT` and delays matrix `delaysGT`.
`AgentsPrefRouterWithDelays(double[][] ranksTG, double[][] ranksGT, double[][] delaysGT)` Constructs a new agents' preference-based router with matrix of ranks `ranksTG` defining how contacts prefer agents, `ranksGT` defining how agents prefer contacts, and `delaysGT` for routing delays.
`AgentsPrefRouterWithDelays(double[][] ranksTG, double[][] ranksGT, double[][] weightsTG, double[][] weightsGT, double[][] delaysGT)` Constructs a new agents' preference-based router with matrix of ranks `ranksTG` defining how contacts prefer agents, and `ranksGT` defining how agents prefer contacts.

Method Summary
`protected boolean` | `checkFreeAgents(AgentGroup group, Agent agent)` This method is called when the agent `agent` in agent group `group` becomes free.
`double` | `getDelayGT(int i, int k)` Returns d (i, k) for the given agent group index `i`, and contact type identifier `k`.
`double[][]` | `getDelaysGT()` Returns the delays matrix used by this router.
`String` | `getDescription()`
`boolean` | `getLongestWaitingTimeStatus()` Returns `true` if the router uses a single-phase agent selection based on the longest waiting time.
`boolean` | `getOverflowTransferStatus()` Returns `true` if the overflow transfer mode is enabled.
`protected double` | `getRankForAgentSelection(int k, int i)` Determines the rank to be used for agent selection for contact type `k`, and agent in group `i`.
`protected double` | `getRankForContactSelection(int i, int k)` Determines the rank to be used for contact selection for contact type `k`, when an agent in group `i` becomes free.
`protected double` | `getReroutingDelay(DequeueEvent dqEv, int numReroutingsDone)` Returns the delay, in simulation time units, after which a queued contact should be rerouted.
`protected double` | `getScoreForAgentSelection(Contact ct, AgentGroup testGroup, Agent testAgent)` Returns the score for contact `ct` associated with agent group `testGroup` and agent `testAgent`.
`protected EndServiceEvent` | `selectAgent(Contact ct)` Begins the service of the contact `contact` by trying to assign it a free agent.
`protected EndServiceEvent` | `selectAgent(DequeueEvent dqEv, int numReroutingsDone)` Selects an agent for serving a queued contact in the context of rerouting.
`protected void` | `selectWaitingQueue(AgentGroup group, Agent agent, double bestRank, boolean[] qCandidates, int numCandidates)` Selects the queued contact for an agent `agent` in group `group`, with waiting queue candidates `qCandidates`.
`void` | `setDelaysGT(double[][] delaysGT)` Sets the delays matrix of this router to `delaysGT`.
`void` | `setLongestWaitingTimeStatus(boolean longestWaitingTime)` Sets the longest waiting time mode to `longestWaitingTime`.
`void` | `setOverflowTransferStatus(boolean overflowTransfer)` Sets the overflow transfer mode to `overFlowTransfer`.
`void` | `setRanksGT(double minWaitingTime, double[][] ranksGT)` Sets the matrix of ranks used for selecting contacts which have waited at least `minWaitingTime`.
`String` | `toLongString()` Returns a string representation of detailed information about the router.

Methods inherited from class umontreal.iro.lecuyer.contactcenters.router.AgentsPrefRouter
`canServe, checkWaitingQueues, getAgentSelectionScore, getContactSelectionScore, getGroupToTypeMap, getRankGT, getRanksGT, getRanksTG, getRankTG, getScoreForContactSelection, getStreamAgentSelection, getStreamContactSelection, getTypeToGroupMap, getWaitingQueueType, getWeightGT, getWeightsGT, getWeightsTG, getWeightTG, needsDetailedAgentGroup, selectAgent, selectContact, selectWaitingQueue, setAgentSelectionScore, setContactSelectionScore, setRanksGT, setRanksTG, setStreamAgentSelection, setStreamContactSelection, setWeightsGT, setWeightsTG`

Methods inherited from class umontreal.iro.lecuyer.contactcenters.router.Router
`addExitedContactListener, agentReroutingEventsIterator, beginService, clearExitedContactListeners, contactReroutingEventsIterator, dequeued, endContact, endService, enqueued, exitBlocked, exitDequeued, exitServed, formatAgentGroups, formatWaitingQueues, getAgentGroup, getAgentGroupListener, getAgentGroups, getAgentReroutingEvents, getContactFactory, getContactReroutingEvents, getCurrentQueueSize, getDialers, getExitedContactListeners, getNeededWaitingQueueComparator, getNeededWaitingQueueStructure, getNumAgentGroups, getNumContactTypes, getNumWaitingQueues, getReroutingDelay, getTotalQueueCapacity, getWaitingQueue, getWaitingQueueListener, getWaitingQueues, init, isKeepingReroutingEvents, mustClearWaitingQueue, newContact, notifyBlocked, notifyDequeued, notifyServed, removeExitedContactListener, restore, save, selectContact, selectWaitingQueue, setAgentGroup, setClearWaitingQueue, setClearWaitingQueues, setContactFactory, setKeepingReroutingEvents, setTotalQueueCapacity, setWaitingQueue, startDialers, toString`

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

Constructor Detail

### AgentsPrefRouterWithDelays

    public AgentsPrefRouterWithDelays(double[][] ranksGT,
                                      double[][] delaysGT)

  Constructs a new agents' preference-based router with matrix of ranks `ranksGT` and delays matrix `delaysGT`. The given matrices must be rectangular with one row per agent group, and one column per contact type. They define the functions (i, k) (with (k, i) = (i, k)), and d (i, k), respectively. The weights matrices are initialized with 1's.

  Parameters:
    `ranksGT` - the contact selection matrix of ranks being used.
    `delaysGT` - the delays matrix.
  Throws:
    `NullPointerException` - if `ranksGT` or `delaysGT` are `null`.
    `IllegalArgumentException` - if the ranks or delays 2D array are not rectangular.

### AgentsPrefRouterWithDelays

    public AgentsPrefRouterWithDelays(double[][] ranksTG,
                                      double[][] ranksGT,
                                      double[][] delaysGT)

  Constructs a new agents' preference-based router with matrix of ranks `ranksTG` defining how contacts prefer agents, `ranksGT` defining how agents prefer contacts, and `delaysGT` for routing delays. The given matrices must be rectangular. The weights matrices are initialized with 1's.

  Parameters:
    `ranksTG` - the matrix of ranks defining how contacts prefer agents.
    `ranksGT` - the matrix of ranks defining how agents prefer contacts.
    `delaysGT` - the delays matrix.
  Throws:
    `NullPointerException` - if `ranksGT`, `ranksTG`, or `delaysGT` are `null`.
    `IllegalArgumentException` - if the given 2D arrays are not rectangular.

### AgentsPrefRouterWithDelays

    public AgentsPrefRouterWithDelays(double[][] ranksTG,
                                      double[][] ranksGT,
                                      double[][] weightsTG,
                                      double[][] weightsGT,
                                      double[][] delaysGT)

  Constructs a new agents' preference-based router with matrix of ranks `ranksTG` defining how contacts prefer agents, and `ranksGT` defining how agents prefer contacts. The weights matrices are set to `weightsTG`, and `weightsGT`. The delays matrix is set to `delaysGT`. The given matrices must be rectangular.

  Parameters:
    `ranksTG` - the matrix of ranks defining how contacts prefer agents.
    `ranksGT` - the matrix of ranks defining how agents prefer contacts.
    `weightsTG` - the weights matrix defining (k, i).
    `weightsGT` - the weights matrix defining (i, k).
    `delaysGT` - the delays matrix.
  Throws:
    `NullPointerException` - if `ranksGT`, `ranksTG`, `weightsTG`, `weightsGT`, or `delaysGT` are `null`.
    `IllegalArgumentException` - if the 2D arrays are not rectangular.

Method Detail

### getDelaysGT

    public double[][] getDelaysGT()

  Returns the delays matrix used by this router.

  Returns:
    the delays matrix.

### getDelayGT

    public double getDelayGT(int i,
                             int k)

  Returns d (i, k) for the given agent group index `i`, and contact type identifier `k`.

  Parameters:
    `i` - the queried agent group index.
    `k` - the queried contact type identifier.
  Returns:
    the delay d (i, k).

### setDelaysGT

    public void setDelaysGT(double[][] delaysGT)

  Sets the delays matrix of this router to `delaysGT`.

  Parameters:
    `delaysGT` - the new delays matrix.
  Throws:
    `NullPointerException` - if `delaysGT` is `null`.
    `IllegalArgumentException` - if `delaysGT` is not rectangular.

### getOverflowTransferStatus

    public boolean getOverflowTransferStatus()

  Returns `true` if the overflow transfer mode is enabled. By default, this returns `false`.

  Returns:
    the status of the overflow transfer mode.

### setOverflowTransferStatus

    public void setOverflowTransferStatus(boolean overflowTransfer)

  Sets the overflow transfer mode to `overFlowTransfer`.

  Parameters:
    `overflowTransfer` - the new status of the mode.
  See Also:
    `getOverflowTransferStatus()`

### getLongestWaitingTimeStatus

    public boolean getLongestWaitingTimeStatus()

  Returns `true` if the router uses a single-phase agent selection based on the longest waiting time.

  Returns:
    the status of the longest waiting time mode.

### setLongestWaitingTimeStatus

    public void setLongestWaitingTimeStatus(boolean longestWaitingTime)

  Sets the longest waiting time mode to `longestWaitingTime`.

  Parameters:
    `longestWaitingTime` - the new status of the mode.
  See Also:
    `getLongestWaitingTimeStatus()`

### setRanksGT

    public void setRanksGT(double minWaitingTime,
                           double[][] ranksGT)

  Sets the matrix of ranks used for selecting contacts which have waited at least `minWaitingTime`.

  Parameters:
    `minWaitingTime` - the minimum waiting time.
    `ranksGT` - the matrix of ranks for this minimal waiting time.

### getRankForContactSelection

    protected double getRankForContactSelection(int i,
                                                int k)

  Description copied from class: `AgentsPrefRouter`
  Determines the rank to be used for contact selection for contact type `k`, when an agent in group `i` becomes free. By default, this returns (i, k), but subclasses may override this method for the rank to depend on some state of the system.

  Overrides:
    `getRankForContactSelection` in class `AgentsPrefRouter`
  Parameters:
    `i` - the agent group index.
    `k` - the contact type index.
  Returns:
    the rank associated with (i, k).

### selectWaitingQueue

    protected void selectWaitingQueue(AgentGroup group,
                                      Agent agent,
                                      double bestRank,
                                      boolean[] qCandidates,
                                      int numCandidates)

  Description copied from class: `AgentsPrefRouter`
  Selects the queued contact for an agent `agent` in group `group`, with waiting queue candidates `qCandidates`. The waiting queues `k` for which `qCandidates[k]` is `true` share the same minimal rank and contain at least one contact. The method must store the selected waiting queue in the field `AgentsPrefRouter.bestQueue` and possibly the contact to be removed in the `AgentsPrefRouter.bestQueuedContact`. If `AgentsPrefRouter.bestQueuedContact` is `null`, the first contact in the best queue will be used. If no waiting queue can be selected, `AgentsPrefRouter.bestQueue` must be set to `null`.

  The default implementation selects the waiting queue with the greatest score as computed by `AgentsPrefRouter.getScoreForContactSelection(AgentGroup,DequeueEvent)`, and the best queued contact is always `null`. This method can be overridden to use an alternate selection scheme, e.g., randomly selecting a queued contact.

  Overrides:
    `selectWaitingQueue` in class `AgentsPrefRouter`
  Parameters:
    `group` - the agent group containing the free agent.
    `agent` - the free agent.
    `bestRank` - the best rank found when searching for candidates.
    `qCandidates` - the waiting queue candidates contacts can be pulled from.

### getRankForAgentSelection

    protected double getRankForAgentSelection(int k,
                                              int i)

  Description copied from class: `AgentsPrefRouter`
  Determines the rank to be used for agent selection for contact type `k`, and agent in group `i`. By default, this returns (k, i), but subclasses may override this method for the rank to depend on some state of the system.

  Overrides:
    `getRankForAgentSelection` in class `AgentsPrefRouter`
  Parameters:
    `k` - the contact type index.
    `i` - the agent group index.
  Returns:
    the rank associated with (k, i).

### getScoreForAgentSelection

    protected double getScoreForAgentSelection(Contact ct,
                                               AgentGroup testGroup,
                                               Agent testAgent)

  Description copied from class: `AgentsPrefRouter`
  Returns the score for contact `ct` associated with agent group `testGroup` and agent `testAgent`. When selecting an agent for contact `ct`, if there are several agent groups with the same minimal rank, the agent group with the greatest score is selected. Returning a negative infinite score prevents an agent group from being selected. The default `AgentsPrefRouter.selectAgent(Contact,double,boolean[],int)` method calls this method with `testAgent = null` if `testGroup` is not an instance of `DetailedAgentGroup`, otherwise the method is called with `testAgent = testGroup.``getLongestIdleAgent()`.

  By default, this returns a score depending on the return value of `AgentsPrefRouter.getAgentSelectionScore()`. This can return the longest weighted idle time (the default), the weighted number of free agents, or the weight only. See `AgentSelectionScore` for more information.

  Overrides:
    `getScoreForAgentSelection` in class `AgentsPrefRouter`
  Parameters:
    `ct` - the contact being assigned an agent.
    `testGroup` - the tested agent group.
    `testAgent` - the tested agent, can be `null`.
  Returns:
    the score given to the association between the contact and the agent.

### getReroutingDelay

    protected double getReroutingDelay(DequeueEvent dqEv,
                                       int numReroutingsDone)

  Description copied from class: `Router`
  Returns the delay, in simulation time units, after which a queued contact should be rerouted. The value of `numReroutingsDone` gives the number of preceding reroutings, and `dqEv` is the dequeue event. If this delay is negative, infinite, or NaN, no rerouting happens for the contact. `numReroutings` will be -1 when this method is called at the time the contact is queued. By default, this method returns `Double.POSITIVE_INFINITY`.

  Overrides:
    `getReroutingDelay` in class `Router`
  Parameters:
    `dqEv` - the dequeue event representing the queued contact.
    `numReroutingsDone` - the number of reroutings so far.
  Returns:
    the rerouting delay.

### selectAgent

    protected EndServiceEvent selectAgent(Contact ct)

  Description copied from class: `Router`
  Begins the service of the contact `contact` by trying to assign it a free agent. The method must select an agent group with a free agent (or a specific free agent), start the service, and return the end-service event if the service was started, or `null` otherwise.

  Overrides:
    `selectAgent` in class `AgentsPrefRouter`
  Parameters:
    `ct` - the contact being routed to an agent.
  Returns:
    the end-service event representing the started service, or `null` if the contact could not be served immediately.

### checkFreeAgents

    protected boolean checkFreeAgents(AgentGroup group,
                                      Agent agent)

  Description copied from class: `Router`
  This method is called when the agent `agent` in agent group `group` becomes free. If the given agent is `null`, the method assumes that one or more arbitrary agents in the group became free. The method must select a contact to be transferred to the free agent. The selected contacts come from waiting queues, and must be removed from the queues with dequeue type `Router.DEQUEUETYPE_BEGINSERVICE` before they are transferred to agents. The method returns `true` if and only if at least one free agent could be made busy.

  The default implementation calls `Router.selectContact(AgentGroup,Agent)` to get a new dequeue event representing the removed contact, extracts the contact, and routes it to an agent, until `group` has no more free agent.

  Overrides:
    `checkFreeAgents` in class `Router`
  Parameters:
    `group` - the affected agent group.
    `agent` - the agent having ended its service.
  Returns:
    `true` if some free agents became busy, `false` otherwise.

### selectAgent

    protected EndServiceEvent selectAgent(DequeueEvent dqEv,
                                          int numReroutingsDone)

  Description copied from class: `Router`
  Selects an agent for serving a queued contact in the context of rerouting. The event `dqEv` is used to represent the dequeued contact, while `numReroutingsDone` indicates the number of reroutings that has happened so far. The method should return the end-service event corresponding to the contact's new service by an agent, or `null` for the contact to stay in queue.

  Overrides:
    `selectAgent` in class `Router`
  Parameters:
    `dqEv` - the dequeue event representing the queued contact.
    `numReroutingsDone` - the number of preceding reroutings.
  Returns:
    the end-service event, or `null`.

### getDescription

    public String getDescription()

  Overrides:
    `getDescription` in class `AgentsPrefRouter`

### toLongString

    public String toLongString()

  Description copied from class: `Router`
  Returns a string representation of detailed information about the router. This returns a string representation of each associated waiting queue and agent group and routing policies. For a short, one-line description, `Router.toString()` should be used.

  Overrides:
    `toLongString` in class `AgentsPrefRouter`
  Returns:
    a string representation of detailed information about the router.

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.