PriorityQueue poll() throwing NullPointerException - java

I am working with a priority queue in Java for the first time and I can't for the life of me understand what I am doing that is leading to the exception. I'm attempting to implement an ant colony type solution to the traveling salesman problem. The following is the only code being called for my AntColony class.
public AntColony(TSPInstance p) {
PriorityQueue<Ant> ants = new PriorityQueue<Ant>(new AntComparator());
size = p.getDimension();
for (int i = 0; i < size; i++) {
ants.offer(new Ant(p));
}
shortestTour = Integer.MAX_VALUE;
}
public void nextMove() {
ants.poll();
}
The code that I'm running afterwards just as a test is as follows (just in a main method).
AntColony a = new AntColony(p);
a.nextMove();
The a.nextMove() throws a NullPointerException at the ants.poll() part, but yet if I change the constructor to (for debugging purposes)
public AntColony(TSPInstance p) {
PriorityQueue<Ant> ants = new PriorityQueue<Ant>(new AntComparator());
size = p.getDimension();
for (int i = 0; i < size; i++) {
ants.offer(new Ant(p));
}
ants.poll(); //ADDED THIS
shortestTour = Integer.MAX_VALUE;
}
and then just do
AntColony a = new AntColony(p);
I don't get an exception. I'm struggling to understand how I'm getting an exception from ants.poll(), but yet when I call it from the constructor everything works. Any help with this would be appreciated. There's a lot of code for various things in this project, so I didn't think uploading it all would help anybody so let me know if there's something I should include, but I don't see how the problem could lie outside these two bits of code.
Added: Actual exception
Exception in thread "main" java.lang.NullPointerException
at data_structures.AntColony.nextMove(AntColony.java:25) (the ants.poll() part)
at algorithms.ACTest.main(ACTest.java:6) The a.nextMove() part

The ants variable in your AntColony constructor is a local variable. So when you exit the constructor, it no longer exists. Apparently the ants variable that your nextMove method is calling, is a class member.
You need to change your constructor to have:
// initialize the class member, not a local instance.
ants = new PriorityQueue<Ant>(new AntComparator());

You can just remove the PriorityQueue declaration in your AntColony constructor.
public AntColony(TSPInstance p) {
ants = new PriorityQueue<Ant>(new AntComparator());
size = p.getDimension();
...
}
UPDATE: The cause for your NullPointerException is that you are not initializing your ants property in your constructor but you are creating a new local ants instead. So the ants object in nextMove method has the same value as you provided in your class level declaration, which it's probably null.

Related

Gridworld Fill Grid

Having trouble filling the grid. Everytime I do it I get a stackoverflow error. Here is my current code :
public void removeSelfFromGrid() {
Grid<Actor> grid = getGrid();
int rows = grid.getNumRows();
int cols = grid.getNumCols();
for (int i=0; i<rows; i++) {
for (int j=0; j<cols; j++) {
Location loc = new Location(i, j);
laugh = new CKiller();
laugh.putSelfInGrid(grid, loc);
}
}
}
and here is the constructor if needed
public CKiller()
{
Color c = null;
setColor(c);
getGrid();
getLocation();
location = new ArrayList<Location>();
location.add(getLocation());
setDirection(direction);
}
And here is the error (part of it, too big to post all. it's just those 2 statements repeated):
java.lang.StackOverflowError
at info.gridworld.actor.Actor.putSelfInGrid(Actor.java:123)
at CKiller.removeSelfFromGrid(CKiller.java:120)
It's saying this is the problem
laugh.putSelfInGrid(grid, loc);
Go through the following:
-Are you defining laugh prior to the removeSelfFromGrid() method call? It doesn't have a type specified before it.
-Should the variable location not be an ArrayList? It might be a Location object.
-Is the int direction defined already?
-Why are you calling getGrid() and getLocation()? They aren't doing anything beneficial.
-Does CKiller inherit the putSelfInGrid() method from the Actor class?
Please include the full code of the CKiller class as well as the main class that contains removeSelfFromGrid().
I think your problem is that you overrode the removeSelfFromGrid() method. You should have created a new method, such as fillGrid().
When an actor calls putSelfInGrid(), if there is currently another actor in that Location it calls removeSelfFromGrid(), which you overrode to fill every Location on the Grid with an actor. If there are any other actors on the grid they will then call removeSelfFromGrid(), which leads to again filling the grid, etc.
Just fix the code in removeSelfFromGrid(), put it in a new method and restore the previous code, and you should be good.

How to adding two method returns together

Ok, So I have a method
public static int getTotalLegCountDog (ArrayList<Dog> dogList)
{
int temp = 0;
for (int i = 0; i < dogList.size(); i++)
{
temp = dogList.get(i).getNumLegs();
totalLegsDogs += temp;
}
return totalLegsDogs;
}
It adds up the total legs of dogs and returns them as totalLegsDogs and there is another that totals the legs for cats.
Now I'd like a method that would take both the returned totalLegsDogs and returned totalLegsCats and add them together. My try is below (It returns 0), any help would be great!
public int getTotalLegCount ()
{
totalLegs = totalLegsDogs + totalLegsCats;
return totalLegs;
}
Was not calling the Method correctly. The math in the Problem was solid. The problem was the Method output call.
As far as I can tell, there's nothing wrong with the methods themselves - likely you're calling getTotalLegCount before actually counting the legs.
Fix 1 (preferred): Have getTotalLegCount call the methods.
public int getTotalLegCount (ArrayList<Dog> dogList, ArrayList<Cat> catList) {
totalLegs = getTotalLegCountDog(dogList) + getTotalLegCountCat;
return totalLegs;
}
Fix 2: Make it very clear that the leg-counting methods are to be called first. This is the inferior solution, as it requires more effort on the future programmer's part (and that might be future-you!).
I don't think you've shown us enough of your code to do any troubleshooting. It looks like you must have a global static count for dog legs and cat legs? I can't figure out your use case, but any rate, you need to make sure both your counting methods are called before you do anything with the member variables or else they will not be initialized. Example:
DogCatCounter.getTotalLegDogCount(...);
DogCatCounter.getTotalLegCatCount(...);
new DogCatCounter().getTotalLegCount();
The result from that third line should be correct as long as no other instances of DogCatCounter have modified your static variables. In other words, if you have multiple instances of DogCatCounter, any calls to your counting methods are going to modify your global static members.

How to Throw a InvalidLockCombinationException

i Have the following code but i am confused how i throw the InvalidLockCombinationException. This
exception (which should not have any methods) will indicate that an attempt to assign a
combination to a lock failed (thus making the combination invalid for that lock). If the combination is invalid
(if not all its numbers are in the dial) then the constructor should throw a new
InvalidLockCombinationException. By throwing this exception we can avoid creating locks with
invalid combinations (which in real life will be defective). All locks are open when created this is what i have so far. Any help would be appreciated on how to get the exception working.
public class Lock{
public Combination correct;
public int upperLimit;
public boolean isOpen;
public Lock(int aLimit, Combination aCombo) throws InvalidLockCombinationException(){
correct = aCombo;
upperLimit = aLimit;
isOpen=true;
int[] comboHolder = new int[3];
comboHolder = aCombo.getNumbers();
for(int i=0; i<comboHolder.length;i++){
if(comboHolder[i]<0 || comboHolder[i]>upperLimit){
throw InvalidLockCombinationException;
}
}
}
}
An exception is an object too. You can't really throw the idea of a ball, you need an actual ball to throw.
throw new InvalidLockCombinationException();
Nullary constructor given since you said it should be a basic exception sans extra fields or methods. I would still try to accept a String message for extra info but that's beyond the scope of this answer.
I recommend using an actual IDE. It would politely tell you about what's happening with its red mark.

ArrayIndexOutOfBoundsException in weka.classifiers.Classifier.classifyInstance

I have written this method. I want to write a Bayesian Network, but I get an exception on the classifyInstance() method.
Here is my code:
public static double bayesNet1(Dataset data, Dataset testingSet) throws Exception {
Instances insts = convertTxtToARFF(data);
K2 learner = new K2();
MultiNomialBMAEstimator estimator = new MultiNomialBMAEstimator();
estimator.setUseK2Prior(true);
EditableBayesNet bn = new EditableBayesNet(insts);
bn.initStructure();
learner.buildStructure(bn, insts);
estimator.estimateCPTs(bn);
double error = 0;
Instances instsTest = convertTxtToARFF(testingSet);
for(int i=0; i<instsTest.numInstances()-1; i++) {
weka.core.Instance inst = instsTest.instance(i);
double predictedValue = bn.classifyInstance(inst);
if(inst.value(inst.classIndex())!= predictedValue)
error++;
}
return error/instsTest.numInstances();
}
And here is the exception:
java.lang.ArrayIndexOutOfBoundsException: 4 at
weka.classifiers.bayes.net.estimate.DiscreteEstimatorBayes.getProbability(DiscreteEstimatorBayes.java:106)
at
weka.classifiers.bayes.net.estimate.SimpleEstimator.distributionForInstance(SimpleEstimator.java:183)
at
weka.classifiers.bayes.BayesNet.distributionForInstance(BayesNet.java:386)
at weka.classifiers.Classifier.classifyInstance(Classifier.java:84)
at
ensembleClassifiersV2.EnsembleClassifierV2.bayesNet1(EnsembleClassifierV2.java:1090)
at
ensembleClassifiersV2.EnsembleClassifierV2.performing(EnsembleClassifierV2.java:800)
at
ensembleClassifiersV2.EnsembleClassifierV2.main(EnsembleClassifierV2.java:1267)
Can anyone help me what is wrong?
I have the same problem. My fault is I had not set the class for the test data. As simple as that.
I find that this error commonly occurs in the distributionForInstance() method for many of the different classifiers when you are dealing with nominal attributes.
If this is the case, it could be that the test data has a nominal attribute with an attribute value that the train data lacks.
In this case, it really depends upon what the best decision is for what you are doing. Perhaps checking the data itself for consistency is the first step and then you go from there.

I fail junit tests because of return type (I think)

So I have a class full of junit tests and a class full of methods that perform binary operations. The tests are checking to see if I have the right values at certain points.
I am failing a lot of tests because of what I believe to be is the return type. For example I get the message
junit.framework.ComparisonFailure: null expected:<[000]> but was <[BinaryNumber#4896b555]>
If I'm understanding this it's saying that it was looking for an array containing 000 but it got a BinaryNumber (which is the required return type). To help clarify here is one of the methods.
public BinaryADT and(BinaryADT y) {
int[] homeArr = pad(((BinaryNumber) y).getNumber());
int[] awayArr = ((BinaryNumber) y).pad(getNumber());
int[] solution = new int[awayArr.length];
int i = 0;
String empty = "";
while(i < solution.length){
solution[i] = homeArr[i] & awayArr[i];
i++;
}
for(int indexF = 0; indexF < solution.length; indexF++){
empty = empty + solution[indexF];
}
System.out.println(empty);
return new BinaryNumber(empty);
}
Am I understanding this right? If not could someone please explain? I'd also like to point out that this is for my homework but I'm not asking for answers/someone to do it for me. Just a point in the right direction at most.
I will gladly clarify more if it is needed (I didn't want to bog everything down).
Also this is my first post on here. I tried to keep to the formatting suggestions but I apologize if anything is sub-par.
As suggested here is the test method
public void testAnd1()
{
BinaryADT x = new BinaryNumber("111");
BinaryADT y = new BinaryNumber("000");
BinaryADT z = x.and(y);
assertNotSame(x,z);
assertNotSame(y,z);
assertEquals("000",z.toString());
}
Whenever you see the output of "toString()" like ClassName#SomeNumber, then you can be sure that toString() method is not implemented for that class (unless toString() method implementation itself is not like this).
In your case, expected value is [000], but you are getting [BinaryNumber#4896b555].
Try to implement toString() method in BinaryNumber class and return the value from this method as per assertEquals() expects. This should solve the problem.
Can you show me your test code?
1.Your expected type is different from the actual type.
2.BinaryADT class didn't overide toString method.

Categories

Resources