Skip to content

Instantly share code, notes, and snippets.

@Eldres
Last active November 27, 2017 23:33
Show Gist options
  • Save Eldres/478eea2f76d49d8d8fb0 to your computer and use it in GitHub Desktop.
Save Eldres/478eea2f76d49d8d8fb0 to your computer and use it in GitHub Desktop.
Write a program to simulate the behavior of a self-serve gas station. The goal of this simulation is to collect statistical information of the gas station’s cars and gas pumps. A gas station consists of several pumps and a car waiting line (i.e. a car queue). In each time unit, at most one new car arrives at the gas station. If the car waiting l…
// DO NOT ADD NEW METHODS OR DATA FIELDS!
package PJ3;
class Car {
private int carId;
private int serviceDuration;
private int arrivalTime;
Car() {
}
Car(int CID, int serviceTime, int arriveTime) {
// add statements
this.carId = CID;
this.serviceDuration = serviceTime;
this.arrivalTime = arriveTime;
}
int getServiceDuration() {
// add statements
return serviceDuration;
}
int getArrivalTime() {
// add statements
return arrivalTime;
}
int getCarId() {
return carId;
}
public String toString() {
return "" + carId + ":" + serviceDuration + ":" + arrivalTime;
}
public static void main(String[] args) {
// quick check!
Car mycar = new Car(20, 30, 40);
System.out.println("Car Info:" + mycar);
}
}
// DO NOT ADD NEW METHODS OR DATA FIELDS!
package PJ3;
class GasPump {
// start time and end time of current interval
private int startIntervalTime;
private int endIntervalTime;
// pump id and current car which is served by this gas pump
private int pumpId;
private Car currentCar;
// for keeping statistical data
private int totalFreeTime;
private int totalBusyTime;
private int totalCars;
// Constructor
GasPump() {
// add statements
this.startIntervalTime = 0;
this.endIntervalTime = 0;
this.pumpId = 0;
this.currentCar = null;
this.totalFreeTime = 0;
this.totalBusyTime = 0;
this.totalCars = 0;
}
// Constructor with gas pump id
GasPump(int gasPumpId) {
// add statements
this.pumpId = gasPumpId;
this.startIntervalTime = 0;
this.endIntervalTime = 0;
this.currentCar = null;
this.totalFreeTime = 0;
this.totalBusyTime = 0;
this.totalCars = 0;
}
// accessor methods
int getPumpId() {
return pumpId;
}
Car getCurrentCar() {
// add statements
return currentCar;
}
// need this to setup priority queue for Busy pumps
int getEndIntervalTime() {
// return end time of busy interval
// add statements
return endIntervalTime;
}
// State transition : FREE interval -> BUSY interval:
void switchFreeToBusy(Car currentCar, int currentTime) {
// Main goal : switch from free interval to busy interval
//
// end free interval, start busy interval
// steps : update totalFreeTime
// set Busy interval - startIntervalTime , endIntervalTime, currentCar,
// update totalCars
// add statements
totalFreeTime += currentTime - startIntervalTime;
this.currentCar = currentCar;
startIntervalTime = currentTime;
endIntervalTime = startIntervalTime + currentCar.getArrivalTime();
totalCars++;
}
// State transition : BUSY interval -> FREE interval:
Car switchBusyToFree() {
// Main goal : switch from busy interval to free interval
//
// end busy interval, start free interval
// steps : update totalBusyTime
// set Free interval - startIntervalTime
// return currentCar
// add statements
totalBusyTime += endIntervalTime - startIntervalTime;
startIntervalTime = endIntervalTime;
Car tempCar = currentCar;
this.currentCar = null;
return tempCar;
}
// use this method at the end of simulation to update gas pump data in free
// and busy queues
void setEndSimulationTime(int endsimulationtime, int intervalType)
{
// for end of simulation
// set endIntervalTime to endsimulationtime,
// for FREE interval, update totalFreeTime
// for BUSY interval, update totalBusyTime
// add statements
endIntervalTime = endsimulationtime;
if (intervalType == 1) {
totalFreeTime += endIntervalTime - startIntervalTime;
} else {
totalBusyTime += endIntervalTime - startIntervalTime;
}
}
// functions for printing statistics :
void printStatistics() {
// print gasPump statistics, see project statement
System.out.println("\tGasPump ID : " + pumpId);
System.out.println("\tTotal free time : " + totalFreeTime);
System.out.println("\tTotal service time : " + totalBusyTime);
System.out.println("\tTotal # of cars : " + totalCars);
if (totalCars > 0)
System.out.format("\tAverage service time : %.2f%n\n",
(totalBusyTime * 1.0) / totalCars);
}
public String toString() {
return "GasPump:" + pumpId + ":" + startIntervalTime + "-"
+ endIntervalTime + ":Car:" + currentCar;
}
public static void main(String[] args) {
Car mycar = new Car(15, 30, 40);
GasPump mypump = new GasPump(5);
mypump.switchFreeToBusy(mycar, 45);
System.out.println(mypump);
}
}
package PJ3;
import java.util.*;
//--------------------------------------------------------------------------
//
// Define simulation queues in a gas station. Queues hold references to Car &
// GasPump objects
//
// Car (FIFO) queue is used to hold waiting cars. If the queue is too long
// (i.e. > carQSizeLimit), car goes away without entering car queue
//
// There are several gas pumps in a gas station. Use PriorityQueue to
// hold BUSY gas pumps and FIFO queue to hold FREE gas pumps,
// i.e. a pump that is FREE for the longest time should start be used first.
//
// To handle gasPump in PriorityQueue, we need to define comparator
// for comparing 2 gasPump objects. Here is a constructor from Java API:
//
// PriorityQueue(int initialCapacity, Comparator<? super E> comparator)
//
// For priority queue, the default compare function is "natural ordering"
// i.e. for numbers, minimum value is returned first
//
// User can define own comparator class for PriorityQueue.
// For GasPump objects, we like to have smallest end busy interval time first.
//
// The following class define compare() for two busy gas pumps :
class BusyGasPumpComparator implements Comparator<GasPump> {
// override compare() method
public int compare(GasPump o1, GasPump o2) {
return o1.getEndIntervalTime() - o2.getEndIntervalTime();
}
}
// DO NOT ADD NEW METHODS OR DATA FIELDS
class GasStation {
// Private data fields:
// define one priority queue
private PriorityQueue<GasPump> busyGasPumpQ;
// define two FIFO queues
private Queue<Car> carQ;
private Queue<GasPump> freeGasPumpQ;
// define car queue size limit
private int carQSizeLimit;
// Constructor
public GasStation() {
// add statements
}
// Constructor
public GasStation(int numGasPumps, int carQlimit, int startGasPumpID) {
// use ArrayDeque to construct FIFO queue objects
carQ = new ArrayDeque<Car>();
freeGasPumpQ = new ArrayDeque<GasPump>();
// construct PriorityQueue object
// override compare() in Comparator to compare busy GasPump objects
busyGasPumpQ = new PriorityQueue<GasPump>(numGasPumps,
new BusyGasPumpComparator());
// initialize carQlimit
// Construct GasPump objects and insert into FreeGasPumpQ
// add statements
this.carQSizeLimit = carQlimit;
for (int i = startGasPumpID; i < startGasPumpID+numGasPumps; i++) {
freeGasPumpQ.add(new GasPump(i));
}
}
public GasPump removeFreeGasPumpQ() {
// remove and return a free gasPump
// Add statements
return freeGasPumpQ.poll();
}
public GasPump removeBusyGasPumpQ() {
// remove and return a busy gasPump
// Add statements
return busyGasPumpQ.poll();
}
public Car removeCarQ() {
// remove and return a car
// Add statements
return carQ.remove();
}
public void insertFreeGasPumpQ(GasPump gasPump) {
// insert a free gasPump
// Add statements
freeGasPumpQ.add(gasPump);
}
public void insertBusyGasPumpQ(GasPump gasPump) {
// insert a busy gasPump
// Add statements
busyGasPumpQ.add(gasPump);
}
public void insertCarQ(Car car) {
// insert a car
// Add statements
carQ.add(car);
}
public boolean emptyFreeGasPumpQ() {
// is freeGasPumpQ empty?
// Add statements
return freeGasPumpQ.isEmpty();
}
public boolean emptyBusyGasPumpQ() {
// is busyGasPumpQ empty?
// Add statements
return busyGasPumpQ.isEmpty();
}
public boolean emptyCarQ() {
// is carQ empty?
// Add statements
return carQ.isEmpty();
}
public int numFreeGasPumps() {
// get number of free gasPumps
// Add statements
if (freeGasPumpQ.isEmpty()) {
return 0;
} else {
return freeGasPumpQ.size();
}
}
public int numBusyGasPumps() {
// get number of busy gasPumps
// Add statements
if (busyGasPumpQ.isEmpty()) {
return 0;
} else {
return busyGasPumpQ.size();
}
}
public int numWaitingCars() {
// get number of cars
// Add statements
if (carQ.isEmpty()) {
return 0;
} else {
return carQ.size();
}
}
public GasPump getFrontBusyGasPumpQ() {
// get front of busy gasPumps
// "retrieve" but not "remove"
// Add statements
return busyGasPumpQ.peek();
}
public boolean isCarQTooLong() {
// is carQ too long?
// Add statements
if ((!carQ.isEmpty() == false) && (carQ.size() >= carQSizeLimit)) {
return true;
}else{
return false;
}
}
public void printStatistics() {
System.out.println("\t# waiting cars : " + numWaitingCars());
System.out.println("\t# busy gas pumps : " + numBusyGasPumps());
System.out.println("\t# free gas pumps : " + numFreeGasPumps());
}
public static void main(String[] args) {
GasStation sc = new GasStation(4, 5, 1001);
Car c1 = new Car(1, 18, 10);
Car c2 = new Car(2, 33, 10);
Car c3 = new Car(3, 21, 10);
Car c4 = new Car(3, 37, 10);
sc.insertCarQ(c1);
sc.insertCarQ(c2);
sc.insertCarQ(c3);
System.out.println("" + sc.carQ);
System.out.println("Remove car:" + sc.removeCarQ());
System.out.println("Remove car:" + sc.removeCarQ());
System.out.println("Remove car:" + sc.removeCarQ());
System.out.println("" + sc.freeGasPumpQ);
GasPump p1 = sc.removeFreeGasPumpQ();
GasPump p2 = sc.removeFreeGasPumpQ();
GasPump p3 = sc.removeFreeGasPumpQ();
GasPump p4 = sc.removeFreeGasPumpQ();
System.out.println("Remove free gas pump:" + p1);
System.out.println("Remove free gas pump:" + p2);
System.out.println("Remove free gas pump:" + p3);
System.out.println("Remove free gas pump:" + p4);
p1.switchFreeToBusy(c1, 13);
p2.switchFreeToBusy(c2, 13);
p3.switchFreeToBusy(c3, 13);
p4.switchFreeToBusy(c4, 13);
sc.insertBusyGasPumpQ(p1);
sc.insertBusyGasPumpQ(p2);
sc.insertBusyGasPumpQ(p3);
sc.insertBusyGasPumpQ(p4);
System.out.println("" + sc.busyGasPumpQ);
p1 = sc.removeBusyGasPumpQ();
p2 = sc.removeBusyGasPumpQ();
p3 = sc.removeBusyGasPumpQ();
p4 = sc.removeBusyGasPumpQ();
System.out.println("Remove busy gas pump:" + p1);
System.out.println("Remove busy gas pump:" + p2);
System.out.println("Remove busy gas pump:" + p3);
System.out.println("Remove busy gas pump:" + p4);
}
}
package PJ3;
import java.util.*;
import java.io.*;
// You may add new functions or data in this class
// You may modify any functions or data members here
// You must use Car, GasPump and GasStation
// to implement your simulator
class GasStationSimulation {
// input parameters
private int numGasPumps, carQSizeLimit;
private int simulationTime, dataSource;
private int chancesOfArrival, maxDuration;
// statistical data
private int numGoAway, numServed, totalWaitingTime;
// internal data
private int carIdCounter;
private GasStation gasStationObj; // Gas station object
private Scanner dataFile; // get car data from file
// private Random dataRandom; // get car data using random function
// most recent car arrival info, see getCarData()
private boolean anyNewArrival;
private int serviceDuration;
Random rand = new Random(); // get car data using random function
// initialize data fields
private GasStationSimulation() {
numGasPumps = 0;
carQSizeLimit = 0;
simulationTime = 0;
dataSource = 0;
chancesOfArrival = 0;
maxDuration = 0;
numGoAway = 0;
numServed = 0;
totalWaitingTime = 0;
carIdCounter = 0;
gasStationObj = null;
dataFile = null;
anyNewArrival = false;
serviceDuration = 0;
}
private void getUserParameters() {
// read input parameters from user
// setup dataFile or dataRandom
Scanner input = new Scanner(System.in);
System.out.println("Enter simulation time: ");
do {
simulationTime = input.nextInt();
} while (simulationTime < 1 || simulationTime > 10000);
System.out.println("Enter maximum service time of cars: ");
do {
maxDuration = input.nextInt();
} while (maxDuration < 1 || maxDuration > 5000);
System.out.println("Enter chances (0% < & <= 100%) of new car: ");
do {
chancesOfArrival = input.nextInt();
} while (chancesOfArrival < 1 || chancesOfArrival > 100);
System.out.println("Enter the number of gas pumps: ");
do {
numGasPumps = input.nextInt();
} while (numGasPumps < 1 || numGasPumps > 10);
System.out.println("Enter car queue size limit: ");
do {
carQSizeLimit = input.nextInt();
} while (carQSizeLimit < 1 || carQSizeLimit > 50);
System.out.println("Enter 1/0 to get data from file/rand(): ");
do {
dataSource = input.nextInt();
} while (dataSource < 0 || dataSource > 1);
/*
* this will ask the user to enter the filename, then checks if the
* filename chosen by the user exists
*/
if (dataSource == 1) {
System.out.println("Enter filename: ");
String file;
Scanner keyboard = new Scanner(System.in);
file = keyboard.nextLine();
try {
dataFile = new Scanner(new File(file));
} catch (FileNotFoundException e) {
System.out.println("Error opening file: " + file);
}
keyboard.close();
}
input.close();
}
// this method is called for each unit simulation time
private void getCarData() {
// get next car data : from file or random number generator
// set anyNewArrival and serviceDuration
if (dataSource == 1) {
int data1 = dataFile.nextInt();
int data2 = dataFile.nextInt();
anyNewArrival = (((data1 % 100) + 1) <= chancesOfArrival);
serviceDuration = (data2 % maxDuration) + 1;
} else {
anyNewArrival = ((rand.nextInt(100) + 1) <= chancesOfArrival);
serviceDuration = rand.nextInt(maxDuration) + 1;
}
}
private void doSimulation() {
// Initialize GasStation
gasStationObj = new GasStation(numGasPumps, carQSizeLimit, 1);
// Time driver simulation loop
for (int currentTime = 0; currentTime < simulationTime; currentTime++) {
System.out.println("Time " + currentTime);
// Step 1: any new car enters the gas station?
getCarData();
if (anyNewArrival) {
// Step 1.1: setup car data
// Step 1.2: check car waiting queue too long?
carIdCounter++;
Car newCar = new Car(carIdCounter, serviceDuration, currentTime);
System.out.println("\tCar #" + carIdCounter
+ " arrives with duration "
+ newCar.getServiceDuration() + " units.");
if (gasStationObj.isCarQTooLong()) {
System.out.println("\tCar Queue is too long: Car #"
+ carIdCounter + " leaves the queue.");
numGoAway++;
} else {
gasStationObj.insertCarQ(newCar);
System.out.println("\tCar # " + carIdCounter
+ " waits in the car queue.");
}
} else {
System.out.println("\tNo new car!");
}
// Step 2: free busy pumps, add to free pumpQ
for (int i = 0; i < gasStationObj.numBusyGasPumps(); i++) {
GasPump newGasPump = gasStationObj.getFrontBusyGasPumpQ();
if (newGasPump.getEndIntervalTime() <= currentTime) {
Car newCar;
newGasPump = gasStationObj.removeBusyGasPumpQ();
newCar = newGasPump.switchBusyToFree();
System.out.println("\tCar # " + newCar.getCarId()
+ " is done.");
gasStationObj.insertFreeGasPumpQ(newGasPump);
System.out.println("\tPump #" + newGasPump.getPumpId()
+ " is free.");
}
}
// Step 3: get free pumps to serve waiting cars
for (int i = 0; i < gasStationObj.numFreeGasPumps(); i++) {
if (gasStationObj.numWaitingCars() != 0) {
Car newCar = gasStationObj.removeCarQ();
GasPump newGasPump = gasStationObj.removeFreeGasPumpQ();
newGasPump.switchFreeToBusy(newCar, currentTime);
gasStationObj.insertBusyGasPumpQ(newGasPump);
System.out.println("\tCar # " + newCar.getCarId()
+ " gets a pump.");
System.out
.println("\tPump # " + newGasPump.getPumpId()
+ " starts serving car # "
+ newCar.getCarId() + " for "
+ newCar.getServiceDuration() + " units.");
System.out.println("\tCar # "
+ newGasPump.getCurrentCar().getCarId()
+ ", currently served, is set to now busy pump # "
+ newGasPump.getPumpId());
numServed++;
totalWaitingTime = totalWaitingTime
+ (currentTime - newCar.getArrivalTime());
}
} // end simulation loop
}
// clean-up
}
private void printStatistics() {
// print out simulation results
// you need to display all free and busy tellers
System.out.println("End of simulation report.");
System.out.println("# total arrival cars: " + carIdCounter);
System.out.println("# cars gone away: " + numGoAway);
System.out.println("# cars served: " + numServed);
System.out.println("*** Current Pump Info. ***");
System.out.println("# waiting cars: " + gasStationObj.numWaitingCars());
System.out.println("# busy pumps: " + gasStationObj.numBusyGasPumps());
System.out.println("# free pumps: " + gasStationObj.numFreeGasPumps());
System.out.println("Total waiting line: " + totalWaitingTime);
System.out.println("*** Busy Pump info ***");
while (gasStationObj.numBusyGasPumps() > 0) {
GasPump gasPump = gasStationObj.removeBusyGasPumpQ();
gasPump.setEndSimulationTime(simulationTime, 0);
gasPump.printStatistics();
}
System.out.println("*** Free Pump info ***");
//System.out.println(gasStationObj.numFreeGasPumps());
while (gasStationObj.numFreeGasPumps() > 0) {
GasPump gasPump = gasStationObj.removeFreeGasPumpQ();
gasPump.setEndSimulationTime(simulationTime, 1);
gasPump.printStatistics();
}
}
// *** main method to run simulation ****
public static void main(String[] args) {
GasStationSimulation gas_station_simulation = new GasStationSimulation();
gas_station_simulation.getUserParameters();
gas_station_simulation.doSimulation();
gas_station_simulation.printStatistics();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment