Hi everyone i've produced an agent based model. The agents can move randomly and use the A* algorithm to move to places to places. There are two main collections 1) arrival Queue (arraylist) and the 2) main agents (arraylist). All the agents are initially placed into the arrival queue, agents are placed into the simulation at certain time intervals e.g. 100 agents per 400 simulation steps).
The issue im getting is every time I increase the population of agents from 3000+ the simulation begins to lag. Also im using the Java 2D libraries for visualizing the 2D array of agents. Bellow ive added a screenshot of the the visualVM of my application is shows the methods which are being called the most (CPU time).
ScreenShot Here
Model code:
package Model;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import Model.Grid;
import Agent.*;
public class Model extends AbstractModel implements Runnable{
private Grid grid;
private Constants modelConstants;
private RandomGenerator randGenerator;
private GridMapLayout Maplayout;
private RoomController roomController;
private AgentFactory agentFacory;
private Statistics stats;
private ArrayList<AbstractAgent> agents;
private Queue<Patient> patientArrivalQueue;
private List<Patient> dischargedPatients;
private Queue<Doctor> doctorsQueue;
private Queue<Nurse> nursesQueue;
private int patientPopulation;
private int doctorPopulation;
private int receptionNurses;
private int aNeNurses;
private int ward1Nurses;
private int ward2Nurses;
private int ward3Nurses;
private boolean running;
private int currentSimCycle;
private int simArrivalCounter;
public CTimer timer = new CTimer();
public Model() {
super();
this.grid = new Grid(150, 150); //if no given size grid uses default size
this.modelConstants = new Constants();
this.randGenerator = new RandomGenerator(modelConstants.getSEED());
this.Maplayout = new GridMapLayout(this);
this.roomController = new RoomController(this);
this.agentFacory = new AgentFactory(this);
this.stats = new Statistics(this);
this.currentSimCycle = 0;
this.simArrivalCounter = 0;
this.agents = new ArrayList<AbstractAgent>();
this.patientArrivalQueue = new LinkedList<Patient>();
this.dischargedPatients = new LinkedList<Patient>();
this.doctorsQueue = new LinkedList<Doctor>();
this.nursesQueue = new LinkedList<Nurse>();
loadModelConstants();
loadMapLayout();
roomController.readyRoomCollections();
createAllAgents();
loadDoctorsInRooms();
loadNursesInRooms();
loadNextPatientArrival();
// randomlyPopulateGrid();
stats.updateStatistics();
stats.setDataValid(false);
// Room entrance = roomController.getAllRooms().get("Entrance");
// Room reception = roomController.getAllRooms().get("Reception");
// Room aNe = roomController.getAllRooms().get("A&E");
// Room ward1 = roomController.getAllRooms().get("Ward 1");
// Room ward2 = roomController.getAllRooms().get("Ward 2");
// Room ward3 = roomController.getAllRooms().get("Ward 3");
// Room canteen = roomController.getAllRooms().get("Canteen");
// Room toilet = roomController.getAllRooms().get("Toilet");
//
// System.out.println(toilet);
// System.out.println(entrance.getDoorLocations().size());
// System.out.println("Reception: " + reception.getRoomLocations().size());
// System.out.println("A&E: " + aNe.getRoomLocations().size());
// System.out.println("Ward 1: " + ward1.getRoomLocations().size());
// System.out.println("Ward 2: " + ward2.getRoomLocations().size());
// System.out.println("Ward 3: " + ward3.getRoomLocations().size());
// System.out.println("Canteen: " + canteen.getRoomLocations().size());
// System.out.println("Toilet: " + toilet.getRoomLocations().size());
}
public void loadModelConstants() {
this.patientPopulation = modelConstants.getPatientPopulation();
this.doctorPopulation = modelConstants.getDoctorPopulation();
this.receptionNurses = modelConstants.getReceptionNursePopulation();
this.aNeNurses = modelConstants.getaNeNursePopulation();
this.ward1Nurses = modelConstants.getWard1NursePopulation();
this.ward2Nurses = modelConstants.getWard2NursePopulation();
this.ward3Nurses = modelConstants.getWard3NursePopulation();
// System.out.println(this.patientPopulation);
// System.out.println(this.doctorPopuation);
// System.out.println(this.nursePopulation);
System.out.println("Loaded Model Constants");
}
public void loadMapLayout() {
Maplayout.loadMapImage();
Maplayout.loadRGBfileAndRooms();
Maplayout.readPixels();
Maplayout.addMapLayout();
// layout.printCells();
System.out.println("Loaded Map Layout");
}
public void createAllAgents() {
ArrayList<Patient> tempPatient = new ArrayList<Patient>();
ArrayList<Doctor> tempDoctor = new ArrayList<Doctor>();
ArrayList<Nurse> tempNurse = new ArrayList<Nurse>();
int totalNurses = + (modelConstants.getReceptionNursePopulation()
+ modelConstants.getaNeNursePopulation()
+ modelConstants.getWard1NursePopulation()
+ modelConstants.getWard2NursePopulation()
+ modelConstants.getWard3NursePopulation()
);
int noOfAgentLeftToCreate = modelConstants.getPatientPopulation() + modelConstants.getDoctorPopulation()
+ totalNurses;
while(tempPatient.size() != this.patientPopulation) {
Patient newPatient = (Patient) this.agentFacory.createAgent("PATIENT", noOfAgentLeftToCreate);
tempPatient.add(newPatient);
noOfAgentLeftToCreate--;
}
while(tempDoctor.size() != this.doctorPopulation) {
Doctor newDoctor = (Doctor)this.agentFacory.createAgent("DOCTOR", noOfAgentLeftToCreate);
tempDoctor.add(newDoctor);
noOfAgentLeftToCreate--;
}
while(tempNurse.size() != totalNurses) {
Nurse newNurse = (Nurse)this.agentFacory.createAgent("NURSE", noOfAgentLeftToCreate);
tempNurse.add(newNurse);
noOfAgentLeftToCreate--;
}
this.patientArrivalQueue.addAll(tempPatient); //Add total patients to arrive queue
this.doctorsQueue.addAll(tempDoctor); //Add all doctors to the doctors agent collection
this.nursesQueue.addAll(tempNurse); //Add all nurses to the nurse agent collection
System.out.println("All agents created");
}
public void loadDoctorsInRooms() {
for(Map.Entry<String, Room> pair : roomController.getDoctorRooms().entrySet()) {
String key = pair.getKey();
Room value = pair.getValue();
if(value.isRoomEmpty()) {
Doctor newDoctor = doctorsQueue.remove();
Location randFreeRoomLoc = value.getRandomFreeRoomLocation();
grid.moveAgentToNewLocation(newDoctor, newDoctor.getLocation(), randFreeRoomLoc);
newDoctor.setLocation(randFreeRoomLoc);
newDoctor.setAllocatedRoom(value);
newDoctor.getAgentController().setCurrentRoom(value);
newDoctor.getAgentController().setTargetRoom(value);
//Tell the room that this agent is now a occupant of the room
value.getCurrentOccupantsMap().put(newDoctor.getAgentID(), newDoctor);
agents.add(newDoctor);
}
}
Room aNeRoom = roomController.getAllRooms().get("A&E");
if(aNeRoom.isRoomEmpty()) {
Doctor aNeDoc = doctorsQueue.remove();
Location randFreeRoomLoc = aNeRoom.getRandomFreeRoomLocation();
grid.moveAgentToNewLocation(aNeDoc, aNeDoc.getLocation(), randFreeRoomLoc);
aNeDoc.setLocation(randFreeRoomLoc);
aNeDoc.setAllocatedRoom(aNeRoom);
aNeDoc.getAgentController().setCurrentRoom(aNeRoom);
aNeDoc.getAgentController().setTargetRoom(aNeRoom);
//Tell the room that this agent is now a occupant of the room
aNeRoom.getCurrentOccupantsMap().put(aNeDoc.getAgentID(), aNeDoc);
agents.add(aNeDoc);
}
System.out.println("All Doctors are placed");
}
public void loadNursesInRooms() {
HashMap<String, Room> nurseRooms = new HashMap<String, Room>();
nurseRooms.putAll( roomController.getAllRooms());
nurseRooms.remove("Toilet");
nurseRooms.remove("Canteen");
nurseRooms.remove("Staff");
nurseRooms.remove("Corridor");
nurseRooms.remove("ISOL Entrance");
nurseRooms.remove("Entrance");
nurseRooms.remove("Exit");
for(Map.Entry<String, Room> drPair : roomController.getDoctorRooms().entrySet()) {
String drKey = drPair.getKey();
Room drValue = drPair.getValue();
for(Map.Entry<String, Room> isolPair : roomController.getIsolRooms().entrySet()) {
String isolKey = isolPair.getKey();
Room isolValue = isolPair.getValue();
if(nurseRooms.containsKey(drKey)) {
nurseRooms.remove(drKey);
}
if(nurseRooms.containsKey(isolKey)) {
nurseRooms.remove(isolKey);
}
}
}
for(Map.Entry<String, Room> pair : nurseRooms.entrySet()) {
String key = pair.getKey();
Room value = pair.getValue();
int noOfNurseToCreate = 0;
if(key.contentEquals("Reception")) {
noOfNurseToCreate = modelConstants.getReceptionNursePopulation();
}
else if(key.contentEquals("A&E")) {
noOfNurseToCreate = modelConstants.getaNeNursePopulation();
}
else if(key.contentEquals("Ward 1")) {
noOfNurseToCreate = modelConstants.getWard1NursePopulation();
}
else if(key.contentEquals("Ward 2")) {
noOfNurseToCreate = modelConstants.getWard2NursePopulation();
}
else if(key.contentEquals("Ward 3")) {
noOfNurseToCreate = modelConstants.getWard3NursePopulation();
}
for(int i=0; i != noOfNurseToCreate; i++) {
Nurse newNurse = nursesQueue.remove();
Location roomLocation = value.getRandomFreeRoomLocation();
grid.moveAgentToNewLocation(newNurse, newNurse.getLocation(), roomLocation);
newNurse.setLocation(roomLocation);
newNurse.setAllocatedRoom(value);
newNurse.getAgentController().setCurrentRoom(value);
newNurse.getAgentController().setTargetRoom(value);
//Tell the room controller that this agent is now an occupant of the room
value.getCurrentOccupantsMap().put(newNurse.getAgentID(), newNurse);
agents.add(newNurse);
}
}
System.out.println("All Nurses are placed");
}
public void loadNextPatientArrival() {
if(this.simArrivalCounter == 0) {
int removeThemPatients = 0;
//If there are more patients in the arrival queue then the specified simPatientarrival rate then
//remove the specified amount of patients per simPatient arrival rate
if(patientArrivalQueue.size() >= modelConstants.getPatientArrivalRate()) {
removeThemPatients = modelConstants.getPatientArrivalRate();
}
//Number of patient to place on the grid is less then the patient arrival rate, just place the rest into the entrance
else {
removeThemPatients = patientArrivalQueue.size();
}
Room reception = roomController.getAllRooms().get("Reception");
Room aNe = roomController.getAllRooms().get("A&E");
for(int i=removeThemPatients; i !=0; i--) {
Patient nextPatient = patientArrivalQueue.remove();
// if(nextPatient.getPatientType().contains("Normal") & nextPatient.getLocation() != null) {
if(grid.checkEmptyAt(nextPatient.getLocation())) {
grid.placeAgent(nextPatient, nextPatient.getLocation());
agents.add(nextPatient);
}
else {
patientArrivalQueue.add(nextPatient);
}
// }
}
//IMPORTANT need to reset the simArrivalCounter back to the specified count
this.simArrivalCounter = this.modelConstants.getSimArrivalCounter();
// System.out.println("More patients have arrived");
}
}
public void removeDischargedPatients() {
//Just iterate through the exit room door locations and remove
//the the discharged patients waiting there into the patient discharge list
Room exit = roomController.getAllRooms().get("Exit");
for(Location loc : exit.getDoorLocations()) {
if(!grid.checkEmptyAt(loc)) {
Patient dischargedPatient = (Patient) grid.getAgentAtLocation(loc);
grid.clearLocationAt(loc);
agents.remove(dischargedPatient);
dischargedPatients.add(dischargedPatient);
}
}
}
public void randomlyPopulateGrid() {
Room reception = roomController.getAllRooms().get("Reception");
while(!this.patientArrivalQueue.isEmpty()) {
Location freeLoc = reception.getRandomFreeRoomLocation();
Patient nextPatient = this.patientArrivalQueue.remove();
grid.moveAgentToNewLocation(nextPatient, nextPatient.getLocation(), freeLoc);
nextPatient.setLocation(freeLoc);
nextPatient.getAgentController().setCurrentRoom(reception);
nextPatient.getAgentController().setTargetRoom(reception);
agents.add(nextPatient);
}
System.out.println("Populate Grid");
}
public void simulateCycles(int maxCycles) {
for(int i=0; i != maxCycles; i++) {
loadNextPatientArrival();
removeDischargedPatients();
updateAgents();
stats.updateStatistics();
stats.setDataValid(false);
this.currentSimCycle++;
this.simArrivalCounter--;
}
notifyViews();
}
public void updateAgents() {
// Iterator<AbstractAgent> it = agents.iterator();
// while(it.hasNext()) {
// AbstractAgent nextAgent = it.next();
// nextAgent.act();
// }
for(AbstractAgent agent : agents) {
agent.act();
}
}
#Override
public void startSimulation() {
new Thread(this).start();
System.out.println("Running Simulation");
}
#Override
public void stopSimulation() {
running = false;
System.out.println("Simulation has stoped");
}
#Override
public void resetSimulation() {
System.out.println("Model Constant set to default");
}
public void run() {
running = true;
// int loop = 0;
while(running) {
// System.out.println("loop: "+ loop);
// loop++;
simulateCycles(1);
try {
Thread.sleep(5);
}
catch (Exception e) {
}
}
}
public Grid getGrid() {
return grid;
}
public List<AbstractAgent> getAgentsCollection() {
return agents;
}
public GridMapLayout getGridMayLayout() {
return Maplayout;
}
public RoomController getRoomController() {
return roomController;
}
public Constants getModelConstants() {
return modelConstants;
}
public RandomGenerator getRandGenerator() {
return randGenerator;
}
public int getCurrentSimCycle() {
return currentSimCycle;
}
public Statistics getStats() {
return stats;
}
}
This is a characteristic of time-stepped agent-based modeling. Since each of n agents can in principle interact with any of the other agents, there are n choose 2 interactions to be evaluated at each time step, which grows as O(n2). Your basic choices are: 1) keep the number of agents small; 2) increase the size of your time steps (which usually introduces modeling errors due to the coarser approximation of what's happening); 3) "localize" the scope of interactions (which may or may not be realistic for what you're modeling); or 4) rewrite your model to use discrete event scheduling rather than time stepping.
Related
this is a snippet of a bigger project. The project is designed to be a customer manager of customers + a job manager of money transfers. Before I can continue, I have a "small" problem I do not understand. I wonder, why
System.out.println(myJobOrganizer.jobNumber); // in the Main.java
outputs 0, allthough I have added two jobs to the jobList. When printing the jobList itself, it prints out
[[[customer1;adress1;accountBalance1];[customer2;adress2;accountBalance2];moneyToTransfer];[[customer3;adress3;accountBalance3];[customer4;address4;accountBalance4];moneyToTransfer2]]
jobOrganizer.java
import java.util.ArrayList;
import java.util.List;
public class jobOrganizer {
private static final jobOrganizer myJobOrganizer = new jobOrganizer();
public static jobOrganizer getMyJobOrganizer() {
return myJobOrganizer;
}
private List<job> jobList = new ArrayList<job>();
public int jobNumber = jobList.size();
public void add_job(job newJob) {
this.jobList.add(newJob);
}
public Iterable<job> all_jobs() {
return this.jobList;
}
public static jobOrganizer getInstance() {
return myJobOrganizer;
}
}
job.java
public class job implements Runnable {
private customer kunde1;
private customer kunde2;
private Double transfer;
public job(customer kunde1, customer kunde2, Double transfer) {
this.kunde1 = kunde1;
this.kunde2 = kunde2;
this.transfer = transfer;
}
#Override
public String toString() {
return "[" + kunde1 + "; " + kunde2 + "; " + transfer + "]";
}
public void run() {
System.out.println("Starting transfer");
Double geber = this.kunde1.getAccountBalance();
Double nehmer = this.kunde2.getAccountBalance();
Double geberNeu = geber - this.transfer;
this.kunde1.setAccountBalance(geberNeu);
Double nehmerNeu = nehmer + this.transfer;
this.kunde2.setAccountBalance(nehmerNeu);
System.out.println("Transfer done");
}
}
Main.java
public class Main {
public static void main(String[] args) {
customerOrganizer myCustomerOrganizer = new customerOrganizer();
jobOrganizer myJobOrganizer = new jobOrganizer();
customer mueller = new customer("Tim Mueller", "Strasse 1", 1077.00);
customer john = new customer("John Doe", "Strasse 2", 503.00);
customer meier = new customer("John Meier", "Strasse 3", 8500.50);
customer wurst = new customer("Hans Wurst", "Strasse 4", 1000.00);
myCustomerOrganizer.add_customer(mueller);
myCustomerOrganizer.add_customer(john);
myCustomerOrganizer.add_customer(meier);
myCustomerOrganizer.add_customer(wurst);
job transfer1 = new job(meier, wurst, 500.50);
job transfer2 = new job(mueller, john, 77.00);
myJobOrganizer.add_job(transfer1);
myJobOrganizer.add_job(transfer2);
System.out.println(myJobOrganizer.jobNumber);
System.out.println(myJobOrganizer.all_jobs().toString());
}
}
public int jobNumber = jobList.size(); isn't getting updated so do it like this, this will return the current jobList and not store an instance of it like your field did.
public int jobNumber(){
return jobList.size();
}
it is because the below code executed while object creation but not after that and you are not updating the value later.
public int jobNumber = jobList.size();
I'm trying to ensure the JFrame remains responsive while updating the GUI. I'm using SwingWorker for this. The scenario is during the sequential flow of the program the following code gets executed.
public int[][] readInputFile(MatrixOperations matrixOperations,
String inputFile, Boolean isDirected) throws IOException {
List<String> fileLines = Files.readAllLines(Paths.get(inputFile),
StandardCharsets.UTF_8);
int[][] adjacencyMatrix = matrixOperations.createAdjacencyMatrixFromFile(
fileLines, isDirected);
//The following two lines perform the computationally expensive operation.
//So I'm asking SwingWorker to do this.
task = new Task(fileLines, isDirected, ROOT_GRAPH);
task.execute();
return adjacencyMatrix;
}
This is the SwingWorker class that is getting executed. The problem I'm facing is during the execution of for-loop within doInBackground(). The three functions namely createNodeFromFile(source), createNodeFromFile(destination),createEdgeFromFile(source, destination, isDirected) are being called in their own order during the execution of doInBackground() but they should be called sequentially. As a result I'm getting ConcurrentModification Exception or sometimes Node does not exist exception ( This is Graphstream library specific exception ). How do I resolve this?
import java.util.List;
import javax.swing.SwingWorker;
import org.graphstream.graph.Graph;
public class Task extends SwingWorker<Void, Integer>{
List<String> list;
Boolean isDirected;
Graph graph;
public Task(List<String> list, Boolean isDirected, Graph graph){
this.list = list;
this.isDirected = isDirected;
this.graph = graph;
}
#Override
public Void doInBackground() throws Exception {
// TODO Auto-generated method stub
int count = 0;
for (int i = 0; i < list.size(); i++) {
// System.out.println(fileContent.get(i));
if ((!list.get(i).startsWith("#"))
&& (list.get(i).length() > 1)) {
count++;
String[] arrLine = list.get(i).trim().split("\\s+");
String source = arrLine[0].trim();
String destination = arrLine[1].trim();
createNodeFromFile(source);
createNodeFromFile(destination);
createEdgeFromFile(source, destination, isDirected);
}
if (count % 1000 == 0) {
System.out.println("Finished processing " + count + " lines");
}
}
return null;
}
public void createNodeFromFile(String nodeId) {
if (graph.getNode(nodeId) == null) {
graph.addNode(nodeId);
showLabelOnRootGraph(nodeId, nodeId);
}
}
public void showLabelOnRootGraph(String nodeId, String label) {
graph.getNode(nodeId).addAttribute("ui.label", label);
}
public void createEdgeFromFile(String source, String destination, Boolean isDirected) {
if (graph.getNode(source).hasEdgeBetween(destination) == false) {
graph.addEdge("S" + source + "D" + destination, source,
destination, isDirected);
}
}
}
I found the answer to this. Basically, we have to return the object Graph from Swing Worker. This object has to be then passed to process(). Here is the solution:
package main.graph.generate;
import java.util.Iterator;
import java.util.List;
import javax.swing.SwingWorker;
import org.graphstream.graph.Graph;
import org.graphstream.ui.view.Viewer;
import org.graphstream.ui.view.ViewerPipe;
public class Task extends SwingWorker<Graph, Graph>{
List<String> list;
Boolean isDirected;
Graph graph;
ViewerPipe viewerPipe;
public Task(List<String> list, Boolean isDirected, Graph graph, ViewerPipe viewerPipe){
this.list = list;
this.isDirected = isDirected;
this.graph = graph;
this.viewerPipe = viewerPipe;
}
#Override
public Graph doInBackground() throws Exception {
// TODO Auto-generated method stub
int count = 0;
//for (int i = 0; i < list.size(); i++) {
// System.out.println(fileContent.get(i));
for(Iterator it = list.iterator();it.hasNext();){
String line = (String) it.next();
if ((!line.startsWith("#"))
&& (line.length() > 1)) {
count++;
String[] arrLine = line.trim().split("\\s+");
String source = arrLine[0].trim();
String destination = arrLine[1].trim();
createNodeFromFile(source);
createNodeFromFile(destination);
createEdgeFromFile(source, destination, isDirected);
publish(graph);
}
if (count % 1000 == 0) {
System.out.println("Finished processing " + count + " lines");
}
}
return graph;
}
#Override
protected void process(List<Graph> graphs){
GraphGenerate.ROOT_GRAPH = graphs.get(graphs.size()-1);
viewerPipe.addAttributeSink(GraphGenerate.ROOT_GRAPH);
}
public void createNodeFromFile(String nodeId) {
if (graph.getNode(nodeId) == null) {
graph.addNode(nodeId);
showLabelOnRootGraph(nodeId, nodeId);
}
}
public void showLabelOnRootGraph(String nodeId, String label) {
graph.getNode(nodeId).addAttribute("ui.label", label);
}
public void createEdgeFromFile(String source, String destination, Boolean isDirected) {
if (graph.getNode(source).hasEdgeBetween(destination) == false) {
graph.addEdge("S" + source + "D" + destination, source,
destination, isDirected);
}
}
}
Cheers!
i am creating a library simulator which has inside a Library, a Librarian and multiple Borrower Objects. It involves multiple Borrower Threads and a single librarian thread that run concurrently, performing tasks like requesting books, returning books etc.
I have been using Synchronized functions to ensure that the functions within each Borrower do not become muddled, but now i am trying to figure out how instead to, once a Borrower begins a function, to put it into a queue with a set sleep between entries, and that the output will be posted to the console within intervals.
My question is once a Borrower gets to a function e.g. RequestBooks, instead of simply outputting it into the console, and due to the fact that there are multiple Borrowers, is there any way that i can put the output of the function or the Borrower executing the function within a queue, so that, say, every 3 seconds, the queue processes an entry, then runs the function so that the output for each function put into the queue prints out in even intervals.
At some point i will be using a Lock system (Which i am also unsure of how to execute over the multiple Threads) which will dictate which Borrower sends a function to the queue, if that helps any confusion.
The Borrower code is below :
public class Borrower extends Thread {
private int noOfBooks;
private Set<Book> BooksBorrowed;
private Set<Integer> booksRequested;
private int id;
private int runs;
private Library library;
private Random randSleep = new Random();
public Borrower(int id, Library library, int runs) {
this.library = library;
this.id = id;
this.runs = runs;
noOfBooks = 1;
}
public Borrower(){}
public String getLoans() {
String output = "";
for(Book b : BooksBorrowed) {
output +=" "+b.getBookId()+" ";
}
return output;
}
public void run()
{
try {
Initialize();
for(int i = 0; i < runs; i++) {
RequestBooks();
ReturnBooks();
}
} finally {}
}
public synchronized void Initialize() {
int min = 1;
int max = 10;
Random r = new Random();
noOfBooks = r.nextInt(max - min + 1) + min;
System.out.println("--------------------------");
System.out.println("Borrower "+id+" Starting");
notifyAll();
}
public synchronized void RequestBooks () {
Random r2 = new Random();
Book temp = null;
ArrayList<Book>books = new ArrayList<Book>(library.getBooks());
ArrayList<Integer>Chosen = new ArrayList<Integer>();
for(int i = 0; i < noOfBooks; i++){
int index = r2.nextInt(books.size());
temp = books.get(index);
int tempId = temp.getBookId();
Chosen.add(tempId);
}
System.out.println("--------------------------");
System.out.println("\nBorrower "+id+" requests " +noOfBooks+" Books from Library ");
booksRequested = new HashSet<Integer>(Chosen);
String requestedBooks = "";
for(Integer bookid : Chosen) {
requestedBooks = requestedBooks+bookid+" ";
booksRequested.add(bookid);
}
System.out.println("Borrower "+id+" request Books: "+requestedBooks);
BooksBorrowed = library.RQST(id,booksRequested);
ArrayList<Book> chosenBooks = new ArrayList<Book>();
chosenBooks.addAll(BooksBorrowed);
System.out.println("Books requested by Borrower "+id+" : "+requestedBooks+"\n");
String receivedBooks = "";
Book[]BookArray = BooksBorrowed.toArray(new Book[BooksBorrowed.size()]);
for(Book b : BookArray) {
receivedBooks = receivedBooks+b.getBookId()+" ";
}
System.out.println("Borrower "+id+" Books recieved :"+receivedBooks);
System.out.println("--------------------------");
notifyAll();
}
public synchronized void ReturnBooks() {
Set<Integer> BooksReturned;
ArrayList<Integer> returningBooks = new ArrayList<Integer>();
String returnedBooks = "";
ArrayList<Book> borrowed = new ArrayList<Book>(BooksBorrowed);
for (Book b : borrowed) {
returningBooks.add(b.getBookId());
returnedBooks = returnedBooks+b.getBookId()+" ";
}
BooksReturned = new HashSet<Integer>(returningBooks);
library.RTRN(BooksReturned);
System.out.println("\nBorrower "+id+" returned books to library: "+returnedBooks+"\n");
}
Here is the librarian code :
public class Librarian extends Thread {
Library library;
int runs = 0;
public Librarian(Library library, int runs) {
this.library = library;
this.runs = runs;
}
public ArrayList<Book> AddBooks() {
ArrayList<Book> addbooks = new ArrayList<Book>();
addbooks.add(new Book("The Lord of the Rings, The Fellowship",1,5));
addbooks.add(new Book("The Lord of the Rings, Two Towers",2,5));
addbooks.add(new Book("The Lord of the Rings, Return of King",3,5));
addbooks.add(new Book("The Hunger Games",4,5));
addbooks.add(new Book("A Game of Thrones",5,5));
addbooks.add(new Book("Storm of Swords",6,5));
addbooks.add(new Book("The Eagles Lair",7,5));
addbooks.add(new Book("The Philosophers Stone",8,5));
addbooks.add(new Book("Programming in Java",9,2));
addbooks.add(new Book("Hit and Run",10,5));
addbooks.add(new Book("The man in the Iron Mask",11,5));
addbooks.add(new Book("A Dance With Dragons",12,5));
addbooks.add(new Book("A Feast for Crows",13,5));
addbooks.add(new Book("Jack the Ripper",14,1));
addbooks.add(new Book("The Oddessey",15,1));
return addbooks;
}
#Override
public void run() {
try {
//Random rsleep = new Random();
Initialize();
for(int i = 0;i < runs; i++) {
//sleep(rsleep.nextInt(10000));
getBorrowers();
}
} catch(Exception e){}
}
public void Initialize(){
System.out.println("\nStarting Librarian");
System.out.println("Library Initializing\n");
}
public void LibraryStatus() {
}
public void getBorrowers() {
System.out.println("\nGetting Current Borrowers\n");
String BorrowedBooks ="";
Set<Entry<Integer,Set<Book>>> tempset = library.getBorrowers().entrySet();
for(Entry<Integer,Set<Book>> entry : tempset) {
for(Book b : entry.getValue()) {
BorrowedBooks = BorrowedBooks + b.toString()+"";
}
System.out.println("Borrower "+entry.getKey()+" borrowed books : "+BorrowedBooks);
BorrowedBooks ="";
}
}
public void setLibrary(Library library2) {
this.library = library2;
}
}
And here is the main class that controls the others :
public class LibraryModel {
Library library = new Library();
Librarian librarian;
ArrayList<Borrower> BorrowArray = new ArrayList<Borrower>();
int runs = 0;
int isFinished;
Boolean isActive = true;
public LibraryModel() {
library.AddBooks();
}
public static void main(String[]args)
{
int borrowCount = 0;
System.out.println("Welcome to the Library Simulator\n");
LibraryModel model = new LibraryModel();
char quit = 'y';
Scanner sc = new Scanner(System.in);
while(quit != 'q') {
System.out.println("\n[S = start, A = About, Q = quit]");
String a = sc.next();
switch (a) {
case "S":
model.isActive = true;
System.out.println("Please enter the number of Borrowers\n");
borrowCount = sc.nextInt();
System.out.println("Please enter how many runs the Program will run");
model.runs = sc.nextInt();
model.isFinished = model.runs;
model.librarian = new Librarian(model.library,model.runs);
for(int i = 0 ;i < borrowCount; i++) {
model.getBorrowers().add(new Borrower(i+1,model.getLibrary(),model.runs));
}
model.librarian().start();
for(Borrower b : model.getBorrowers()) {
b.start();
}
try {
model.librarian.join();
for(Borrower b : model.getBorrowers()) {
b.join();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
case "A":
break;
case "Q" :
quit = 'q';
break;
default :
System.out.println("Incorrect Entry, please enter a correct");
break;
}
}
}
public Library getLibrary() {
return library;
}
public ArrayList<Borrower> getBorrowers() {
return BorrowArray;
}
public Librarian librarian() {
return librarian;
}
public int runs() {
return runs;
}
}
Thankyou in advance for the help
I really just need a point in the right direction for this code. I do not understand how to accomplish what it is asking.
Modify the ProductMainApp class so it responds appropriately if the addProduct and deleteProduct mwthod in the ProductTextFile class returns a flase value.
Modify the ProductTextFile class so it writes exceptions to a tex file names errorLog.txt instead of printing them to the console. To do that, add a method named printToLogFile that accepts an IOException as an argument. This method should append two records to the log file: one that indicates the date and time the exception occured and one that contains information about the exception.
Modify the getProducts and saveProducts methods so they call the printToLogFile method when an error occurs.
Here is the PrintTextFile:
import java.util.*;
import java.io.*;
import java.nio.file.*;
public final class ProductTextFile implements ProductDAO
{
private ArrayList<Product> products = null;
private Path productsPath = null;
private File productsFile = null;
private final String FIELD_SEP = "\t";
public ProductTextFile()
{
productsPath = Paths.get("products.txt");
productsFile = productsPath.toFile();
products = this.getProducts();
}
public ArrayList<Product> getProducts()
{
// if the products file has already been read, don't read it again
if (products != null)
return products;
products = new ArrayList<>();
if (Files.exists(productsPath)) // prevent the FileNotFoundException
{
try
{
if (true)
{
// throw new IOException();
}
// open the input stream
BufferedReader in =
new BufferedReader(
new FileReader(productsFile));
// read all products stored in the file
// into the array list
String line = in.readLine();
while(line != null)
{
String[] columns = line.split(FIELD_SEP);
String code = columns[0];
String description = columns[1];
String price = columns[2];
Product p = new Product(
code, description, Double.parseDouble(price));
products.add(p);
line = in.readLine();
}
// close the input stream
in.close();
}
catch(IOException e)
{
//System.out.println(e);
return null;
}
}
return products;
}
public Product getProduct(String code)
{
for (Product p : products)
{
if (p.getCode().equals(code))
return p;
}
return null;
}
public boolean addProduct(Product p)
{
products.add(p);
return this.saveProducts();
}
public boolean deleteProduct(Product p)
{
products.remove(p);
return this.saveProducts();
}
public boolean updateProduct(Product newProduct)
{
// get the old product and remove it
Product oldProduct = this.getProduct(newProduct.getCode());
int i = products.indexOf(oldProduct);
products.remove(i);
// add the updated product
products.add(i, newProduct);
return this.saveProducts();
}
private boolean saveProducts()
{
try
{
// open the output stream
PrintWriter out = new PrintWriter(
new BufferedWriter(
new FileWriter(productsFile)));
// write all products in the array list
// to the file
for (Product p : products)
{
out.print(p.getCode() + FIELD_SEP);
out.print(p.getDescription() + FIELD_SEP);
out.println(p.getPrice());
}
// close the output stream
out.close();
}
catch(IOException e)
{
System.out.println(e);
return false;
}
return true;
}
}
Here is the ProductMainApp:
import java.util.Scanner;
import java.util.ArrayList;
public class ProductMaintApp implements ProductConstants
{
// declare two class variables
private static ProductDAO productDAO = null;
private static Scanner sc = null;
public static void main(String args[])
{
// display a welcome message
System.out.println("Welcome to the Product Maintenance application\n");
// set the class variables
productDAO = DAOFactory.getProductDAO();
sc = new Scanner(System.in);
// display the command menu
displayMenu();
// perform 1 or more actions
String action = "";
while (!action.equalsIgnoreCase("exit"))
{
// get the input from the user
action = Validator.getString(sc,
"Enter a command: ");
System.out.println();
if (action.equalsIgnoreCase("list"))
displayAllProducts();
else if (action.equalsIgnoreCase("add"))
{
addProduct();
}
else if (action.equalsIgnoreCase("del") || action.equalsIgnoreCase("delete"))
deleteProduct();
else if (action.equalsIgnoreCase("help") || action.equalsIgnoreCase("menu"))
displayMenu();
else if (action.equalsIgnoreCase("exit") || action.equalsIgnoreCase("quit"))
System.out.println("Bye.\n");
else
System.out.println("Error! Not a valid command.\n");
}
}
public static void displayMenu()
{
System.out.println("COMMAND MENU");
System.out.println("list - List all products");
System.out.println("add - Add a product");
System.out.println("del - Delete a product");
System.out.println("help - Show this menu");
System.out.println("exit - Exit this application\n");
}
public static void displayAllProducts()
{
System.out.println("PRODUCT LIST");
ArrayList<Product> products = productDAO.getProducts();
Product p = null;
StringBuilder sb = new StringBuilder();
if (productDAO.getProducts().equals(null))
{
System.out.println("Value Null");
System.exit(0);
}
for (int i = 0; i < products.size(); i++)
{
p = products.get(i);
sb.append(StringUtils.padWithSpaces(
p.getCode(), CODE_SIZE + 4));
sb.append(StringUtils.padWithSpaces(
p.getDescription(), DESCRIPTION_SIZE + 4));
sb.append(
p.getFormattedPrice());
sb.append("\n");
}
System.out.println(sb.toString());
}
public static void addProduct()
{
String code = Validator.getString(
sc, "Enter product code: ");
String description = Validator.getLine(
sc, "Enter product description: ");
double price = Validator.getDouble(
sc, "Enter price: ");
Product product = new Product();
product.setCode(code);
product.setDescription(description);
product.setPrice(price);
productDAO.addProduct(product);
System.out.println();
System.out.println(description
+ " has been added.\n");
}
public static void deleteProduct()
{
String code = Validator.getString(sc,
"Enter product code to delete: ");
Product p = productDAO.getProduct(code);
System.out.println();
if (p != null)
{
productDAO.deleteProduct(p);
System.out.println(p.getDescription()
+ " has been deleted.\n");
}
else
{
System.out.println("No product matches that code.\n");
}
}
}
You can use Exception.printStackTrace (stream) where stream is a outputstream to a file.
http://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html#printStackTrace(java.io.PrintStream)
So I have this cyclingmanager game, and I want to show a list of riders by names, and then I want to show their abilities when the user picks a rider. The program compiles and runs nicely, the problem is in my riders() method.It just does not print out c1, my first rider. Thanks in advance.
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class CyclingManager2 {
public static void main(String[] args) {
//menyvalgene
Menu m = new Menu();
m.choice();
}
}
class Menu {
Scanner in = new Scanner(System.in);
Cyclist cy = new Cyclist();
//choices
public void choice() {
int choice = -1;
while (choice != 0) {
System.out.println("Choose something: ");
System.out.println("-0 will exit the program" + "\n-Pressing 1 will open the database menu");
choice = in.nextInt();
switch(choice) {
case 0: choice = 0; break;
case 1: database(); break;
default: System.out.println("You have to choose either 0 or 1"); break;
}
}
}
public void database() {
System.out.println("Welcome to the database \nThese are the options:\n0 = Back to menu\n1: Riders");
int dbChoice = -1;
while (dbChoice != 0) {
System.out.println();
dbChoice = in.nextInt();
switch(dbChoice) {
case 0: dbChoice = 0; break;
case 1: cy.riders(); System.out.println("Press 0 for going back to the menu\nPress 1 for showing the riders");break;
default: System.out.println("Choose either 0 or 1"); break;
}
}
}
}
class Cyclist {
List<Cyclist> cyclists = new ArrayList<>();
private String name;
private int mountain;
private int timeTrial;
private int sprint;
private int age;
Cyclist c1 = null;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setMountain(int mountain) {
this.mountain = mountain;
}
public int getMountain() {
return mountain;
}
public void setTimeTrial(int timeTrial) {
this.timeTrial = timeTrial;
}
public int getTimeTrial() {
return timeTrial;
}
public void setSprint(int sprint) {
this.sprint = sprint;
}
public int getSprint() {
return sprint;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public void riders() {
abilities();
for (int i = 0; i < cyclists.size(); i++){
System.out.print(((Cyclist) cyclists).getName());
}
}
public void abilities() {
//Pardilla is created
c1 = new Cyclist();
c1.setName("Sergio Pardilla");
c1.setMountain(75);
c1.setTimeTrial(60);
c1.setSprint(60);
c1.setAge(30);
/*System.out.println(c1.getName() + "'s abilities:");
System.out.println("Mountain - " + c1.getMountain());
System.out.println("TimeTrial - " + c1.getTimeTrial());
System.out.println("Sprint - " + c1.getSprint());
System.out.println("Age - " +c1.getAge());
cyclists.add(c1); //adds Pardilla to cyclists arraylist*/
}
}
You have this for-loop:
for (int i = 0; i < cyclists.size(); i++) {
System.out.print(((Cyclist) cyclists).getName());
}
It is not going to work. You are casting the entire cyclists (an ArrayList) to one cyclist instance. You probably want to iterate over the contents of the ArrayList and get each Cyclist-object in the cyclists array. Try a foreach-loop:
for (Cyclist cyclist : cyclists) {
System.out.print(cyclist.getName());
}
or use a for loop with index based retrieval:
for (int i = 0; i < cyclists.size(); i++) {
cyclists.get(i).getName());
}
I think you want more something like:
public void riders() {
abilities();
for (int i = 0; i < cyclists.size(); i++){
System.out.print(cyclists.get(i).getName());
}
}
Another thing, is that I'm not sure you want List<Cyclist> cyclists = new ArrayList<>(); to be part of Cyclist class.
Two issues:
The part where you add your rider to the ArrayList is commented out.
The way you loop over your ArrayList is by no means correct. Try like this:
for (Cyclist cyclist : cyclists) {
System.out.println(cyclist.getName());
}
You should get Objects from List by calling it number: cyclists.get(i).getName())