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 QueueRatioOverflowRouter

    java.lang.Object
      umontreal.iro.lecuyer.contactcenters.router.Router
          umontreal.iro.lecuyer.contactcenters.router.QueueRatioOverflowRouter

All Implemented Interfaces:
  NewContactListener

    public class QueueRatioOverflowRouter

extends Router

This router sends new contacts to agent groups using a fixed list, but for each agent group, routing occurs conditional on the expected waiting time. More specifically, the router uses a K×I ranks matrix giving a rank (k, i) for each contact type k and agent group i. The lower is this rank, the higher is the priority of assigning contacts of type k to agents in group i. If a rank is ∞, the corresponding assignment is not allowed. The ranks matrix giving (k, i) for all k and i is used to generate overflow lists defined as follows. For each contact type k, the router creates a list of agent groupsets sharing the same priority. The jth groupset for contact type k is denoted i(k, j) = {i = 0,…, I - 1 | (k, i) = rk, j}. Here, rk, j1 < rk, j2 < ∞ for any j1 < j2. The overflow list for contact of type k is then i(k, 0), i(k, 1),… For example, suppose we have the following ranks matrix:

()

The overflow list for contact type 0 is ((0, 1),(2)), while the overflow list for contact type 1 is ((0),(2)).

When a new contact of type k arrives, the router performs two phases to assign an agent group or waiting queues to the contact. Here, each waiting queue corresponds to a single agent group. The first phase tries to associate an agent groupset with the contact while the second phase, which occurs when the first phase fails, associates a waiting queue to the contact. The first phase checks every agent groupset i(k, j) sequentially, and stops as soon as a groupset containing a free agent is found. For each considered groupset, the router tests every agent group to determine if at least one agent is free. If a single agent is free, the contact is routed to that agent. If several agents of that groupset are free, the contact is routed to the agent with the longest idle time.

If no agent is available in the tested groupset, one or more waiting queues must be selected to add the contact to. A waiting queue i with size Qi(t) is associated with a single agent group, which has Ni(t) agents, where t is the current simulation time. The router considers waiting queues in the current groupset only, and selects a queue only if the queue ratio (Si(t) + 1)/Ni(t) is greater than the agent-group specific target. This queue ratio gives an estimate of the expected waiting time of the contact. Note that this estimate assumes that service times are exponential, and no abandonment is allowed. If no candidate waiting queue is available, e.g., all waiting queues in the groupset have a queue ratio greater than the target queue ratio, the router checks the next agent groupset.

If there are no more groupset, the router performs the second phase as follows. Since no groupset contains a free agent or waiting queue with a small enough queue ratio, the router checks every authorized waiting queue, i.e., each queue i for which (k, i) < ∞, and selects the waiting queue with the smallest queue ratio. In this phase, the queue ratio is allowed to be greater than the target.

The queues the contact is sent to depend on two flags associated with this router: the copy and overflow modes. The copy mode determines if contacts can be queued to multiple agent groups. The overflow mode, which is used only when contacts can be added into multiple queues, can be set to transfer or promotion. In transfer mode, the contact moves from groupsets to groupsets. In promotion mode, a copy of the contact is left in every considered groupset.

More specifically, if queueing to multiple targets is disabled, the router always sends the contact to the queue with the smallest queue ratio among the considered candidates. In the first phase, these candidates are the queues in the current groupset with a queue ratio smaller than the target. In the second phase, this corresponds to all queues the contact is authorized in.

If contacts can be added to multiple queues, the overflow mode has the following effect. If candidates were found during the first phase, when checking agent groupset i(k, j), the contact is queued to all queues in that groupset when the overflow mode is transfer. However, if the overflow mode is promotion, the contact is also added to all queues in the preceding groupsets, i.e., groupsets i(k, j') for j' = 0,…, j. If the router reaches the second phase, the contact is always sent to the queue with the smallest queue ratio. In promotion mode, it is also queued to all other authorized waiting queues.

This router needs agent groups taking individual agents into account to select agents based on their longest idle times.

Field Summary

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
`QueueRatioOverflowRouter(int numGroups, double[][] ranksTG, double[] targetQueueRatio, boolean allowCopies, boolean overflowTransfer)` Constructs a new queue-ratio overflow router with ranks matrix `ranksTG`, `numGroups` agent groups, and target queue ratio for contact type k set to `targetQueueRatio[k]`.

Method Summary
`boolean` | `canServe(int i, int k)` Returns `true` if and only if some agents in group `i` are authorized to serve contacts of type `k` by this router.
`protected void` | `checkWaitingQueues(AgentGroup group)` This method is called when the agent group `group` contains no more online agents, i.e., `AgentGroup.getNumAgents()` returns 0.
`protected void` | `dequeued(DequeueEvent ev)` This method is called when a contact leaves a waiting queue, `ev` representing the corresponding dequeue event.
`String` | `getDescription()`
`double[][]` | `getRanksTG()` Returns the ranks matrix defining how contacts prefer agents, used for agent selection.
`double[]` | `getTargetQueueRatio()` Gets the target queue ratio for each contact type.
`WaitingQueueType` | `getWaitingQueueType()` Returns an indicator describing how the implemented routing policies organizes waiting queues.
`boolean` | `isAllowCopies()` Determines if contacts can be added to multiple queues.
`boolean` | `isOverflowTransfer()` Determines if the overflow mode is transfer.
`protected EndServiceEvent` | `selectAgent(Contact contact)` Begins the service of the contact `contact` by trying to assign it a free agent.
`protected DequeueEvent` | `selectContact(AgentGroup group, Agent agent)` Returns a dequeue event representing a queued contact to be served by the agent `agent` in agent group `group`.
`protected DequeueEvent` | `selectWaitingQueue(Contact contact)` Selects a waiting queue and puts the contact `contact` into it.
`void` | `setAllowCopies(boolean allowCopies)` Sets the allow-copies flag to `allowCopies`.
`void` | `setOverflowTransfer(boolean overflowTransfer)` Sets the overflow mode to `overflowTransfer`.
`void` | `setRanksTG(double[][] ranksTG)` Sets the ranks matrix defining how contacts prefer agents to `ranksTG`.
`void` | `setTargetQueueRatio(double[] targetQueueRatio)` Sets the target queue ratio for each contact type to `targetQueueRAtio`.
`String` | `toLongString()` Returns a string representation of detailed information about the router.

Methods inherited from class umontreal.iro.lecuyer.contactcenters.router.Router
`addExitedContactListener, agentReroutingEventsIterator, beginService, checkFreeAgents, clearExitedContactListeners, contactReroutingEventsIterator, endContact, endService, enqueued, exitBlocked, exitDequeued, exitServed, formatAgentGroups, formatWaitingQueues, getAgentGroup, getAgentGroupListener, getAgentGroups, getAgentReroutingEvents, getContactFactory, getContactReroutingEvents, getCurrentQueueSize, getDialers, getExitedContactListeners, getNeededWaitingQueueComparator, getNeededWaitingQueueStructure, getNumAgentGroups, getNumContactTypes, getNumWaitingQueues, getReroutingDelay, getReroutingDelay, getTotalQueueCapacity, getWaitingQueue, getWaitingQueueListener, getWaitingQueues, init, isKeepingReroutingEvents, mustClearWaitingQueue, needsDetailedAgentGroup, newContact, notifyBlocked, notifyDequeued, notifyServed, removeExitedContactListener, restore, save, selectAgent, 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

### QueueRatioOverflowRouter

    public QueueRatioOverflowRouter(int numGroups,
                                    double[][] ranksTG,
                                    double[] targetQueueRatio,
                                    boolean allowCopies,
                                    boolean overflowTransfer)

  Constructs a new queue-ratio overflow router with ranks matrix `ranksTG`, `numGroups` agent groups, and target queue ratio for contact type k set to `targetQueueRatio[k]`. The `allowCopies` flag determines if contacts can be added to multiple waiting queues, while the `overflowTransfer` flag determines if the transfer overflow mode is active. If this latter flag is `false`, overflow mode is set to promotion. The second flag has no effect if the first flag is `false`.

  Parameters:
    `numGroups` - the number of agent groups.
    `ranksTG` - the ranks matrix.
    `targetQueueRatio` - the target queue ratio for each contact type.
    `allowCopies` - the allow-copies flag.
    `overflowTransfer` - the overflow-transfer flag.
  Throws:
    `NullPointerException` - if any argument is `null`.
    `IllegalArgumentException` - if the length of `targetQueueRatio` does not correspond to the number of rows in the ranks matrix.

Method Detail

### getRanksTG

    public double[][] getRanksTG()

  Returns the ranks matrix defining how contacts prefer agents, used for agent selection.

  Returns:
    the ranks matrix defining how contacts prefer agents.

### setRanksTG

    public void setRanksTG(double[][] ranksTG)

  Sets the ranks matrix defining how contacts prefer agents to `ranksTG`.

  Parameters:
    `ranksTG` - the new agent selection ranks matrix.
  Throws:
    `NullPointerException` - if `ranksTG` is `null`.
    `IllegalArgumentException` - if `ranksTG` is not rectangular or has wrong dimensions.

### isAllowCopies

    public boolean isAllowCopies()

  Determines if contacts can be added to multiple queues.

  Returns:
    `true` if and only if contacts can be added to multiple queues.

### setAllowCopies

    public void setAllowCopies(boolean allowCopies)

  Sets the allow-copies flag to `allowCopies`.

  Parameters:
    `allowCopies` - the new value of the flag.
  See Also:
    `isAllowCopies()`

### isOverflowTransfer

    public boolean isOverflowTransfer()

  Determines if the overflow mode is transfer.

  Returns:
    `true` if the overflow mode is transfer.

### setOverflowTransfer

    public void setOverflowTransfer(boolean overflowTransfer)

  Sets the overflow mode to `overflowTransfer`.

  Parameters:
    `overflowTransfer` - the new overflow mode.
  See Also:
    `isOverflowTransfer()`

### getTargetQueueRatio

    public double[] getTargetQueueRatio()

  Gets the target queue ratio for each contact type.

  Returns:
    the target queue ratios.

### setTargetQueueRatio

    public void setTargetQueueRatio(double[] targetQueueRatio)

  Sets the target queue ratio for each contact type to `targetQueueRAtio`.

  Parameters:
    `targetQueueRatio` - the new target queue ratios.
  Throws:
    `IllegalArgumentException` - if the length of `targetQueueRatio` does not correspond to the number of rows in the ranks matrix.

### getWaitingQueueType

    public WaitingQueueType getWaitingQueueType()

  Description copied from class: `Router`
  Returns an indicator describing how the implemented routing policies organizes waiting queues. The supported modes of organization cover the most common cases only: waiting queues corresponding to contact types or agent groups. For any other modes, the `WaitingQueueType.GENERAL` must be used.

  By default, this method returns `WaitingQueueType.GENERAL`.

  Overrides:
    `getWaitingQueueType` in class `Router`
  Returns:
    the organization mode of waiting queues.

### checkWaitingQueues

    protected void checkWaitingQueues(AgentGroup group)

  Description copied from class: `Router`
  This method is called when the agent group `group` contains no more online agents, i.e., `AgentGroup.getNumAgents()` returns 0. It must check each waiting queue accessible for agents in this group to determine if they need to be cleared. A queue is cleared if no agent, whether free or busy, is available to serve any contact in it.

  Specified by:
    `checkWaitingQueues` in class `Router`
  Parameters:
    `group` - the agent group with no more agents.

### canServe

    public boolean canServe(int i,
                            int k)

  Description copied from class: `Router`
  Returns `true` if and only if some agents in group `i` are authorized to serve contacts of type `k` by this router.

  Specified by:
    `canServe` in class `Router`
  Parameters:
    `i` - the agent group index.
    `k` - the contact type index.
  Returns:
    determines if contacts can be served.

### selectAgent

    protected EndServiceEvent selectAgent(Contact contact)

  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.

  Specified by:
    `selectAgent` in class `Router`
  Parameters:
    `contact` - 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.

### selectWaitingQueue

    protected DequeueEvent selectWaitingQueue(Contact contact)

  Description copied from class: `Router`
  Selects a waiting queue and puts the contact `contact` into it. Returns the dequeue event if the contact could be queued, or `null` otherwise.

  Specified by:
    `selectWaitingQueue` in class `Router`
  Parameters:
    `contact` - the contact being queued.
  Returns:
    the dequeue event representing the queued contact, or `null` if the contact could not be queued.

### dequeued

    protected void dequeued(DequeueEvent ev)

  Description copied from class: `Router`
  This method is called when a contact leaves a waiting queue, `ev` representing the corresponding dequeue event. By default, for any effective dequeue type other than 0, this calls `Router.exitDequeued(DequeueEvent)`. This method should not notify an exiting contact for a 0 dequeue type since it is reserved for queued and served contacts.

  Overrides:
    `dequeued` in class `Router`
  Parameters:
    `ev` - the dequeue event.

### selectContact

    protected DequeueEvent selectContact(AgentGroup group,
                                         Agent agent)

  Description copied from class: `Router`
  Returns a dequeue event representing a queued contact to be served by the agent `agent` in agent group `group`. If `agent` is `null`, the method must return a contact that can be served by any agent in the group. If no contact is available, this method returns `null`. The selected contacts come from waiting queues attached to the router. Before the selected contact is returned, it must be removed from its queue with dequeue type `Router.DEQUEUETYPE_BEGINSERVICE`, e.g., by using `queue.removeFirst (DEQUEUETYPE_BEGINSERVICE)`, or `queue.remove (ev, DEQUEUETYPE_BEGINSERVICE)`, etc.

  Generally, it is sufficient to override this method instead of `Router.checkFreeAgents(AgentGroup,Agent)`. One can override `Router.checkFreeAgents(AgentGroup,Agent)` to improve efficiency when looking for contacts in the same waiting queue. This method is not abstract and returns `null` by default in order to allow `Router.checkFreeAgents(AgentGroup,Agent)` to be overridden without implementing this method.

  Overrides:
    `selectContact` in class `Router`
  Parameters:
    `group` - the affected agent group.
    `agent` - the agent having ended its service.
  Returns:
    the dequeue event representing the contact being selected.

### getDescription

    public String getDescription()

  Overrides:
    `getDescription` in class `Router`

### 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 `Router`
  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.