
\documentclass[11pt]{article}
\setlength{\textwidth}{5.5in}
%\setlength{\evensidemargin}{-0.5in}
\usepackage{TRmydraft} % title page report
\usepackage{wmff} % algorithm
\usepackage{yprob} % algorithm listing, code, report exercises

\usepackage{graphicx}
\usepackage{float}
\usepackage{url}

\pagestyle{myheadings}
\markright{Models with Priorities\hfill}

\begin{document}

\reptitle{\bf Multi-Server Models with Priorities}
\author{Dr. Jos\'e M. Garrido}

%\date{February, 2009}

\subtitle{\bf }
\subsubtitle{\bf}


\authoraffil{Department of Computer Science} 
 
%
%\halftitlepage
%

\titlepage

\mdraft
%\maketitle
%\newpage
%\tableofcontents
%\newpage





\section{Introduction}

Models with multiple types of customers are also known as models of multi-class\index{multi-class} systems. The queuing models described in previous chapters had only one customer type, so all customers were treated alike. In models with multiple types of customers, each customer type has its own mean arrival rate, mean service period, and other workload parameters. Usually, each customer type is given a priority. 

A priority\index{priority} is used by the server object to select a customer for service. The server normally selects the customer with the highest priority. The priority affects the order of removal from the queue --- the queue discipline\index{queue discipline}. In previous models, there was only one type of customer and the simple discipline first-in-first-out (FIFO\index{FIFO}) was always implied.

There are many applications for queuing models with priorities. Some examples are: 
\begin{itemize}
  \item Computer communication networks, in which data may be routed in different ways, according to the message priorities
  \item Medical attention in a hospital, in which patients are attended according to the degree of the emergency
  \item Operating systems, in which  processes are serviced according to the process' priority

\end{itemize}

All simulation models with priorities include at least one priority queue for arriving customers. A priority queue\index{priority queue} is a queue that stores customers in order of priority and uses FIFO ordering for customers with the same priority. Customers with the highest priority are always at the head of the queue.

\section{Priorities With Single-Server Models}

Customer objects of different types arrive and join a priority queue. The priority is assigned by the arrivals object. Since customer objects of the various types have different mean inter-arrival periods and different mean service periods, for each type of customers a different arrivals object is created. Each arrivals object creates customer objects of the same type. Figure~\ref{fig:pqueue} shows the general structure of a model of a single-server system with priorities. 

\begin{figure}
\vspace{.1in}
\center
\includegraphics[width=2.75in]{pqueue.png}
%\centereps{3.90in}{1.05in}{pqueue.eps}
\caption{Model of a simple system with priorities}
\label{fig:pqueue}
%\vskip\baselineskip
\end{figure}


\subsection{Process Priorities}
 
 The priority of a process is an integer value and represents its relative importance in relation to other processes. In OOSimL, the highest priority value is 0. To access the priority of a process, the statement {\bf assign priority} is used. The general structure of the statement follows.

\vspace{0.1in}
%\begin{quote}
{\tt %\footnotesize
\begin{algorithm}
{\bf assign priority} [{\bf of} $\langle$ ref\_variable $\rangle$]{\bf to} $\langle$ prio\_var $\rangle$   
\end{algorithm}
}
%\end{quote}
\vspace{0.1in}

For example, the following lines of code gets the priority of process referenced by {\em machine}, assigns it to variable {\em mach\_prio}, and gets the priority of the current process and assigns it to variable {\em myprio}. 
 

%\begin{quote}
{\tt \small
\begin{verbatim}
define mach_prio of type integer   // priority of machine
define myprio of type integer      // priority of self
define machine of class Server     // reference to server object
...  
assign priority of machine to mach_prio
assign priority to myprio         // get priority of self
\end{verbatim}
}
%\end{quote}
 
To set the priority of a process, the statement {\bf fix priority} is used. The general structure of the statement follows.

\vspace{0.1in}
%\begin{quote}
{\tt %\footnotesize
\begin{algorithm}
{\bf fix priority} $\langle$ prio\_var $\rangle$ [{\bf to} $\langle$ ref\_variable $\rangle$ ]
\end{algorithm}
}
%\end{quote}
\vspace{0.1in}

For example, the following lines of code set the priority 5 to the current process, then it sets priority 1 to another process referenced by {\em machine}. 

%\begin{quote}
{\tt \small
\begin{verbatim} 
fix priority 5
fix priority 1 to machine
\end{verbatim}
}
%\end{quote}

The following lines of code increase the priority of a process referenced by {\em machine} by 1. The code defines an integer variable {\em m\_priority\/} to store the priority of the process.

%\begin{quote}
{\tt \small
\begin{verbatim}
define m_priority of type integer
...
assign priority of machine to m_priority   
increment m_priority           // increment current priority
fix priority m_priority to machine  // set new priority
\end{verbatim}
}
%\end{quote}

\subsection{Priority Queues}

Priority queues allow the simulation model to retrieve or remove processes from the queue, based on the priority of the processes. As such, priority queues do not behave as FIFO queues. A priority queue is an object of class {\em Pqueue}. The OOSimL statements in this section are used to define and manipulate priority queues. 

\subsubsection{Create Objects of Class Pqueue}

The constructor for creating a priority queue requires the name of the queue, the optional number of different priorities, and the queue size for all priorities, which is also optional. If the second argument is not included, the number of priorities is assigned to 300 (default). If the third argument is not included, the assigned default queue size is 1,000 for every priority. 

The following lines of code declare and create the priority queue with reference name {\em cust\_queue}, with queue name ``Customer Queue'', using 8 different priorities, and size (capacity) of 25 customers for every priority.
 
%\begin{quote}
{\tt \small
\begin{verbatim}
define cust_queue of class Pqueue     // declare priority queue
...
// create priority queue
create cust_queue of class Pqueue using "Customer Queue", 8, 25
\end{verbatim}
}
%\end{quote}

\subsubsection{Priority Queue Length}

This {\bf assign} statement gets the current size (total number of processes) in the specified priority queue. An integer value that corresponds to the current length of the queue is assigned to the specified integer variable. The general structure of the statement follows. 

\vspace{0.1in}
%\begin{quote}
{\tt %\footnotesize
\begin{algorithm}
{\bf assign length of} $\langle$ queue\_ref $\rangle${\bf to} $\langle$ variable $\rangle$
\end{algorithm}
}
%\end{quote}
\vspace{0.1in}

For example, the following lines of code get the current length of priority queue {\em cust\_queue} (defined above) and assign this value to variable {\em mqlength}.
 
%\begin{quote}
{\tt \small
\begin{verbatim}
define mqlength of type integer
...
assign length of cust_queue to mqlength   // get queue length
\end{verbatim}
}
%\end{quote}
 
\subsubsection{Check Priority Queue Empty}

In a similar manner as for simple queues, the {\bf if} statement with the {\bf empty} condition checks if a queue is empty. 

For example, the following lines of code check if queue object {\em cust\_queue} (defined above) is empty. The current process suspends itself if the queue is empty, otherwise, it proceeds to remove a process from the queue.

%\begin{quote}
{\tt \small
\begin{verbatim}
  if cust_queue is empty then
     // if queue is empty, suspend here
     suspend self
     ...
  else
     // dequeue process
     ...
  endif
\end{verbatim}
}
%\end{quote} 
 
\subsubsection{Queue Length with Priority} 

This {\bf assign} statement gets the number of processes of a specified priority in a priority queue, and assigns it to a specified (integer) variable. 


\vspace{0.1in}
%\begin{quote}
{\tt %\footnotesize
\begin{algorithm}
{\bf assign length of} $\langle$ queue\_ref $\rangle${\bf with priority} $\langle$ prio\_var $\rangle$
\ \ \ \ \ \ \ \ {\bf to} $\langle$ variable $\rangle$
\end{algorithm}
}
%\end{quote}
\vspace{0.1in}

For example, the following line of code gets the current number of processes in the priority queue {\em cust\_queue}, with priority {\em l\_prio}, and assigns this number to variable {\em num\_proc}.
 
%\begin{quote}
{\tt \small
\begin{verbatim}
assign length of cust_queue with priority l_prio to num_proc 
\end{verbatim}
}
%\end{quote}
 
\subsubsection{Insert Process Into Priority Queue}
 
The {\bf insert} statement inserts the specified process into the priority queue. The size of the queue is increased by one. The priority of the process is automatically used to insert the process. The general structure of the statement follows.

\vspace{0.1in}
%\begin{quote}
{\tt \small
\begin{algorithm}
{\bf insert} $\langle$ ref\_variable $\rangle${\bf into} $\langle$ queue\_ref $\rangle$ 
% \ \ \ \ {\bf with priority} $\langle$ prio\_var $\rangle$
{\bf insert self into} $\langle$ queue\_ref $\rangle$
% {\bf with priority} $\langle$ prio\_var $\rangle$
{\bf enqueue} $\langle$ ref\_variable $\rangle${\bf into} $\langle$ queue\_ref $\rangle$
% \ \ \ \ {\bf with priority} $\langle$ prio\_var $\rangle$
{\bf enqueue self into}$\langle$ queue\_ref $\rangle$
% {\bf with priority} $\langle$ prio\_var $\rangle$
\end{algorithm}
}
%\end{quote}
\vspace{0.1in}

The following lines of code insert (enqueue) process {\em cust\_obj} into priority queue {\em pcust\_queue}.
 
%\begin{quote}
{\tt \small
\begin{verbatim}
 define cust_prio = 3 of type integer
 define cust_obj of class Customer  // reference customer
 ...
 // enqueue customer process
 insert cust_obj into pcust_queue 
\end{verbatim}
}
%\end{quote}
 
\subsubsection{Remove Process with Specified Priority}

This statement removes (dequeues) a process of a specified priority,  from a priority queue. After removal, the size of the queue is reduced by one, as a result of this operation. The general structure of the statement is as follows:

\vspace{0.1in}
%\begin{quote}
{\tt \small
\begin{algorithm}
{\bf remove} [{\bf object}] $\langle$ ref\_var $\rangle${\bf of class} $\langle$ cl\_name $\rangle$
\ \ {\bf from} [{\bf queue}] $\langle$ queue\_ref $\rangle${\bf with priority} $\langle$ prio\_variable $\rangle$
{\bf dequeue} [{\bf object}] $\langle$ ref\_var $\rangle${\bf of class} $\langle$ cl\_name $\rangle$
\ \ {\bf from} [{\bf queue}] $\langle$ queue\_ref $\rangle${\bf with priority} $\langle$ prio\_variable $\rangle$
\end{algorithm}
}
%\end{quote}
\vspace{0.1in}

For example, the following lines of code remove (dequeue) a customer process from queue {\em cust\_queue} and assigns a reference {\em cust\_obj} to it, given priority {\em cust\_prio}. 
 
%\begin{quote}
{\tt \small
\begin{verbatim}
define cust_prio of type integer
...
remove object cust_obj of class Customer from queue cust_queue 
    with priority cust_prio
\end{verbatim}
}
%\end{quote}
 
The reference to class Customer is necessary to specify the type of process dequeued. If no priority is specified, the statement removes the highest priority process from the priority queue.


\section{Car Wash Model with Priorities}

The following process descriptions are related to the model of the Carwash system with priorities. The system has vehicles (cars) of various types: small cars, luxury cars, sport utilities, etc. Each type of vehicle usually has a different mean arrival rate and a different mean service period. 




\subsection{Description of the Server Object}

A description of the server  assumes that the arrival queue for car objects uses priority ordering. The server always takes the car with the highest priority from the car queue. The following sequence of activities defines the behavior of the server object:

\begin{enumerate}

 \item While the car queue is not empty, execute the following 
       activities: 
  \begin{enumerate}
      \item    Remove the car object at the head of the queue.
      \item    Perform the service of the car object.
      \item    Reactivate the car object so it will continue its own  activities.
  \end{enumerate}
  \item Wait (in the idle state) until the next car object arrives, then start from step 1.
\end{enumerate}

As with previous models, the servicing of a car object takes some finite time interval known as the {\em service interval}\index{service interval} of the car object. The simulation clock\index{simulation clock} is advanced by an interval that is the duration of the service activity.

When the car queue is empty, the server object suspends itself and changes to the idle\index{idle state} state. The server object will be reactivated\index{reactivate} by a new car object on arrival; and the queue becomes non-empty. 

\subsection{The Arrivals Objects}

In this model there are several types of customers, each one with a different priority. There are several Arrivals objects created, one for each car priority. Each Arrivals object generates the customers of that priority. The following sequence of activities defines the behavior of an Arrivals object.
\begin{enumerate}
\item
Repeat until close arrivals or until simulation period expires:
\begin{enumerate}
  \item Generate a random inter-arrival period.
  \item Wait until the clock advances by an amount equal to the inter-arrival period.
  \item Generate a random service period.
  \item Create a car object with its random service period, and its priority.
\end{enumerate}
\item
Terminate
\end{enumerate}

Every Arrivals object generates  two random numbers\index{random numbers}:
\begin{itemize}
  \item The generation of an inter-arrival interval for an arrival event
  \item The generation of a service interval\index{service interval} 
\end{itemize}



These two random numbers are drawn from two different probability distributions\index{distributions}. The decision of which probability distribution to use results from statistical analysis based on observations carried out previously on the real system or a similar system.

The Arrivals object creates a sequence of car objects of a specified priority. One car object is created after every inter-arrival time interval. Every car object has a different service interval.

\subsection{The Car Objects}

As mentioned previously, the car objects are grouped into categories (or types), and a different priority is assigned to each group by the corresponding arrivals object. There are several car objects created by each arrivals object. 

Each car object includes its priority (type) in addition to its service period, as part of its relevant attributes. A car object joins the car queue according to its priority. The following sequence of activities describes the behavior of each car object:

\begin{enumerate} 
  \item Join the car queue if it is not full 
  \item Reactivate the server object if the server is idle 
  \item Suspend\index{suspend} (itself), go into the idle state to wait for service
  \item After the service is completed, continue with own activities
  \item Terminate\index{terminate}
  \item If the queue is full, terminate (i.e., the car object is rejected)
\end{enumerate}


After a car object is created, it enters the car queue\index{queue} by priority.  If the server is idle\index{idle}, the car object will reactivate\index{reactivate} the server. The car object then suspends\index{suspend} itself and waits for service. If the queue is full, the arriving car object will terminate\index{terminate} immediately.

The server object removes the car object from the head of the queue and starts its service. 

\subsection{Outputs of a Simulation Run}

The summary statistics output of a simulation run of the model of Carwash system with priorities, appears in Listing~\ref{chap:prio}.1. This output also shows the values of the following performance\index{performance} measures for every priority:
\begin{itemize}
  \item Throughput, i.e., the numbers of cars serviced;
  \item Average wait period for the cars.
\end{itemize}

\newpage

\vspace{0.1in}
\centerline{Listing~\ref{chap:prio}.1 \ Summary statistics of a simulation run.}
\vspace{0.05in}
%\nopagebreak
\hrule
%\nopagebreak
\vspace{0.1in}
%\begin{minipage}{4.5in}
{\tt \small
\begin{verbatim}
OOSimL model: Model of Carwash System with Priorities
Simulation date: date: 9/17/2015 time: 10:14
--------------------STATISTICS REPORT-------------------------
--------------------------------------------------------------
Priority queue: Cust Queue
Capacity of queue: 200
Number of observations: 586
Max number of objects in queue: 146
Average number of objects in queue: 69
Average time in queue: 1.7935666936304733
Queue utilization: 0.8617723660473778
Queue usage: 0.4789908220792021
--------------------------------------------------------------
Random generator: Inter-arrival type 4
Distribution: Negative exponential
Number of obs: 29
Seed: 55
Mean: 25.2
--------------------------------------------------------------
Random generator: Inter-arrival type 3
Distribution: Negative exponential
Number of obs: 122
Seed: 43
Mean: 5.2
--------------------------------------------------------------
Random generator: Inter-arrival type 2
Distribution: Negative exponential
Number of obs: 35
Seed: 31
Mean: 14.2
--------------------------------------------------------------
Random generator: Inter-arrival type 1
Distribution: Negative exponential
Number of obs: 75
Seed: 19
Mean: 8.5
--------------------------------------------------------------
Random generator: Inter-arrival type 0
Distribution: Negative exponential
Number of obs: 120
Seed: 7
Mean: 5.2
--------------------------------------------------------------
Random generator: Service Period type 4
Distribution: Normal
Number of obs: 29
Seed: 61
Mean: 2.2
Standard deviation: 0.0
--------------------------------------------------------------
Random generator: Service Period type 3
Distribution: Normal
Number of obs: 122
Seed: 49
Mean: 3.5
Standard deviation: 0.85
--------------------------------------------------------------
Random generator: Service Period type 2
Distribution: Normal
Number of obs: 35
Seed: 37
Mean: 3.0
Standard deviation: 0.85
--------------------------------------------------------------
Random generator: Service Period type 1
Distribution: Normal
Number of obs: 75
Seed: 25
Mean: 2.6
Standard deviation: 0.85
--------------------------------------------------------------
Random generator: Service Period type 0
Distribution: Normal
Number of obs: 120
Seed: 13
Mean: 4.6
Standard deviation: 0.85
-------------------------------------------------------------- 
 
End Simulation of Model of Carwash System with Priorities
  date: 9/17/2015 time: 10:14
 
Total cars of type 0 serviced : 120
Car type 0 average wait period: 10.587397344561573
Total cars of type 1 serviced : 68
Car type 1 average wait period: 235.79209727808004
Total cars of type 2 serviced : 35
Car type 2 average wait period: 442.1166150740475
Total cars of type 3 serviced : 41
Car type 3 average wait period: 750.9129750062083
Total cars of type 4 serviced : 29
Car type 4 average wait period: 701.8389044542504

Total number of cars serviced: 293
Car average wait period: 286.414
Average period car spends in the shop: 289.953
Machine utilization: 0.994
\end{verbatim}
}
\hrule
\vspace{0.1in}

The trace of the simulation run shows the sequence of events that occurred during the simulation run and appears in Listing~\ref{chap:prio}.2. 

\vspace{0.1in}
\centerline{Listing~\ref{chap:prio}.2 \ Trace of a simulation run of the model with priorities.}
\vspace{0.05in}
%\nopagebreak
\hrule
%\nopagebreak
\vspace{0.1in}
%\begin{minipage}{4.5in}
{\tt \small
\begin{verbatim}
OOSimL model: Model of Carwash System with Priorities
Simulation date: 9/17/2015 time: 10:15
------------------------- TRACE ------------------------------
Time: 0 Car Wash System with priorities holds for 1200
Time: 0 Arrivals0 holds for 6.822
Time: 0 Arrivals1 holds for 11.208
Time: 0 Arrivals2 holds for 18.667
Time: 0 Arrivals3 holds for 6.76
Time: 0 Arrivals4 holds for 32.927
Time: 0 Wash_machine deactivated
Time: 6.76 Arrivals3 holds for 9.962
Time: 6.76 Car1 priority 3 arrives
Time: 6.76 Car1 enqueued into Cust Queue
Time: 6.76 Wash_machine to reactivate
Time: 6.76 Car1 deactivated
Time: 6.76 Entity: Car1 dequeued from Cust Queue
Time: 6.76 Wash_machine begins service of Car1 type 3
Time: 6.76 Wash_machine holds for 3.812
Time: 6.822 Arrivals0 holds for 7.191
Time: 6.822 Car2 priority 0 arrives
Time: 6.822 Car2 enqueued into Cust Queue
Time: 6.822 Car2 deactivated
Time: 10.572 Wash_machine completed service of Car1
Time: 10.572 Car1 to reactivate
Time: 10.572 Entity: Car2 dequeued from Cust Queue
Time: 10.572 Wash_machine begins service of Car2 type 0
Time: 10.572 Wash_machine holds for 6.03
Time: 10.572 Car1 terminating
Time: 11.208 Arrivals1 holds for 3.771
Time: 11.208 Car3 priority 1 arrives
Time: 11.208 Car3 enqueued into Cust Queue
Time: 11.208 Car3 deactivated
Time: 14.014 Arrivals0 holds for 2.227
Time: 14.014 Car4 priority 0 arrives
Time: 14.014 Car4 enqueued into Cust Queue
. . .
Time: 1037.185 Entity: Car366 dequeued from Cust Queue
Time: 1037.185 Wash_machine begins service of Car366 type 4
Time: 1037.185 Wash_machine holds for 2.2
Time: 1037.185 Car348 terminating
Time: 1039.385 Wash_machine completed service of Car366
Time: 1039.385 Car366 to reactivate
Time: 1039.385 Entity: Car374 dequeued from Cust Queue
Time: 1039.385 Wash_machine begins service of Car374 type 4
Time: 1039.385 Wash_machine holds for 2.2
Time: 1039.385 Car366 terminating
Time: 1041.585 Wash_machine completed service of Car374
Time: 1041.585 Car374 to reactivate
Time: 1041.585 Entity: Car380 dequeued from Cust Queue
Time: 1041.585 Wash_machine begins service of Car380 type 4
Time: 1041.585 Wash_machine holds for 2.2
Time: 1041.585 Car374 terminating
Time: 1043.785 Wash_machine completed service of Car380
Time: 1043.785 Car380 to reactivate
Time: 1043.785 Wash_machine deactivated
Time: 1043.785 Car380 terminating
-------------------------------------------------------------- 
 
End Simulation of Model of Carwash System with Priorities
 date: 9/17/2015 time: 8:21
\end{verbatim}
}
\hrule
\vspace{0.1in}

\subsection{Implementation Of the Carwash Model}

The class definitions of the model of the Carwash System with priorities are very similar to the model without priorities. Listing~\ref{chap:prio}.3 shows the OOSimL implementation of the main class, {\em PCarwash}. 

The critical parts of class {\em PCarwash\/} are:
\begin{itemize}
  \item The car queue, {\em car\_queue}, is a priority queue. It is an object of class {\em Pqueue} 
  \item Arrays are defined and created for the calculations of the performance measures for each car priority
  \item Several objects of class {\em Arrivals} are created, one for each car priority

\end{itemize}

%\vfill
%\pagebreak

\vspace{0.1in}
%\renewcommand{\baselinestretch}{1}
%\def\baselinestretch{1}
%{\samepage
\centerline{Listing~\ref{chap:prio}.3 \ OOSimL Implementation of class PCarwash.}
\vspace{0.05in}
%\nopagebreak
\hrule
%\nopagebreak
%\vspace{0.1in}
%\begin{minipage}{4.5in}
{\tt \small
\begin{verbatim}
  use all java.io
  use java.text.DecimalFormat
  use all psimjava
  
  description
  A single-server model of a Carwash system with priorities.
  Arriving cars (customers) join a priority queue to wait for 
  service. The server is a Carwash machine that services one
  car at a time. Service consists of a complete external wash
  of a car.
  
  OOSimL model J. Garrido, Jan 10, 2008
  Main class: PCarwash
  
  This class sets up simulation parameters and creates the
  relevant objects.
  There are four classes of active objects: PCarwash, 
     Server, Arrivals, and Car.
  There is one passive object, the car_queue of class Pqueue.
  The arrivals objects create the various car objects of a 
  given type that arrive at random intervals. 
  Every type of car is given a priority and has its own 
  workload. Random variables: inter-arrival period of a 
  negative exponential distribution and service period of 
  a Normal distribution.
   
  File: PCarwash.osl
  */
  public class PCarwash as process is
     private
     object references
        //
        // files for reporting
        define  static statf of class PrintWriter  
        define  static tracef of class PrintWriter 
     public
     constants
        // number of car types
        define static K = 5 of type integer 
     variables
        define static gui_flag of type boolean
        // input car queue size
        define static totalQSize = 40 of type integer
        // 
        // simulation period   
        define static simPeriod = 1200.0 of type double 
        //
        // time to close arrival of cars
        define static close_arrival = 600.5 of type double 
        //
        // Workload parameters for every type of customer
        //
        // mean car inter-arrival interval
        define static MeanInterarrival array [] 
                  of type double 
        //
        // mean car service interval 
        define static MeanServiceDur array [] of type double  
        //
        // standard deviation of service interval
        define static StdServiceDur array [] of type double
        //
        // Accumulative variables for every customer type
        //
        // accumulated customer service time
        define static custServiceTime array [] of type double  
        // accumulated customer sojourn time
        define static custSojournTime array [] of type double
        // accumulated car waiting time  
        define static custWaitTime array [] of type double  
        //         
        // current number of customers serviced
        define static num_serviced array [] of type integer   
        // current number of cars that arrived 
        define static num_arrived array [] of type integer    
        // current number of cars rejected
        define static num_rejected array [] of type integer  
        // 
        // Totals
        // accum server idle time
        define static accum_idle = 0.0 of type double  
        // accumulated waiting time
        define static totalWait = 0.0 of type double
        define static totalSojourn = 0.0 of type double
        // total number of cars arrived
        define static num_car of type integer
        // total number of cars serviced
        define static carServiced of type integer         
     object references  
        //
        // Simulation model essential objects
        define static sim of class Simulation
        //
        // Queues for the model
        // queue for arrived waiting cars
        define static car_queue of class Pqueue       
        // 
        // Classes for the active objects of the model
        define static wash_machine of class Server
        //
        define static genCust array [] of class Arrivals  
        define static shop of class PCarwash 
        define model of class SimModel
        //
      // constructor
      function initializer parameters ss of class String is  
      begin
            call super using ss
      endfun initializer
      //
      function main is
      variables
          define j of type integer
      begin  
           set gui_flag = false    
           create MeanInterarrival array [K] of type double
           create MeanServiceDur array [K] of type double
           create StdServiceDur array [K] of type double
           create custServiceTime array [K] of type double
           create custSojournTime array [K] of type double
           create custWaitTime array [K] of type double
           create num_serviced array [K] of type integer
           create num_arrived array [K] of type integer
           create num_rejected array [K] of type integer 
           //                     
           //      highest priority is 0
           set MeanInterarrival[0] = 5.2 
           set MeanServiceDur[0] = 4.6 
           set StdServiceDur[0] = 0.85
           set MeanInterarrival[1] = 8.5 
           set MeanServiceDur[1] = 2.6 
           set StdServiceDur[1] = 0.85
           set MeanInterarrival[2] = 14.2 
           set MeanServiceDur[2] = 3.0 
           set StdServiceDur[2] = 0.85
           set MeanInterarrival[3] = 5.2 
           set MeanServiceDur[3] = 3.5
           set StdServiceDur[3] = 0.85
           set MeanInterarrival[4] = 25.2 
           set MeanServiceDur[4] = 2.2 
           set StdServiceDur[0] = 0.85
           //
           for j = 0 to K - 1 do    
               set custServiceTime[j] = 0.0 
               set custSojournTime[j] = 0.0 
               set custWaitTime[j] = 0.0 
               set num_serviced[j] = 0 
               set num_arrived[j] = 0 
               set num_rejected[j] = 0 
           endfor
          //
          // set-up simulation with an object 
          //        of class simulation
          simulation title 
             "Model of Carwash System with Priorities"
          // setup files for reporting
          trace file "pcarwtrace.txt"
          statistics file "pcarwstatf.txt"
          //
          // create queues (passive objects)
          create car_queue of class Pqueue using 
               "Cust Queue", K, totalQSize
          //
          // Create and start the main active objects of 
          //   the model
          create shop of class PCarwash using 
               "Car Wash System with Priorities"
          start object shop
      endfun main
      //
      description
         This function is called by the class object with 
         interactive I/O
         */                
      function pbegin parameters sm of class SimModel is
        variables
           define jin of type integer
           define din of type double
           define j of type integer
        begin  
           set gui_flag = true       
           create MeanInterarrival array [K] of type double
           create MeanServiceDur array [K] of type double
           create StdServiceDur array [K] of type double
           create custServiceTime array [K] of type double
           create custSojournTime array [K] of type double
           create custWaitTime array [K] of type double
           create num_serviced array [K] of type integer
           create num_arrived array [K] of type integer
           create num_rejected array [K] of type integer 
           //                     
           //      highest priority is 0
           set MeanInterarrival[0] = 5.2 
           set MeanServiceDur[0] = 4.6 
           set StdServiceDur[0] = 0.85
           set MeanInterarrival[1] = 8.5 
           set MeanServiceDur[1] = 2.6 
           set StdServiceDur[1] = 0.85
           set MeanInterarrival[2] = 14.2 
           set MeanServiceDur[2] = 3.0 
           set StdServiceDur[2] = 0.85
           set MeanInterarrival[3] = 5.2 
           set MeanServiceDur[3] = 3.5
           set StdServiceDur[3] = 0.85
           set MeanInterarrival[4] = 25.2 
           set MeanServiceDur[4] = 2.2 
           set StdServiceDur[0] = 0.85
           //
           for j = 0 to K - 1 do    
               set custServiceTime[j] = 0.0 
               set custSojournTime[j] = 0.0 
               set custWaitTime[j] = 0.0 
               set num_serviced[j] = 0 
               set num_arrived[j] = 0 
               set num_rejected[j] = 0 
           endfor
           //  
           set model = sm
           call println of model using 
               "Model of Carwash System with Priorities"
           // call model.println using 
           //  "Input workload parameters for Car Wash Model"
           // Input parameters
           call model.readInt using "Enter queue size (40): " 
               return to jin
           if jin > 0 then
              set totalQSize = jin
           endif
           //
           set din = model.readDouble
                   ("Enter simulation period (1200.0): ")
           if din > 0.0 then
              set simPeriod = din
           endif
           //
           call model.readDouble using 
                "Enter close time (600.5): " 
                return value to din
           if din > 0.0 then
              set close_arrival = din
           endif
           //   
           //
           for j = 0 to K - 1 do 
             call model.readDouble using "Car type " concat j 
                 concat " Mean inter-arrival period (" 
                 concat MeanInterarrival[j] concat "): "
                 return value to din
             if din > 0.0 then
                set MeanInterarrival[j] = din
             endif
             //
             call model.readDouble using "Car type " concat j 
                   concat " Mean service period (" 
                   concat MeanServiceDur[j] concat "): " 
			       return to din
             if din > 0.0 then
                set MeanServiceDur[j] = din
             endif
             //
             call model.readDouble using "Car type " 
                 concat j concat " Service time std (" 
                 concat StdServiceDur[j] concat ": " 
			          return value to din
             if din > 0.0 then
                set StdServiceDur[j] = din
             endif
           endfor
           //
           // set-up simulation
           simulation title 
               "Model of Carwash System with Priorities"
           //
           // Set up report files
           trace file "pcarwtrace.txt"
           statistics file "pcarwstatf.txt"
           //
           // Create  passive objects: queues
           // priority queue with K priorities and 
           // totalQSize per priority
           create car_queue of class Pqueue using "CustQ", K, 
                totalQSize
           //
           // start main active object in model
           start self
      endfun pbegin
      //
      //
      method Main_body is
      variables
          define pname of type string
          define machutil of type double
          //
          // formatting strings
          define fmtout1 of type string
          define fmtout2 of type string
          define fmtout3 of type string
          define dispouta of type string
          define dispoutb of type string
          define j of type integer
          //
      object references
          define dfmt of class DecimalFormat
      begin
          create genCust array [K] of class Arrivals
          //
          access statistics file
          //
          // create the other active objects of the model
          create wash_machine of class Server 
                 using "Wash_machine"      
          set j = 0
          for j = 0 to K - 1 do    
              create genCust[j] of class Arrivals 
                 using "Arrivals"+j, j, MeanInterarrival[j], 
                    MeanServiceDur[j], StdServiceDur[j]
              start object genCust[j]
          endfor
          //
          start object wash_machine
          //
          // display "Workload - car mean inter-arrival: ", 
          //      MeanInterarrival, " mean service: ", 
          //      MeanServiceDur
          //
          // starting simulation
          start simulation with simPeriod
          //
          for j = 0 to K-1 do
             display "Total cars of type ", j, 
                " serviced : ", num_serviced[j]
             statwrite "Total cars of type ", j, 
                " serviced : ", num_serviced[j] 
             if num_serviced[j] > 0
             then
                 statwrite "Car type ", j, 
                   " average wait period: ",
                   custWaitTime[j] / num_serviced[j]
                 display "Car type ", j, 
                   " average wait period: ",
                   custWaitTime[j] / num_serviced[j]
             endif
          endfor
          //
          // set formatting round output to 3 dec places
          create dfmt of class DecimalFormat using "0.###"
          //
          statwrite " "
          display "Total number of cars serviced: ",
               carServiced
          statwrite "Total number of cars serviced: ", 
               carServiced                     
          if carServiced > 0 
          then
            set fmtout1 = call dfmt.format using 
                 totalWait/carServiced
            display "Car average wait period: ", fmtout1                     
            statwrite "Total Car average wait period: ",
                 fmtout1
            //
            set fmtout2 = call dfmt.format using 
                 totalSojourn/carServiced         
            display 
                 "Average period car spends in the shop: ", 
                 fmtout2
            statwrite 
                 "Average period car spends in the shop: ",
                 fmtout2
          endif
          //
          // machine utilization
          set machutil = (simPeriod - accum_idle)/simPeriod
          set fmtout3 = call dfmt.format using machutil
          //
          statwrite "Machine utilization: ", fmtout3
          display "Machine utilization: ", fmtout3
          //
          set dispouta = "Cars serviced: " concat 
                     carServiced concat "\n" concat
                     "Avg wait: " concat 
                     dfmt.format(totalWait/carServiced) 
                     concat "\n" 
          set dispoutb = dispouta concat
                     "Mach util: " concat
                     dfmt.format
                     ((simPeriod-accum_idle)/simPeriod) 
                     concat "\n" concat
                     "Avg time in shop: " concat
                     dfmt.format(totalSojourn/carServiced)
          if gui_flag equal true then
             call model.println using dispoutb
          endif
          exit     
      endmethod Main_body
  endclass PCarwash
\end{verbatim}
}
\hrule\
\vspace{0.1in}

The OOSimL source files for the implementation of this model are stored in files: {\tt PCarwash.osl}, {\tt Arrivals.osl}, {\tt Server.osl}, and {\tt Car.osl}. These files are all contained in the archive file {\tt pcarwash.jar}.

\section{Multi-Server Models with Priorities}

The same modifications to the single-server model without priorities\index{priorities} that were described in the previous sections, are carried out for the multi-server model without priorities to develop the multi-server model with priorities. The complete multi-server model with priorities is left as an exercise.

\begin{figure}
\vspace{.1in}
\center
\includegraphics[width=2.75in]{mserverp.png}
%\centereps{3.5in}{2.92in}{mserverp.eps}
\caption{A multi-server queuing model with a priority queue}
\label{fig:mserverp}
%\vskip\baselineskip
\end{figure}


In the model, a server object removes the customer with the highest priority from the  priority queue. If there are several customer objects with the same priority, the one chosen is the one that has been the longest time in the queue (FIFO ordering).

Figure~\ref{fig:mserverp} shows a multi-server queuing model with a priority queue. Any server object can remove the next customer object from the priority queue. 


\section{Summary}

Models of queuing systems with priorities are discussed in this chapter. The priority\index{priority} is an attribute of an active object. The priority is the measure of the relative importance of the active object. The priority affects the ordering of service to customer objects. This also affects the estimation of the waiting period\index{waiting period} compared to other customers of a different priority. The priority is represented as an integer variable, and the value 0 corresponds to the highest priority\index{priority}.

Models with multiple simple queues\index{queues}, one for each priority, can also be analyzed. More common are the models with a single priority queue. The server selects the next customer with the highest priority to service. If there are several customers with the same priority, the server will provide service using the usual FIFO order as with simple queues. 

Other variations to this mechanism are possible, such as the case when there is a server for each priority (or for each group of priorities). 

\section{Key Terms}

\begin{tabular}{lll}
 customer types \ \ & multi-class & priority \\
 priority ordering \ \ & low priority & high priority    \\
\end{tabular}   

\end{document}
