Am trying to solve a labyrinth by DFS, using adj List to represent the vertices and edges of the graph. In total there are 12 nodes (3 rows[A,B,C] * 4 cols[0,..,3]). My program starts by saving all the vertex labels (A0,..C3), so far so good, then checks the adjacent nodes, also no problems, if movement is possible, it proceeds to create the edge, here its where al goes wrong.
adjList[i].add(vList[j].label);
I used the debugger and found that vList[j].label is not null it contains a correct string (ie. "B1"). The only variables which show null are in adjList[i], which leads me to believe i have implemented it wrongly. this is how i did it.
public class GraphList {
private ArrayList<String>[] adjList;
...
public GraphList(int vertexcount) {
adjList = (ArrayList<String>[]) new ArrayList[vertexCount];
...
}
...
public void addEdge(int i, int j) {
adjList[i].add(vList[j].label); //NULLPOINTEREXCEPTION HERE
}
...
}
I will really appreaciate if anyone can point me on the right track regrading to what its going wrong... Thanks!
You've created the array, but you still need to go through and create the ArrayList objects. As it's written, adjList[i] returns null because nothing has been assigned to it yet.
I see that you created the container but are you sure you populated the list with elements?
Why don't you add assert((adjList[i] != null) && (adjList[j] != null)) to addEdge just to be sure either of them are not null. Run with java -ea ...
Related
Trying to be simple:
If I have a Graph of cities like:
Berlin(edges: London, Berlin) --next--> London(edges: Paris) --next--> Paris.
And I have a method to disconnect Nodes e.g.
disconnect(London, Paris);
I want to test (JUnit) if the disconnect was successful. My idea: write a method isStillConnected(London) which returns false, if London has no edge-list/ if edge-list is null, else true. Code idea:
public boolean isStillConnected(ListItem<Node<City, Road>> berlin) {
boolean edgeExists = false;
if(berlin.key.edgesGoingToHere.key.whereEdgeGoesTo != null) {
edgeExists = true;
}
return edgeExists;
}
PROBLEM: If the edge hasn't got an edge (which I am requesting), there is a NULLPOINTER because I want to access "whereEdgeGoesTo" which is null.
edgesGoingToHere is the head of the Edge-list.
whereEdgeGoesTo is the Node, where the Edge is pointing at.
Thanks for any answer!
I'm not sure I understand your objects structure just by looking at that small portion of code, but assuming that the if statement is checking the right values, to avoid a nullPointerException, instead of reading the values in the list and comparing them to null check the size of the list using .size() and return true if that value is higher than 0.
I am having trouble figuring out how to remove and print every item in an IntStack object until it is empty. Would I need to use an if statement? I know the basics of stacks, for example:
Suppose s refers to an IntStack object.
If I wanted to add the value 100 to the top of s, I would simply use s.push(100)
If I wanted to remove and print the top value of s, I would use s.pop()
If I wanted to print the top value without removing it, I would use s.peek()
I run into trouble once I try to remove and print every item in s until it is empty.
Even If InStack is some third party stack, as per the description in question it implements all the standard stack methods, so following should work.
public void print(Stack s)
{
while(!s.isEmpty())
{
System.out.println(s.pop());
}
}
Assumming when there is nothing in the stack, s.peek() will return null,
while(s.peek() != null){
System.out.println(s.pop());
}
So, basically this is what I have so far.
public List<String> cycleSearch(Graph<String,String> g) throws Exception{
List<String> list = null;
Graph<String,String> auxG = g;
for(String aux : g.getVertices()){
String aux2 = aux;
if(g.degree(aux)>1){
if(auxG.removeVertex(aux2)){
for(String d : g.getSuccessors(aux2)){
for(String a : g.getSuccessors(aux)){
if(a!=d){
list = findPath(auxG,d,a);
if(list!=null){
list.add(0,aux);
list.add(aux);
return list;
}
}
}
}
}
}
auxG = g;
}
return null;
}
What the method does is basically to search for a cycle in a hypergraph based on JUNG.
The idea it's to recieve a graph on the parameters and then create a variable (as the same type) to later remove a vertex from it without making any changes on the original graph, just in case a cycle isn't found. That way I can use a method called findPath(,,), once the vertex is removed. The method will 'create' another path without walking through the removed vertex.
My compiler says there is problem right here:
for(String d : g.getSuccessors(aux2))
I've been programming graphs in Java(JUNG) for only 1 month.
HELP
There is a bug in JUNG that this code has turned--getSuccessors() should be returning an empty collection if the graph does not have the vertex, rather than returning null, which is what SetHypergraph's implementation does. Sorry about that. (In general, you can avoid this by wrapping the getSuccessors(x) inside a containsVertex(x) if statement.)
However, the reason why you're encountering this bug is that you're doing at least a couple of things that do not make sense:
(1) you're assigning auxG to g (so they're referencing the same object); this is misleading and not helpful.
Similarly, you're assigning aux2 to aux, which is also misleading.
(2) you're removing aux[2] from auxG and then asking for aux2's successors in auxG. aux2 will not have any successors in auxG once it's removed.
(3) Since aux2 and aux are the same vertex, your innermost loop will also not do anything useful for the same reason; there will be no successors.
You need to rethink your entire algorithm, because this simply is not correct as designed.
Instead of using null to represnt no successors, you could just use an empty list, and thus avoid the NullPointerException. Replace return null; with return new LinkedList<>();.
The following code should be returning 16 as far as I can tell but for some reason, it returns 10. Does anyone know what my bug might be? Basically it's the Knapsack problem in Java and I've ran through the whole code on paper and it seems to return the right answer to me but I cannot figure out why when it's properly run, it returns back 10.
Any help would be much appreciated. Thanks!
import java.util.Stack;
public class knapsackProblem
{
public static int optimalValue(Stack<item> items, int totalWeight)
{
if (items.isEmpty())
return 0;
int value = items.peek().value;
int weight = items.peek().weight;
items.pop();
if (totalWeight<weight)
return optimalValue(items, totalWeight);
return Math.max(optimalValue(items,totalWeight), value + optimalValue(items, totalWeight-weight));
}
public static void main(String args[])
{
int knapsackWeight = 15;
Stack<item> items = new Stack<item>();
items.push(new item(7,10));
items.push(new item(3,6));
System.out.println(optimalValue(items, knapsackWeight));
}
}
class item
{
public int weight;
public int value;
public item(int aWeight, int aValue)
{
weight = aWeight;
value = aValue;
}
}
Your Stack is being modified across the calls. So a line like
return Math.max(optimalValue(items,totalWeight), value + optimalValue(items, totalWeight-weight));
will have two different copies of items for each call. Not what you want.
Instead of using Stack, try changing things around to use an ArrayList. Then pass your index of which item you're evaluating into the optimalValue method instead. This should help you work through the items correctly.
I haven't gone through the whole algorithm, but an obvious problem is that every time you call optimalValue on a Stack, it will pop one or more items from the stack. But a Stack, and the items in the stack, are objects, which means they're passed around by reference. So in this line:
return Math.max(optimalValue(items,totalWeight), value + optimalValue(items, totalWeight-weight));
This calls optimalValue twice. The first time you call it with items as a parameter, optimalValue will pop one or more elements from items. Then the statement calls optimalValue again with items as a parameter--and this will NOT use the same items stack that you passed to the first optimalValue call, but it will use the items with the already-popped-off items still popped off (from the first call). I really doubt this is what you want. If you do things this way, then at some point I think you'll have to make a copy of your Stack. Or you'll need to rethink things and do it a different way (maybe you can use an array or ArrayList, so that the items aren't actually popped off but you could pass a "starting index" from one optimalValue call to the recursive call).
I don't know whether there are other problems with your solution in addition to this one.
I'm having trouble inserting into a binomial heap, When I call insert 1 it prints (1) and then I insert 2 it displays (2) instead of (1(2)) and then three it displays (3) instead of (3)(1(2)). I would be very grateful if someone could help figure out my problem. Thank you in advance. Here is my code
public class BHeap {
int key;
int degree;//The degree(Number of children)
BHeap parent, leftmostChild, rightmostChild, rightSibling,root,previous,next;
public BHeap(){
key =0;
degree=0;
parent =null;
leftmostChild=null;
rightmostChild=null;
rightSibling=null;
root=null;
previous=null;
next=null;
}
public BHeap merge(BHeap y){
BHeap newHeap = new BHeap();
BHeap currentHeap = y;
BHeap nextHeap = y.rightSibling;
while(currentHeap.rightSibling !=null){
if(currentHeap.degree==nextHeap.degree){
if(currentHeap.key<nextHeap.key){
if(currentHeap.degree ==0){
currentHeap.leftmostChild=nextHeap;
currentHeap.rightmostChild=nextHeap;
currentHeap.rightSibling=nextHeap.rightSibling;
nextHeap.rightSibling=null;
nextHeap.parent=currentHeap;
currentHeap.degree++;
}
else{
newHeap = currentHeap;
newHeap.rightmostChild.rightSibling=nextHeap;
newHeap.rightmostChild=nextHeap;
nextHeap.parent=newHeap;
newHeap.degree++;
nextHeap.rightSibling=null;
nextHeap=newHeap.rightSibling;
}
}
else{
if(currentHeap.degree==0){
nextHeap.rightmostChild=currentHeap;
nextHeap.rightmostChild.root = nextHeap.rightmostChild;//add
nextHeap.leftmostChild=currentHeap;
nextHeap.leftmostChild.root = nextHeap.leftmostChild;//add
currentHeap.parent=nextHeap;
currentHeap.rightSibling=null;
currentHeap.root=currentHeap;//add
nextHeap.degree++;
}
else{
newHeap=nextHeap;
newHeap.rightmostChild.rightSibling=currentHeap;
newHeap.rightmostChild=currentHeap;
currentHeap.parent= newHeap;
newHeap.degree++;
currentHeap=newHeap.rightSibling;
currentHeap.rightSibling=null;
}
}
}
else{
currentHeap=currentHeap.rightSibling;
nextHeap=nextHeap.rightSibling;
}
}
return y;
}
public void Insert(int x){
BHeap newHeap= new BHeap();
newHeap.key=x;
if(this.root==null){
this.root=newHeap;
}
else{
this.root = merge(newHeap);
}
}
public void Display(){
System.out.print("(");
System.out.print(this.root.key);
if(this.leftmostChild != null){
this.leftmostChild.Display();
}
System.out.print(")");
if(this.rightSibling!=null){
this.rightSibling.Display();
}
}
}
When you are inserting, you are making a new BHeap object and then passing that to merge(). Your new BHeap has no rightSibling, so you skip the entire while loop and just return the new BHeap. So the new BHeap becomes the root of the whole BHeap and you throw out what was there before.
Update: I'm not going to write pseudo-code because it's right there in your code.
So you make a new BHeap and Insert(1). Your Insert method makes a second new BHeap and then checks the root of the current BHeap. That's null, so the second BHeap becomes the root. That's fine.
Now you Insert(2). Again, create another BHeap. This time the root of the current BHeap is not null so we call merge passing in the new BHeap. Note that this new BHeap is now referred (inside merge) as y. Also note that you have done nothing to this new BHeap aside from setting the key field so all other fields are null.
Inside merge you make yet another BHeap object, and make another reference currentHeap that refers to y. (Again, only the key field has been set so all other fields are null.) You refer to y's rightSibling as nextHeap and then comes the while loop. The while loop says that while the rightSibling of currentHeap is not null, do a bunch of stuff.
But as I've said above, everything about currentHeap (aka y aka the brand new BHeap you created in Insert) is null. So the entire while loop is skipped and you return y from merge.
Insert then accepts the return value from y and sets that as the root of the current BHeap. The old root is discarded and sits in the corner weeping bitterly at its sad fate before the garbage collector comes along and shuffles it into an early grave. The new root cheers triumphantly and reigns supreme, the king of the BHeap (and the only member of the BHeap)... until you call Insert(3).
And you? You learn how to use a debugger.
In your method merge you pass a BHeap object y. You do change anything as the BHeap object you have created and passed to merge in your insert method does not add any siblings. The while loop is never run.
Also, I think you may want to review your merge method. It seems you do not ever take into account the current BHeap that you are merging into and simply reformat the given BHeap argument.