init
This commit is contained in:
commit
08f94aa5d3
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
Lab1.pdf
|
34
ArrivalEvent.java
Normal file
34
ArrivalEvent.java
Normal file
@ -0,0 +1,34 @@
|
||||
|
||||
class ArrivalEvent extends BaseShopEvent {
|
||||
|
||||
double serviceTime;
|
||||
|
||||
public ArrivalEvent(double time, int customerId, boolean[] available, double serviceTime) {
|
||||
super(time, customerId, available);
|
||||
this.availableCounters = available;
|
||||
this.serviceTime = serviceTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Event[] simulate() {
|
||||
int counter = -1;
|
||||
for (int i = 0; i < this.availableCounters.length; i++) {
|
||||
if (this.availableCounters[i]) {
|
||||
counter = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (counter == -1) {
|
||||
return new Event[] { new DepartureEvent(this.getTime(), customerId, availableCounters) };
|
||||
}
|
||||
|
||||
return new Event[] {
|
||||
new ServiceBeginEvent(this.getTime(), this.customerId, this.availableCounters, this.serviceTime,
|
||||
counter) };
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + String.format(": Customer %d arrives", this.customerId);
|
||||
}
|
||||
}
|
22
BaseShopEvent.java
Normal file
22
BaseShopEvent.java
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
/**
|
||||
* This class encapsulates an event in the shop
|
||||
* simulation. Your task is to replace this
|
||||
* class with new classes, following proper OOP principles.
|
||||
*
|
||||
* @author Wei Tsang
|
||||
* @version CS2030S AY21/22 Semester 2
|
||||
*/
|
||||
|
||||
abstract class BaseShopEvent extends Event {
|
||||
|
||||
final int customerId;
|
||||
boolean[] availableCounters;
|
||||
|
||||
public BaseShopEvent(double time, int customerId, boolean[] availableCounters) {
|
||||
super(time);
|
||||
this.customerId = customerId;
|
||||
this.availableCounters = availableCounters;
|
||||
}
|
||||
|
||||
}
|
19
DepartureEvent.java
Normal file
19
DepartureEvent.java
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
class DepartureEvent extends BaseShopEvent {
|
||||
|
||||
public DepartureEvent(double time, int customerId, boolean[] available) {
|
||||
super(time, customerId, available);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString()
|
||||
+ String.format(": Customer %d departed", this.customerId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Event[] simulate() {
|
||||
return new Event[] {};
|
||||
}
|
||||
|
||||
}
|
72
Event.java
Normal file
72
Event.java
Normal file
@ -0,0 +1,72 @@
|
||||
/**
|
||||
* The Event class is an abstract class that encapsulates a
|
||||
* discrete event to be simulated. An event encapsulates the
|
||||
* time the event occurs. A subclass of event _must_ override
|
||||
* the simulate() method to implement the logic of the
|
||||
* simulation when this event is simulated. The simulate method
|
||||
* returns an array of events, which the simulator will then
|
||||
* add to the event queue. Note that an event also implements
|
||||
* the Comparable interface so that a PriorityQueue can
|
||||
* arrange the events in the order of event time.
|
||||
*
|
||||
* @author Wei Tsang
|
||||
* @version CS2030S AY21/22 Semester 2
|
||||
*/
|
||||
abstract class Event implements Comparable<Event> {
|
||||
/** The time this event occurs in the simulation. */
|
||||
private final double time;
|
||||
|
||||
/**
|
||||
* Creates an event that occurs at the given time.
|
||||
*
|
||||
* @param time The time the event occurs.
|
||||
*/
|
||||
public Event(double time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter to return the time of this event.
|
||||
*
|
||||
* @return The time this event occurs.
|
||||
*/
|
||||
public double getTime() {
|
||||
return this.time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare this event with a given event e.
|
||||
*
|
||||
* @param e The other event to compare to.
|
||||
* @return 1 if this event occurs later than e;
|
||||
* 0 if they occur the same time;
|
||||
* -1 if this event occurs earlier.
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(Event e) {
|
||||
if (this.time > e.time) {
|
||||
return 1;
|
||||
} else if (this.time == e.time) {
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the string representation this event.
|
||||
*
|
||||
* @return A string consists of the time this event occurs.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%.3f", this.time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate this event.
|
||||
*
|
||||
* @return An array of new events to be scheduled by the simulator.
|
||||
*/
|
||||
public abstract Event[] simulate();
|
||||
}
|
26
Lab1.java
Normal file
26
Lab1.java
Normal file
@ -0,0 +1,26 @@
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* The main class for CS2030S Lab 1.
|
||||
*
|
||||
* @author Wei Tsang
|
||||
* @version CS2030S AY21/22 Semester 2
|
||||
*/
|
||||
class Lab1 {
|
||||
public static void main(String[] args) {
|
||||
|
||||
// Create a scanner to read from standard input.
|
||||
Scanner sc = new Scanner(System.in);
|
||||
|
||||
// Create a simulation. The ShopSimulation
|
||||
// constructor will read the simulation parameters
|
||||
// and initial events using the scanner.
|
||||
Simulation simulation = new ShopSimulation(sc);
|
||||
|
||||
// Create a new simulator and run the simulation
|
||||
new Simulator(simulation).run();
|
||||
|
||||
// Clean up the scanner.
|
||||
sc.close();
|
||||
}
|
||||
}
|
27
ServiceBeginEvent.java
Normal file
27
ServiceBeginEvent.java
Normal file
@ -0,0 +1,27 @@
|
||||
|
||||
class ServiceBeginEvent extends BaseShopEvent {
|
||||
|
||||
double serviceTime;
|
||||
int counterId;
|
||||
|
||||
public ServiceBeginEvent(double time, int customerId, boolean[] available, double serviceTime, int counterId) {
|
||||
super(time, customerId, available);
|
||||
this.serviceTime = serviceTime;
|
||||
this.counterId = counterId;
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString()
|
||||
+ String.format(": Customer %d service begin (by Counter %d)", this.customerId, this.counterId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Event[] simulate() {
|
||||
this.availableCounters[this.counterId] = false;
|
||||
double endTime = this.getTime() + this.serviceTime;
|
||||
return new Event[] {
|
||||
new ServiceEndEvent(endTime, this.customerId, this.availableCounters, this.counterId) };
|
||||
}
|
||||
}
|
23
ServiceEndEvent.java
Normal file
23
ServiceEndEvent.java
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
class ServiceEndEvent extends BaseShopEvent {
|
||||
|
||||
int counterId;
|
||||
|
||||
public ServiceEndEvent(double time, int customerId, boolean[] available, int counterId) {
|
||||
super(time, customerId, available);
|
||||
this.counterId = counterId;
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString()
|
||||
+ String.format(": Customer %d service done (by Counter %d)", this.customerId, this.counterId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Event[] simulate() {
|
||||
this.availableCounters[counterId] = true;
|
||||
return new Event[] { new DepartureEvent(this.getTime(), customerId, availableCounters) };
|
||||
}
|
||||
}
|
58
ShopSimulation.java
Normal file
58
ShopSimulation.java
Normal file
@ -0,0 +1,58 @@
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* This class implements a shop simulation.
|
||||
*
|
||||
* @author Wei Tsang
|
||||
* @version CS2030S AY21/22 Semester 2
|
||||
*/
|
||||
class ShopSimulation extends Simulation {
|
||||
/**
|
||||
* The availability of counters in the shop.
|
||||
*/
|
||||
public boolean[] availableCounters;
|
||||
|
||||
/**
|
||||
* The list of customer arrival events to populate
|
||||
* the simulation with.
|
||||
*/
|
||||
public Event[] initEvents;
|
||||
|
||||
/**
|
||||
* Constructor for a shop simulation.
|
||||
*
|
||||
* @param sc A scanner to read the parameters from. The first
|
||||
* integer scanned is the number of customers; followed
|
||||
* by the number of service counters. Next is a
|
||||
* sequence of (arrival time, service time) pair, each
|
||||
* pair represents a customer.
|
||||
*/
|
||||
public ShopSimulation(Scanner sc) {
|
||||
initEvents = new Event[sc.nextInt()];
|
||||
int numOfCounters = sc.nextInt();
|
||||
|
||||
availableCounters = new boolean[numOfCounters];
|
||||
for (int i = 0; i < numOfCounters; i++) {
|
||||
availableCounters[i] = true;
|
||||
}
|
||||
|
||||
int id = 0;
|
||||
while (sc.hasNextDouble()) {
|
||||
double arrivalTime = sc.nextDouble();
|
||||
double serviceTime = sc.nextDouble();
|
||||
initEvents[id] = new ArrivalEvent(arrivalTime, id, availableCounters, serviceTime);
|
||||
id += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an array of events to populate the
|
||||
* simulator with.
|
||||
*
|
||||
* @return An array of events for the simulator.
|
||||
*/
|
||||
@Override
|
||||
public Event[] getInitialEvents() {
|
||||
return initEvents;
|
||||
}
|
||||
}
|
20
Simulation.java
Normal file
20
Simulation.java
Normal file
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* This class is a general abstract class that
|
||||
* encapsulates a simulation. To implement a
|
||||
* simulation, inherit from this class and implement
|
||||
* the `getInitialEvents` method.
|
||||
*
|
||||
* @author Wei Tsang
|
||||
* @version CS2030S AY21/22 Semester 2
|
||||
*/
|
||||
abstract class Simulation {
|
||||
/**
|
||||
* An abstract method to return an array of events
|
||||
* used to initialize the simulation.
|
||||
*
|
||||
* @return An array of initial events that the
|
||||
* simulator can use to kick-start the
|
||||
* simulation.
|
||||
*/
|
||||
public abstract Event[] getInitialEvents();
|
||||
}
|
51
Simulator.java
Normal file
51
Simulator.java
Normal file
@ -0,0 +1,51 @@
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
/**
|
||||
* This class implements a discrete event simulator.
|
||||
* The simulator maintains a priority queue of events.
|
||||
* It runs through the events and simulates each one until
|
||||
* the queue is empty.
|
||||
*
|
||||
* @author Wei Tsang
|
||||
* @version CS2030S AY21/22 Semester 2
|
||||
*/
|
||||
public class Simulator {
|
||||
/** The event queue. */
|
||||
private final PriorityQueue<Event> events;
|
||||
|
||||
/**
|
||||
* The constructor for a simulator. It takes in
|
||||
* a simulation as an argument, and calls the
|
||||
* getInitialEvents method of that simulation to
|
||||
* initialize the event queue.
|
||||
*
|
||||
* @param simulation The simulation to simulate.
|
||||
*/
|
||||
public Simulator(Simulation simulation) {
|
||||
this.events = new PriorityQueue<Event>();
|
||||
for (Event e : simulation.getInitialEvents()) {
|
||||
this.events.add(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the simulation until no more events is in
|
||||
* the queue. For each event in the queue (in
|
||||
* increasing order of time), print out its string
|
||||
* representation, then simulate it. If the
|
||||
* simulation returns one or more events, add them
|
||||
* to the queue, and repeat.
|
||||
*/
|
||||
public void run() {
|
||||
Event event = this.events.poll();
|
||||
while (event != null) {
|
||||
System.out.println(event);
|
||||
Event[] newEvents = event.simulate();
|
||||
for (Event e : newEvents) {
|
||||
this.events.add(e);
|
||||
}
|
||||
event = this.events.poll();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
4
inputs/Lab1.1.in
Normal file
4
inputs/Lab1.1.in
Normal file
@ -0,0 +1,4 @@
|
||||
3 1
|
||||
1.0 1.0
|
||||
3.0 1.0
|
||||
5.0 1.0
|
4
inputs/Lab1.2.in
Normal file
4
inputs/Lab1.2.in
Normal file
@ -0,0 +1,4 @@
|
||||
3 1
|
||||
1.1 2.0
|
||||
2.2 2.0
|
||||
3.3 2.0
|
6
inputs/Lab1.3.in
Normal file
6
inputs/Lab1.3.in
Normal file
@ -0,0 +1,6 @@
|
||||
5 2
|
||||
1.0 1.0
|
||||
1.2 1.0
|
||||
1.4 1.0
|
||||
1.6 1.0
|
||||
2.1 1.0
|
5
inputs/Lab1.4.in
Normal file
5
inputs/Lab1.4.in
Normal file
@ -0,0 +1,5 @@
|
||||
4 2
|
||||
1.0 1.0
|
||||
1.1 1.0
|
||||
2.2 1.0
|
||||
2.3 1.0
|
4
inputs/Lab1.5.in
Normal file
4
inputs/Lab1.5.in
Normal file
@ -0,0 +1,4 @@
|
||||
3 2
|
||||
1.0 4
|
||||
2.1 1
|
||||
4.2 1
|
12
outputs/Lab1.1.out
Normal file
12
outputs/Lab1.1.out
Normal file
@ -0,0 +1,12 @@
|
||||
1.000: Customer 0 arrives
|
||||
1.000: Customer 0 service begin (by Counter 0)
|
||||
2.000: Customer 0 service done (by Counter 0)
|
||||
2.000: Customer 0 departed
|
||||
3.000: Customer 1 arrives
|
||||
3.000: Customer 1 service begin (by Counter 0)
|
||||
4.000: Customer 1 service done (by Counter 0)
|
||||
4.000: Customer 1 departed
|
||||
5.000: Customer 2 arrives
|
||||
5.000: Customer 2 service begin (by Counter 0)
|
||||
6.000: Customer 2 service done (by Counter 0)
|
||||
6.000: Customer 2 departed
|
10
outputs/Lab1.2.out
Normal file
10
outputs/Lab1.2.out
Normal file
@ -0,0 +1,10 @@
|
||||
1.100: Customer 0 arrives
|
||||
1.100: Customer 0 service begin (by Counter 0)
|
||||
2.200: Customer 1 arrives
|
||||
2.200: Customer 1 departed
|
||||
3.100: Customer 0 service done (by Counter 0)
|
||||
3.100: Customer 0 departed
|
||||
3.300: Customer 2 arrives
|
||||
3.300: Customer 2 service begin (by Counter 0)
|
||||
5.300: Customer 2 service done (by Counter 0)
|
||||
5.300: Customer 2 departed
|
16
outputs/Lab1.3.out
Normal file
16
outputs/Lab1.3.out
Normal file
@ -0,0 +1,16 @@
|
||||
1.000: Customer 0 arrives
|
||||
1.000: Customer 0 service begin (by Counter 0)
|
||||
1.200: Customer 1 arrives
|
||||
1.200: Customer 1 service begin (by Counter 1)
|
||||
1.400: Customer 2 arrives
|
||||
1.400: Customer 2 departed
|
||||
1.600: Customer 3 arrives
|
||||
1.600: Customer 3 departed
|
||||
2.000: Customer 0 service done (by Counter 0)
|
||||
2.000: Customer 0 departed
|
||||
2.100: Customer 4 arrives
|
||||
2.100: Customer 4 service begin (by Counter 0)
|
||||
2.200: Customer 1 service done (by Counter 1)
|
||||
2.200: Customer 1 departed
|
||||
3.100: Customer 4 service done (by Counter 0)
|
||||
3.100: Customer 4 departed
|
16
outputs/Lab1.4.out
Normal file
16
outputs/Lab1.4.out
Normal file
@ -0,0 +1,16 @@
|
||||
1.000: Customer 0 arrives
|
||||
1.000: Customer 0 service begin (by Counter 0)
|
||||
1.100: Customer 1 arrives
|
||||
1.100: Customer 1 service begin (by Counter 1)
|
||||
2.000: Customer 0 service done (by Counter 0)
|
||||
2.000: Customer 0 departed
|
||||
2.100: Customer 1 service done (by Counter 1)
|
||||
2.100: Customer 1 departed
|
||||
2.200: Customer 2 arrives
|
||||
2.200: Customer 2 service begin (by Counter 0)
|
||||
2.300: Customer 3 arrives
|
||||
2.300: Customer 3 service begin (by Counter 1)
|
||||
3.200: Customer 2 service done (by Counter 0)
|
||||
3.200: Customer 2 departed
|
||||
3.300: Customer 3 service done (by Counter 1)
|
||||
3.300: Customer 3 departed
|
12
outputs/Lab1.5.out
Normal file
12
outputs/Lab1.5.out
Normal file
@ -0,0 +1,12 @@
|
||||
1.000: Customer 0 arrives
|
||||
1.000: Customer 0 service begin (by Counter 0)
|
||||
2.100: Customer 1 arrives
|
||||
2.100: Customer 1 service begin (by Counter 1)
|
||||
3.100: Customer 1 service done (by Counter 1)
|
||||
3.100: Customer 1 departed
|
||||
4.200: Customer 2 arrives
|
||||
4.200: Customer 2 service begin (by Counter 1)
|
||||
5.000: Customer 0 service done (by Counter 0)
|
||||
5.000: Customer 0 departed
|
||||
5.200: Customer 2 service done (by Counter 1)
|
||||
5.200: Customer 2 departed
|
73
test.sh
Normal file
73
test.sh
Normal file
@ -0,0 +1,73 @@
|
||||
#!/bin/bash
|
||||
function control_c() {
|
||||
if [ -e $out ]
|
||||
then
|
||||
rm -f $out
|
||||
fi
|
||||
}
|
||||
|
||||
trap control_c INT
|
||||
|
||||
if [ $# -ne 1 ]
|
||||
then
|
||||
echo "usage: $0 <main class>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PROG=$1
|
||||
if [ ! -e $PROG.class ]
|
||||
then
|
||||
echo "$PROG.class does not exist. Have you compiled it with make or javac?"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
num_failed=0
|
||||
i=1
|
||||
while true
|
||||
do
|
||||
if [ -e inputs/$PROG.$i.in ]
|
||||
then
|
||||
if [ $(uname) == "Darwin" ]
|
||||
then
|
||||
out=$(mktemp -t $PROG)
|
||||
else
|
||||
out=$(mktemp --suffix=$PROG)
|
||||
fi
|
||||
java $PROG < inputs/$PROG.$i.in > $out
|
||||
status="$?"
|
||||
if [ "$status" -ne "0" ]
|
||||
then
|
||||
echo "$PROG: return non-zero status $status for test case $i"
|
||||
# cat inputs/$PROG.$i.in
|
||||
num_failed=$((num_failed + 1))
|
||||
else
|
||||
if [ -e $out ]
|
||||
then
|
||||
if [ `diff -bB $out outputs/$PROG.$i.out | wc -l` -ne 0 ]
|
||||
then
|
||||
echo "test $i: failed"
|
||||
#cat inputs/$PROG.$i.in
|
||||
num_failed=$((num_failed + 1))
|
||||
else
|
||||
echo "test $i: passed"
|
||||
fi
|
||||
rm -f $out
|
||||
else
|
||||
echo "$PROG: cannot find output file. Execution interrupted?"
|
||||
num_failed=$((num_failed + 1))
|
||||
fi
|
||||
fi
|
||||
i=$((i + 1))
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $i -eq 1 ]
|
||||
then
|
||||
echo "$PROG: no test cases found 🤷"
|
||||
elif [ $num_failed -eq 0 ]
|
||||
then
|
||||
echo "$PROG: passed everything 🎉"
|
||||
fi
|
||||
# vim:noexpandtab:sw=4:ts=4
|
Loading…
Reference in New Issue
Block a user