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);
Related
I using this exact code for this. I modified it a little. So far I added a start and end node index to the calculateShortestDistances() method. Also the path ArrayList for collecting the path node indexes. Also: new to Java...
How do I collect the indexes of nodes in the path ArrayList?
I just can't come up with the solution on a level that I am not even positive this code could do what I want. I only have intuition on my side and little time.
What I tried:
Adding the nextNode value to the list then removing it if it was not
a shorter distance.
Adding the neighbourIndex to the list then removing it if it was not a shorter distance.
I made a Path.java with ArrayList but that was went nowhere (it was a class with a public variable named path) but it went nowhere.
Main.java:
public class Main {
public static void main(String[] args) {
Edge[] edges = {
new Edge(0, 2, 1), new Edge(0, 3, 4), new Edge(0, 4, 2),
new Edge(0, 1, 3), new Edge(1, 3, 2), new Edge(1, 4, 3),
new Edge(1, 5, 1), new Edge(2, 4, 1), new Edge(3, 5, 4),
new Edge(4, 5, 2), new Edge(4, 6, 7), new Edge(4, 7, 2),
new Edge(5, 6, 4), new Edge(6, 7, 5)
};
Graph g = new Graph(edges);
g.calculateShortestDistances(4,6);
g.printResult(); // let's try it !
System.out.println(g.path);
}
}
Graph.java:
This is the Graph.java file. Here I added a sAt and eAt variable, so I can tell it what path I am after. Also I created a public path ArrayList, where I intend to collect the path.
import java.util.ArrayList;
// now we must create graph object and implement dijkstra algorithm
public class Graph {
private Node[] nodes;
private int noOfNodes;
private Edge[] edges;
private int noOfEdges;
private int sAt;
private int eAt;
public ArrayList<Integer> path = new ArrayList<>();
public Graph(Edge[] edges) {
this.edges = edges;
// create all nodes ready to be updated with the edges
this.noOfNodes = calculateNoOfNodes(edges);
this.nodes = new Node[this.noOfNodes];
for (int n = 0; n < this.noOfNodes; n++) {
this.nodes[n] = new Node();
}
// add all the edges to the nodes, each edge added to two nodes (to and from)
this.noOfEdges = edges.length;
for (int edgeToAdd = 0; edgeToAdd < this.noOfEdges; edgeToAdd++) {
this.nodes[edges[edgeToAdd].getFromNodeIndex()].getEdges().add(edges[edgeToAdd]);
this.nodes[edges[edgeToAdd].getToNodeIndex()].getEdges().add(edges[edgeToAdd]);
}
}
private int calculateNoOfNodes(Edge[] edges) {
int noOfNodes = 0;
for (Edge e : edges) {
if (e.getToNodeIndex() > noOfNodes)
noOfNodes = e.getToNodeIndex();
if (e.getFromNodeIndex() > noOfNodes)
noOfNodes = e.getFromNodeIndex();
}
noOfNodes++;
return noOfNodes;
}
public void calculateShortestDistances(int startAt, int endAt) {
// node 0 as source
this.sAt = startAt;
this.eAt = endAt;
this.nodes[startAt].setDistanceFromSource(0);
int nextNode = startAt;
// visit every node
for (int i = 0; i < this.nodes.length; i++) {
// loop around the edges of current node
ArrayList<Edge> currentNodeEdges = this.nodes[nextNode].getEdges();
for (int joinedEdge = 0; joinedEdge < currentNodeEdges.size(); joinedEdge++) {
int neighbourIndex = currentNodeEdges.get(joinedEdge).getNeighbourIndex(nextNode);
// only if not visited
if (!this.nodes[neighbourIndex].isVisited()) {
int tentative = this.nodes[nextNode].getDistanceFromSource() + currentNodeEdges.get(joinedEdge).getLength();
if (tentative < nodes[neighbourIndex].getDistanceFromSource()) {
nodes[neighbourIndex].setDistanceFromSource(tentative);
}
}
}
// all neighbours checked so node visited
nodes[nextNode].setVisited(true);
// next node must be with shortest distance
nextNode = getNodeShortestDistanced();
}
}
// now we're going to implement this method in next part !
private int getNodeShortestDistanced() {
int storedNodeIndex = 0;
int storedDist = Integer.MAX_VALUE;
for (int i = 0; i < this.nodes.length; i++) {
int currentDist = this.nodes[i].getDistanceFromSource();
if (!this.nodes[i].isVisited() && currentDist < storedDist) {
storedDist = currentDist;
storedNodeIndex = i;
}
}
return storedNodeIndex;
}
// display result
public void printResult() {
String output = "Number of nodes = " + this.noOfNodes;
output += "\nNumber of edges = " + this.noOfEdges;
output += "\nDistance from "+sAt+" to "+eAt+":" + nodes[eAt].getDistanceFromSource();
System.out.println(output);
}
public Node[] getNodes() {
return nodes;
}
public int getNoOfNodes() {
return noOfNodes;
}
public Edge[] getEdges() {
return edges;
}
public int getNoOfEdges() {
return noOfEdges;
}
}
Addittionally here are the Edge.java and the Node.java classes.
Node.java:
import java.util.ArrayList;
public class Node {
private int distanceFromSource = Integer.MAX_VALUE;
private boolean visited;
private ArrayList<Edge> edges = new ArrayList<Edge>(); // now we must create edges
public int getDistanceFromSource() {
return distanceFromSource;
}
public void setDistanceFromSource(int distanceFromSource) {
this.distanceFromSource = distanceFromSource;
}
public boolean isVisited() {
return visited;
}
public void setVisited(boolean visited) {
this.visited = visited;
}
public ArrayList<Edge> getEdges() {
return edges;
}
public void setEdges(ArrayList<Edge> edges) {
this.edges = edges;
}
}
Edge.java
public class Edge {
private int fromNodeIndex;
private int toNodeIndex;
private int length;
public Edge(int fromNodeIndex, int toNodeIndex, int length) {
this.fromNodeIndex = fromNodeIndex;
this.toNodeIndex = toNodeIndex;
this.length = length;
}
public int getFromNodeIndex() {
return fromNodeIndex;
}
public int getToNodeIndex() {
return toNodeIndex;
}
public int getLength() {
return length;
}
// determines the neighbouring node of a supplied node, based on the two nodes connected by this edge
public int getNeighbourIndex(int nodeIndex) {
if (this.fromNodeIndex == nodeIndex) {
return this.toNodeIndex;
} else {
return this.fromNodeIndex;
}
}
}
I know it looks like a homework. Trust me it isn't. On the other hand I have not much time to finish it, that is why I do it at Sunday. Also I am aware how Dijkstra algorithm works, I understand the concept, I can do it on paper. But collecting the path is beyond me.
Thanks for Christian H. Kuhn's and second's comments I managed to come up with the code.
I modified it as follows (I only put in the relevant parts)
Node.java
Here I added a setPredecessor(Integer predecessor) and a getPredecessor() methods to set and get the value of the private variable predecessor (so I follow the original code's style too).
[...]
private int predecessor;
[...]
public int getPredecessor(){
return predecessor;
}
public void setPredecessor(int predecessor){
this.predecessor = predecessor;
}
[...]
Graph.java
Here I created the calculatePath() and getPath() methods. calculatePath() does what the commenters told me to do. The getPath() returns the ArrayLists for others to use.
[...]
private int sAt;
private int eAt;
private ArrayList<Integer> path = new ArrayList<Integer>();
[...]
public void calculateShortestDistances(int startAt, int endAt) {
[...]
if (tentative < nodes[neighbourIndex].getDistanceFromSource()) {
nodes[neighbourIndex].setDistanceFromSource(tentative);
nodes[neighbourIndex].setPredecessor(nextNode);
}
[...]
public void calculatePath(){
int nodeNow = eAt;
while(nodeNow != sAt){
path.add(nodes[nodeNow].getPredecessor());
nodeNow = nodes[nodeNow].getPredecessor();
}
}
public ArrayList<Integer> getPath(){
return path;
}
[...]
Main.java so here I can do this now:
[...]
Graph g = new Graph(edges);
g.calculateShortestDistances(5,8);
g.calculatePath();
String results = "";
ArrayList<Integer> path = g.getPath();
System.out.println(path);
[...]
I know it shows the path backwards, but that is not a problem, as I can always reverse it. The point is: I not only have the the distance from node to node, but the path through nodes too. Thank you for the help.
While coding I was trying to declare a class that can create an arraylist of arraylists, but soon enough I found it hard to define a proper constructor for my class. I wanted to define some methods for me to handle the huge outer arraylist(1000*1000), but I might be affected by C and always tried to use something like structdef.
How should I define my class? I guess declaring every lines seperatedly is not a wise choice, and I don't want to use 2D arraylist directly. Besides, how should I define a constructor to get an object that is an 2D arraylist?
//Update here
Below is my code example:
class farbicMap {
//attribute
ArrayList<Integer> farbicUnit = new ArrayList<Integer>();
//constructor
farbicMap () {
for (int i=0;i<1000;++i) {
farbicUnit.add(0);
}//this gives an arraylist with size of 100
//I want to use the above arraylist to construct another list here
}
//method
setUnitValue(int v) {
...
}
}
Seems that I didn't really understand the concept of class... I wanted to use the class to represent a map with some nodes. Now that's much clearer to me.
This is how I understood your consern:
class Test {
public static void main(String[] args) {
Board board = new Board(1000, 1000);
board.put(1, 2, "X");
Object x = board.get(1, 2);
System.out.println("x = " + x);
}
}
class Board {
private final int xSize;
private final int ySize;
private ArrayList<ArrayList<Object>> board = new ArrayList<>();
public Board(int xSize, int ySize) {
this.xSize = xSize;
this.ySize = ySize;
for (int i = 0; i < xSize; i++) {
board.add(getListOfNulls());
}
}
public Object get(int x, int y) {
return board.get(x).get(y);
}
public void put(int x, int y, Object toAdd) {
List<Object> xs = board.get(x);
if (xs == null) {
xs = getListOfNulls();
}
xs.add(y, toAdd);
}
private ArrayList<Object> getListOfNulls() {
ArrayList<Object> ys = new ArrayList<>();
for (int j = 0; j < ySize; j++) {
ys.add(null);
}
return ys;
}
}
You should use Array if size is fixed.
I am making a priority queue heap of type T. When I add more than one integer to my heap, I get a null pointer exception on line 55, which is where the reheapUp method uses the comparator to decide which integer gets priority.
I've been stuck on this for hours. At first I thought I had to implement a generic compare method but that doesn't make sense because there would be nothing specific enough to compare. The compare method I am using is from an old project where I made a binary search tree map that compared strings.
/*
* PQHeap.java
* 11/12/18
*/
import java.util.Comparator;
import java.util.*;
public class PQHeap<T>{
private Object[] heap; //hash table
private int heapSize;
private int capacity;
private Comparator<T> comparator;
public PQHeap(Comparator<T> comparator){
heapSize = 0;
capacity = 100;
heap = new Object[capacity];
}
public int size(){
return this.heapSize;
}
public void add(T obj){
ensureCapacity();
//add to lower right most leaf
heap[heapSize++] = obj;
reheapUp();
}
public void ensureCapacity(){
if(heapSize < heap.length/2)
return;
Object newHeap[] = new Object[2*heap.length];
for(int i=0; i<heap.length; i++)
newHeap[i] = heap[i];
heap = newHeap;
}
#SuppressWarnings("unchecked")
private void reheapUp(){
int outOfPlaceInd = heapSize - 1;
while(outOfPlaceInd > 0){
int parentInd = (outOfPlaceInd - 1)/2;
**if (comparator.compare((T)heap[outOfPlaceInd], (T)heap[parentInd]) < 0)**
{
swap(outOfPlaceInd, parentInd);
outOfPlaceInd = (outOfPlaceInd-1)/2;
}
else{
return;
}
}
}
private void swap(int i, int j){
Object copy = heap[i];
heap[i] = heap[j];
heap[j] = copy;
}
#SuppressWarnings("unchecked")
public T remove(){
if(heapSize == 0)
throw new IllegalStateException("Trying to remove from an empty PQ!");
Object p = heap[0];
heap[0] = heap[--heapSize];
reheapDown();
return (T)p;
}
#SuppressWarnings("unchecked")
private void reheapDown(){
int outOfPlaceInd = 0;
int leftInd = 2*outOfPlaceInd+1; //left child
int rightInd = 2*outOfPlaceInd+2; //right child
while(leftInd <= heapSize-1){
int smallerChildInd = leftInd;
if ((rightInd < heapSize) && (comparator.compare((T)heap[rightInd], (T)heap[leftInd]) < 0))
smallerChildInd = rightInd;
// is the parent smaller or equal to the smaller child
int compare = comparator.compare((T)heap[outOfPlaceInd], (T)heap[smallerChildInd]);
// if the parent is larger than the child...swap with smaller child
if (compare > 0)
{
swap(outOfPlaceInd, smallerChildInd);
// update indices
outOfPlaceInd = smallerChildInd;
leftInd = 2*outOfPlaceInd + 1;
rightInd = 2*outOfPlaceInd + 2;
}
else
{
return;
}
}
}
public static void main( String[] args ) {
PQHeap<Integer> pq = new PQHeap<Integer>(new TestIntComparator());
pq.add( 10 );
pq.add( 20 );
System.out.println(pq.size());
pq.add( 20 );
pq.add( 30 );
class TestIntComparator implements Comparator<Integer> {
public TestIntComparator() {;}
public int compare(Integer o1, Integer o2) {
return o1-o2;
}
}
}
}
// class NaturalComparator<T extends Comparable<T>> implements Comparator<T> {
// public int compar(T a, T b) {
// return a.compareTo(b);
// }
// }
In PQHeap constructor you don't assign input comparator object to class field. Add line like this:
this.comparator = comparator;
in your constructor
import.util.Arrays;
public class AList<T> implements ListInterface<T>{
private T[] list;
private int numberOfEntries;
private static final int DEFAILT_INI_CAPACITY=25;
public AList()
{
this(DEFAILT_INI_CAPACIT);
}
public AList
{
numberOfEntries = 0;
// the cast is safe because the new array contains null entries
#SuppressWarnings("unchecked")
T[] tempList = (T[])new Object[initialCapacity];
list = tempList;
}
public void add(T newEntry) {
ensureCapacity();
list[numberOfEntries] = newEntry;
numberOfEntries++;
} // end add
public int getLength() {
return numberOfEntries;
} // end getLength
public boolean isEmpty() {
return numberOfEntries == 0; // or getLength() == 0
} // end isEmpty
public T[] toArray() {
// the cast is safe because the new array contains null entries
#SuppressWarnings("unchecked")
T[] result = (T[])new Object[numberOfEntries];
for (int index = 0; index < numberOfEntries; index++) {
result[index] = list[index];
} // end for
return result;
} // end toArray
Prolbems from Data Strucutre and Algorithum in Java by Frank.
On chapter 13 exercise 12 I'm stuck on the following:
the following method Reduce the size of the array:
private boolean isTooBig()
This method return true if the number if entries in the list is less than half the size of the array and the size of the array is greater than 20.
The second new method creates a new array that is three quarters the size of the current array and then copies the object in the list of the new array:
private void reduceArray()
My Attempt:
private boolean isTooBig()
{
int half = (2 / getLenght());;
return ((numberOfEntries < half) && (numberOfEntries > 20));
}
private void reduceArray()
{
private T[] list2;
stuck...
}
My question: I do not know what is The array that I am reducing.
After I reduce the array. I do not know how to copy an ArrayList to another ArrayList.
Also I am stuck on Main project one.
1) Write a program that thoroughly tests the class AList.
My attempt:
public class test {
public static void main(String[] args)
{
AList<integer> listOfInt = new AList<integer>();
listOfInt.add(1);
listOfInt.add(2);
System.out.println(listOfInt);
}
The output is the address of listOfInt, but I want the literal value 1,2 to be printed.
Is there a way to implement a loop using final variables?
I mean a loop that would run for a specified number of iterations when you are not allowed to change anything after initialization!
Is recursion allowed, or do you literally need a loop construct like for or while? If you can use recursion, then:
void loop(final int n) {
if (n == 0) {
return;
} else {
System.out.println("Count: " + n);
loop(n-1);
}
}
One way is to create an Iterable<Integer> class representing an arbitrary range (without actually having to store all of the values in a list):
public static class FixedIntRange implements Iterable<Integer> {
private final int min;
private final int max;
public FixedIntRange(final int min, final int max) {
this.min = min;
this.max = max;
}
#Override
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
private Integer next = FixedIntRange.this.min;
#Override
public boolean hasNext() {
return next != null;
}
#Override
public Integer next() {
final Integer ret = next;
next = ret == max ? null : next + 1;
return ret;
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}
and then iterate over it normally:
for (final int i : new FixedIntRange(-10, 20)) {
// this will be run for each i in the range [-10, 20]
}
Create an array whose size is the required number of iterations, then use it in a for-each loop:
public class Test {
public static void main(String[] args) {
final int N = 20;
final int[] control = new int[N];
for(final int i : control){
System.out.println(i);
}
}
}
The trick here is that the iteration indexing is generated by the compiler as part of the enhanced for statement, and does not use any user-declared variable.
Something like this -
final int max = 5;
for(int i=0; i<max; i++) {}
Or another interesting one-
final boolean flag = true;
while(flag) {
// keep doing your stuff and break after certain point
}
One more-
List<String> list = ......
for(final Iterator iterator = list.iterator(); iterator.hasNext(); ) {
}