feat: finish Lab3

This commit is contained in:
Yadunand Prem
2022-09-08 16:04:23 +08:00
parent 383d5c3434
commit 8d5961fdd3
8 changed files with 113 additions and 30 deletions

View File

@@ -1,18 +1,18 @@
/** /**
* The Array<T> for CS2030S * The Array<T> for CS2030S
* *
* @author Yadunand Prem * @author Yadunand Prem
* @version CS2030S AY21/22 Semester 2 * @version CS2030S AY21/22 Semester 2
*/ */
class Array<T extends Comparable<T>> { class Array<T extends Comparable<T>> {
private T[] array; private T[] array;
public Array(int size) { public Array(int size) {
// The only way to add values to `array` is via set(), and we can only put // The only way to add values to `array` is via set(), and we can only put
// objects of type T via that method. Thus, it is safe to cast Comparable[] // objects of type T via that method. Thus, it is safe to cast Comparable[]
// to T[]. // to T[].
@SuppressWarnings({"unchecked", "rawtypes"}) @SuppressWarnings("unchecked")
T[] temp = (T[]) new Comparable[size]; T[] temp = (T[]) new Comparable[size];
this.array = temp; this.array = temp;
} }
@@ -27,7 +27,7 @@ class Array<T extends Comparable<T>> {
public T min() { public T min() {
T result = this.array[0]; T result = this.array[0];
for (T i: this.array) { for (T i : this.array) {
if (i.compareTo(result) < 0) { if (i.compareTo(result) < 0) {
result = i; result = i;
} }
@@ -35,6 +35,10 @@ class Array<T extends Comparable<T>> {
return result; return result;
} }
public int length() {
return this.array.length;
}
@Override @Override
public String toString() { public String toString() {
StringBuilder s = new StringBuilder("[ "); StringBuilder s = new StringBuilder("[ ");

View File

@@ -22,16 +22,22 @@ class ArrivalEvent extends Event {
@Override @Override
public Event[] simulate() { public Event[] simulate() {
ServiceCounter availableCounter = this.shop.getAvailableCounter(); ServiceCounter availableCounter = this.shop.getAvailableCounter();
// check if counters are available. If none, push customer to queue if not full. // check if counters are available. If available, start service for that
// If full, customer departs // customer
if (availableCounter == null) { if (availableCounter != null) {
if (this.shop.isQueueFull()) { return new Event[] {
return new Event[] { new DepartureEvent(this.getTime(), customer, shop) }; new ServiceBeginEvent(this.getTime(), customer, shop, availableCounter) };
}
return new Event[] { new JoinQueueEvent(customer, shop) };
} }
return new Event[] { // if no counters available, check if queue slots avialable in counters
new ServiceBeginEvent(this.getTime(), customer, shop, availableCounter) }; availableCounter = this.shop.findCounterWithQueue();
if (availableCounter != null) {
return new Event[] { new JoinCounterQueueEvent(this.getTime(), this.customer, this.shop, availableCounter) };
}
// if shop queue isn't empty, join shop queue
if (!this.shop.isQueueFull()) {
return new Event[] { new JoinShopQueueEvent(customer, shop) };
}
return new Event[] { new DepartureEvent(this.getTime(), customer, shop) };
} }

View File

@@ -0,0 +1,24 @@
public class JoinCounterQueueEvent extends Event {
private Customer customer;
private Shop shop;
private ServiceCounter counter;
public JoinCounterQueueEvent(double time, Customer customer, Shop shop, ServiceCounter counter) {
super(time);
this.customer = customer;
this.shop = shop;
}
@Override
public Event[] simulate() {
this.counter.joinQueue(customer);
return new Event[] {};
}
@Override
public String toString() {
return String.format("%s: %s joined counter queue (at %s)",
super.toString(),
this.customer, this.counter);
}
}

View File

@@ -1,9 +1,9 @@
class JoinQueueEvent extends Event { class JoinShopQueueEvent extends Event {
private Customer customer; private Customer customer;
private Shop shop; private Shop shop;
public JoinQueueEvent(Customer customer, Shop shop) { public JoinShopQueueEvent(Customer customer, Shop shop) {
super(customer.getArrivalTIme()); super(customer.getArrivalTIme());
this.customer = customer; this.customer = customer;
this.shop = shop; this.shop = shop;
@@ -12,12 +12,12 @@ class JoinQueueEvent extends Event {
@Override @Override
public Event[] simulate() { public Event[] simulate() {
this.shop.joinQueue(customer); this.shop.joinQueue(customer);
return new Event[] {}; return new Event[] {};
} }
@Override @Override
public String toString() { public String toString() {
return String.format("%s: %s joined queue %s", return String.format("%s: %s joined shop queue %s",
super.toString(), super.toString(),
this.customer, this.shop.queueString()); this.customer, this.shop.queueString());
} }

View File

@@ -29,10 +29,10 @@ class Queue<T> {
*/ */
public Queue(int size) { public Queue(int size) {
this.maxSize = size; this.maxSize = size;
// The only way to add values to `items` is via enq(), and we can only put // The only way to add values to `items` is via enq(), and we can only put
// objects of type T via that method. Thus, it is safe to cast Comparable[] // objects of type T via that method. Thus, it is safe to cast Comparable[]
// to T[]. // to T[].
@SuppressWarnings({"unchecked", "rawtypes"}) @SuppressWarnings("unchecked")
T[] temp = (T[]) new Object[size]; T[] temp = (T[]) new Object[size];
this.items = temp; this.items = temp;
this.first = -1; this.first = -1;

View File

@@ -24,6 +24,22 @@ public class ServiceCounter implements Comparable<ServiceCounter> {
this.available = true; this.available = true;
} }
public boolean isQueueFull() {
return this.queue.isFull();
}
public boolean isQueueEmpty() {
return this.queue.isEmpty();
}
public void joinQueue(Customer customer) {
this.queue.enq(customer);
}
public Customer leaveQueue() {
return this.queue.deq();
}
public ServiceCounter(int queueSize) { public ServiceCounter(int queueSize) {
this.id = lastId++; this.id = lastId++;
this.available = true; this.available = true;
@@ -32,7 +48,7 @@ public class ServiceCounter implements Comparable<ServiceCounter> {
@Override @Override
public String toString() { public String toString() {
return "S" + id; return String.format("S%s %s", id, this.queue);
} }
@Override @Override

View File

@@ -26,7 +26,33 @@ class ServiceEndEvent extends Event {
@Override @Override
public Event[] simulate() { public Event[] simulate() {
// if there are customers in the counter queue, they will be serviced next.
// Customers in the shop queue will then be added to the counter queue
if (!this.counter.isQueueEmpty()) {
Customer serviceCustomer = this.counter.leaveQueue();
if (!this.shop.isQueueEmpty()) {
return new Event[] {
new DepartureEvent(this.getTime(), this.customer, this.shop, this.counter),
new ServiceBeginEvent(this.getTime(), serviceCustomer, this.shop, this.counter),
new JoinCounterQueueEvent(this.getTime(), this.shop.leaveQueue(), this.shop, counter)
};
}
return new Event[] {
new DepartureEvent(this.getTime(), this.customer, this.shop, this.counter),
new ServiceBeginEvent(this.getTime(), serviceCustomer, this.shop, this.counter),
};
}
// There can also be the case where the counter queue may be empty but there are
// customers in the shop queue.
if (!this.shop.isQueueEmpty()) {
return new Event[] {
new DepartureEvent(this.getTime(), this.customer, this.shop, this.counter),
new ServiceBeginEvent(this.getTime(), this.shop.leaveQueue(), this.shop, this.counter),
};
}
// else there are no more customers in the queue, and the counter can be freed
this.counter.free(); this.counter.free();
return new Event[] { new DepartureEvent(this.getTime(), customer, shop, counter) }; return new Event[] { new DepartureEvent(this.getTime(), this.customer, this.shop, this.counter) };
} }
} }

View File

@@ -26,20 +26,19 @@ public class Shop {
*/ */
public ServiceCounter getAvailableCounter() { public ServiceCounter getAvailableCounter() {
// Check if this logic can be moved elsewhere for (int i = 0; i < this.counters.length(); i++) {
/* ServiceCounter counter = this.counters.get(i);
for (int i = 0; i < this.counters.length; i++) { if (counter.isAvailable()) {
if (this.counters[i].isAvailable()) { return counter;
return counters[i];
} }
} }
*/
return null; return null;
} }
public boolean isQueueFull() { public boolean isQueueFull() {
return this.queue.isFull(); return this.queue.isFull();
} }
public boolean isQueueEmpty() { public boolean isQueueEmpty() {
return this.queue.isEmpty(); return this.queue.isEmpty();
} }
@@ -52,6 +51,14 @@ public class Shop {
return this.queue.deq(); return this.queue.deq();
} }
public ServiceCounter findCounterWithQueue() {
ServiceCounter minCounter = this.counters.min();
if (!minCounter.isQueueFull()) {
return minCounter;
}
return null;
}
public String queueString() { public String queueString() {
return this.queue.toString(); return this.queue.toString();
} }