• Tidak ada hasil yang ditemukan

PPT Slide 1

N/A
N/A
Protected

Academic year: 2023

Membagikan "PPT Slide 1"

Copied!
78
0
0

Teks penuh

(1)

Data Structures for Java

William H. Ford William R. Topp

Chapter 15

Queues and Priority Queues

Bret Ford

© 2005, Prentice Hall

(2)

Queue Collection

• A queue is a list of items that allows for

access only at the two ends of the sequence, called the front and back of the queue. An item enters at the back and exits from the front.

• A waiting line at a grocery store or a bank is a model

of a stack.

(3)

Queue Operations

• Queue operations are restricted to the ends of the list, called front and back.

push(item) adds item at the back

pop() removes element from the front

peek() accesses value at the front

(4)

Queue Operations (cont)

• An item removed (pop) from the queue

is the first element that was added (push) into the queue. A queue has FIFO (first-in-first-out) ordering.

• Queue inserts followed by queue deletions maintain the order

of the elements

(5)

Queue Interface

• The generic Queue interface defines a restricted set of collection operations that access and

update elements only at the end of the list.

(6)

Queue Interface

(concluded)

(7)

LinkedQueue Class

• The Queue interface is an adapter which defines a restricted set of

list methods. A Queue class can be efficiently implemented using

a linked list as the storage structure. The LinkedQueue class uses a

LinkedList collection and composition.

(8)

LinkedQueue Class (continued)

public class LinkedQueue<T> implements Queue<T>

{

private LinkedList<T> qlist = null;

public LinkedQueue () {

qlist = new LinkedList<T>();

}

. . . }

(9)

Implementing LinkedQueue Method pop()

• Method has runtime efficiency O(1)

public T pop() {

// if the queue is empty, throw // NoSuchElementException

if (isEmpty())

throw new NoSuchElementException(

"LinkedQueue pop(): queue empty");

// remove and return the first element in the list return qlist.removeFirst();

}

(10)

Program 15.1

• The program implements an interview scheduler

that is a queue of Time24 objects. Output lists the

times and the potential length of each interview.

(11)

Program 15.1 (continued)

import java.io.*;

import java.util.Scanner;

import ds.util.LinkedQueue;

import ds.time.Time24;

public class Program15_1 {

public static void main(String[] args) throws IOException

{

final Time24 END_DAY = new Time24(17,00);

String apptStr;

// time interval from current appt to next appt Time24 apptTime = null, interviewTime = null;

// input stream to read times as strings from // file "appt.dat"

Scanner input = new Scanner(

new FileReader("appt.dat"));

(12)

Program 15.1 (continued)

// queue to hold appointment time // for job applicants

LinkedQueue<Time24> apptQ = new LinkedQueue<Time24>();

// construct the queue by appt times as // strings from file; use parseTime to // convert to Time24 object

while (input.hasNext()) {

apptStr = input.nextLine();

apptQ.push(Time24.parseTime(apptStr));

}

// output the day's appointment schedule

System.out.println("Appointment Interview");

(13)

Program 15.1 (continued)

// pop next appt time and determine // available time for interview (peek // at next appt at front of queue) while (!apptQ.isEmpty())

{

// get the next appointment apptTime = apptQ.pop();

// interview time is interval to next // appt or to END_DAY

if (!apptQ.isEmpty())

interviewTime = apptTime.interval(

apptQ.peek());

else

interviewTime = apptTime.interval(END_DAY);

(14)

Program 15.1 (concluded)

// display appointment time and interview time System.out.println(" " + apptTime +

" " + interviewTime);

} } }

(15)

Program 15.1 (Run)

File "appt.dat":

10:00 11:15 13:00 13:45 14:30 15:30 16:30 Run:

Appointment Interview 10:00 1:15 11:15 1:45 13:00 0:45 13:45 0:45 14:30 1:00 15:30 1:00 16:30 0:30

(16)

Radix Sort

• The radix sort is a linear algorithm that sorts an array of integers. It uses successive digits in the numbers to partially sort the list.

• Successive elements in the array are passed

into an array of ten queues (index 0 to 9) using

a digit as the index. Elements are copied from

the array back to the array, creating a partially

sorted list.

(17)

Radix Sort Example

• List: [91, 6, 85, 15, 92, 35, 30, 22, 39]

After Pass 0: [30, 91, 92, 22, 85, 15, 35, 6, 39]

After Pass 2: [6, 15, 22, 30, 35, 39, 85, 91, 92]

(18)

Radix Sort (continued)

• Any two numbers with different ten's digits,

such as 35 and 92 will be in the proper relative order since the algorithm collects numbers

from the 3-bin before numbers from the 9-bin.

• Pass 0 assures the ordering of numbers with

the same tens digit. Such numbers will appear

in the tens queue in order of their ones digit.

(19)

Radix Sort (continued)

Initial sequence: {91, 6, 85, 15, 92, 35, 30, 22, 39}

Same tens digit. In order by ones digit

(20)

Radix Sort Method

• The radixSort() method uses the expanded base-10 representation of a number.

value = x

d-1

10

d-1

+ x

d-2

10

d-2

+ ... + x

2

10

2

+ x

1

10

1

+ x

0

10

0

• The implementation uses 10 queues // allocate 10 null references to a LinkedQueue LinkedQueue[] digitQueue = new LinkedQueue[10];

// initialize each element of digitQueue to be // an empty queue

for (i=0;i < digitQueue.length;i++)

digitQueue[i] = new LinkedQueue();

(21)

Radix Sort Method (continued)

• The radixSort() method must execute d

iterations, one for each digit. The i-th iteration distributes the numbers into the array of

queues, digitQueue, by using the digit

corresponding to the power 10

i

. To determine the value of the digit at any position i, divide a number by the power = 10i and take the

remainder after division by 10.

digitQueue[(arr[i] / power) % 10].push(new Integer(arr[i]));

(22)

Radix Sort distribute()

// support method for radixSort()

// distribute array elements into one of 10 queues // using the digit corresponding to power

// power = 1 ==> 1's digit // power = 10 ==> 10's digit // power = 100 ==> 100's digit // ...

private static void distribute(int[] arr, LinkedQueue[] digitQueue, int power)

{

int i;

// loop through the array, inserting each

// element into the queue (arr[i] / power) % 10 for (i = 0; i < arr.length; i++)

digitQueue[(arr[i] / power) % 10].push(arr[i]);

}

(23)

Radix Sort collect()

// support method for radixSort()

// gather elements from the queues and copy // back to the array

private static void collect(

LinkedQueue[] digitQueue, int[] arr) {

int i = 0, digit;

// scan the array of queues using // indices 0, 1, 2, etc.

for (digit = 0; digit < 10; digit++) // collect items until queue empty // and copy items back to the array while (!digitQueue[digit].isEmpty()) {

arr[i] = digitQueue[digit].pop());

i++;

} }

(24)

radixSort() Method

public static void radixSort(int[] arr, int d) {

int i;

// current digit found by dividing by 10^power int power = 1;

// allocate 10 null references to a LinkedQueue LinkedQueue[] digitQueue = new LinkedQueue[10];

// initialize each element of digitQueue to be // an empty queue

for (i=0; i < digitQueue.length; i++) digitQueue[i] = new LinkedQueue();

for (i=0; i < d; i++) {

distribute(arr, digitQueue, power);

collect(digitQueue, arr);

power *= 10;

} }

(25)

radixSort() Method (concluded)

 Runtime efficiency of radixSort() is O(dn) Runtime efficiency of radixSort() is O(dn) where the array has n elements and the where the array has n elements and the

maximum integer has d digits.

maximum integer has d digits.

(26)

Program 15.2

• The program illustrates radixSort() for an array

of 50 integers in the range 0-99,999.

(27)

Program 15.2 (continued)

import java.util.Random;

import ds.util.Arrays;

public class Program15_2 {

public static void main(String[] args) {

// array to hold the data that is sorted int[] arr = new int[50];

Random rnd = new Random();

int i;

// initialize array with 50 random numbers in // range 0 - 99999

for (i = 0; i < 50; i++)

arr[i] = rnd.nextInt(100000);

// apply the radix sort and output // the sorted array

Arrays.radixSort(arr, 5);

displayArray(arr);

(28)

Program 15.2 (continued)

private static void displayArray(int[] arr) {

int i, j, strnLength;

String s, strn;

for (i=0; i < arr.length; i++) {

// represent value of arr[i] as a string strn = String.valueOf(arr[i]);

// capture the length of strn strnLength = strn.length();

s = "";

// justify strn in a field // of 8 print positions

for (j=0; j < 8-strnLength; j++) s += " ";

s += strn;

(29)

Program 15.2 (concluded)

// output the justified integer value System.out.print(s);

// newline every 6 numbers if ((i+1) % 6 == 0)

System.out.println();

}

System.out.println();

} }

(30)

Program 15.2 (Run)

RUN

2554 3097 5231 6876 8539 12446 16483 20040 23202 24353 24758 25996 28922 29730 30672 32032 32198 32261 36705 36867 47340 47688 51547 53617 54797 55577 56055 59553 61588 65289 65465 68416 68935 71586 73017 77119 80185 80659 81371 83443 87678 88138 90076 90717 93637 94948 95470 96984 97332 98616

(31)

Bounded Queue

• A bounded queue is a queue that can contain a fixed number of elements. An insert into the

queue can occur only when the queue is not already full.

• The BQueue class implements a bounded queue. The class implements the Queue

interface. The boolean method full() indicates whether the queue is full.

• The class uses an array to store the elements.

(32)

BQueue Class API

(33)

BQueue Class Example

• The example illustrates the declaration of a

BQueue object and the use of full() to avoid

attempting an insertion into a full queue. An

exception occurs when we call push() from

within a try block and attempt to add an

element to a full queue.

(34)

BQueue Class Example (continued)

// declare an empty bounded queue with fixed size 15 BQueue<Integer> q = new BQueue<Integer>(15);

int i;

// fill-up the queue

for (i=1; !q.full(); i++) q.push(i);

// output element at the front of q and the queue size System.out.println(q.peek() + " " + q.size());

try {

q.push(40); // exception occurs }

catch (IndexOutOfBoundsException iobe)

(35)

BQueue Class Example (concluded)

Output:

1 15

java.lang.IndexOutOfBoundsException: BQueue push(): queue full

(36)

BQueue Class

public class BQueue<T> implements Queue<T>

{

// array holding the queue elements private T[] queueArray;

// index of the front and back of the queue private int qfront, qback;

// the capacity of the queue and the current size private int qcapacity, qcount;

// create an empty bounded queue with specified size public BQueue(int size)

{

qcapacity = size;

queueArray = (T[])new Object[qcapacity];

qfront = 0;

qback = 0;

qcount = 0;

}

(37)

BQueue Class (concluded)

public BQueue() {

// called non-default constructor // with capacity = 50

BQueue(50);

}

< method full() and methods in the Queue interface >

}

(38)

BQueue Class Implementation

No room for E.

Need a way to use

the slots at indices 0, 1.

(39)

BQueue Class Implementation (continued)

• Think of the queue as a circular sequence with a series of slots that allow element to enter in a clockwise

fashion. The element at index qfront exits the queue

and an element enters the queue at index qback.

(40)

BQueue Class Implementation (continued)

• Treating the array as a circular sequence involves

updating qfront and qback to cycle back to the front the array as soon as they move past the end of the array.

Move qback forward: qback = (qback + 1) % qcapacity;

Move qfront forward: qfront = (qfront + 1) % qcapacity;

(41)

BQueue Class full()

public boolean full() {

return qcount == qcapacity;

}

(42)

BQueue Class push()

public void push(T item) {

// is queue full? if so, throw an // IndexOutOfBoundsException

if (qcount == qcapacity)

throw new IndexOutOfBoundsException(

"BQueue push(): queue full");

// insert into the circular queue queueArray[qback] = item;

qback = (qback+1) % qcapacity;

// increment the queue size qcount++;

}

(43)

BQueue Class pop()

public T pop() {

// if queue is empty, throw a // NoSuchElementException

if (count == 0)

throw new NoSuchElementException(

"BQueue pop(): empty queue");

// save the front of the queue

T queueFront = queueArray[qfront];

// perform a circular queue deletion qfront = (qfront+1) % qcapacity;

// decrement the queue size qcount--;

// return the front return queueFront;

}

(44)

Priority Queue Collection

• A priority queue is a collection in which all elements have a comparison (priority) ordering.

• It provides only simple access and update operations where a deletion always removes the element of

highest priority

(45)

PQueue Interface

• The generic PQueue resembles a queue

with the same method names.

(46)

PQueue Interface

(concluded)

(47)

HeapPQueue Class

• The collection class HeapPQueue implements the PQueue interface.

– By default, the element of highest priority is the one with the largest value (a maximum priority queue); that is, if x and y are two elements in a

priority queue and x > y, then x has higher priority

than y.

(48)

HeapPQueue Class Example

// create an empty priority queue of generic type String HeapPQueue<String> pq = new HeapPQueue<String>();

int n;

pq.push("green");

pq.push("red");

pq.push("blue");

// output the size and element with the highest priority System.out.println(pq.size() + " " + pq.peek());

// use pop() to clear the collection and list elements in // priority (descending) order

while (!pq.isEmpty())

System.out.print(pq.pop() + " ");

Output:

3 red

red green blue

(49)

Support Services Pool

• The application processes job requests to a company

support service pool. A request has a job ID, a job status, and a time requirement.

• JobStatus is an enum with a listing of employee categories with values that allows for comparison of objects.

• The JobRequest class implements Comparable and describes job objects.

(50)

Support Services Pool (continued)

enum JobStatus {

clerk (0), manager (1), director(2), president(3);

int jsValue;

JobStatus(int value) { jsValue = value; } public int value() { return jsValue; } }

(51)

Support Services Pool (continued)

(52)

Support Services Pool (continued)

(53)

Program 15.3

• The program processes job requests with

different employee statuses. Output lists the

jobs by status along with their total time.

(54)

Program 15.3 (continued)

import java.io.*;

import java.util.Scanner;

import ds.util.HeapPQueue;

public class Program15_3 {

public static void main(String[] args) throws IOException

{

// handle job requests

HeapPQueue<JobRequest> jobPool = new HeapPQueue<JobRequest>();

// job requests are read from file "job.dat"

Scanner sc = new Scanner(new FileReader(

"job.dat"));

(55)

Program 15.3 (continued)

// time spent working for each category // of employee

// initial time 0 for each category int[] jobServicesUse = {0,0,0,0};

JobRequest job = null;

// read file; insert each job into // priority queue

while ((job = JobRequest.readJob(sc)) != null) jobPool.push(job);

// delete jobs from priority queue // and output information

System.out.println("Category Job ID" + " Job Time");

(56)

Program 15.3 (continued)

while (!jobPool.isEmpty()) {

// remove a job from the priority // queue and output it

job = (JobRequest)jobPool.pop();

System.out.println(job);

// accumulate job time for the // category of employee

jobServicesUse[job.getStatus().value()] +=

job.getJobTime();

}

System.out.println();

writeJobSummary(jobServicesUse);

}

(57)

Program 15.3 (concluded)

private static void writeJobSummary(

int[] jobServicesUse) {

System.out.println("Total Pool Usage");

System.out.println(" President " + jobServicesUse[3]);

System.out.println(" Director " + jobServicesUse[2]);

System.out.println(" Manager " + jobServicesUse[1]);

System.out.println(" Clerk " + jobServicesUse[0]);

} }

(58)

Program 15.3 (Run)

Run

Category Job ID Job Time President 303 25 President 306 50 Director 300 20 Director 307 70 Director 310 60 Director 302 40 Manager 311 30 Manager 304 10 Manager 305 40 Clerk 308 20 Clerk 309 20 Clerk 301 30 Total Pool Usage

President 75 Director 190 Manager 80

(59)

Event-Driven Simulation

• An event-driven simulation uses a priority

queue to store events that occur over time as the simulation unfolds.

• The bank simulation looks a stream of

customers that are served by two tellers.

Different event types deal with arrival, service, and departure of a customer. Arrival times

and service times are random.

(60)

Event-Driven Simulation (continued)

• The graphic illustrates events (A

i

= arrival, S

i

= service,

D

i

= departure) for four customers. Solid line is service

and dotted line is waiting time.

(61)

Event Classes

• Event classes are defined in an inheritance hierarchy.

The abstract base class Event compares the time

events occurs and defines the method doEvent()

which is implemented in each subclass.

(62)

Event Class

public abstract class Event implements Comparable<Event>

{

protected int time;

// constructor sets time for the event public Event(int t)

{ time = t; }

abstract void doEvent(); // describes activity

(63)

Event Class (concluded)

// used to order the events (elements) // in a priority queue

public int compareTo(Event e) {

if(time < e.time) return -1;

else if (time == e.time) return 0;

else

return 1;

} }

(64)

EventDrivenSimulation Class

import ds.util.HeapPQueue;

public class EventDrivenSimulation {

// minimum heap pops event elements // in order of their time

private HeapPQueue<Event> eventQueue =

new HeapPQueue<Event>(new Less<Event>());

// adds an Event object to the queue public void pushEvent(Event e)

{ eventQueue.push(e); }

(65)

EventDrivenSimulation Class (concluded)

// runs simulation by processing events // as they exit the priority queue

public void run() {

while (!eventQueue.isEmpty()) {

// extract event and process it // with doEvent()

Event nextEvent = eventQueue.pop();

nextEvent.doEvent();

} } }

(66)

BankSimulation Class

public class BankSimulation extends EventDrivenSimulation

{

// parameters used to describe the simulation int simulationLength; // simulation length int numTellers;

int arrivalLow, arrivalHigh; // next arrival range int serviceLow, serviceHigh; // service range

// variables used to monitor the simulation int numCustomers = 0;

int totalWaitTime = 0;

// used for delay between arrivals int prevArrTime = 0;

// detail each event?

boolean verboseRun = false;

// use for random times Random rnd = new Random();

// list of tellers

Teller[] tList = null;

(67)

BankSimulation Class (concluded)

// key method inputs parameters, creates events, // runs simulation and outputs results

public void startSimulation() { . . . }

}

(68)

startSimulation()

public void startSimulation() {

// read simulation parameters from keyboard inputParameters();

// create instances for each teller;

// for convenience, tellers are referenced // with indices beginning at 1

for (int i = 1; i <= numTellers; i++) tList[i] = new Teller();

(69)

startSimulation() (continued)

// for the length of the simulation, create // successive arrival events at random arrival // times; push events on the priority queue // and update prevArrTime

int t = 0;

while (t < simulationLength) {

// randomTime() returns random integer // in the range arrivalLow to arrivalHigh t += randomTime(arrivalLow, arrivalHigh);

if (t >= simulationLength) break;

// create an arrival event and add it // to priority queue

pushEvent(new ArrivalEvent(t, prevArrTime));

// update prevArrTime for use by next arrival prevArrTime = t;

}

(70)

startSimulation() (concluded)

// with arrival events loaded in the priority // queue, begin execution of the simulation;

// Note: during execution, the queue will

// dynamically grow since when an arrival event // exits the queue, its doEvent() method adds // a service event to the queue; when a service // event exits the queue, its doEvent() method // adds a departure event

run();

// display a summary of results displayResults();

}

(71)

ArrivalEvent Class

private class ArrivalEvent extends Event {

private int elapsedTime;

public ArrivalEvent(int time, int prevArrTime) {

super(time);

elapsedTime = time - prevArrTime;

}

public void doEvent() {

int i, minTeller, serviceTime;

DecimalFormat numberFmt = new DecimalFormat("00");

// increment number of customers numCustomers++;

(72)

ArrivalEvent Class (continued)

// use elapsedTime to update backService // for each teller; return teller with // minimum backService; this is the next // available teller

minTeller = minTellerService(tList, elapsedTime);

// backService for teller is wait // time for customer

totalWaitTime += tList[minTeller].backService;

// generate service time for customer;

// add to backService for minTeller who // will serve customer

serviceTime = randomTime(serviceLow, serviceHigh);

tList[minTeller].backService += serviceTime;

(73)

ArrivalEvent Class (continued)

if (verboseRun) . . .

// create ServiceEvent object and add // to priority queue

pushEvent(new ServiceEvent(

time + tList[minTeller].backService, numCustomers,

minTeller,

serviceTime));

}

private int minTellerService(Teller[] tList, int elapsedTime)

{

int i, minTeller = 1;

(74)

ArrivalEvent Class (concluded)

for (i = 1; i <= numTellers; i++)

tList[i].backService = (tList[i].backService - elapsedTime <= 0) ? 0 :

tList[i].backService - elapsedTime;

for (i = 2; i <= numTellers; i++) if (tList[i].backService <

tList[minTeller].backService) minTeller = i;

return minTeller;

} }

(75)

Program 15.4

public class Program15_4 {

public static void main(String[] args) {

// create bank simulation object and start it up BankSimulation bank = new BankSimulation();

bank.startSimulation();

} }

(76)

Program 15.4 (Run #1)

Run 1:

Use verbose run ('Y' or 'N'): Y

Enter the simulation time in minutes: 40 Enter number of available tellers: 2

Enter range of potential arrival times: 3 7 Enter range of potential service times: 5 11 Customer #01 Arrival 6 Wait 6

Customer #01 Begin service at 12 by teller 1 Service time 6 Customer #02 Arrival 13 Wait 8

Customer #01 Departs 18 Served by 1 Customer #03 Arrival 18 Wait 8

Customer #02 Begin service at 21 by teller 1 Service time 8 Customer #04 Arrival 22 Wait 11

Customer #03 Begin service at 26 by teller 2 Service time 8 Customer #02 Departs 29 Served by 1

(77)

Program 15.4

(Run #1, concluded)

Customer #05 Arrival 29 Wait 9

Customer #04 Begin service at 33 by teller 1 Service time 11 Customer #03 Departs 34 Served by 2

Customer #06 Arrival 36 Wait 6

Customer #05 Begin service at 38 by teller 2 Service time 9 Customer #06 Begin service at 42 by teller 1 Service time 6 Customer #04 Departs 44 Served by 1

Customer #05 Departs 47 Served by 2 Customer #06 Departs 48 Served by 1 Simulation Summary

Number of customers is 6

Average waiting time is 0.0 minutes Service time for tellers

Teller 1: Busy 64.6% Overtime 8 Teller 2: Busy 36.2% Overtime 7

(78)

Program 15.4 (Run #2)

Run 2:

Use verbose run ('Y' or 'N'): N

Enter the simulation time in minutes: 480 Enter number of available tellers: 3

Enter range of potential arrival times: 1 5 Enter range of potential service times: 4 11 Simulation Summary

Number of customers is 156

Average waiting time is 1.0 minutes Service time for tellers

Teller 1: Busy 88.4% Overtime 12 Teller 2: Busy 80.0% Overtime 10 Teller 3: Busy 65.3% Overtime 19

Referensi

Dokumen terkait

Tóm lại, qua nghiên cứu tác động của lãnh đạo, công tác quản lý và hệ thống văn bản đến việc xây dựng văn hóa chất lượng ở Trường Đại học Sư phạm – ĐHĐN chúng tôi rút ra được tác động

Reflections on the First Biological-Geological Expedition to Marion and Prince Edward Islands - 50 Years of Success in Research and Conservation Brian J Huntley Antarctic Legacy of