public class Solution {
public static void main(String[] args) throws Exception { //have this return the result of DFS
Scanner input = new Scanner(System.in);
int vertices = input.nextInt();
Graph mygraph = new Graph (vertices);
int edges = input.nextInt();
//set up input as edges
while (input.hasNextInt()) {
int from = input.nextInt() - 1;
int to = input.nextInt() - 1;
//add the reciprocating vertex neighbors
mygraph.nodes[from].addNeighbor(mygraph.nodes[to]);//null pointer here
mygraph.nodes[to].addNeighbor(mygraph.nodes[from]);
}
}
}
class Graph {
int size;
Vertex[] nodes;
Graph(int size) {
this.size = size;
this.nodes = new Vertex[size];
}
}
class Vertex {
int value;
Vertex[] neighbors;
int available;
Vertex(int value) {
this.value = value;
this.neighbors = new Vertex[50];
this.available = 0;
}
//add to the neighbors list of this array
void addNeighbor(Vertex v) {
this.neighbors[this.available] = v;
this.available = this.available + 1;
}
}
not sure as to why I'm getting a null pointer here? To my understanding, null pointers are when something is not getting initialized properly--any guidance?
What I'm trying to do is add the neighbors of vertices to one another as they come up in the input. One possible issue is that in the Vertex class I'm initializing the size of the Vertex array as size, but I don't see any other way to accurately get the size of the array.
I haven't seen any other problem online like this one, hence why Im asking!
Related
I'm trying to test out my program to see how it works, but I'm not sure how to call upon it in the main method. I've tried doing Assignment5Solution.findOrder() but it does not work. Any help with this issue would be greatly appreciated. The code is supposed to take the number of classes a student has to take along with the prerequisites for each course if there are any, and put the correct order of what classes the student should take.
package Assignment5;
import java.lang.reflect.Array;
import java.util.*;
/**
*
* #author harpe
*/
class Assignment5Solution {
public int[] findOrder(int numCourses, int[][] prerequisites) {
int E = prerequisites.length;
Graph G = new Graph(numCourses);
for (int i = 0; i < E; i++) {
G.addEdge(prerequisites[i][1], prerequisites[i][0]);
} // Graph is constructed
DFS d = new DFS(G); // depth first search
return d.reverseDFSorder();
}
public class DFS {
private boolean[] marked;
private int[] courseOrder; // i.e., reverse post order
private boolean hasCycle;
private int index; // index for the array courseOrder, index 0 is for the course taken first, …
private HashSet<Integer> callStack; // used to detect if there are cycles on the graph
DFS(Graph G) {
marked = new boolean[G.V()];
courseOrder = new int[G.V()];
index = courseOrder.length - 1; // index 0 of courseOrder will be course taken first, lastIndex will be taken last
callStack = new HashSet<Integer>(); // HashSet is a hash table, for O(1) search
for (int v = 0; v < G.V(); v++) { // to visit each node, including those on islands or isolated
if (!marked[v] && !hasCycle) {
dfs(G, v);
}
}
}
private void dfs(Graph G, int v) {
marked[v] = true;
callStack.add(v); // use HashSet to simulate callStack
for (int w : G.adj(v)) {
if (!marked[w]) {
dfs(G, w);
} else if (callStack.contains(w)) // search in HashSet is O(1)
{
hasCycle = true; // this is a cycle!
break;
}
}
callStack.remove(v);
courseOrder[index--] = v; // index starts from array length -1, decrease by 1 each time, and then ends at 0
}
public int[] reverseDFSorder() {
if (hasCycle) {
return new int[0]; // return an empty int array (with size 0)
}
return courseOrder;
}
} // end of class DFS
public class Graph {
private int V;
private List[] adj;
Graph(int V) // constructor
{
this.V = V;
adj = new List[V];
for (int i = 0; i < V; i++) {
adj[i] = new ArrayList<Integer>();
}
}
public void addEdge(int v, int w) {
adj[v].add(w);
}
public Iterable<Integer> adj(int v) {
return adj[v];
}
public int V() {
return V;
}
} // end of class Graph
} // end of class Solution
public int[] findOrder(int numCourses, int[][] prerequisites) {}
would need to be:
public static int[] findOrder(int numCourses, int[][] prerequisites) {}
The static keyword means you do not need to a declare an object of the class to use it. So you can use it using:
Assignment5Solution.findOrder(numCourses, prerequisites)
//numCourses and prerequisites can be any int and int[][] respectively.
EDIT: Another note too, depending on where your main method is you may need to make class Assignment5Solution a public class with:
public class Assignment5Solution {
It currently is package protected so it will only be able to be used if it is in the same package.
EDIT2:
If you want to use it as a nonstatic method you need to do something like this(change null and 0 to the real values):
Assignment5Solution test = new Assignment5Solution() {};
int numCourses = 0;
int [][] prereqs = null;
int[] reverseOrder = test.findOrder(numCourses, prereqs);
I am trying to to create a stacks which has the following API:
Stacks(int n)// creates stacks of size n
pop() //returns the last element pushed in the stacks
pop(int n) //returns an array of of n elements
push(int e) //appends an element to the stacks
push(int n, ar[]) //appends an array to the stack
The stacks should be able to dynamically change size when needed, so client programs dont have to do it every time.
I have done all that only my problem is when assigning object A to object B doesn't that mean that A will now points to the address of B?
Here is my code and i hope it explaines what i mean
public class Stacks {
/*
* constructs a stack object
* #param n that will determine that size of the stacks to be constructed
*/
public Stacks(int n)
{
this.elemetns= new int[n];
this.size=n;
this.top=-1;
}
/*
* constructs a stack object, with size of 2 when no parameter is given
*/
public Stacks()
{
this.elemetns= new int[2];
this.size=2;
this.top=-1;
}
public int pop()
{
if (top<0)
{
System.out.println("Error code 2: Empty stacks");
return -1;
}
else
{
int n= this.elemetns[top];
top--;
return n;
}
}
public int [] pop(int size)
{
if (this.size<size)
{
System.out.println("Error code 3: The Maximum number of elements that can be acquired is "+ this.size);
return null;
}
else
{
int res[]= new int[size];
for (int i=0;i<size;i++)
{
res[i]=pop();
}
return res;
}
}
public void push(int e)
{
if (!isFull())
{
this.elemetns[++top]=e;
System.out.println(e+" has been pushed to the stack ");
}
else
{
updateStacksSize(this);
this.elemetns[++top]=e;
System.out.println(e+" has been pushed to the stack ");
}
}
public void push(int n,int [] ar)
{
for (int i=0;i<n;i++)
this.push(ar[i]);
}
private void updateStacksSize(Stacks s)
{
int newSize= s.top*2;
Stacks newStacks= new Stacks(newSize);
for (int i = s.top; i>-1;i--)
newStacks.elemetns[i]=s.pop();
s= newStacks;//shouldnt newStacks get garbage collected
//and s gets the new address and attributes of newStacks?
}
private boolean isFull(){return this.size==(this.top+1);}
public static void main(String[] args)
{
Stacks s= new Stacks(5);
for (int i=0;i<7;i++)
s.push(i+1);
System.out.println();
int []arr= s.pop(6);
for (int i=0;i<arr.length;i++){
System.out.println(arr[i]);
}
}
private int elemetns[];
private int top;
private int size;
}
Why does running this program results in problem with the old size although the current object's has been updated.
one more question is it possible to assign this= newStacks instead of instantiating new Stacks object
In Java you assign object references to variables.
I have done all that only my problem is when assigning object A to object B doesn't that mean that A will now points to the address of B?
s= newStacks;//shouldnt newStacks get garbage collected
//and s gets the new address and attributes of newStacks?
It is the other way around since the assignment in Java is from right to left.
"I have done all that only my problem is when assigning object A to object B doesn't that mean that A will now points to the address of B?"
if this is what you meant then:
Stacks A = new Stacks();
Stacks B = A;
Then what this means is that B is now pointing to A.
You're kinda over do it. A stack should consist of a chain of nodes, like an singel-linked list of nodes. I've written an example on this below, see if you can see how it works.
public class Stack <E> {
private StackItem<E> currTop;
private int size;
private int max;
private static class StackItem<E> {
private E e;
private StackItem<E> next;
}
public Stack(int max) {
currTop = null;
size = 0;
this.max = max;
}
public void add(E e){
if ((size+1) == max) throw new StackOverflowError("Max items in stack is reached");
StackItem<E> old = currTop;
currTop = new StackItem<>();
currTop.e = e;
currTop.next = old;
size++;
}
public E getFirst() {
if (currTop == null) return null;
E output = currTop.e;
currTop = currTop.next;
size --;
return output;
}
public E showFirst() {
return currTop.e;
}
public int getSize() {
return size;
}
}
I'm trying to create a 2 dimensional array of "Node" objects as follows
public static void main(String[] args) throws IOException {
length=getNumber("Enter the length of the field: ");
breadth=getNumber("Enter the breadth of the filed: ");
node n = new node();
node [][] field = new node[length][breadth];
for(i=0;i<=length;i++){
for(j=0;j<=breadth;j++){
F =getNumber("Enter the F value");
field[i][j].setF(F);
System.out.println(" "+field[i][j].getF(F);
}
}
}
in above code getNumber is a function wherein i print and accept the number
Here is my node class:
public class node {
public int F;
public int G;
public int H;
public boolean isVisited;
public boolean isCurrent;
public void node(int F,int G,int H,boolean isVisited, boolean isCurrent){
this.F=F;
this.G=G;
this.H=H;
this.isVisited=isVisited;
this.isCurrent=isCurrent;
}
public int getF() {
return G+H;
}
public void setF(int f) {
F = f;
}
public int getG() {
return G;
}
public void setG(int g) {
G = g;
}
public int getH() {
return H;
}
public void setH(int h) {
H = h;
}
public boolean isVisited() {
return isVisited;
}
public void setVisited(boolean isVisited) {
this.isVisited = isVisited;
}
public boolean isCurrent() {
return isCurrent;
}
public void setCurrent(boolean isCurrent) {
this.isCurrent = isCurrent;
}
}
all i want to do is, to store/access various values of F,G,H etc in each of the node objects, the problem however is i'm getting java.lang.NullPointerException for field[i][j].setF(F);
i dont know where i'm going wrong, need some help.
You initialized the array, but you did not populate it.
Consider this line:
field[i][j].setF(F);
When you do
field[i][j]
you are accessing the array; i.e. getting what is in the array at that position. Since you didn't put anything in the array, you get a null. But you immediately try to call setF.
I noticed you do
node n = new node();
outside the loop. You probably want to do that in the loop.
node n = new node();
n.setF(F);
field[i][j] = n;
This code creates a node instance, sets a value on it, and then puts it in the array at the specified position. A bit more fancy approach would be to do something like
node n = field[i][j];
if (n == null) { // initialize n at the position if it doesn't exist
n = new node();
field[i][j] = n;
}
field[i][j].setF(f);
Alternatively, you could loop over the array and put a new node at each position, right after you initialize the array.
Finally, in Java standard practice is to start class names with capital letters. node should be Node.
Try this:
for(i=0;i<=length;i++){
for(j=0;j<=breadth;j++){
F =getNumber("Enter the F value");
node tmp = new node();
tmp.setF(F);
field[i][j] = tmp;
System.out.println(" "+field[i][j].getF(F);
}
}
PS in java it is convention for class names to start with a capital and should be written in CamelCase
[edit]
Be careful with your get/setF() functions as they do not operate on the same variables
not related to your question, but you might want to read through this document this will teach you about naming conventions in java and help you write code that is easier to read
I'm implementing an algorithm to find all the euler paths in a graph. I'm basing myself, to create the dfs, in the code found here: Find all possible Euler cycles
Here is my current code:
public class Graph {
private int numVertex;
private int numEdges;
private boolean[][] adj;
public Graph(int numVertex, int numEdges) {
this.numVertex = numVertex;
this.numEdges = numEdges;
this.adj = new boolean[numVertex+1][numVertex+1];
}
public void addEdge(int start, int end){
adj[start][end] = true;
adj[end][start] = true;
}
public Integer DFS(Graph G, int startVertex){
int i=0;
pilha.push(startVertex);
for(i=0; i<G.numVertex; i++){
if(G.adj[i][startVertex] != false){
System.out.println("i: " + i);
G.adj[i][startVertex] = false;
G.adj[startVertex][i] = false;
DFS(G, i);
G.adj[i][startVertex] = true;
G.adj[startVertex][i] = true;
}
}
return -1;
}
Stack<Integer> pilha = new Stack();
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int numVertices = input.nextInt();
int numLinks = input.nextInt();
int startNode = input.nextInt();
Graph g = new Graph(numVertices, numLinks);
for(int i = 0; i<numLinks; i++){
g.addEdge(input.nextInt(),input.nextInt());
}
}
}
Unfortunately i don't get the right results and i can't seem to figure out why. I've tried a lot of thing as storing the results from the dfs in a list and print them, but still i got no paths.
any idea on how can i modify my code so i start getting the euler paths?
What do you expect the result from your program to be? You are pushing the nodes to a temporary stack(pilha). You need to keep that stack because it will in fact determine the order in which you should visit the nodes. Also the DFS method is void but somehow you add the result from its invocation in the list res. Does this code even run successfully?
I'm writing a Java program that searches for and outputs cycles in a graph. I am using an adjacency list for storing my graph, with the lists stored as LinkedLists. My program takes an input formatted with the first line as the number of nodes in the graph and each subsequent line 2 nodes that form an edge e.g.:
3
1 2
2 3
3 1
My problem is that when the inputs get very large (the large graph I am using has 10k nodes and I don't know how many edges, the file is 23mb of just edges) I am getting a java.lang.StackOverflowError, but I don't get any errors with small inputs. I'm wondering if it would be better to use another data structure to form my adjacency lists or if there is some method I could use to avoid this error, as I'd rather not just have to change a setting on my local installation of Java (because I have to be sure this will run on other computers that I can't control the settings on as much). Below is my code, the Vertex class and then my main class. Thanks for any help you can give!
Vertex.java:
package algorithms311;
import java.util.*;
public class Vertex implements Comparable {
public int id;
public LinkedList adjVert = new LinkedList();
public String color = "white";
public int dTime;
public int fTime;
public int prev;
public Vertex(int idnum) {
id = idnum;
}
public int getId() {
return id;
}
public int compareTo(Object obj) {
Vertex vert = (Vertex) obj;
return id-vert.getId();
}
#Override public String toString(){
return "Vertex # " + id;
}
public void setColor(String newColor) {
color = newColor;
}
public String getColor() {
return color;
}
public void setDTime(int d) {
dTime = d;
}
public void setFTime(int f) {
fTime = f;
}
public int getDTime() {
return dTime;
}
public int getFTime() {
return fTime;
}
public void setPrev(int v) {
prev = v;
}
public int getPrev() {
return prev;
}
public LinkedList getAdjList() {
return adjVert;
}
public void addAdj(int a) { //adds a vertex id to this vertex's adj list
adjVert.add(a);
}
}
CS311.java:
package algorithms311;
import java.util.*;
import java.io.*;
public class CS311 {
public static final String GRAPH= "largegraph1";
public static int time = 0;
public static LinkedList[] DFS(Vertex[] v) {
LinkedList[] l = new LinkedList[2];
l[0] = new LinkedList();
l[1] = new LinkedList(); //initialize the array with blank lists, otherwise we get a nullpointerexception
for(int i = 0; i < v.length; i++) {
v[i].setColor("white");
v[i].setPrev(-1);
}
time = 0;
for(int i = 0; i < v.length; i++) {
if(v[i].getColor().equals("white")) {
l = DFSVisit(v, i, l);
}
}
return l;
}
public static LinkedList[] DFSVisit(Vertex[] v, int i, LinkedList[] l) { //params are a vertex of nodes and the node id you want to DFS from
LinkedList[] VOandBE = new LinkedList[2]; //two lists: visit orders and back edges
VOandBE[0] = l[0]; // l[0] is visit Order, a linked list of ints
VOandBE[1] = l[1]; // l[1] is back Edges, a linked list of arrays[2] of ints
VOandBE[0].add(v[i].getId());
v[i].setColor("gray"); //color[vertex i] <- GRAY
time++; //time <- time+1
v[i].setDTime(time); //d[vertex i] <- time
LinkedList adjList = v[i].getAdjList(); // adjList for the current vertex
for(int j = 0; j < adjList.size(); j++) { //for each v in adj[vertex i]
if(v[(Integer)adjList.get(j)].getColor().equals("gray") && v[i].getPrev() != v[(Integer)adjList.get(j)].getId()) { // if color[v] = gray and Predecessor[u] != v do
int[] edge = new int[2]; //pair of vertices
edge[0] = i; //from u
edge[1] = (Integer)adjList.get(j); //to v
VOandBE[1].add(edge);
}
if(v[(Integer)adjList.get(j)].getColor().equals("white")) { //do if color[v] = WHITE
v[(Integer)adjList.get(j)].setPrev(i); //then "pi"[v] <- vertex i
DFSVisit(v, (Integer)adjList.get(j), VOandBE); //DFS-Visit(v)
}
}
VOandBE[0].add(v[i].getId());
v[i].setColor("black");
time++;
v[i].setFTime(time);
return VOandBE;
}
public static void main(String[] args) {
try {
// --Read First Line of Input File
// --Find Number of Vertices
FileReader file1 = new FileReader("W:\\Documents\\NetBeansProjects\\algorithms311\\src\\algorithms311\\" + GRAPH);
BufferedReader bReaderNumEdges = new BufferedReader(file1);
String numVertS = bReaderNumEdges.readLine();
int numVert = Integer.parseInt(numVertS);
System.out.println(numVert + " vertices");
// --Make Vertices
Vertex vertex[] = new Vertex[numVert];
for(int k = 0; k <= numVert - 1; k++) {
vertex[k] = new Vertex(k);
}
// --Adj Lists
FileReader file2 = new FileReader("W:\\Documents\\NetBeansProjects\\algorithms311\\src\\algorithms311\\" + GRAPH);
BufferedReader bReaderEdges = new BufferedReader(file2);
bReaderEdges.readLine(); //skip first line, that's how many vertices there are
String edge;
while((edge = bReaderEdges.readLine()) != null) {
StringTokenizer ST = new StringTokenizer(edge);
int vArr[] = new int[2];
for(int j = 0; ST.hasMoreTokens(); j++) {
vArr[j] = Integer.parseInt(ST.nextToken());
}
vertex[vArr[0]-1].addAdj(vArr[1]-1);
vertex[vArr[1]-1].addAdj(vArr[0]-1);
}
for(int i = 0; i < vertex.length; i++) {
System.out.println(vertex[i] + ", adj nodes: " + vertex[i].getAdjList());
}
LinkedList[] l = new LinkedList[2];
l = DFS(vertex);
System.out.println("");
System.out.println("Visited Nodes: " + l[0]);
System.out.println("");
System.out.print("Back Edges: ");
for(int i = 0; i < l[1].size(); i++) {
int[] q = (int[])(l[1].get(i));
System.out.println("[" + q[0] + "," + q[1] + "] ");
}
for(int i = 0; i < l[1].size(); i++) { //iterate through the list of back edges
int[] q = (int[])(l[1].get(i)); // q = pair of vertices that make up a back edge
int u = q[0]; // edge (u,v)
int v = q[1];
LinkedList cycle = new LinkedList();
if(l[0].indexOf(u) < l[0].indexOf(v)) { //check if u is before v
for(int z = l[0].indexOf(u); z <= l[0].indexOf(v); z++) { //if it is, look for u first; from u to v
cycle.add(l[0].get(z));
}
}
else if(l[0].indexOf(v) < l[0].indexOf(u)) {
for(int z = l[0].indexOf(v); z <= l[0].indexOf(u); z++) { //if it is, look for u first; from u to v
cycle.add(l[0].get(z));
}
}
System.out.println("");
System.out.println("Cycle detected! : " + cycle);
if((cycle.size() & 1) != 0) {
System.out.println("Cycle is odd, graph is not 2-colorable!");
}
else {
System.out.println("Cycle is even, we're okay!");
}
}
}
catch (IOException e) {
System.out.println("AHHHH");
e.printStackTrace();
}
}
}
The issue is most likely the recursive calls in DFSVisit. If you don't want to go with the 'easy' answer of increasing Java's stack size when you call the JVM, you may want to consider rewriting DFSVisit to use an iterative algorithm instead of recursive. While Depth First Search is more easily defined in a recursive manner, there are iterative approaches to the algorithm that can be used.
For example: this blog post
The stack is a region in memory that is used for storing execution context and passing parameters. Every time your code invokes a method, a little bit of stack is used, and the stack pointer is increased to point to the next available location. When the method returns, the stack pointer is decreased and the portion of the stack is freed up.
If an application uses recursion heavily, the stack quickly becomes a bottleneck, because if there is no limit to the recursion depth, there is no limit to the amount of stack needed. So you have two options: increase the Java stack (-Xss JVM parameter, and this will only help until you hit the new limit) or change your algorithm so that the recursion depth is not as deep.
I am not sure if you were looking for a generic answer, but from a brief glance at your code it appears that your problem is recursion.
If you're sure your algorithm is correct and the depth of recursive calls you're making isn't accidental, then solutions without changing your algorithm are:
add to the JVM command line e.g. -Xss128m to set a 128 MB stack size (not a good solution in multi-threaded programs as it sets the default stack size for every thread not just the particular thread running your task);
run your task in its own thread, which you can initialise with a stack size specific to just that thread (and set the stack size within the program itself)-- see my example in the discussion of fixing StackOverflowError, but essentially the stack size is a parameter to the Thread() constructor;
don't use recursive calls at all-- instead, mimic the recursive calls using an explicit Stack or Queue object (this arguably gives you a bit more control).