base reforge + Q1 TODO better passenger repartition on bus lines

This commit is contained in:
violette 2024-03-21 12:40:08 -04:00
parent f59aeac67b
commit 78c88d9279
4 changed files with 152 additions and 72 deletions

View file

@ -9,16 +9,16 @@ import java.util.concurrent.ExecutorService;
* Hello world! * Hello world!
* *
*/ */
public class App public class App {
{
static private int numStops = 10; static private int numStops = 10;
static private int numBusses = 10; static private int numBusses = 10;
static private int numStopPerBus = 2; static private int numStopPerBus = 2;
static private int numPassengersPerBus = 2; static private int numPassengersPerBus = 2;
static private int numPassengers = 20; static private int numPassengersPerStop = 5;
static private int numPassengersPerStop = 2; static private int numPassengers = numPassengersPerStop * numStops;
static private int numThreads = 5; static private int numThreads = 1;
static private int timeBetweenStops = 5; static private int timeBetweenStops = 0;
static private int timeEmbark = 0;
public static void main(String[] args) { public static void main(String[] args) {
ExecutorService threads = Executors.newFixedThreadPool(numThreads); ExecutorService threads = Executors.newFixedThreadPool(numThreads);
@ -30,9 +30,25 @@ public class App
Stop s = new Stop(k, numPassengersPerStop); Stop s = new Stop(k, numPassengersPerStop);
stops.add(s); stops.add(s);
threads.submit(s); //threads.submit(s);
} }
for (int k = 0; k < numBusses; k++) {
ArrayList<Stop> s_list = new ArrayList<Stop>();
Stop s;
while (s_list.size() < numStopPerBus) {
do {
s = stops.get((int) (Math.random() * numStops));
} while (s_list.contains(s));
s_list.add(s);
}
Bus b = new Bus(s_list, k, timeBetweenStops, timeEmbark, numPassengersPerBus);
busses.add(b);
}
// TODO put pasengers at stops they can catch their bus
// ie, start and stop in bus path + stop after start
for (int k = 0; k < numPassengers; k++) { for (int k = 0; k < numPassengers; k++) {
Stop start, dest; Stop start, dest;
@ -48,34 +64,22 @@ public class App
start.addPassenger(p); start.addPassenger(p);
} }
for (int k = 0; k < numBusses; k++) { for (Bus b : busses) {
ArrayList<Stop> s_list = new ArrayList<Stop>();
Stop s;
while (s_list.size() < numStopPerBus) {
do {
s = stops.get((int) (Math.random() * numStops));
} while (s_list.contains(s));
s_list.add(s);
}
Bus b = new Bus(s_list, k, timeBetweenStops, numPassengersPerBus);
b.printDetails(); b.printDetails();
busses.add(b);
synchronized (b) {
b.notify();
}
} }
// start bus thread // start bus thread
// (here so init logs are clean) // (here so init logs are clean)
for (Bus b : busses) { for (Bus b : busses) {
threads.submit(b); //threads.submit(b);
b.run();
} }
threads.shutdown();
try { try {
threads.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); threads.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
} catch (InterruptedException e) { } catch (InterruptedException e) {}
}
} }
} }

View file

@ -10,29 +10,57 @@ public class Bus extends Thread {
private int maxCapacity; private int maxCapacity;
private int currentCapacity; private int currentCapacity;
private int timeBetweenStops; private int timeBetweenStops;
private Stop currentStop; private int timeEmbark;
private Stop nextStop;
private int timeEmbark() {
return (int) (Math.random() * timeEmbark);
}
private int timeBetweenStops() { private int timeBetweenStops() {
return (int) (Math.random() * timeBetweenStops * timeBetweenStops); return (int) (Math.random() * timeBetweenStops);
}
private boolean askStop() {
boolean res = false;
for (Passenger p : passengers){
if (p.getDest() == nextStop) {
res = true;
Logger.getInstance().print(id, "Stop asked");
break;
}
}
return res;
} }
private Stop goToNextStop() { private Stop goToNextStop() {
currentStop = stops.remove(0); // if no reason to stop, skip current stop
do {
try {
nextStop = stops.remove(0);
} catch (IndexOutOfBoundsException e) {
nextStop = null;
}
} while ((getNextStopPassengers().isEmpty() || currentCapacity >= maxCapacity) && askStop());
try { try {
Thread.sleep(timeBetweenStops() * 1000); Thread.sleep(timeBetweenStops() * 1000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
System.out.println(e.getMessage());
} }
return currentStop; return nextStop;
} }
// TODO ?? // TODO what
private ArrayList<Passenger> getNextStopPassengers() { private ArrayList<Passenger> getNextStopPassengers() {
ArrayList<Passenger> res = new ArrayList<Passenger>(); ArrayList<Passenger> res = new ArrayList<Passenger>();
if (nextStop != null)
for (Passenger p : passengers) { for (Passenger p : passengers) {
Stop next = stops.get(1); if (p.getDest() == nextStop) {
next.getPassengerByDest(stops); res.add(p);
}
} }
return res; return res;
@ -40,52 +68,63 @@ public class Bus extends Thread {
@Override @Override
public void run() { public void run() {
while (currentStop != null) { try {
embarkPassengers(); while (nextStop != null) {
disembarkPassengers(); disembarkPassengers();
embarkPassengers();
currentStop = goToNextStop(); nextStop = goToNextStop();
} }
} catch (Exception e) {
Logger.getInstance().print(id, "[BUS] exception: " + e.getMessage());
}
Logger.getInstance().print(id, "[BUS] exiting!");
} }
Bus(ArrayList<Stop> s, int id, int time, int maxCapacity) { Bus(ArrayList<Stop> s, int id, int timeStop, int timeEmbark, int maxCapacity) {
this.timeBetweenStops = time; this.timeBetweenStops = timeStop;
this.timeEmbark = timeEmbark;
this.name = "Bus n°" + id; this.name = "Bus n°" + id;
this.id = id; this.id = id;
this.passengers = new ArrayList<Passenger>(); this.passengers = new ArrayList<Passenger>();
this.stops = s; this.stops = s;
this.currentStop = stops.get(0); this.nextStop = stops.remove(0);
this.currentCapacity = 0; this.currentCapacity = 0;
this.maxCapacity = maxCapacity; this.maxCapacity = maxCapacity;
} }
public synchronized void disembarkPassengers() { public synchronized void disembarkPassengers() {
synchronized (nextStop.getMutex()) {
for (Passenger p : passengers) { for (Passenger p : passengers) {
Logger.getInstance().print(id, "[BUS] " + p.getName() + " got out of " + name); Logger.getInstance().print(id, "\t[BUS] " + p.getName() + " disembarked " + name);
if (p.getDest() == currentStop) { if (p.getDest() == nextStop) {
p.disembark(); p.disembark();
currentCapacity--; currentCapacity--;
} }
} }
} }
}
public synchronized void embarkPassengers() { public synchronized void embarkPassengers() {
synchronized (nextStop.getMutex()) {
try { try {
ArrayList<Passenger> list = currentStop.getPassengerByDest(stops); ArrayList<Passenger> list = nextStop.getPassengerByDest(stops);
Logger.getInstance().print(id, "[BUS] hop into " + name + "!"); Logger.getInstance().print(id, "[BUS] hop into " + name + " at stop " + nextStop.getName() + "!");
Thread.sleep(timeEmbark() * 1000);
if (currentCapacity >= maxCapacity) if (currentCapacity >= maxCapacity)
throw new OverCapacityException("Over bus capacity."); throw new OverCapacityException("Over bus capacity.");
for (Passenger p : list) { for (Passenger p : list) {
passengers.add(p); passengers.add(p);
currentStop.removePassenger(p); nextStop.removePassenger(p);
currentCapacity++; currentCapacity++;
Logger.getInstance().print(id, Logger.getInstance().print(id,
"[BUS] " + p.getName() + " embarked in " + name + " at " + currentStop.getName()); "\t[BUS] " + p.getName() + " embarked in " + name + " at " + nextStop.getName());
}
} catch (IndexOutOfBoundsException | OverCapacityException | InterruptedException e) {
Logger.getInstance().print(id, "Exception: " + e.getMessage());
} }
} catch (IndexOutOfBoundsException | OverCapacityException e) {
Logger.getInstance().print(id, "ERROR " + e.getMessage());
} }
} }
@ -94,10 +133,10 @@ public class Bus extends Thread {
Logger.getInstance().print(id, "\t".repeat(indent) + name); Logger.getInstance().print(id, "\t".repeat(indent) + name);
Logger.getInstance().print(id, "\t".repeat(indent) + "time between stops: " + timeBetweenStops); Logger.getInstance().print(id, "\t".repeat(indent) + "time between stops: " + timeBetweenStops);
Logger.getInstance().print(id, "\t".repeat(indent) + "max capacity: " + maxCapacity); Logger.getInstance().print(id, "\t".repeat(indent) + "max capacity: " + maxCapacity);
Logger.getInstance().print(id, "\t".repeat(indent) + "current stop: " + currentStop.getName()); Logger.getInstance().print(id, "\t".repeat(indent) + "current stop: " + nextStop.getName());
Logger.getInstance().print(id, "\t".repeat(indent) + "stops: "); Logger.getInstance().print(id, "\t".repeat(indent) + "stops: ");
nextStop.printDetails(indent + 1);
for (Stop s : stops) { for (Stop s : stops) {
s.printDetails(indent + 1); s.printDetails(indent + 1);
} }
@ -106,5 +145,4 @@ public class Bus extends Thread {
public void printDetails() { public void printDetails() {
printDetails(0); printDetails(0);
} }
} }

View file

@ -4,6 +4,7 @@ public class Passenger {
private String name; private String name;
private int id; private int id;
private int color = -1;
private Stop dest; private Stop dest;
private Stop start; private Stop start;
@ -30,9 +31,14 @@ public class Passenger {
return name; return name;
} }
public void setName(int color) {
this.color = color;
}
public void printDetails(int indent) { public void printDetails(int indent) {
Logger.getInstance().print(id, "\t".repeat(indent) + "---".repeat(3) + " Passenger details " + "---".repeat(3)); if (color == -1) color = id;
Logger.getInstance().print(id, "\t".repeat(indent) + name + " start: " + start.getName() + " dest: " + dest.getName()); Logger.getInstance().print(color, "\t".repeat(indent) + "---".repeat(3) + " Passenger details " + "---".repeat(3));
Logger.getInstance().print(color, "\t".repeat(indent) + name + " start: " + start.getName() + " dest: " + dest.getName());
} }
public void printDetails() { public void printDetails() {

View file

@ -1,13 +1,17 @@
package usherbrooke.ift630; package usherbrooke.ift630;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Stop implements Runnable { public class Stop implements Runnable {
private String name; private String name;
private int id; private int id;
private int maxCapacity; private int maxCapacity;
private ArrayList<Passenger> passengers; private ArrayList<Passenger> passengers;
private Lock mutex = new ReentrantLock();
// TODO lock mutex when stop is used
@Override @Override
public void run() { public void run() {
// xd do nothing for now // xd do nothing for now
@ -63,6 +67,18 @@ public class Stop implements Runnable {
return maxCapacity; return maxCapacity;
} }
public Lock getMutex() {
return mutex;
}
public void printDetails(int indent, int color) {
Logger.getInstance().print(color, "\t".repeat(indent) + "---".repeat(3) + " Stop details " + "---".repeat(3));
Logger.getInstance().print(color, "\t".repeat(indent) + name);
for (Passenger p : passengers) {
p.printDetails(indent + 1);
}
}
public void printDetails(int indent) { public void printDetails(int indent) {
Logger.getInstance().print(id, "\t".repeat(indent) + "---".repeat(3) + " Stop details " + "---".repeat(3)); Logger.getInstance().print(id, "\t".repeat(indent) + "---".repeat(3) + " Stop details " + "---".repeat(3));
@ -77,8 +93,24 @@ public class Stop implements Runnable {
printDetails(0); printDetails(0);
} }
public void busArrive() {
synchronized(this) {
mutex.lock();
}
}
public void busLeave() {
synchronized(this) {
mutex.unlock();
}
}
public void removePassenger(Passenger p) { public void removePassenger(Passenger p) {
// Logger.getInstance().print(id, "Passenger " + p.getName() + " left " + name); // Logger.getInstance().print(id, "Passenger " + p.getName() + " left " + name);
try {
passengers.remove(p); passengers.remove(p);
} catch(Exception e) {
System.out.println("exception" + e.getMessage());
}
} }
} }