I am trying to recursively populate a tree, but my code is only only fill out one depth length, and then quiting. i.e. each node only has one child. Is there something am failing to take in to consideration?
public static void populate(Node n, int depth, String player){
System.out.println("Depth: " + depth);
if(player.equalsIgnoreCase("X"))
player = "O";
else
player = "X";
int j = 0;
System.out.println("empty spots: " + ((Board)n.getData()).noOfEmpty());
for(int i=0; i<((Board)n.getData()).noOfEmpty(); i++){
if(((Board)n.getData()).getSquare(j).equalsIgnoreCase("X")
|| ((Board)n.getData()).getSquare(j).equalsIgnoreCase("O"))
j++;
else{
Board tmp = new Board(((Board)n.getData()), j, player);
Node newNode = new Node(tmp);
tree.insert(n, newNode);
populate(newNode, depth-1, player);
}
}
}
P.S. and i check the noOfEmpty() return value, which should determine the number of children a node should have.
edit:#eznme the complete code as requested:
public class MinMax {
protected static Tree tree;
public static void createTree(Board b){
tree = new Tree();
tree.setRoot(new Node(b));
populate(tree.getRoot(), 5, "X");
//System.out.println("printing tree");
//tree.print(1);
}
public static void populate(Node n, int depth, String player){
System.out.println("Depth: " + depth);
if(player.equalsIgnoreCase("X"))
player = "O";
else
player = "X";
int j = 0;
System.out.println("empty spots: " + ((Board)n.getData()).noOfEmpty());
for(int i=0; i<((Board)n.getData()).noOfEmpty(); i++){
if(((Board)n.getData()).getSquare(j).equalsIgnoreCase("X")
|| ((Board)n.getData()).getSquare(j).equalsIgnoreCase("O"))
j++;
else{
Board tmp = new Board(((Board)n.getData()), j, player);
Node newNode = new Node(tmp);
tree.insert(n, newNode);
populate(newNode, depth-1, player);
}
}
}
}
import java.util.ArrayList;
/**
*
* #author Greg
*/
public class Node {
protected Object data;
protected int score; //fields to be used by the MaxMin class
protected ArrayList<Node> children;
//constructors
public Node(){
children = new ArrayList(0);
data = null;
}
public Node(Object obj){
children = new ArrayList(0);
data = obj;
}
public void setChild(Node n){
//EFFECT: set the ith child to node t
children.add(n);
}
public void setChildren(Node[] t){
//EFFECT: copy the array t, into the array children, effectively
// setting all the chidern of this node simultaneouly
int l = children.size();
for(int i=0; i<t.length; i++){
children.add(l, t[i]);
}
}
public void setData(Object obj){
//EFFECT: set the date of this node to obj, and also set the number of
// children this node has
data = obj;
}
public Node getChild(int i){
//EFFECT: returns the child at index i
return children.get(i);
}
public int noOfChildren(){
//EFFECT: return the length of this node
return children.size();
}
public Object getData(){
//EFFECT: returns the data of this node
return data;
}
#Override
public String toString(){
//EFFECT: returns the string form of this node
return "" + data.toString() + "\nwith " + noOfChildren()+ "\n";
}
public boolean isLeaf(){
if(children.size()==0)
return true;
return false;
}
public void setScore(int scr){
score = scr;
}
public int getScore(){
return score;
}
}
public class Tree {
private Node root;
public Tree(){
setRoot(null);
}
public Tree(Node n){
setRoot(n);
}
public Tree(Object obj){
setRoot(new Node(obj));
}
protected Node getRoot(){
return root;
}
protected void setRoot(Node n){
root = n;
}
public boolean isEmpty(){
return getRoot() == null;
}
public Object getData(){
if(!isEmpty())
return getRoot().getData();
return null;
}
public Object getChild(int i){
return root.getChild(i);
}
public void setData(Object obj){
if(!isEmpty())
getRoot().setData(obj);
}
public void insert(Node p,Node c){
if(p != null)
p.setChild(c);
}
public void print(int mode){
if(mode == 1) pretrav();
else if(mode == 2) postrav();
else
System.out.println("yeah... mode 1 or 2...nothing else, try agn");
}
public void pretrav(){
pretrav(getRoot());
}
protected void pretrav(Node t){
if(t == null)
return;
System.out.println(t.getData()+" \n");
for(int i=0; i<t.noOfChildren(); i++)
pretrav(t.getChild(i));
}
public void postrav(){
postrav(getRoot());
}
protected void postrav(Node t){
if(t == null)
return;
System.out.print(t.getData()+" ");
for(int i=0; i<t.noOfChildren(); i++)
pretrav(t.getChild(i));
System.out.print(t.getData()+" ");
}
}
public class Board {
boolean isFull = false; // a check to see if the board is full
String[] grid = new String[9]; //an array represting the 9 square on a board
int hV;
String MIN, MAX;
public Board(){
for(int i=0; i<grid.length;i++)
grid[i] = Integer.toString(i);
hV = heuristicValue(this);
}
public Board(Board b, int x, String player){
this.grid = b.getBoard();
if(!(grid[x].equalsIgnoreCase("X")|| grid[x].equalsIgnoreCase("X")))
grid[x] = player;
}
public boolean setSquare(String player, int position){
/*
EFFECT:set a square on the board to either a X or a O, debending on the player
PRECON: square (x,y) is empty
POATCON: square (x,y) has player 'symbol'
*/
boolean isValidPlay = false;
try{
//as a sanity
Integer.parseInt(grid[position]);
grid[position] = player;
isValidPlay = true;
}catch(NumberFormatException e){
System.out.println("positon " + position + "is already occupied");
}
return isValidPlay;
}
public boolean endGame(){
/*
* EFFECT: check to see if the game have been won or drawn
*/
if(ticTacToe(0,1,2)){
//System.out.println("Player " + grid[0] + " wins");
return true;
}
else if(ticTacToe(3,4,5)){
//System.out.println("Player " + grid[3] + " wins");
return true;
}
else if(ticTacToe(6,7,8)){
//System.out.println("Player " + grid[6] + " wins");
return true;
}
else if(ticTacToe(0,4,8)){
//System.out.println("Player " + grid[0]+ " wins");
return true;
}
else if(ticTacToe(0,3,6)){
//System.out.println("Player " + grid[0]+ " wins");
return true;
}
else if(ticTacToe(1,4,7)){
//System.out.println("Player " + grid[1] + " wins");
return true;
}
else if(ticTacToe(2,5,8)){
//System.out.println("Player " + grid[2] + " wins");
return true;
}else if(ticTacToe(2,4,6)){
//System.out.println("Player " + grid[2] + " wins");
return true;
}
else
return isDrawn();
}
public boolean ticTacToe(int x, int y, int z){
/*
* check is x, y and z has the same value
*/
try{
Integer.parseInt(grid[x]);
return false;
}catch(NumberFormatException e){
if( grid[x].equals(grid[y])
&& grid[x].equals(grid[z]))
return true;
else
return false;
}
}
public String getSquare(int i){
return grid[i];
}
#Override
public String toString(){
String msg = "";
for(int i=0; i<grid.length; i++){
msg = msg + grid[i] + " ";
if(i==2 || i==5)
msg = msg+ "\n";
}
return msg;
}
public boolean isDrawn(){
/*
* check to see if there are any 'free' spaces on the board, if there are any
* return false, else return true
*/
for(int i=0; i<grid.length; i++){
try{
Integer.parseInt(grid[i]);
return false;
}catch(NumberFormatException e){
}
}
System.out.println("Game drawn");
return true;
}
public String[] getBoard(){
return grid;
}
public int noOfEmpty(){
//EFFECT: returns the number of empty squares
int count = 0;
for(int i=0; i<grid.length; i++)
if (!(grid[i].equalsIgnoreCase("X") || grid[i].equalsIgnoreCase("O")))
count++;
return count;
}
public int heuristicValue(Board b){
String MAX = "X", MIN = "O";
/*
* calculate a value that will be used as a heuristic function
* the function works for ever X in a row WITHOUT O: 1 point,
* for two X in a row WITHOUT a O: 5 points
* and 3 X in a row: 100 points
*/
//System.out.println("Computing heuristic");
//System.out.println("Computing horizontals");
int hCount = 0;
//sum up the horizontals
for(int i=0; i<9; i=i+3){
int tmpMAX = playerCount(b, MAX,i,i+1,i+2);
int tmpMIN = playerCount(b, MIN,i,i+1,i+2);
//System.out.println(tmpMAX);
//System.out.println(tmpMIN);
if(tmpMIN > 0){
//System.out.println("Min was zero");
}
else if(tmpMAX==1){
//System.out.println("has one");
hCount = hCount + 1;
}
else if(tmpMAX==2){
//System.out.println("was tw0");
hCount = hCount + 5;
}
else if(tmpMAX==3){
//System.out.println("full 100");
hCount = hCount + 100;
}
}
//System.out.println("Computing verticals");
//sum up the verticals
for(int i=0; i<3; i++){
int tmpMAX = playerCount(b, MAX,i,i+3,i+6);
int tmpMIN = playerCount(b, MIN,i,i+3,i+6);
if(tmpMIN > 0){}
else if(tmpMAX==1){
hCount = hCount +1;
}
else if(tmpMAX==2){
hCount = hCount + 5;
}
else if(tmpMAX==3){
hCount = hCount + 100;
}
}
//System.out.println("Computing diagonals");
//sum up diagonals
if(playerCount(b, MIN,0,4,8)==0){
if(playerCount(b, MAX,0,4,8)==1){
hCount = hCount + 1;
}
if(playerCount(b, MAX,0,4,8)==2)
hCount = hCount + 5;
if(playerCount(b, MAX,0,4,8)==3)
hCount = hCount + 100;
}
if(playerCount(b, MIN,2,4,6)==0){
if(playerCount(b, MAX,2,4,6)==1){
hCount = hCount + 1;
}
if(playerCount(b, MAX,2,4,6)==2)
hCount = hCount + 5;
if(playerCount(b, MAX,2,4,6)==3)
hCount = hCount + 100;
}
//System.out.println("Computing completed");
int hV = hCount;
return hV;
}
int playerCount(Board b, String player, int x, int y, int z){
int count = 0;
if(b.getSquare(x).equals(player))
count = count + 1;
if(b.getSquare(y).equals(player))
count = count + 1;
if(b.getSquare(z).equals(player))
count = count + 1;
//System.out.println("playerCount; " + count);
return count;
}
}
import java.io.*;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException{
BufferedReader reader = new BufferedReader(new
InputStreamReader(System.in));
Board thisGame = new Board();
System.out.println("Start \n" + thisGame.toString());
MinMax.createTree(thisGame);
System.exit(0);
}
}
In order to recursively build a n-ary tree, I would do this:
public static void populate(Node n, int height){
if(height = 0){
n = new Node();
}else{
n = new Node();
for(int i = 0; i < n.nbChilds(); i++){
populate(n.getChildAt(i), height - 1);
}
}
}
I hope it helps.
Order of nodes creation with this algo (on a binary tree):
1
2 9
3 6 10 13
4 5 7 8 11 12 14 15
So here is what I would do in your case (minimax tic-tac-toe):
Terminology:
Height of a node: Distance from this node to it's further leaf.
Depth of a node: Distance from the root of the tree, to this node.
You have to keep trying all cases until: the board is full OR one player won. So, your tree's height is numberOfCells + 1.
If we simplify the problem and don't worry about symmetric duplicates:
Each node will have numberOfcells - nodeDepth childs.
public static void main(String[] args){
Tree t = new Tree();
int nbCells = 9;
t.setRoot(buildTree(new Board(nbCells), 0, -1));
}
public static Node buildTree(Board b, int player, int positionToPlay){
if(player != 0){
b.setCellAt(positionToPlay, player);
}
Node n = new Node(b, b.nbEmptyCells());
int j = 0;
for(int i = 0; i < b.nbCells(); i++){
if(b.getCellAt(i) == 0)
n.setChildAt(j++, buildTree(new Board(b), changePlayer(player), i));
}
return n;
}
public static int changePlayer(int p){
switch(p){
case 0:
return 1;
case 1:
return 2;
case 2:
return 1;
default:
return 0;
}
}
Node class:
public class Node {
private Board board;
private Node[] childs;
public Node(Board b, int nbChilds){
this.board = new Board(b);
this.childs = new Node[nbChilds];
}
public Node getChildAt(int i){
return childs[i];
}
public int nbChilds(){
return childs.length;
}
public void setChildAt(int i, Node n){
this.childs[i] = n;
}
public Board getBoard(){
return this.board;
}
I think you got a wrong approach.
First of all, you're doing a loop and recursion, besides using a depth variable that has no meaning since you never check it's value either to end the recursion, or to know something about what you want to do.
The use a a dynamic function within the loop itself is not quite good, since the iteration should be well defined from the beginning of the loop.
i is just useless in your context.
So if I understand your code, a problematic case would be a case where there is 3 empty squares and 4 non empty squares since you would iterate i from 0 to 3 and do nothing but incrementing j from 0 to 3 then exit because i would have reach 3.
Of course I may be mistaken on some points because I don't know what tree is, from where did it come from? is it related to n? What is a board.
I hope my contribution can help you and I encourage you to post more details to clarify the holes and enable me to help you a bit more.
Related
This is programming exercise from Lafore's Data Structures & Algorithms book:
So far I have this:
public class DequeLong {
private int maxSize;
private long[] dequeArray;
private int front;
private int rear;
private int nItems;
public DequeLong(int size){
maxSize = size;
dequeArray = new long[maxSize];
front = 0;
rear = -1;
nItems = 0;
}
public void insertLeft(long j){
if(rear == maxSize - 1)
rear = -1;
dequeArray[++rear] = j;
nItems++;
getDequeArray();
}
public void insertRight(long j){
if(front == maxSize)
front = 0;
dequeArray[front] = j;
front++;
nItems++;
getDequeArray();
}
public long removeLeft(){
long temp = dequeArray[rear];
if(rear == 0)
rear = maxSize - 1;
else{
rear--;
}
nItems--;
getDequeArray();
return temp;
}
public long removeRight(){
long temp = dequeArray[front++];
if(front == maxSize)
front = 0;
nItems--;
getDequeArray();
return temp;
}
public long peekFront(){
return dequeArray[front];
}
public long peekRear(){
return dequeArray[rear];
}
public boolean isFull(){
return nItems == maxSize;
}
public boolean isEmpty(){
return nItems == 0;
}
public int size(){
return nItems;
}
public long get(int i){
return dequeArray[i];
}
public void getDequeArray(){
System.out.print("[");
for(int i = 0; i < nItems; i++){
System.out.print(dequeArray[i] + " ");
}
System.out.print("]");
System.out.println();
}
}
And main class:
public class DequeApp {
public static void main(String[] args) {
DequeLong dl = new DequeLong(5);
//check stack - insertLeft() & removeLeft()
dl.insertLeft(100);
dl.insertLeft(200);
dl.insertLeft(300);
dl.insertLeft(400);
dl.insertLeft(500);
dl.removeLeft();
dl.removeLeft();
dl.insertLeft(600);
dl.insertLeft(700);
System.out.println("");
for(int i = 0; i < dl.size(); i++){
System.out.print(dl.get(i) + " ");
}
System.out.println("");
while(!dl.isEmpty())
System.out.println("removed: " + dl.removeLeft());
System.out.println("*************************");
//check queue - insertLeft() & removeRight()
dl.insertLeft(1_000);
dl.insertLeft(2_000);
dl.insertLeft(3_000);
dl.insertLeft(4_000);
dl.insertLeft(5_000);
dl.removeRight();
dl.removeRight();
dl.insertLeft(6_000);
dl.insertLeft(7_000);
System.out.println("");
for(int i = 0; i < dl.size(); i++){
System.out.print(dl.get(i) + " ");
}
System.out.println("");
while(!dl.isEmpty())
System.out.println("removed: " + dl.removeRight());
System.out.println("*************************");
//insertRight() & removeLeft()
dl.insertRight(10_000);
dl.insertRight(20_000);
dl.insertRight(30_000);
dl.insertRight(40_000);
dl.insertRight(50_000);
dl.removeLeft();
dl.removeLeft();
dl.insertRight(60_000);
dl.insertRight(70_000);
System.out.println("");
for(int i = 0; i < dl.size(); i++){
System.out.print(dl.get(i) + " ");
}
System.out.println("");
while(!dl.isEmpty())
System.out.println("removed: " + dl.removeLeft());
System.out.println("*************************");
//insertRight() & removeRight()
dl.insertRight(100_000);
dl.insertRight(200_000);
dl.insertRight(300_000);
dl.insertRight(400_000);
dl.insertRight(500_000);
dl.removeRight();
dl.removeRight();
dl.insertRight(600_000);
dl.insertRight(700_000);
System.out.println("");
for(int i = 0; i < dl.size(); i++){
System.out.print(dl.get(i) + " ");
}
System.out.println("");
while(!dl.isEmpty())
System.out.println("removed: " + dl.removeRight());
System.out.println("*************************");
}
}
Questions:
1) Right now I am applying all operations on the same object, am I doing it right? or I have to create new object(or add reset method to existing one) in order to apply insertLeft(), insertRight(), removeLeft(), removeRight() combos sequentially?
2) If it's possible to use methods sequentially, does my code returns correct results?
I need to give the widest path from one chosen node to another in a self-generated graph. After this, I need to state the "bottleneck" or smallest weight on the computed path. As it is, I don't know where to start to find the bottleneck and I'm having trouble showing the path. Under the Graph class, in the printPath method, I am currently getting a StackOverflow Error from presumably infinite recursion, though I don't understand how its recurring infinitely in the first place. I've used some code from here: https://www.geeksforgeeks.org/printing-paths-dijkstras-shortest-path-algorithm/ with slight modification to find the largest path rather than the shortest as well renaming variables. I feel an error in said modification is most likely one source of the problem. Following is the output of my most recent test:
Enter a positive integer.
5
Node list: {1,2,3,4,5}
Edge list: {(2,3,17),(2,4,8),(3,5,3)}
Enter a source node.
1
Enter a destination node
5
Vertex: 1 --> 5
Distance: 20
Path: Exception in thread "main" java.lang.StackOverflowError
at Graph.printPath(Graph.java:104)
at Graph.printPath(Graph.java:104)
at Graph.printPath(Graph.java:104)
Here's my code so far. I've had my code in separate classes, so I apologize for any errors I may have made combining them to one file. I also apologize for the massive and messy block of code but I don't think there's anything here I can weed out before posting.
import java.util.Scanner;
import java.util.ArrayList;
import java.util.Random;
public class Graph{
private ArrayList<Node> nodes = new ArrayList<Node>();
private ArrayList<Edge> edges = new ArrayList<Edge>();
private int[][] adjMatrix;
Graph(int numNodes, int weightBound, double probability){
ArrayList<Node> tempNodeList = new ArrayList<Node>(numNodes);
for(int i = 0; i < numNodes; i++) {
Node tempNode = new Node(i+1);
tempNodeList.add(tempNode);
}
this.nodes = tempNodeList;
Random rand = new Random();
for(int i = 0; i < numNodes; i++) {
for(int j = i+1; j < numNodes; j++) {
if(rand.nextInt((int)Math.round(1/probability)) == 0) {
Edge tempEdge = new Edge(rand.nextInt(5*numNodes-1)+1, nodes.get(i), nodes.get(j));
edges.add(tempEdge);
}
}
}
adjMatrix = new int[numNodes][numNodes];
for(int i = 0; i < edges.size(); i++) {
adjMatrix[edges.get(i).getNode(0).getID()-1][edges.get(i).getNode(1).getID()-1] = edges.get(i).getWeight();
adjMatrix[edges.get(i).getNode(1).getID()-1][edges.get(i).getNode(0).getID()-1] = edges.get(i).getWeight();
}
}
public void printGraph() {
System.out.print("Node list: {");
for(int i = 0; i < nodes.size(); i++) {
nodes.get(i).printNode();
if(i != nodes.size()-1) {
System.out.print(",");
}
}
System.out.println("}");
System.out.print("Edge list: {");
for(int i = 0; i < edges.size(); i++) {
edges.get(i).printEdge();
if(i != edges.size()-1) {
System.out.print(",");
}
}
System.out.println("}");
}
public void widestPath(int source, int dest){
int numVertices = adjMatrix[0].length;
int[] longestDists = new int[numVertices];
boolean[] inPath = new boolean[numVertices];
for(int i = 0; i < numVertices; i++) {
inPath[i] = false;
}
longestDists[source] = 0;
Node tempNode = nodes.get(source);
tempNode.setParent(-1);
nodes.set(source, tempNode);
for(int i = 1; i < numVertices; i++) {
int furthestNode = -1;
int longestDist = Integer.MIN_VALUE;
for(int index = 0; index < numVertices; index++) {
if(!inPath[index] && longestDists[index] > longestDist) {
furthestNode = index;
longestDist = longestDists[index];
}
}
inPath[furthestNode] = true;
for(int index = 0; index < numVertices; index++) {
int edgeWeight = adjMatrix[furthestNode][index];
if(edgeWeight > 0 && ((longestDist + edgeWeight) > (longestDists[index]))){
tempNode = nodes.get(index);
tempNode.setParent(furthestNode);
nodes.set(index, tempNode);
longestDists[index] = longestDist + edgeWeight;
}
}
}
printResult(source, longestDists, dest);
}
public void printResult(int source, int[] dists, int dest) {
System.out.println("Vertex: " + (source+1) + " --> " + (dest+1));
System.out.println("Distance: " + dists[dest]);
System.out.print("Path: ");
printPath(dest);
}
public void printPath(int dest) {
if(nodes.get(dest).getParent() == -1) {
return;
}
printPath(nodes.get(dest).getParent()); // StackOverflow here
System.out.print((dest+1) + " ");
}
}
public class Node {
private int ID;
private int distance = Integer.MIN_VALUE;
private int parent;
Node(int id){
this.ID = id;
}
public int getID() {
return this.ID;
}
public void printNode() {
System.out.print(this.ID);
}
public void setDist(int dist) {
this.distance = dist;
}
public int getDist() {
return this.distance;
}
public void setParent(int p) {
this.parent = p;
}
public int getParent() {
return this.parent;
}
}
public class Edge {
private int weight;
private ArrayList<Node> vertices = new ArrayList<Node>(2);
Edge(int weight){
this.weight = weight;
}
Edge(int weight, Node n1, Node n2){
this.weight = weight;
this.vertices.add(n1);
this.vertices.add(n2);
}
public int getWeight() {
return weight;
}
public void setNodes(Node n1, Node n2) {
this.vertices.set(0, n1);
this.vertices.set(1, n2);
}
public ArrayList<Node> getNodes(){
return vertices;
}
public void printEdge() {
System.out.print("(" + vertices.get(0).getID() + "," + vertices.get(1).getID() + "," + this.weight + ")");
}
public int otherNodeIndex(int ID) {
if(vertices.get(0).getID() == ID) {
return 1;
}else if(vertices.get(1).getID() == ID) {
return 0;
} else {
return -1;
}
}
public Node getNode(int index) {
return vertices.get(index);
}
}
public class Driver {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int input = -1;
while(input <= 0) {
System.out.println("Enter a positive integer.");
input = sc.nextInt();
}
double probability = 0.25;
Graph gr = new Graph(input, input*5, probability);
gr.printGraph();
int source = -1;
int dest = -1;
while(source < 0 || source > input) {
System.out.println("Enter a source node.");
source = sc.nextInt()-1;
}
while(dest < 0 || dest > input) {
System.out.println("Enter a destination node");
dest = sc.nextInt()-1;
}
gr.widestPath(source, dest);
}
}
Hello StackOverflow community, need your help. I have a final for my java class and its asking for:
Generate a graph with 100,000 nodes, where each node randomly has between 1 and 5 connections to other nodes. Each node should contain within it a random value between 1 and 300,000. (So generally about 1 in 3 searches will yield a query match). Allow the user to enter a number to search for, and implement each of the following three types of searching algorithms. Breadth-First. (30 points) Depth-First. (30 points) Dijkstra's Algorithm. (40 points)
Do not allow back-tracking in your searches. (Mark nodes that you already searched as complete, and do not re-visit them in the same search). Each search should return the following: The Success/Failure of your search. The length of the shortest path to the found node. The total number of nodes examined during the search. Optionally you may return the exhaustive display of the shortest path, for testing and verification.
For some reason, my IDE shows that BFS and Dijkstras has "duplicated code fragment 17 lines long" can someone look at tell me how to fix it or maybe a better way to implement it? Also, if i try to do nodesNum > 30k in "Driver Class" i get a memory leak.
Here is the code:
Class Graph:
import java.util.*;
import javax.swing.JOptionPane;
class Graph
{
private Listing[] vertex;
private int[][] edge;
private int max;
private int numberOfVertices;
private int nodeCheck = 0;
private int selectNum = 0;
Graph(int g)
{
vertex = new Listing[g];
edge = new int[g][g];
max = g;
numberOfVertices = 0;
}
private void depthFirstSearch(int firstVertex)
{
int v;
Stack<Integer> nodeStack = new Stack<>();
for(int i = 0; i<numberOfVertices; i++)
{
if (vertex[i] != null) {
vertex[i].setPushed(false);
}
}
nodeStack.push(firstVertex);
vertex[firstVertex].setPushed(true);
while (!nodeStack.empty())
{
v = nodeStack.pop();
vertex[v].visit();
nodeCheck++;
for (int column = 0; column < numberOfVertices; column++)
{
if(edge[v][column] == 1 && vertex[column].getPushed())
{
nodeStack.push(column);
vertex[column].setPushed(true);
}
}
}
}
private void breathFirstSearch(int firstVertex)
{
int V;
Queue<Integer> nodeQueue = new LinkedList<>();
for(int i = 0; i < numberOfVertices; i++)
{
if(vertex[i] != null)
vertex[i].setPushed(false);
}
nodeQueue.add(firstVertex);
vertex[firstVertex].setPushed(true);
while(!nodeQueue.isEmpty())
{
V = nodeQueue.remove();
vertex[V].visit();
nodeCheck++;
for(int column = 0; column < numberOfVertices; column++)
{
if(edge[V][column] == 1 && vertex[column].getPushed())
{
nodeQueue.add(column);
vertex[column].setPushed(true);
}
}
}
}
private void Dijkstra(int firstVertex)
{
int v;
LinkedList<Integer> nodeQueue = new LinkedList<>();
int i = 0;
while (i < numberOfVertices)
{
if(vertex[i] != null)
vertex[i].setPushed(false);
i++;
}
nodeQueue.add(firstVertex);
vertex[firstVertex].setPushed(true);
while(!nodeQueue.isEmpty())
{
v = nodeQueue.remove();
vertex[v].visit();
nodeCheck++;
for(int column = 0; column < numberOfVertices; column++)
{
if(edge[v][column] == 1 && vertex[column].getPushed())
{
nodeQueue.add(column);
vertex[column].setPushed(true);
}
}
}
}
private void insertVertex(int vertexNumber, Listing newListing)
{
if(vertexNumber >= max)
{
return;
}
vertex[vertexNumber] = newListing.deepCopy();
numberOfVertices++;
}
private void insertEdge(int fromVertex, int toVertex)
{
if(vertex[fromVertex] == null || vertex[toVertex] == null)
return;
edge[fromVertex][toVertex] = 1;
}
void showVertex(int vertexNumber)
{
System.out.print(vertex[vertexNumber]);
}
void showEdges(int vertexNumber)
{
for(int column = 0; column < numberOfVertices; column++)
{
if(edge[vertexNumber][column] == 1)
{
System.out.println(vertexNumber + "," + column);
}
}
System.out.println();
}
void InitializeNodes(Graph G, int nodesNum)
{
Random random = new Random();
for (int i = 0; i < nodesNum; i++ )
{
Listing v = new Listing(random.nextInt(300000) + 1);
G.insertVertex(i, v);
}
int vertexListNumber = G.vertex.length;
List<Integer> list = new ArrayList<>();
for (int i = 0; i < nodesNum; i++ )
{
list.add(i);
}
Collections.shuffle(list);
for (int i = 0; i < vertexListNumber; i++ )
{
int randnum = random.nextInt(5);
for (int j = 0; j < randnum; j++ )
{
int rand = random.nextInt(5);
G.insertEdge(i, list.get(rand));
}
}
}
int Search()
{
String search = JOptionPane.showInputDialog("Enter Node to search:");
try
{
if(search != null)
{
selectNum = Integer.parseInt(search);
}
}
catch (NumberFormatException e)
{
selectNum = 0;
}
return selectNum;
}
private int SelectPane()
{
String paneSelect = JOptionPane.showInputDialog("Choose a search method:" +
"\n\t1: Use Depth-First Search" +
"\n\t2: Use Breadth-First Search" +
"\n\t3: Use Dijkstra's Search" +
"\n\t4: Close Program");
int selectNum = 0;
try{
if(paneSelect != null)
{
selectNum = Integer.parseInt(paneSelect);
}
}
catch (NumberFormatException ignored)
{
}
return selectNum;
}
void algorithmChoice(Graph graph, int vertexStart)
{
int paneNum = 0;
while (paneNum != 4)
{
paneNum = SelectPane();
switch (paneNum)
{
case 1:
graph.depthFirstSearch(vertexStart);
System.out.println("Nodes counted were: " + nodeCheck);
System.out.println("------------------------------------");
break;
case 2:
graph.breathFirstSearch(vertexStart);
System.out.println("Nodes counted were: " + nodeCheck);
System.out.println("------------------------------------");
break;
case 3:
graph.Dijkstra(vertexStart);
System.out.println("Nodes counted were: " + nodeCheck);
System.out.println("------------------------------------");
break;
case 4:
break;
default:
JOptionPane.showMessageDialog(null, "Enter 4 to quit.");
break;
}
}
}
}
Class Listing:
public class Listing
{
private int value;
private boolean pushed;
Listing(int v)
{
value = v;
}
public String toString()
{
return ("Vertex: " + value + "\n" );
}
Listing deepCopy()
{
return new Listing(value);
}
boolean getPushed()
{
return !pushed;
}
void setPushed(boolean value)
{
pushed = value;
}
void visit()
{
System.out.println(this);
}
}
Class Driver:
public class Driver
{
public static void main(String[] args)
{
int nodesNum = 30000; //Can go up to 30k nodes, otherwise causes memory leak.
Graph graph = new Graph(nodesNum);
graph.InitializeNodes(graph, nodesNum);
for(int i = 0; i<5; i++)
{
System.out.print("Node " + i + "\'s ");
graph.showVertex(i);
System.out.print("Its routes are:\n");
graph.showEdges(i);
}
int select = graph.Search();
graph.algorithmChoice(graph, select);
}
}
Thanks alot for your help!
The error you get is due to exceeding max heap size when creating a edge = new int[g][g]; where g can be as high as 100,000 in your case.
I would suggest avoiding the use of such huge matrix.
Instead introduce an Edge object :
class Edge{
private final int fromVertex, toVertex;
Edge(int fromVertex, int toVertex){
this.fromVertex = fromVertex;
this.toVertex = toVertex;
}
#Override
public boolean equals(Object obj) {
if( ! (obj instanceof Edge)) return false;
Edge other = (Edge)obj;
return connects(other.fromVertex, other.toVertex);
}
boolean connects(int fromVertex, int toVertex){
return fromVertex == this.fromVertex && toVertex == this.toVertex ||
fromVertex == this.toVertex && toVertex == this.fromVertex;
}
}
and use it in Graph.
Instead of private int[][] edge; use a collection of Edges:
private final Set<Edge> edges = new HashSet<>();
Change insertEdge to:
private void insertEdge(int fromVertex, int toVertex)
{
if(vertex[fromVertex] == null || vertex[toVertex] == null)
return;
edges.add(new Edge(fromVertex, toVertex));
}
and add a method to check if there is an edge between two vertices:
private boolean isEdgeBetween(int fromVertex, int toVertex)
{
for(Edge edge : edges){
if(edge.connects(fromVertex, toVertex)) return true;
}
return false;
}
Usage : if( isEdgeBetween(v,column) && vertex[column].getPushed())
instead of: if(edge[v][column] == 1 && vertex[column].getPushed())
I am currently implementing Eight Puzzle problem using A* Algorithm (Hamming) method and have provided code :
public class Board
{
int board[][];
public Board()
{
board = new int[3][3];
}
public void initialise(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int n9)
{
//first row
board[0][0] = n1;
board[0][1] = n2;
board[0][2] = n3;
//second row
board[1][0] = n4;
board[1][1] = n5;
board[1][2] = n6;
//third row
board[2][0] = n7;
board[2][1] = n8;
board[2][2] = n9;
}
public int states_out_of_order()
{
int count = 0;
for(int i = 0; i < 3; i++)
{
//Checking if first row is
//1 2 3
if(i==0)
{
if(board[i][0]!=1)
{
count++;
}
if(board[i][1]!=2)
{
count++;
}
if(board[i][2]!=3)
{
count++;
}
}
//Checking if second row is
//4 5 6
if(i==1)
{
if(board[i][0]!=4)
{
count++;
}
if(board[i][1]!=5)
{
count++;
}
if(board[i][2]!=6)
{
count++;
}
}
//Checking if second row is
//7 8 0
if(i==2)
{
if(board[i][0]!=7)
{
count++;
}
if(board[i][1]!=8)
{
count++;
}
if(board[i][2]!=9)
{
count++;
}
}
}
return count;
}
public boolean GoalStateCheck()
{
//Checking first row
if(board[0][0]!=1)
{
return false;
}
if(board[0][1]!=2)
{
return false;
}
if(board[0][2]!=3)
{
return false;
}
//Checking second row
if(board[1][0]!=4)
{
return false;
}
if(board[1][1]!=5)
{
return false;
}
if(board[1][2]!=6)
{
return false;
}
//Checking third row
if(board[2][0]!=7)
{
return false;
}
if(board[2][1]!=8)
{
return false;
}
if(board[2][2]!=0)
{
return false;
}
return true;
}
public void printBoard()
{
System.out.print(board[0][0] + " " + board[0][1] + " " + board[0][2]);
System.out.println();
System.out.print(board[1][0] + " " + board[1][1] + " " + board[1][2]);
System.out.println();
System.out.print(board[2][0] + " " + board[2][1] + " " + board[2][2]);
System.out.println();
}
}
And now the solver class
import java.util.ArrayList;
public class Solver
{
ArrayList<Board> list;
int steps;
public Solver()
{
list = new ArrayList<Board>();
steps = 0;
}
public Board SwapStates(Board b, int a[][], int r1, int c1, int r2, int c2)
{
int temp = a[r1][c1];
a[r1][c1] = a[r2][c2];
a[r2][c2] = temp;
return b;
}
//Find the board in ArrayList according the number of states out of order
public Board findBoard(int num)
{
for(int i = 0; i < list.size(); i++)
{
if(num == list.get(i).states_out_of_order())
{
return list.get(i);
}
}
return null;
}
//Choose the puzzle state with minimum states that are out of order
public int min()
{
int n = 10;
for(int i = 0; i < list.size(); i++)
{
if(list.get(i).states_out_of_order() < n)
{
n = list.get(i).states_out_of_order();
}
}
return n;
}
//Find the board in ArrayList and remove it
public void matchRemove(Board b)
{
for(int i = 0; i < list.size(); i++)
{
if(b == list.get(i))
{
list.remove(list.get(i));
break;
}
}
}
public void Hamming(Board b)
{
boolean solved = b.GoalStateCheck();
while(!solved)
{
if(b.board[0][0] == 0)
{
//Pointer to original board
final Board ptr = b;
Board b1 = ptr;
Board b2 = ptr;
//Check move #1 from original state
b1 = SwapStates(b1, b1.board,0,0,0,1);
//Check move #2 from original state
//Problem is that it is not swapping ptr but rather its swapping b1. why?
b2 = SwapStates(b2, b2.board,0,0,1,0);
//Add the moves to the Arraylist
list.add(b1);
list.add(b2);
//Find the board with minimum number of states out of order and remove it frm list
int n = min();
Board temp = findBoard(n);
matchRemove(temp);
//Assign removed board as optimum move
b = temp;
steps++;
b.printBoard();
}
else if(b.board[0][1] == 0)
{
}
else if(b.board[0][2] == 0)
{
}
else if(b.board[1][0] == 0)
{
}
else if(b.board[1][1] == 0)
{
}
else if(b.board[1][2] == 0)
{
}
else if(b.board[2][0] == 0)
{
}
else if(b.board[2][1] == 0)
{
}
else if(b.board[2][2] == 0)
{
}
else
{
System.out.println("Board is not in its proper form");
break;
}
}
/*System.out.println("Goal State has been achieved!!");
System.out.println("It took " + steps + " moves");
b.printBoard();*/
}
}
In the Hamming function of my Solver class at the first if statement i have this line
final Board ptr = b;
Board b1 = ptr;
Board b2 = ptr;
However when at these two lines:
//Check move #1 from original state
b1 = SwapStates(b1, b1.board,0,0,0,1);
//Check move #2 from original state
//Problem is that it is not swapping ptr but rather its swapping b1. why?
b2 = SwapStates(b2, b2.board,0,0,1,0);
b2 is using the swapped state of b1 instead of the original ptr which i want to use. why?
When you've written
final Board ptr = b;
Board b1 = ptr;
Board b2 = ptr;
You did not create an immutable copy of b called ptr and two mutable copies of ptr called b1 and b2.
You simply created 3 references to the same object. Any modification on the object using any of the 4 references will end up affecting the object in the same way and thus, change the visible state for all 4 references.
What you should do is add a public Board copy() method in your board class which would return another instance of Board (using a new Board() and copying values) and change your code by :
final Board ptr = b.copy(); // but is there any sense to use ptr rather than b ?
Board b1 = ptr.copy();
Board b2 = ptr.copy();
Greeting to everyone. I currently work on a program that sorting the emergency number of patients(the number that assigned by nurse when they enter the emergency room and this number determines the seriousness of their sickness too). However, if there are more than 1 patient who hold the same emergency numbers(eg: 2 patients hold emergency number 1), the one who came earlier should receive the treatment first. For this reason, I have 2 sortings, one is to sort the emergency number in ascending order and the other is to sort the time in ascending order too. But unfortunately the second sorting cannot work correctly.The following are the explanations for the type of emergency numbers:
Emergency number : 1 – Immediately life threatening
Emergency number : 2 – Urgent, but not immediately life threatening
Emergency number : 3 – Less urgent
So,now comes the coding part(Please note that this is a linkedlist)
Interface:
public interface ListInterface<T> {
public boolean add(T newEntry);
public boolean add(int newPosition, T newEntry);
public T remove(int givenPosition);
public void clear();
public boolean replace(int givenPosition, T newEntry);
public T getEntry(int givenPosition);
public boolean contains(T anEntry);
public int getLength();
public boolean isEmpty();
public boolean isFull();
}
LList class:
/**
* LList.java
* A class that implements the ADT list by using a chain of nodes,
* with the node implemented as an inner class.
*/
public class LList<T> implements ListInterface<T> {
private Node firstNode; // reference to first node
private int length; // number of entries in list
public LList() {
clear();
}
public final void clear() {
firstNode = null;
length = 0;
}
public boolean add(T newEntry) {
Node newNode = new Node(newEntry); // create the new node
if (isEmpty()) // if empty list
firstNode = newNode;
else { // add to end of nonempty list
Node currentNode = firstNode; // traverse linked list with p pointing to the current node
while (currentNode.next != null) { // while have not reached the last node
currentNode = currentNode.next;
}
currentNode.next = newNode; // make last node reference new node
}
length++;
return true;
}
public boolean add(int newPosition, T newEntry) { // OutOfMemoryError possible
boolean isSuccessful = true;
if ((newPosition >= 1) && (newPosition <= length+1)) {
Node newNode = new Node(newEntry);
if (isEmpty() || (newPosition == 1)) { // case 1: add to beginning of list
newNode.next = firstNode;
firstNode = newNode;
}
else { // case 2: list is not empty and newPosition > 1
Node nodeBefore = firstNode;
for (int i = 1; i < newPosition - 1; ++i) {
nodeBefore = nodeBefore.next; // advance nodeBefore to its next node
}
newNode.next = nodeBefore.next; // make new node point to current node at newPosition
nodeBefore.next = newNode; // make the node before point to the new node
}
length++;
}
else
isSuccessful = false;
return isSuccessful;
}
public T remove(int givenPosition) {
T result = null; // return value
if ((givenPosition >= 1) && (givenPosition <= length)) {
if (givenPosition == 1) { // case 1: remove first entry
result = firstNode.data; // save entry to be removed
firstNode = firstNode.next;
}
else { // case 2: givenPosition > 1
Node nodeBefore = firstNode;
for (int i = 1; i < givenPosition - 1; ++i) {
nodeBefore = nodeBefore.next; // advance nodeBefore to its next node
}
result = nodeBefore.next.data; // save entry to be removed
nodeBefore.next = nodeBefore.next.next; // make node before point to node after the
} // one to be deleted (to disconnect node from chain)
length--;
}
return result; // return removed entry, or
// null if operation fails
}
public boolean replace(int givenPosition, T newEntry) {
boolean isSuccessful = true;
if ((givenPosition >= 1) && (givenPosition <= length)) {
Node currentNode = firstNode;
for (int i = 0; i < givenPosition - 1; ++i) {
// System.out.println("Trace| currentNode.data = " + currentNode.data + "\t, i = " + i);
currentNode = currentNode.next; // advance currentNode to next node
}
currentNode.data = newEntry; // currentNode is pointing to the node at givenPosition
}
else
isSuccessful = false;
return isSuccessful;
}
public T getEntry(int givenPosition) {
T result = null;
if ((givenPosition >= 1) && (givenPosition <= length)) {
Node currentNode = firstNode;
for (int i = 0; i < givenPosition - 1; ++i) {
currentNode = currentNode.next; // advance currentNode to next node
}
result = currentNode.data; // currentNode is pointing to the node at givenPosition
}
return result;
}
public boolean contains(T anEntry) {
boolean found = false;
Node currentNode = firstNode;
while (!found && (currentNode != null)) {
if (anEntry.equals(currentNode.data))
found = true;
else
currentNode = currentNode.next;
}
return found;
}
public int getLength() {
return length;
}
public boolean isEmpty() {
boolean result;
if (length == 0)
result = true;
else
result = false;
return result;
}
public boolean isFull() {
return false;
}
public String toString() {
String outputStr = "";
Node currentNode = firstNode;
while (currentNode != null) {
outputStr += currentNode.data + "\n";
currentNode = currentNode.next;
}
return outputStr;
}
private class Node {
private T data;
private Node next;
private Node(T data) {
this.data = data;
this.next = null;
}
private Node(T data, Node next) {
this.data = data;
this.next = next;
}
} // end Node
} // end LList
Patient class:
public class Patient {
private int emergencyNo;
private int queueTime;
private String patientName;
private String patientIC;
private String patientGender;
private String patientTelNo;
private String patientAdd;
private String visitDate;
public Patient() {
}
public Patient(int emergencyNo, int queueTime, String patientName, String patientIC, String patientGender, String patientTelNo, String patientAdd, String visitDate)
{
this.emergencyNo = emergencyNo;
this.queueTime = queueTime;
this.patientName = patientName;
this.patientIC = patientIC;
this.patientGender = patientGender;
this.patientTelNo = patientTelNo;
this.patientAdd = patientAdd;
this.visitDate = visitDate;
}
//set methods
public void setQueueTime(int queueTime)
{
this.queueTime = queueTime;
}
public boolean setEmergencyNo(int emergencyNo)
{
boolean varEmergencyNo = true;
if (emergencyNo != 1 && emergencyNo != 2 && emergencyNo != 3)
{
varEmergencyNo = false;
System.out.println("Emergency number is in invalid format!");
System.out.println("Emergency number is either 1, 2 or 3 only!");
System.out.println("\n");
}
else
{
this.emergencyNo = emergencyNo;
}
return varEmergencyNo;
}
public boolean setPatientName(String patientName)
{
boolean varPatientName = true;
if (patientName.equals("") || patientName.equals(null))
{
varPatientName = false;
System.out.println("The patient name cannot be empty!\n");
}
else
{
this.patientName = patientName;
}
return varPatientName;
}
public boolean setPatientIC(String patientIC)
{
boolean varPatientIC = true;
if(!patientIC.matches("^[0-9]{12}$"))
{
varPatientIC = false;
System.out.println("IC is in invalid format!");
System.out.println("It must consist of 12 numbers only!\n");
}
else
{
this.patientIC = patientIC;
}
return varPatientIC;
}
public boolean setPatientGender(String patientGender)
{
boolean varPatientGender = true;
if(!patientGender.equals("F") && !patientGender.equals("f") && !patientGender.equals("M") && !patientGender.equals("m"))
{
varPatientGender = false;
System.out.println("Gender is in invalid format!");
System.out.println("It must be either 'M' or 'F' only!\n");
}
else
{
this.patientGender = patientGender;
}
return varPatientGender;
}
public boolean setPatientTelNo(String patientTelNo)
{
boolean varPatientTelNo = true;
if((!patientTelNo.matches("^01[02346789]\\d{7}$")) && (!patientTelNo.matches("^03\\d{8}$")))
{
varPatientTelNo = false;
System.out.println("Invalid phone number!");
System.out.println("It must be in the following format : 0167890990 / 0342346789!\n");
System.out.print("\n");
}
else
{
this.patientTelNo = patientTelNo;
}
return varPatientTelNo;
}
public boolean setPatientAdd(String patientAdd)
{
boolean varPatientAdd = true;
if (patientAdd.equals("") || patientAdd.equals(null))
{
varPatientAdd = false;
System.out.println("The patient address cannot be empty!\n");
}
else
{
this.patientAdd = patientAdd;
}
return varPatientAdd;
}
public void setVisitDate(String visitDate)
{
this.visitDate = visitDate;
}
//get methods
public int getQueueTime()
{
return this.queueTime;
}
public int getEmergencyNo()
{
return this.emergencyNo;
}
public String getPatientName()
{
return this.patientName;
}
public String getPatientIC()
{
return this.patientIC;
}
public String getPatientGender()
{
return this.patientGender;
}
public String getPatientTelNo()
{
return this.patientTelNo;
}
public String getPatientAdd()
{
return this.patientAdd;
}
public String getVisitDate()
{
return this.visitDate;
}
#Override
public String toString()
{
return (this.emergencyNo + "\t\t" + this.patientName + "\t\t" + this.patientIC +
"\t\t" + this.patientGender + "\t\t" + this.patientTelNo + "\t\t" + this.patientAdd + "\t\t" + this.visitDate);
}
public String anotherToString()
{
return (this.emergencyNo + "\t\t\t\t\t\t" + this.patientName + "\t\t\t " + this.visitDate);
}
}
EmergencyCmp(Comparator)--->use for sorting the emergency numbers of the patients
import java.util.Comparator;
public class EmergencyCmp implements Comparator<Patient>
{
#Override
public int compare(Patient p1, Patient p2)
{
if(p1.getEmergencyNo() > p2.getEmergencyNo())
{
return 1;
}
else
{
return -1;
}
}
}
QueueCmp(Comparator)--->use for sorting the arrival time of the patients
import java.util.Comparator;
public class QueueCmp implements Comparator<Patient>
{
#Override
public int compare(Patient p1, Patient p2)
{
if(p1.getQueueTime() > p2.getQueueTime())
{
return 1;
}
else
{
return -1;
}
}
}
Main function:
import java.util.Calendar;
import java.util.Scanner;
import java.util.Arrays;
import java.util.*;
public class DSA {
public DSA() {
}
public static void main(String[] args) {
//patient's attributes
int emergencyNo;
int queueTime;
String patientName;
String patientIC;
String patientGender;
String patientTelNo;
String patientAdd;
String visitDate;
//counter
int j = 0;
int x = 0;
int y = 0;
int z = 0;
int count1 = 0;
int count2 = 0;
int count3 = 0;
int countEnteredPatient = 1;
int totalCount = 0;
//calendar
int nowYr, nowMn, nowDy, nowHr, nowMt, nowSc;
//others
boolean enterNewPatient = true;
String continueInput;
boolean enterNewPatient1 = true;
String continueInput1;
boolean continueEmergencyNo;
Scanner scan = new Scanner(System.in);
ListInterface<Patient> patientList = new LList<Patient>();
ListInterface<Patient> newPatientList = new LList<Patient>();
Patient[] patientArr1 = new Patient[10000];
Patient[] patientArr2 = new Patient[10000];
Patient[] patientArr3 = new Patient[10000];
Patient tempoPatient;
do{
//do-while loop for entering new patient details after viewing patient list
System.out.println("Welcome to Hospital Ten Stars!\n");
do{
//do-while loop for entering new patient details
System.out.println("Entering details of patient " + countEnteredPatient);
System.out.println("===================================\n");
Calendar calendar = Calendar.getInstance();
nowYr = calendar.get(Calendar.YEAR);
nowMn = calendar.get(Calendar.MONTH);
nowDy = calendar.get(Calendar.DAY_OF_MONTH);
nowHr = calendar.get(Calendar.HOUR);
nowMt = calendar.get(Calendar.MINUTE);
nowSc = calendar.get(Calendar.SECOND);
queueTime = calendar.get(Calendar.MILLISECOND);
visitDate = nowDy + "/" + nowMn + "/" + nowYr + ", " + nowHr + ":" + nowMt + ":" + nowSc;
//input emergency number
do{
tempoPatient = new Patient();
continueEmergencyNo = false;
int EmergencyNoOption;
try
{
do{
System.out.print("Please select 1 – Immediately life threatening, 2 – Urgent, but not immediately life threatening or 3 – Less urgent(Eg: 1) : ");
EmergencyNoOption = scan.nextInt();
scan.nextLine();
System.out.print("\n");
}while(tempoPatient.setEmergencyNo(EmergencyNoOption) == false);
}
catch(InputMismatchException ex)
{
System.out.print("\n");
System.out.println("Invalid input detected.");
scan.nextLine();
System.out.print("\n");
continueEmergencyNo = true;
}
}while(continueEmergencyNo);
//input patient name
do{
System.out.print("Patient name(Eg: Christine Redfield) : ");
patientName = scan.nextLine();
System.out.print("\n");
}while(tempoPatient.setPatientName(patientName) == false);
//input patient ic no
do{
System.out.print("Patient IC number(Eg: 931231124567) : ");
patientIC = scan.nextLine();
System.out.print("\n");
}while(tempoPatient.setPatientIC(patientIC) == false);
//input patient gender
do{
System.out.print("Patient gender(Eg: M) : ");
patientGender = scan.nextLine();
System.out.print("\n");
}while(tempoPatient.setPatientGender(patientGender) == false);
//input patient tel. no
do{
System.out.print("Patient tel.No(without'-')(Eg: 0162345678/0342980123) : ");
patientTelNo = scan.nextLine();
System.out.print("\n");
}while(tempoPatient.setPatientTelNo(patientTelNo) == false);
//input patient address
do{
System.out.print("Patient address(Eg: 4-C9 Jln Besar 123, Taman Besar, 56000 Kuala Lumpur) : ");
patientAdd = scan.nextLine();
System.out.print("\n");
}while(tempoPatient.setPatientAdd(patientAdd) == false);
tempoPatient.setQueueTime(queueTime);
tempoPatient.setVisitDate(visitDate);
patientList.add(tempoPatient);
//decide whether want to enter a new patient or not
do{
System.out.print("Do you want to enter another new patient?(Eg: Y/N) : ");
continueInput = scan.nextLine();
if(continueInput.equals("Y") || continueInput.equals("y"))
{
enterNewPatient = true;
System.out.print("\n");
}
else if(continueInput.equals("N") || continueInput.equals("n"))
{
enterNewPatient = false;
}
else
{
System.out.println("\n");
System.out.println("Please enter Y/N only.\n");
}
}while(!continueInput.equals("Y") && !continueInput.equals("y") && !continueInput.equals("N") && !continueInput.equals("n"));
countEnteredPatient++;
}while(enterNewPatient); //end do-while loop for entering new patient details
System.out.println("\nWaiting list of patient will be displayed soon.\n");
try{
Thread.sleep(1000);
}
catch (Exception e)
{
}
System.out.println("Waiting list of patients");
System.out.println("========================\n");
System.out.println("Number\t\tEmergency number\t\tPatient name\t\t ArrivalTime");
System.out.println("============================================================================");
for(int i = 1; i <= patientList.getLength(); i++)
{
System.out.println(i + "\t\t\t" + patientList.getEntry(i).anotherToString());
}
do{
System.out.print("\nSo, now do you want to enter another new patient?(Eg: Y/N) : ");
continueInput1 = scan.nextLine();
if(continueInput1.equals("Y") || continueInput1.equals("y"))
{
enterNewPatient1 = true;
System.out.print("\n");
}
else if(continueInput1.equals("N") || continueInput1.equals("n"))
{
enterNewPatient1 = false;
}
else
{
System.out.println("\n");
System.out.println("Please enter Y/N only.\n");
}
}while(!continueInput1.equals("Y") && !continueInput1.equals("y") && !continueInput1.equals("N") && !continueInput1.equals("n"));
}while(enterNewPatient1);//end do-while loop for entering new patient details after viewing patient list
System.out.println("\nNow rearranging the list based on the seriouness and their arrival time.");
try{
Thread.sleep(1000);
}
catch (Exception e)
{
}
//create an unsorted array
Patient[] tempoPatientArr = new Patient[patientList.getLength()];
//copy the contents of patientList into tempoPatientArr
for(int i = 1; i <= patientList.getLength(); i++ )
{
tempoPatientArr[i-1] = patientList.getEntry(i);
}
//sort tempoPatientArr
Arrays.sort(tempoPatientArr, new EmergencyCmp());
//the above part until this comment line does not have problem
//check the emergency no and then categorise accordingly
for(int i = 0; i < tempoPatientArr.length; i++)
{
if(tempoPatientArr[i].getEmergencyNo() == 1)
{
patientArr1[x] = tempoPatientArr[i];
x++;
}
else if(tempoPatientArr[i].getEmergencyNo() == 2)
{
patientArr2[y] = tempoPatientArr[i];
y++;
}
else if(tempoPatientArr[i].getEmergencyNo() == 3)
{
patientArr3[z] = tempoPatientArr[i];
z++;
}
}
//to check how many !null elements by using count for 3 sub-arrays
for(int i = 0; i < patientArr1.length; i++)
{
if(patientArr1[i] != null)
{
count1++;
}
else
{
break;
}
}
for(int i = 0; i < patientArr2.length; i++)
{
if(patientArr2[i] != null)
{
count2++;
}
else
{
break;
}
}
for(int i = 0; i < patientArr3.length; i++)
{
if(patientArr3[i] != null)
{
count3++;
}
else
{
break;
}
}
//new array with elimination of null values
Patient[] newPatientArr1 = new Patient[count1];
Patient[] newPatientArr2 = new Patient[count2];
Patient[] newPatientArr3 = new Patient[count3];
//copy the contents of old sub arrays(the arrays with null values) into the new sub arrays(without null values)
for(int i = 0; i < newPatientArr1.length; i++)
{
newPatientArr1[i] = patientArr1[i];
}
for(int i = 0; i < newPatientArr2.length; i++)
{
newPatientArr2[i] = patientArr2[i];
}
for(int i = 0; i < newPatientArr3.length; i++)
{
newPatientArr3[i] = patientArr3[i];
}
totalCount = count1 + count2 + count3;
//array that used to combine all the sub-arrays
Patient[] newPatientArr = new Patient[totalCount];
//sort all sub new arrays
Arrays.sort(newPatientArr1, new QueueCmp());
Arrays.sort(newPatientArr2, new QueueCmp());
Arrays.sort(newPatientArr3, new QueueCmp());
//combine the contents of sub new arrays into the newPatientArr array
do{
for (int i = 0; i < count1; i++)
{
newPatientArr[j] = newPatientArr1[i];
j++;
}
for (int b = 0; b < count2; b++)
{
newPatientArr[j] = newPatientArr2[b];
j++;
}
for (int c = 0; c < count3; c++)
{
newPatientArr[j] = newPatientArr3[c];
j++;
}
}while(j < totalCount);
//relink the nodes
for(int i = 0; i < newPatientArr.length; i++)
{
newPatientList.add(newPatientArr[i]);
}
System.out.println("\nSorted waiting list of patients");
System.out.println("===============================\n");
System.out.println("Number\t\tEmergency number\t\tPatient name\t\t ArrivalTime");
System.out.println("============================================================================");
for(int i = 1; i <= newPatientList.getLength(); i++)
{
System.out.println(i + "\t\t\t" + newPatientList.getEntry(i).anotherToString());
}
}
}
Interface and LList class definitely do not have problems. So everyone can skip the 2 parts.
For the main function, I have a comment like this:
//the above part until this comment line does not have problem
When you all see the comment, that means the previous code does not have problem and you all may skip it and below is an attachment of the result that I got earlier:
So, from the picture you all can see that the sorting of arrival time is not correct. I hope that I can know why does this problem occurs since I cannot figure it out by myself. Thanks to all of you first.
So, after taking the advice of #Scott Hunter, I have made the following modification to the EmergencyCmp:
#Override
public int compare(Patient p1, Patient p2)
{
int value = 0;
if(p1.getEmergencyNo() > p2.getEmergencyNo())
{
value = 1;
}
else if(p1.getEmergencyNo() < p2.getEmergencyNo())
{
value = -1;
}
else if(p1.getEmergencyNo() == p2.getEmergencyNo())
{
if(p1.getQueueTime() > p2.getQueueTime())
{
return 1;
}
else
{
return -1;
}
}
return value;
}
However, the time sorting still produce a wrong result.
As I understand it (which I may not; you provided a LOT of extraneous stuff), it looks like you are trying to perform 2 distinct sorts, one after the other, such that the second is undoing the work of the first. Instead, you should define a single Comparator which compares emergency numbers and, only if they are the same, compares arrival times.