So I had to write this to simulate queues on two servers running the same operation, to compare if a shop needs to hire a second cashier depending on how efficient the simulation runs. Single queue with single server vs single queue with two servers. I write all my code in main rather than creating additional classes and calling/extending since JAVA is not my strong suite, it takes me a ton of time to come up with this stuff and I write very simple code so it gets really long as you can see. Are there any pointers that you folks can give me based on what you see, to help me streamline this? Within the methods, constructors or classes, groups of lines or code that can be reduced, be more efficient? This works with the desired results though. My apologies if this is not the right way to ask or not the right thing to ask, I will delete it. Thanks in advance.
public class SimulationProject1 {
private static int poissonDistr(double mean) {
Random x = new Random();
double J = Math.exp(-mean);
int i = 0;
double pD = 1.0;
do {
pD = pD * x.nextDouble();
i++;
} while (pD > J);
return i - 1;
}
public class listNode {
int data;
listNode next;
public listNode(int data) {
this.data = data;
this.next = null;
}
}
private final listNode head;
public SimulationProject1() {
this.head = null;
}
public boolean isEmpty() {
return (this.head == null);
}
public int getFirst() {
return head.data;
}
public static class LinkedQueue extends SimulationProject1 {
int size;
int totalTime;
private class Node {
int items;
int waitTime;
int dead;
Node next;
public Node(int items) {
this.items = items;
waitTime = 0;
dead = 0;
size++;
this.next = null;
}
}
private Node head;
public void enqueue(int items) {
if (head == null) {
head = new Node(items);
} else {
Node tmp = head;
while (tmp.next != null) {
tmp = tmp.next;
}
tmp.next = new Node(items);
}
this.size++;
}
public void dequeue() {
if (this.head == null) {
System.out.println("No customers in line");
} else {
this.head = head.next;
}
this.size--;
}
public void setWaitTime() {
Node temp = head;
while (temp != null) {
temp.waitTime++;
temp = temp.next;
}
}
public void getWaitTime() {
Node temp = head;
if(temp != null){
while (temp != null) {
totalTime = temp.waitTime + totalTime;
System.out.println("Total wait time: " + totalTime);
temp = temp.next;
}
}else{
System.out.println("Noone's waiting..");
}
}
public void setTimeout() {
Node temp = head;
while (temp != null) {
if (temp.waitTime >= 8) {
temp.dead = 1;
this.size--;
} else if (temp.waitTime <= 8) {
temp.waitTime++;
}
temp = temp.next;
}
}
}
public static void oneServer(LinkedQueue line, LinkedQueue cashier) {
int cost = 0;
int profit = 0;
int timedOut = 0;
int inLine = 0;
double mean = 0.2;
int [] customersServiced = new int[50];
int [] customerWaitTime = new int[50];
int [] customersInLine = new int[50];
int [] profitData = new int[50];
int [] costData = new int[50];
for (int i = 0; i < 50; i++) {
cost = cost - 3;
for (int j = 0; j < poissonDistr(mean); j++) {
System.out.println("Customers Arriving");
int items = (int) (Math.random() * 6 + 2);
line.enqueue(items);
}
if (line.head != null && line.head.dead == 1) {
timedOut++;
line.dequeue();
cost = cost - 10;
}
if (cashier.head == null && line.head != null && line.head.dead == 0) {
System.out.println("Line Moving");
cashier.head = line.head;
line.head = line.head.next;
}
if (cashier.head != null && cashier.head.items > 0) {
cashier.head.items--;
} else if (cashier.head != null && cashier.head.items <= 0) {
System.out.println("Available");
profit++;
cashier.head = null;
}
line.setWaitTime();
line.setTimeout();
System.out.println("Number currently in line: " + line.size);
customersInLine[i] = line.size;
line.getWaitTime();
customerWaitTime[i] = line.totalTime;
System.out.println("Customers serviced: " + profit);
customersServiced[i] = profit;
profitData[i] = profit;
costData[i] = cost;
}
while (line.head != null) {
line.head = line.head.next;
inLine++;
}
System.out.println("\n" + "-------------------------Stats-----------------------------" + "\n" + "Cost: " +
cost + "\nPer iteration: " + Arrays.toString(costData) + "\n");
System.out.println("Profit: " + profit + "\nPer iteration: " + Arrays.toString(profitData) + "\n");
System.out.println("In the line: " + inLine + "\nAccrued per iteration: " + Arrays.toString(customersInLine) + "\n");
System.out.println("Timed out: " + timedOut + "\n");
System.out.println("Total wait time: " + line.totalTime + "\nPer iteration: " + Arrays.toString(customerWaitTime) + "\n");
}
public static void twoServer(LinkedQueue line, LinkedQueue cashier, LinkedQueue cashier2) {
int cost = 0;
int profit = 0;
int timedOut = 0;
int inLine = 0;
double mean = 0.2;
int[] customersServiced = new int[50];
int[] customerWaitTime = new int[50];
int[] customersInLine = new int[50];
int[] profitData = new int[50];
int[] costData = new int[50];
for (int i = 0; i < 50; i++) {
cost = cost - 6;
for (int j = 0; j < poissonDistr(mean); j++) {
System.out.println("Customers Arriving");
int items = (int) (Math.random() * 6 + 2);
line.enqueue(items);
}
if (line.head != null && line.head.dead == 1) {
timedOut++;
line.dequeue();
cost = cost - 10;
}
if (cashier.head == null && line.head != null && line.head.dead == 0) {
System.out.println("Line Moving");
cashier.head = line.head;
line.head = line.head.next;
}
if (cashier2.head == null && line.head != null && line.head.dead == 0) {
System.out.println("Line Moving");
cashier2.head = line.head;
line.head = line.head.next;
}
if (cashier.head != null && cashier.head.items > 0) {
cashier.head.items--;
} else if (cashier.head != null && cashier.head.items <= 0) {
System.out.println("Available");
profit++;
cashier.head = null;
}
if (cashier2.head != null && cashier2.head.items > 0) {
cashier2.head.items--;
} else if (cashier2.head != null && cashier2.head.items <= 0) {
System.out.println("Available");
profit++;
cashier2.head = null;
}
line.setWaitTime();
line.setTimeout();
System.out.println("Number currently in line: " + line.size);
customersInLine[i] = line.size;
line.getWaitTime();
customerWaitTime[i] = line.totalTime;
System.out.println("Customers serviced: " + profit);
customersServiced[i] = profit;
profitData[i] = profit;
costData[i] = cost;
}
while (line.head != null) {
line.head = line.head.next;
inLine++;
}
System.out.println("\n" + "-------------------------Stats-----------------------------" + "\n" +
"Cost: " + cost + "\nPer iteration: " + Arrays.toString(costData) + "\n");
System.out.println("Profit: " + profit + "\nPer iteration: " + Arrays.toString(profitData) + "\n");
System.out.println("In the line: " + inLine + "\nAccrued per iteration: " + Arrays.toString(customersInLine) + "\n");
System.out.println("Timed out: " + timedOut + "\n");
System.out.println("Total wait time: " + line.totalTime + "\nPer iteration: " + Arrays.toString(customerWaitTime) + "\n");
}
public static void main(String[] args) {
LinkedQueue line = new LinkedQueue();
LinkedQueue line2 = new LinkedQueue();
LinkedQueue cashier = new LinkedQueue();
LinkedQueue cashier2 = new LinkedQueue();
oneServer(line, cashier);
System.out.println("-------------------------Double Server------------------------------------");
twoServer(line2, cashier, cashier2);
}
}
The output it too large to post, it has stuff like
Numbers in line
Currently Waiting
Currently serviced
Cost
Loss
Profit
etc
Related
I'm trying to implement an algorithm for Huffman coding, I have a very simple code at the moment that works fine. In my code, the weight of the character is based on the frequency of occurrence of that character, however I would like to improve it so that it meets the following criteria:
I would like my code to consider the order in which a node is encountered. For example if ’e’ and ’ ’ have the same frequency, but ’e’ occurs first, its weight would be considered greater. I have been trying to implement this for my code but it seems to give me mixed results.
Here is what I have. Any input on how to go about this would be greatly appreciated. I apologize in advance if this is too simple, but I'm a student and still learning.
import java.util.ArrayList;
public class Huffman {
static Node node;
static Node newRoot;
static String codedString = "";
public static void main(String[] args) {
String message = "'twas brillig, and the slithy toves did gyre and gimble in the wabe: all mimsy were the borogoves, and the mome raths outgrabe. "
+ "\"beware the jabberwock, my son! the jaws that bite, the claws that catch! beware the jubjub bird, and shun the frumious bandersnatch!\" "
+ "he took his vorpal sword in hand: long time the manxome foe he sought -- so rested he by the tumtum tree, and stood awhile in thought. "
+ "and, as in uffish thought he stood, the jabberwock, with eyes of flame, came whiffling through the tulgey wood, and burbled as it came! "
+ "one, two! one, two! and through and through the vorpal blade went snicker-snack! he left it dead, and with its head he went galumphing back. "
+ "\"and, has thou slain the jabberwock? come to my arms, my beamish boy! o frabjous day! callooh! callay!\" "
+ " he chortled in his joy. 'twas brillig, and the slithy toves did gyre and gimble in the wabe; "
+ " all mimsy were the borogoves, and the mome raths outgrabe.";
// Convert the string to char array
char[] msgChar = message.toCharArray();
ArrayList<Character> characters = new ArrayList<Character>();
/*
* Get a List of all the chars which are present in the string No
* repeating the characters!
*/
for (int i = 0; i < msgChar.length; i++) {
if (!(characters.contains(msgChar[i]))) {
characters.add(msgChar[i]);
}
}
/* Print out the available characters */
// System.out.println(characters);
/* Count the number of occurrences of Characters */
int[] countOfChar = new int[characters.size()];
/* Fill The Array Of Counts with one as base value */
for (int x = 0; x < countOfChar.length; x++) {
countOfChar[x] = 0;
}
/* Do Actual Counting! */
for (int i = 0; i < characters.size(); i++) {
char checker = characters.get(i);
for (int x = 0; x < msgChar.length; x++) {
if (checker == msgChar[x]) {
countOfChar[i]++;
}
}
}
/* Sort the arrays is descending order */
for (int i = 0; i < countOfChar.length - 1; i++) {
for (int j = 0; j < countOfChar.length - 1; j++) {
if (countOfChar[j] < countOfChar[j + 1]) {
int temp = countOfChar[j];
countOfChar[j] = countOfChar[j + 1];
countOfChar[j + 1] = temp;
char tempChar = characters.get(j);
characters.set(j, characters.get(j + 1));
characters.set(j + 1, tempChar);
}
}
}
/* Print Out The Frequencies of the Characters */
for (int x = 0; x < countOfChar.length; x++) {
System.out.println(characters.get(x) + " - " + countOfChar[x]);
}
/* Form the Tree! */
/* Form Leaf Nodes and Arrange them in a linked list */
Node root = null;
Node current = null;
Node end = null;
for (int i = 0; i < countOfChar.length; i++) {
Node node = new Node(characters.get(i).toString(), countOfChar[i]);
if (root == null) {
root = node;
end = node;
} else {
current = root;
while (current.linker != null) {
current = current.linker;
}
current.linker = node;
current.linker.linkerBack = current;
end = node;
}
}
// Recursively add and make nodes!
TreeMaker(root, end);
// inOrder(root);
System.out.println();
inOrder(node);
// preOrder(root);
System.out.println();
preOrder(node);
// Calculate the ends and the meets!
char[] messageArray = message.toCharArray();
char checker;
for (int i = 0; i < messageArray.length; i++) {
current = node;
checker = messageArray[i];
String code = "";
while (true) {
if (current.left.value.toCharArray()[0] == checker) {
code += "0";
break;
} else {
code += "1";
if (current.right != null) {
if (current.right.value.toCharArray()[0] == characters
.get(countOfChar.length - 1)) {
break;
}
current = current.right;
} else {
break;
}
}
}
codedString += code;
}
System.out.println();
System.out.println("The coded string is " + codedString);
}
public static void preOrder(Node root) {
if (root != null) {
System.out.print(root.value + "->");
preOrder(root.left);
preOrder(root.right);
}
}
public static void inOrder(Node root) {
if (root != null) {
inOrder(root.left);
System.out.print(root.value + "->");
inOrder(root.right);
}
}
public static void TreeMaker(Node root, Node end) {
node = new Node(end.linkerBack.value + end.value, end.linkerBack.count
+ end.count);
node.left = end.linkerBack;
node.right = end;
end.linkerBack.linkerBack.linker = node;
node.linkerBack = end.linkerBack.linkerBack;
end = node;
end.linker = null;
Node current = root;
while (current.linker != null) {
System.out.print(current.value + "->");
current = current.linker;
}
System.out.println(current.value);
if (root.linker == end) {
node = new Node(root.value + end.value, root.count + end.count);
node.left = root;
node.right = end;
node.linker = null;
node.linkerBack = null;
System.out.println(node.value);
newRoot = node;
} else {
TreeMaker(root, end);
}
}
}
class Node {
String value;
int count;
Node left;
Node right;
Node linker;
Node linkerBack;
Node(String value, int count) {
this.value = value;
this.count = count;
this.left = null;
this.right = null;
this.linker = null;
this.linkerBack = null;
}
}
I read objects(Movies) from a file and i compare based on their likes. I want to get the median after every Movie insertion in the queue. In the code below there are :
Movie method compareTo
PQ insert and getMax methods with swim and sink
Main class
I'm creating both priority queues for higher and less objects than median, but i don't know how to dynamically calculate it. Every movie element is created with id, title, likes in this order.
public int compareTo(Movie m) {
if (this.likes == m.likes) {
return -this.title.compareTo(m.title);
} else if (this.likes > m.likes) {
return 1;
} else {
return -1;
}
}
public class PQ {
private Movie[] pq;
private int size;
public PQ(int capacity) {
if (capacity < 1) {
throw new IllegalArgumentException();
}
this.pq = new Movie[capacity + 1];
this.size = 0;
}
public void insert(Movie movie) {
if (this.size == this.pq.length - 1) {
throw new IllegalArgumentException();
}
if (movie == null) {
throw new IllegalArgumentException();
}
this.size++;
this.pq[this.size] = movie;
swim(this.size);
}
public void swim(int i) {
while (i > 1) {
int p = i / 2;
int result = this.pq[p].compareTo(this.pq[i]);
if (result <= 0)
return;
swap(i, p);
i = p;
}
}
public Movie Max() {
if (this.size == 0)
throw new IllegalArgumentException();
return this.pq[1];
}
public Movie getMax() {
if (this.size == 0)
throw new IllegalArgumentException();
Movie m = this.pq[1];
if (this.size > 1)
this.pq[1] = this.pq[this.size];
this.pq[this.size--] = null;
sink(1);
return m;
}
private void sink(int i) {
int left = 2 * i;
int right = left + 1;
int max = left;
while (left <= this.size) {
if (right <= this.size) {
max = this.pq[right].compareTo(this.pq[left]) < 0 ? right
: left;
}
if (this.pq[max].compareTo(this.pq[i]) >= 0)
return;
swap(i, max);
i = max;
left = 2 * i;
right = left + 1;
max = left;
}
}
private void swap(int i, int j) {
Movie tmp = pq[i];
pq[i] = pq[j];
pq[j] = tmp;
}
}
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Dynamic_Median {
public static void main(String[] args) {
BufferedReader br = null;
PQ higher_median = new PQ(4);
PQ less_median = new PQ(4);
Movie median = null;
try { // try to read the file
br = new BufferedReader(new FileReader("movies.txt"));
String line;
String title = "";
int id = 0;
int likes = 0;
while ((line = br.readLine()) != null) {
line = line.trim();
line = line.replaceAll("/t", "");
String[] tokens = line.split(" "); // store every token in an
// String array
id = Integer.parseInt(tokens[0]);
likes = Integer.parseInt(tokens[tokens.length - 1]);
for (int i = 1; i < tokens.length - 1; i++) {
title = title + " " + tokens[i];
}
title = "";
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
ki esy re kopela mou teleftaia mera ths prothesmias thymithikes na rwthseis? :P
I have this singly linked list where each node holds a name and a weight. I'm trying to write a method that will spit out the list by weight(least to greatest).
Here is the method of the SLL class:
public void printWeights() {
int weightCache;
String nameCache;
index=this.head;
for (int j = 0; j < count; j++) {
for (int i =0; i<count-j;i++) {
indexCheck = index.next;
if (index.next==null||indexCheck==null){
index=index.next;
indexCheck = index.next;
break;
}
if (index.weight>indexCheck.weight) {
weightCache = index.weight; nameCache = index.name;
index.weight=indexCheck.weight; index.name=indexCheck.name;
indexCheck.weight= index.weight; indexCheck.name= index.name;
indexCheck.weight = weightCache;indexCheck.name = nameCache;
indexCheck=indexCheck.next;
}
}
}
if (head == null) {
System.out.println("List is Empty!");
}
for (int i = 1; i <= count; i++) {
if (i < count) {
System.out.print(this.head.name + " - " + this.head.weight + ", ");
head = head.next;
} else {
System.out.print(this.head.name + " - " + this.head.weight + ". \nDone.");
}
}
}
I want to implement the Java AVL tree and to rotate the tree left and right. I am not getting this.
Can anybody by looking at the code below tell me how can I possibly rotate the tree left and right and then use fix up with those two functions to balance the AVL tree?
I hope someone here can guide me through this.
import java.util.Random;
import java.util.SortedSet;
import java.util.TreeSet;
public class AVLTree<T> extends
BinarySearchTree<AVLTree.Node<T>, T> implements SSet<T> {
Random rand;
public static class Node<T> extends BSTNode<Node<T>,T> {
int h; // the height of the node
}
public AVLTree() {
sampleNode = new Node<T>();
rand = new Random();
c = new DefaultComparator<T>();
}
public int height(Node<T> u) {
return (u == null) ? 0 : u.h;
}
public boolean add(T x) {
Node<T> u = new Node<T>();
u.x = x;
if (super.add(u)) {
for (Node<T> w = u; w != nil; w = w.parent) {
// walk back up to the root adjusting heights
w.h = Math.max(height(w.left), height(w.right)) + 1;
}
fixup(u);
return true;
}
return false;
}
public void splice(Node<T> u) {
Node<T> w = u.parent;
super.splice(u);
for (Node<T> z = u; z != nil; z = z.parent)
z.h = Math.max(height(z.left), height(z.right)) + 1;
fixup(w);
}
public void checkHeights(Node<T> u) {
if (u == nil) return;
checkHeights(u.left);
checkHeights(u.right);
if (height(u) != 1 + Math.max(height(u.left), height(u.right)))
throw new RuntimeException("Check heights shows incorrect heights");
int dif = height(u.left) - height(u.right);
if (dif < -1 || dif > 1)
throw new RuntimeException("Check heights found height difference of " + dif);
}
/**
* TODO: finish writing this method
* #param u
*/
public void fixup(Node<T> u) {
while (u != nil) {
int dif = height(u.left) - height(u.right);
if (dif > 1) {
// TODO: add code here to fix AVL condition
// on the path from u to the root, if necessary
} else if (dif < -1) {
// TODO: add code here to fix AVL condition
// on the path from u to the root, if necessary
}
u = u.parent;
}
}
public Node rotateLeft() {
return rotateLeft(u.parent);
}
public void rotateLeft(Node<T> u) {
// TODO: Recompute height values at u and u.parent
}
public void rotateRight(Node<T> u) {
// TODO: Recompute height values at u and u.parent
}
public static <T> T find(SortedSet<T> ss, T x) {
SortedSet<T> ts = ss.tailSet(x);
if (!ts.isEmpty()) {
return ts.first();
}
return null;
}
/**
* This just does some very basic correctness testing
* #param args
*/
public static void main(String[] args) {
AVLTree<Integer> t = new AVLTree<Integer>();
Random r = new Random(0);
System.out.print("Running AVL tests...");
int n = 1000;
for (int i = 0; i < n; i++) {
t.add(r.nextInt(2*n));
t.checkHeights(t.r);
}
for (int i = 0; i < n; i++) {
t.remove(r.nextInt(2*n));
t.checkHeights(t.r);
}
System.out.println("done");
t.clear();
System.out.print("Running correctness tests...");
n = 100000;
SortedSet<Integer> ss = new TreeSet<Integer>();
Random rand = new Random();
for (int i = 0; i < n; i++) {
Integer x = rand.nextInt(2*n);
boolean b1 = t.add(x);
boolean b2 = ss.add(x);
if (b1 != b2) {
throw new RuntimeException("Adding " + x + " gives " + b2
+ " in SortedSet and " + b1 + " in AVL Tree");
}
}
for (int i = 0; i < n; i++) {
Integer x = rand.nextInt(2*n);
Integer x1 = t.find(x);
Integer x2 = find(ss, x);
if (x1 != x2) {
throw new RuntimeException("Searching " + x + " gives " + x2
+ " in SortedSet and " + x1 + " in AVL Tree");
}
ss.headSet(x);
}
for (int i = 0; i < n; i++) {
Integer x = rand.nextInt(2*n);
boolean b1 = t.remove(x);
boolean b2 = ss.remove(x);
if (b1 != b2) {
throw new RuntimeException("Error (2): Removing " + x + " gives " + b2
+ " in SortedSet and " + b1 + " in AVL Tree");
}
}
for (int i = 0; i < n; i++) {
Integer x = rand.nextInt(2*n);
Integer x1 = t.find(x);
Integer x2 = find(ss, x);
if (x1 != x2) {
throw new RuntimeException("Error (3): Searching " + x + " gives " + x2
+ " in SortedSet and " + x1 + " in AVL Tree");
}
ss.headSet(x);
}
System.out.println("done");
}
}
Full AVL tree implementation:
public class AVLTree<T> {
private AVLNode<T> root;
private static class AVLNode<T> {
private T t;
private int height;
private AVLNode<T> left;
private AVLNode<T> right;
private AVLNode(T t) {
this.t = t;
height = 1;
}
}
public void insert(T value) {
root = insert(root, value);
}
private AVLNode<T> insert(AVLNode<T> n, T v) {
if (n == null) {
n = new AVLNode<T>(v);
return n;
} else {
int k = ((Comparable) n.t).compareTo(v);
if (k > 0) {
n.left = insert(n.left, v);
} else {
n.right = insert(n.right, v);
}
n.height = Math.max(height(n.left), height(n.right)) + 1;
int heightDiff = heightDiff(n);
if (heightDiff < -1) {
if (heightDiff(n.right) > 0) {
n.right = rightRotate(n.right);
return leftRotate(n);
} else {
return leftRotate(n);
}
} else if (heightDiff > 1) {
if (heightDiff(n.left) < 0) {
n.left = leftRotate(n.left);
return rightRotate(n);
} else {
return rightRotate(n);
}
} else;
}
return n;
}
private AVLNode<T> leftRotate(AVLNode<T> n) {
AVLNode<T> r = n.right;
n.right = r.left;
r.left = n;
n.height = Math.max(height(n.left), height(n.right)) + 1;
r.height = Math.max(height(r.left), height(r.right)) + 1;
return r;
}
private AVLNode<T> rightRotate(AVLNode<T> n) {
AVLNode<T> r = n.left;
n.left = r.right;
r.right = n;
n.height = Math.max(height(n.left), height(n.right)) + 1;
r.height = Math.max(height(r.left), height(r.right)) + 1;
return r;
}
private int heightDiff(AVLNode<T> a) {
if (a == null) {
return 0;
}
return height(a.left) - height(a.right);
}
private int height(AVLNode<T> a) {
if (a == null) {
return 0;
}
return a.height;
}
}
Here's a full implementation of AVL tree in Java
class Node {
int key;
Node left;
Node right;
int height;
Node(int value) {
key = value;
left = null;
right = null;
height = 1;
}
}
class AVLTree {
Node root;
int height(Node root) {
if (root == null)
return 0;
return root.height;
}
int findHeight() {
return height(root);
}
int findHeightFrom(int value) {
Node node = search(root, value);
if (node == null)
return -1;
return node.height;
}
Node search(Node root, int value) {
if (root == null)
return null;
else {
if (value == root.key)
return root;
else if (value < root.key)
return search(root.left, value);
else
return search(root.right, value);
}
}
boolean find(int value) {
Node node = search(root,value);
if (node == null)
return false;
return true;
}
int max(int one, int two) {
return (one > two) ? one : two;
}
Node rightRotate(Node root) {
Node rootLeftChild = root.left;
root.left = rootLeftChild.right;
rootLeftChild.right = root;
root.height = max(height(root.left), height(root.right)) + 1;
rootLeftChild.height = max(height(rootLeftChild.left), height(rootLeftChild.right)) + 1;
return rootLeftChild;
}
Node leftRotate(Node root) {
Node rootRightChild = root.right;
root.right = rootRightChild.left;
rootRightChild.left = root;
root.height = max(height(root.left), height(root.right)) + 1;
rootRightChild.height = max(height(rootRightChild.left), height(rootRightChild.right)) + 1;
return rootRightChild;
}
Node insertNode(Node root, int value) {
if (root == null)
root = new Node(value);
else {
if (value < root.key)
root.left = insertNode(root.left, value);
else
root.right = insertNode(root.right, value);
}
root.height = max(height(root.left), height(root.right)) + 1;
int balanceFactor = height(root.left) - height(root.right);
if (balanceFactor > 1) {
// either left-left case or left-right case
if (value < root.left.key) {
// left-left case
root = rightRotate(root);
} else {
// left-right case
root.left = leftRotate(root.left);
root = rightRotate(root);
}
} else if (balanceFactor < -1) {
// either right-right case or right-left case
if (value > root.right.key) {
// right-right case
root = leftRotate(root);
} else {
// right-left case
root.right = rightRotate(root.right);
root = leftRotate(root);
}
}
return root;
}
void insert(int value) {
root = insertNode(root, value);
}
void inorder(Node root) {
if (root != null) {
inorder(root.left);
System.out.print(root.key + " ");
inorder(root.right);
}
}
void inorderTraversal() {
inorder(root);
System.out.println();
}
void preorder(Node root) {
if (root != null) {
System.out.print(root.key + " ");
preorder(root.left);
preorder(root.right);
}
}
void preorderTraversal() {
preorder(root);
System.out.println();
}
}
public class AVLTreeExample {
public static void main(String[] args) {
AVLTree avl = new AVLTree();
avl.insert(10);
avl.insert(20);
avl.insert(30);
avl.insert(40);
avl.insert(50);
avl.insert(25);
System.out.print("Inorder Traversal : "); avl.inorderTraversal();
System.out.print("Preorder Traversal : "); avl.preorderTraversal();
System.out.println("Searching for 10 : " + avl.find(10));
System.out.println("Searching for 11 : " + avl.find(11));
System.out.println("Searching for 20 : " + avl.find(20));
System.out.println("Height of the tree : " + avl.findHeight());
System.out.println("Finding height from 10 : " + avl.findHeightFrom(10));
System.out.println("Finding height from 20 : " + avl.findHeightFrom(20));
System.out.println("Finding height from 25 : " + avl.findHeightFrom(25));
}
}
in order to rotate it right
you need to first check if the parent is not root
then if the parent is the right of the grand parent
if so, set the right of the grand parent to the child
else, set the left of the gran parent to the child
otherwise,
root is child
I've been trying all day to get this algorithm up and running, but I cant for the life of me. I've read many tutorials on the net, and source code in AS3, javascript, and C++; but I cannot adapt what I am seeing to my own code.
I have created an AStar class that has a nested class named Node. The map is a 2D array named MAP.
The biggest problem that I am having is pulling the F value in the pathfind function.
I have implemented the F = G + H, my problem is the actual AStar algorithm. Can someone please help, this is how far I've got as of yet:
import java.util.ArrayList;
public class AStar
{
int MAP[][];
Node startNode, endNode;
public AStar(int MAP[][], int startXNode, int startYNode,
int endXNode, int endYNode)
{
this.MAP = MAP;
startNode = new Node(startXNode, startYNode);
endNode = new Node(endXNode, endYNode);
}
public void pathfinder()
{
ArrayList openList = new ArrayList();
ArrayList closedList = new ArrayList();
}
public int F(Node startNode, Node endNode)
{
return (H(startNode, endNode) + G(startNode));
}
//H or Heuristic part of A* algorithm
public int H(Node startNode, Node endNode)
{
int WEIGHT = 10;
int distance = (Math.abs(startNode.getX() - endNode.getX()) + Math.abs(startNode.getY() - endNode.getY()));
return (distance * WEIGHT);
}
public int G(Node startNode)
{
if(MAP[startNode.getX() - 1][startNode.getY()] != 1)
{
return 10;
}
if(MAP[startNode.getX() + 1][startNode.getY()] != 1)
{
return 10;
}
if(MAP[startNode.getX()][startNode.getY() -1] != 1)
{
return 10;
}
if(MAP[startNode.getX()][startNode.getY() + 1] != 1)
{
return 0;
}
return 0;
}
public class Node
{
private int NodeX;
private int NodeY;
private int gScore;
private int hScore;
private int fScore;
public Node(int NodeX, int NodeY)
{
this.NodeX = NodeX;
this.NodeY = NodeY;
}
public int getX()
{
return NodeX;
}
public int getY()
{
return NodeY;
}
public int getG()
{
return gScore;
}
public void setG(int gScore)
{
this.gScore = gScore;
}
public int getH()
{
return hScore;
}
public void setH(int hScore)
{
this.hScore = hScore;
}
public int getF()
{
return fScore;
}
public void setF(int fScore)
{
this.fScore = fScore;
}
}
}
This is the furthest I can ever get with the pathfinder function:
public void pathfinder()
{
LinkedList<Node> openList = new LinkedList();
LinkedList<Node> closedList = new LinkedList();
Node currentNode;
openList.add(startNode);
while(openList.size() > 0)
{
currentNode = (Node) openList.get(0);
closedList.add(currentNode);
for(int i = 0; i < openList.size(); i++)
{
int cost = F(currentNode, endNode);
}
}
}
I recently threw this A* code together to solve a Project Euler problem. You'll have to fill in the details for a matrix of Node objects. Use it at your own risk, however I can say it solved the problem :)
public class Node {
List<Node> neighbors = new ArrayList<Node>();
Node parent;
int f;
int g;
int h;
int x;
int y;
int cost;
}
public List<Node> aStar(Node start, Node goal) {
Set<Node> open = new HashSet<Node>();
Set<Node> closed = new HashSet<Node>();
start.g = 0;
start.h = estimateDistance(start, goal);
start.f = start.h;
open.add(start);
while (true) {
Node current = null;
if (open.size() == 0) {
throw new RuntimeException("no route");
}
for (Node node : open) {
if (current == null || node.f < current.f) {
current = node;
}
}
if (current == goal) {
break;
}
open.remove(current);
closed.add(current);
for (Node neighbor : current.neighbors) {
if (neighbor == null) {
continue;
}
int nextG = current.g + neighbor.cost;
if (nextG < neighbor.g) {
open.remove(neighbor);
closed.remove(neighbor);
}
if (!open.contains(neighbor) && !closed.contains(neighbor)) {
neighbor.g = nextG;
neighbor.h = estimateDistance(neighbor, goal);
neighbor.f = neighbor.g + neighbor.h;
neighbor.parent = current;
open.add(neighbor);
}
}
}
List<Node> nodes = new ArrayList<Node>();
Node current = goal;
while (current.parent != null) {
nodes.add(current);
current = current.parent;
}
nodes.add(start);
return nodes;
}
public int estimateDistance(Node node1, Node node2) {
return Math.abs(node1.x - node2.x) + Math.abs(node1.y - node2.y);
}
I dont know if you are trying only to use simple types, or if you just didn't think about it, but you need to have a PriorityQueue to get your A* working.
A good way to think is that you put your startpoint into a priority queue with distance 0, and then start a loop that only stops when the prioriy queue is empty.
In the loop you take the min-node out, and check to see if it hasnt been open before, or if it has, if you have now found a shorter way to it.
If either these are true, you add the distance to the new node, add the edge/from-square to a map, and then add the distance + heuristic to the priority queue.
I have written this to work on a grid of booleans, and a constant conversion between 1D and 2D arrays, but I hope it is readable:
public void AStarRoute()
{
gridDist = new double[rows][cols];
System.out.println("Start of AStarRoute");
MinPriorityQueue pq = new MinPriorityQueue(rows * cols);
edgeTo = new HashMap<Integer, Integer>();
gridDist[x1Dto2D(start)][y1Dto2D(start)] = 0;
pq.insert(start, 0);
int from;
while (!pq.isEmpty()) {
from = pq.delMin();
int x = x1Dto2D(from);
int y = y1Dto2D(from);
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
int newX = x + i;
int newY = y + j;
if (newX >= 0 && newY >= 0 && newX < cols && newY < rows && !(i == 0 && j == 0)) {
if (grid[newX][newY]) {
//System.out.println("NewDist: " + gridDist[newX][newY] + " - OldDist+dist: " + (gridDist[x][y] + ((Math.abs(i) == Math.abs(j)) ? 1.4 : 1.0)) + ":" + (int)(gridDist[x][y] + ((Math.abs(i) == Math.abs(j)) ? 1.4 : 1.0)));
if (!edgeTo.containsKey(convert2Dto1D(newX, newY)) || gridDist[newX][newY] > (gridDist[x][y] + ((Math.abs(i) == Math.abs(j)) ? 14 : 10))) {
gridDist[newX][newY] = (int)(gridDist[x][y] + ((Math.abs(i) == Math.abs(j)) ? 14 : 10));
maxDistToEnd = (int)Math.max(maxDistToEnd, gridDist[newX][newY]);
edgeTo.put(convert2Dto1D(newX, newY), convert2Dto1D(x, y));
pq.insert(convert2Dto1D(newX, newY), gridDist[newX][newY] + (int)Math.sqrt(Math.pow((newX - x1Dto2D(end))*10, 2) + Math.pow((newY - y1Dto2D(end))*10, 2)));
if(convert2Dto1D(newX, newY) == end){
System.out.println("End found at (" + newX + ", " + newY + ")");
paintGridDist = true;
route = new ArrayList<Integer>();
int n = convert2Dto1D(newX, newY);
route.add(n);
do{
n = edgeTo.get(n);
route.add(n);
}while(start != n);
repaint();
return;
}
}
}
}
}
}
}
paintGridDist = true;
repaint();
}