I have spent entire weekend playing around with this. I am trying to store the nodes in PriorityQueue data structure. My astar function doesnt seem to be doing what it should. Anyone mind having a look?
public void aStar(Node from, Node to) {
PriorityQueue<Node> exploreList = new PriorityQueue<Node>();
ArrayList<Node> visited = new ArrayList<Node>();
ArrayList<Node> successors = new ArrayList<Node>();
Node current = from;
System.out.println(current.getName());
while (current != to) {
successors = current.getConnected();
Collections.sort(successors);
for (Node n : successors) {
if (!visited.contains(n)) {
exploreList.add(n);
}
for (Node n1 : successors) {
if (n.fSum() > n1.fSum()) {
exploreList.remove(n);
exploreList.add(n1);
}
}
}
visited.add(current);
current = exploreList.remove();
System.out.println(current.getName());
}
Node Class here
public class Node implements Comparable {
private String name;
private int travDist;
private int straightDist;
private ArrayList<Arc> arcs;
/**
* Constructor for a new node
*
* #param n
*/
public Node(String n, int aTravDist, int aStraightDist) {
name = n;
travDist = aTravDist;
straightDist = aStraightDist;
arcs = new ArrayList<Arc>();
}
/**
* Adds a new arc
*
* #param to
* #param c
*/
public void addArc(Node to, int c) {
arcs.add(new Arc(to, c));
}
/**
* Gets the list of connected nodes to this node
*
* #return
*/
public ArrayList<Node> getConnected() {
ArrayList<Node> returnData = new ArrayList<Node>();
for (Arc a : arcs) {
returnData.add(a.getNode());
}
return returnData;
}
#Override
public int compareTo(Object o) {
//return name.compareTo(((Node) o).getName());
Integer sum = ((Node)o).fSum();
return sum.compareTo(fSum());
}
public int fSum () {
return travDist + straightDist;
}
/**
* Gets the name of the Node
*
* #return
*/
public String getName() {
return name;
}
}
What you are doing is not a proper A star algorithm.
Collections.sort(successors);
You shouldn't do that. In A star you always consider all the successors. You needn't worry about the order- the priority queue will take care of that. However, adding this line increases the complexity of the algorithm.
for (Node n1 : successors) {
if (n.fSum() > n1.fSum()) {
exploreList.remove(n);
exploreList.add(n1);
}
}
This is entirely wrong. What you are doing here is: you only add the closest of all the successors. This will be a beam search with a beam of size 1, not A star - just keep them all in.
Related
I am trying to simulate SDN based shortest path routing using Dijkstra algorithm. Is there anything that I can improve in the following code ? I am using Floodlight controller and trying to optimize routing between two hosts.
Here is my sample code:
public static Graph calculateShortestPathFromSource(Graph graph, Node source)
{
source.setDistance(0);
Set<Node> settledNodes = new HashSet<>();
Set<Node> unsettledNodes = new HashSet<>();
unsettledNodes.add(source);
while (unsettledNodes.size() != 0) {
Node currentNode = getLowestDistanceNode(unsettledNodes);
unsettledNodes.remove(currentNode);
for (Map.Entry < Node, Integer> adjacencyPair:
currentNode.getAdjacentNodes().entrySet()) {
Node adjacentNode = adjacencyPair.getKey();
Integer edgeWeight = adjacencyPair.getValue();
if (!settledNodes.contains(adjacentNode)) {
CalculateMinimumDistance(adjacentNode, edgeWeight, currentNode);
unsettledNodes.add(adjacentNode);
}
}
settledNodes.add(currentNode);
}
return graph;
}
/**
* Function to get minimum distance.
* Source: Baeldung (www.baeldung.com/java-dijkstra)
*/
private static Node getLowestDistanceNode(Set < Node > unsettledNodes)
{
Node lowestDistanceNode = null;
int lowestDistance = Integer.MAX_VALUE;
for (Node node: unsettledNodes) {
int nodeDistance = node.getDistance();
if (nodeDistance < lowestDistance) {
lowestDistance = nodeDistance;
lowestDistanceNode = node;
}
}
return lowestDistanceNode;
}
/**
* Function to get minimum distance.
* Source: Baeldung (www.baeldung.com/java-dijkstra)
*/
private static void CalculateMinimumDistance(Node evaluationNode, Integer edgeWeigh, Node sourceNode)
{
Integer sourceDistance = sourceNode.getDistance();
if (sourceDistance + edgeWeigh < evaluationNode.getDistance())
{
evaluationNode.setDistance(sourceDistance + edgeWeigh);
LinkedList<Node> shortestPath = new LinkedList<>(sourceNode.getShortestPath());
shortestPath.add(sourceNode);
evaluationNode.setShortestPath(shortestPath);
}
}
I'm trying to write a Huffman-tree decode function to decode a given Boolean array.I'm using the recursion method in the decode_helper() but I keep getting caught in an infinite loop, and I'm not sure as to why because I thought I implemented a proper base case to stop the recursive calls.
I've tried playing around with different base cases but nothing that I try seems to stop the recursive calls.
public class HuffmanTree {
public class HuffmanTree {
// ******************** Start of Stub Code ******************** //
// ************************************************************ //
/** Node<E> is an inner class and it is abstract.
* There will be two kinds
* of Node, one for leaves and one for internal nodes. */
abstract static class Node implements Comparable<Node>{
/** The frequency of all the items below this node */
protected int frequency;
public Node(int freq) {
this.frequency = freq;
}
/** Needed for the Minimum Heap used later in this stub. */
public int compareTo(Node other) {
return this.frequency - other.frequency;
}
}
/** Leaves of a Huffman tree contain the data items */
protected static class LeafNode extends Node {
// Data Fields
/** The data in the node */
protected char data;
/** Constructor to create a leaf node (i.e. no children) */
public LeafNode(char data, int freq) {
super(freq);
this.data = data;
}
/** toString method */
public String toString() {
return "[value= "+this.data + ",freq= "+frequency+"]";
}
}
/** Internal nodes contain no data,
* just references to left and right subtrees */
protected static class InternalNode extends Node {
/** A reference to the left child */
protected Node left;
/** A reference to the right child */
protected Node right;
/** Constructor to create an internal node */
public InternalNode(Node leftC, Node rightC) {
super(leftC.frequency + rightC.frequency);
left = leftC; right = rightC;
}
public String toString() {
return "(freq= "+frequency+")";
}
}
// Enough space to encode all "extended ascii" values
// This size is probably overkill (since many of the values are not
//"printable" in the usual sense)
private static final int codex_size = 256;
/* Data Fields for Huffman Tree */
private Node root;
public HuffmanTree(String s) {
root = buildHuffmanTree(s);
}
/**
* Returns the frequencies of all characters in s.
* #param s
* #return
*/
//How many times a character shows up in a string
public static int[] frequency(String s) {
int[] freq = new int[codex_size];
for (char c: s.toCharArray()) {
freq[c]++;
}
return freq;
}
public String decode(boolean[] coding) {
// TODO Complete decode method
//Function to decode the binary input
String code = "";
Node temp = root;
int i = 0;
if (coding.length == 0) {
throw new IllegalArgumentException("The given code cannot be empty");
}
for(int j = 0; j < coding.length; j++) {
if(coding[j] != true && coding[j] != false) {
throw new IllegalArgumentException("The given code has an invalid
input");
}
}
decode_helper(temp, code, coding);
return code;
}
public void decode_helper(Node root, String code, boolean[] coding) {
int i = 0;
if(root == null) {
throw new IllegalArgumentException("Given tree is empty");
}
//Base case for the recursion
if(i != coding.length) {
if (root instanceof InternalNode) {
InternalNode n = (InternalNode)root;
if(coding[i] == false) {
n.left = (InternalNode)root;
i++;
decode_helper(n.left, code, coding);
}
if(coding[i] == true) {
n.right = (InternalNode)root;
i++;
decode_helper(n.right, code, coding);
}
}
else if (root instanceof LeafNode) {
LeafNode l = (LeafNode)root;
code += l.data;
i++;
decode_helper(root, code, coding);
}
}
}
The issue is because you are initializing int i = 0 within the decode_helper method. And that method is called recursively. Since i is always initialized to zero, it would never become equal to coding.length and hence the infinite loop.
You might need to initialize i outside the decode_helper method and pass it inside it.
I have a DListNode class with a member name item.
/* DListNode.java */
/**
* DListNode is a node in DList(Doubly linked list).
* #author mohet01
*
*/
public class DListNode {
/**
* item references the item stored in the current node.
* prev references the previous node in the DList.
* next references the next node in the DList.
*/
Object item;
DListNode prev;
DListNode next;
/**
* DListNode constructor with zero args
*/
public DListNode(){
this.item=null;
this.prev=null;
this.next=null;
}
/**
* DListNode constructor with one arg
*/
public DListNode(Object obj){
this.item = obj;
this.prev = null;
this.next = null;
}
/**
* getItem() returns the size of the queried item
* #return
*/
public Object getItemSize() {
//solution required
return item;
}
}
If DListNode member item points to object of type TypeAndSize class,
public class TypeAndSize {
public int type; //Ocean.EMPTY, Ocean.UNVISITEDSHARK, or Ocean.FISH
public int size; // Number of cells in the run
/**
* Constructor for a TypeAndSize of specified species and run length.
* #param species is Ocean.EMPTY, Ocean.SHARK, or Ocean.FISH.
* #param runLength is the number of identical cells in this run.
* #return the newly constructed Critter.
*
*/
public TypeAndSize(int species, int runLength){
if((species != Ocean.EMPTY) && (species != Ocean.SHARK) && (species != Ocean.FISH)){
System.out.println("TypeAndSize Error: Illegal species.");
System.exit(1);
}
if(runLength < 1){
System.out.println("TypeAndSize Error: runLength must be atleast 1.");
System.exit(1);
}
this.type = species;
this.size = runLength;
}
public int getSize(){
return size;
}
}
My goal is to bring the member size by writing code in getItemSize() method of DListNode class.
These above two classes are skeletons given by professor.
http://www.cs.berkeley.edu/~jrs/61bf06/hw/pj1/
I created getSize() method in TypeAndSize class.
Please help me!!!
FYI...
This is my first experience in using such scenario, as am learning java at home from cs61B Fall 2006 Berkeley course webcast. This is part of assignment in Project1
Please help me!!!
Assuming you will call this method only on the first of the elements of the list, this should solve your problem:
public int getItemSize() {
int size = 0;
DListNode node = this;
while (node != null) {
size++;
node = node.next;
}
return size;
}
If you want this to be called from any node, use this other solution
public Object getItemSize() {
int size = 0;
DListNode node = this;
while (node != null) {
size++;
node = node.next;
}
node = prev;
while (node != null) {
size++;
node = node.prev;
}
return size;
}
I am using Algorithms 4th edition to polish up my graph theory a bit. The books comes with a lot of code for graph processing.
Currently, I am stuck with the following problems: How to find all cycles in an undirected graph?
I was looking to modify the existing code for cycle detection to do that.
Here is the important part:
private void dfs(Graph G, int u, int v) {
marked[v] = true;
for (int w : G.adj(v)) {
// short circuit if cycle already found
if (cycle != null) return;
if (!marked[w]) {
edgeTo[w] = v;
dfs(G, v, w);
}
// check for cycle (but disregard reverse of edge leading to v)
else if (w != u) {
cycle = new Stack<Integer>();
for (int x = v; x != w; x = edgeTo[x]) {
cycle.push(x);
}
cycle.push(w);
cycle.push(v);
}
}
}
Now, if I were to find ALL cycles, I should remove the line that returns when a cycle is found and each time a cycle is created I would store it. The part I cannot figure out is: when does the algorithm stop? How can I be sure I have found all cycles?
Can the above code even be modified in a way to allow me to find all cycles?
Cycle detection is much easier than finding all cycles. Cycle detection can be done in linear time using a DFS like you've linked, but the number of cycles in a graph can be exponential, ruling out an polytime algorithm altogether. If you don't see how this could be possible, consider this graph:
1 -- 2
| / |
| / |
3 -- 4
There are three distinct cycles, but a DFS would find only two back-edges.
As such, modifying your algorithm to find all cycles will take a fair bit more work than simply changing a line or two. Instead, you have to find a set of base cycles, then combine them to form the set of all cycles. You can find an implementation of an algorithm that'll does this in this question.
/**
* In this program we create a list of edges which is an ordered pair of two
* integers representing two vertices.
*
* We iterate through each edge and apply Union Find algorithm to detect
* cycle.
*
* This is a tested code and gives correct result for all inputs.
*/
package com.divyanshu.ds.disjointSet;
import java.util.HashMap;
/**
* #author Divyanshu
* DisjointSet is a data structure with three operations :
* makeSet, union and findSet
*
* Algorithms Used : Union by rank and path compression for detecting cycles
* in an undirected graph.
*/
public class DisjontSet {
HashMap<Long, Node> map = new HashMap<>();
class Node {
long data;
Node parent;
int rank;
}
public void makeSet(long data) {
Node node = new Node();
node.data = data;
node.parent = node;
node.rank = 0;
map.put(data, node);
}
public void union(long firstSet,
long secondSet) {
Node firstNode = map.get(firstSet);
Node secondNode = map.get(secondSet);
Node firstParent = findSet(firstNode);
Node secondParent = findSet(secondNode);
if (firstParent.data == secondParent.data) {
return;
}
if (firstParent.rank >= secondParent.rank) {
firstParent.rank = (firstParent.rank == secondParent.rank) ? firstParent.rank + 1 : firstParent.rank;
secondParent.parent = firstParent;
} else {
firstParent.parent = secondParent;
}
}
public long findSet(long data) {
return findSet(map.get(data)).data;
}
private Node findSet(Node node) {
if (node.parent == node) {
return node;
}
node.parent = findSet(node.parent);
return node.parent;
}
}
=============================================================================
package com.divyanshu.ds.client;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import com.divyanshu.ds.disjointSet.DisjontSet;
import com.divyanshu.ds.disjointSet.Edge;
public class DisjointSetClient {
public static void main(String[] args) {
int edgeCount = 4;
int vertexCount = 12;
List<Edge> graph = generateGraph(edgeCount, vertexCount);
System.out.println("Generated Graph : ");
System.out.println(graph);
DisjontSet disjontSet = getDisjointSet(graph);
Boolean isGraphCyclic = isGraphCyclic(graph, disjontSet);
System.out.println("Graph contains cycle : " + isGraphCyclic);
}
private static Boolean isGraphCyclic(List<Edge> graph,
DisjontSet disjontSet) {
Boolean isGraphCyclic = false;
for (Edge edge : graph) {
if (edge.getFirstVertex() != edge.getSecondVertex()) {
Long first = disjontSet.findSet(edge.getFirstVertex());
Long second = disjontSet.findSet(edge.getSecondVertex());
if (first.equals(second)) {
isGraphCyclic = true;
break;
} else {
disjontSet.union(first, second);
}
}
}
return isGraphCyclic;
}
private static DisjontSet getDisjointSet(List<Edge> graph) {
DisjontSet disjontSet = new DisjontSet();
for (Edge edge : graph) {
disjontSet.makeSet(edge.getFirstVertex());
disjontSet.makeSet(edge.getSecondVertex());
}
return disjontSet;
}
private static List<Edge> generateGraph(int edgeCount,
int vertexCount) {
List<Edge> graph = new ArrayList<>();
HashSet<Edge> edgeSet = new HashSet<>();
Random random = new Random();
for (int j = 0; j < vertexCount; j++) {
int first = random.nextInt(edgeCount);
int second = random.nextInt(edgeCount);
if (first != second) {
edgeSet.add(new Edge(first, second));
} else {
j--;
}
}
for (Edge edge : edgeSet) {
graph.add(edge);
}
return graph;
}
}
===================================================================
/**
*
*/
package com.divyanshu.ds.disjointSet;
/**
* #author Divyanshu
*
*/
public class Edge {
private long firstVertex;
private long secondVertex;
public Edge(long firstVertex,
long secondVertex) {
this.firstVertex = firstVertex;
this.secondVertex = secondVertex;
}
public long getFirstVertex() {
return firstVertex;
}
public void setFirstVertex(long firstVertex) {
this.firstVertex = firstVertex;
}
public long getSecondVertex() {
return secondVertex;
}
public void setSecondVertex(long secondVertex) {
this.secondVertex = secondVertex;
}
#Override
public String toString() {
return "(" + firstVertex + "," + secondVertex + ")";
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (firstVertex ^ (firstVertex >>> 32));
result = prime * result + (int) (secondVertex ^ (secondVertex >>> 32));
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Edge other = (Edge) obj;
if (firstVertex != other.firstVertex)
return false;
if (secondVertex != other.secondVertex)
return false;
return true;
}
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I am looking for some help with a class I have designed for an assignment. It adds game scores to a linked list and lists them from highest to lowest. The max number of scores is 10. I have it almost working but I can't figure something out. I add the first score and it works, then if I add a second score, it only works if that score is higher than the first. If not, it throws a java.lang.NullPointerException. Can someone take a look at my insert(String name, int score) method and let me know what the problem is?
public class GamerList {
/**
* The node class stores a list element and a reference to the next node.
* #author johnmckillip
*
*/
private class Node {
String name;
int score;
Node next;
/**
* Constructor.
* #param val The element to store in the node.
* #param n The reference to the successor node.
*/
Node(String val1, int val2, Node n) {
name = val1;
score = val2;
next = n;
}
/**
* Constructor.
* #param val The element to store in the node.
*/
Node(String val1, int val2) {
this(val1, val2, null);
}
}
private Node head;
private Node tail;
/**
* Constructor.
*/
public GamerList() {
head = null;
tail = null;
}
/**
* The isEmpty method checks to see if the list is empty.
* #return true if the list is empty, false otherwise.
*/
public boolean isEmpty() {
return head == null;
}
/**
* The size method returns the length of the list.
* #return The number of elements in the list.
*/
public int size() {
int count = 0;
Node p = head;
while(p != null) {
count++;
p = p.next;
}
return count;
}
public void insert(String name, int score) {
Node node = new Node(name, score);
if(isEmpty()) {
head = node;
tail = node;
}
else if(head.score <= node.score) {
node.next = head;
head = node;
}
else {
Node frontPtr = head.next;
Node backPtr = head;
while(frontPtr.score > node.score && frontPtr.next != null) {
backPtr = backPtr.next;
frontPtr = frontPtr.next;
}
if(frontPtr != null && frontPtr.score <= node.score) {
backPtr.next = node;
node.next = frontPtr;
}
else {
frontPtr.next = node;
tail = node;
}
}
if(size() > 10) {
Node currentPtr = head;
while(currentPtr.next != tail) {
currentPtr = currentPtr.next;
}
tail = currentPtr;
currentPtr.next = null;
}
}
public void printList() {
Node temp = head;
while(temp != null) {
System.out.print(temp.name + " " + temp.score + " ");
System.out.println("");
temp = temp.next;
}
}
}
Here is my class to test GamerList:
public class TestGamerList {
/**
* #param args
*/
public static void main(String[] args) {
GamerList list1 = new GamerList();
list1.insert("Fry", 89);
list1.insert("Bender", 25);
list1.insert("Leela", 90);
list1.insert("Zoidburg", 23);
list1.insert("Amy", 34);
list1.insert("Hermes", 96);
list1.insert("Zapp",123);
list1.insert("Nibbler", 56);
list1.insert("Calculon", 12);
list1.insert("Hypnotoad", 189);
list1.insert("Lrrr", 5);
list1.insert("Scruffy", 28);
System.out.println("Top 10 Scores: ");
list1.printList();
}
}
Looks like you don't set head's next. That's one problem. The second is, even if you do that, you'll get into infinite loop, 'cause you have done the insertion logic incorrectly. I've changed you insert() a bit to make it work, but that still lacks elegance and is far from effective implementation. For example, on every insertion after you've got 10 elements you are running size() which makes your code complexity increase by a factor of approx. N = size(). If you really want to do that, make size a variable and just increase it at the end of every insert(). Anyway, edited code:
public class GamerList {
private class Node {
String name;
int score;
Node next;
Node(String val1, int val2, Node n) {
name = val1;
score = val2;
next = n;
}
Node(String val1, int val2) {
this(val1, val2, null);
}
}
private Node head;
private Node tail;
/**
* Constructor.
*/
public GamerList() {
head = null;
tail = null;
}
/**
* The isEmpty method checks to see if the list is empty.
* #return true if the list is empty, false otherwise.
*/
public boolean isEmpty() {
return head == null;
}
/**
* The size method returns the length of the list.
* #return The number of elements in the list.
*/
public int size() {
int count = 0;
Node p = head;
while(p != null) {
count++;
p = p.next;
}
return count;
}
public void insert(String name, int score) {
Node node = new Node(name, score);
if(isEmpty()) {
head = node;
head.next = tail;
}
else if(head.score <= node.score) {
node.next = head;
head = node;
}
else {
Node beforeNode = head;
while(beforeNode.score > node.score && beforeNode.next != null) {
beforeNode = beforeNode.next;
}
node.next = beforeNode.next;
beforeNode.next = node;
}
if(size() > 10) {
Node currentPtr = head;
for (int i = 0; i < 9; i++) {
currentPtr = currentPtr.next;
}
currentPtr.next = null;
}
}
public void printList() {
Node temp = head;
while(temp != null) {
System.out.print(temp.name + " " + temp.score + " ");
System.out.println("");
temp = temp.next;
}
}
}
Without stack trace is complex.
but probably error is here
while(frontPtr.score > node.score && frontPtr.next != null)
since frontPtr is null.
add a check on the
if (frontPtr!=null)
while(frontPtr.score > node.score && frontPtr.next != null)