Question text in black, answers in blue.
add
and poll
methods
of the Java library PriorityQueue
class. Why those two
-- wouldn't add
and remove
, or
offer
and poll
, be more natural pairings?
Yes, they would. I didn't mean anything by picking those two --
either of the pair would work in either case. The difference only
matters if you are planning to poll an empty
PriorityQueue
, which you probably shouldn't be doing.
spoons
field as well?
Yes. Neither of your two new methods should have any side effects on
the calling Maze
object.
spoons
as an instance field
for Maze
, as well as one for each cell. That way I can
have
the bestPath
method record the optimum number of spoons
there,
for me to use later. Is that all right?
Sure. We are only specifying the public methods of Maze
,
and this would be a private field that you may use as you see fit.
getPQCellArray
to set some of the open cells to be
towns. We weren't told what to call the main array of the
Maze
class, and I'm worried that your driver will not
accept
my code if I have a different name for a method like that.
That is a legitimate worry, but we are aware of
it
and we would not insist on a particular name like that when it
wasn't specified. Our student benefactor wrote their driver before
seeing
the new Maze
constructor, taking 0's, 1's, and 2's, that
I
put in MazeStub.java
. We would use that means of setting
towns and villages in the driver.
Remember that whether or not a cell is in the priority queue, it is always in the maze. You can find it from its coordinates, and then look at its other fields. If it has been put on the queue, its parent and spoons fields will be set. If you find a new path, you can compare the new spoons number against the old one to see whether the new path is better. You only need one parent field because you only care about the parent for the best path.
When you take a cell off of the path to look at its neighbors, you know that the path you have to it is the best one. (We won't prove this, but you can take it as fact. The reason is that a better path could only come from a place to which you could transport more spoons, and any such cells have come off the queue before this cell.) So that is the time to mark the cell as seen.
bestPath
method replace the old
path
method, or do we keep them both because they have
two different functions?
The old path
method is written in
terms of QCells
rather than PQCells
-- it
might
still work, but if so it would find paths that had the fewest number
of steps, not ones that would bring the most spoons. You could
possibly make some use of that -- for example, you could run
isPath
on your source and destination first, and not
bother with spoons if there is no path at all -- but I don't see a lot
of point in that. We don't expect the Project #5 maze class to have
the functionality of the Project #4 class -- that would have been a
reasonable thing to ask for, but we didn't ask for it and won't grade
for it.
PriorityQueue
is a library class and I can't easily
see its code, how can I tell how it is going to order the elements in
its list? Do I need to tell it how to order them in terms of spoons?
Well, one of us needs to tell it how, and
fortunately I have already done it. Remember that
PriorityQueue
uses the "natural order" for its ordering,
and that the natural order on a class T
(that implements
Comparable<T>
) is given by that class'
compareTo
method. The class PQCell
that I
gave you contains a compareTo
method, that defines the
"smaller" cell to be the one to which you can bring more spoons.
Question P5.9, posted 1 November:
You say that we should use a PriorityQueue
object to hold
the list of cells that are currently being searched. Do I have to write a
PriorityQueue
class myself, or may I use the one in the Java
library?
I intended for you to use the one in the library (
in Note that when we say "implement a I don't think the Ah, this is the problem that questioner P5.3 above had
in mind. They suggest one solution -- another would be to make java.util
) --
sorry if this wasn't clear. That class is not actually implemented as an
ordered list (it uses a heap, as we will see later in the course), but it
will work as if it were except for running faster in some cases. You may
implement it if you want, which is good practice, but you don't need to for
the project.
PriorityQueue
class", we
don't mean to say that the word implements
should be in your
code, to have your class implement an interface.
PriorityQueue
behave correctly if I change the spoons number? Or can I take the cell out,
change it, and put it back in?
java.util
priority queue is
ready for you to change the elements while they are in it. So you need your
second idea, removing the cell from the queue, changing it, and adding it
back in. The zero-parameter remove
method will not help you here,
because it will only remove the cell with the most spoons. Fortunately, there
is another remove
method in PriorityQueue
that takes
an Object
as a parameter and removes that object if it is in the
queue. (How do I know this? I looked in the API.) So removing, changing, and
reinserting the cell is a viable option. The other general approach would be
to create a new PQCell
object for the second copy, and have both
live in the queue at the same time. This can work but could be tricky -- you
need to make sure that you discard the second or later versions when they
come out of the queue, and you want to make sure that the cell that is actually
in the maze is the one that you want.
spoons
method call my bestPath
method and get the
spoons number from the path that it returns. But my bestPath
method cleans up all the spoons
fields of the cells before it
terminates! How do I get the number?
spoons
a near-copy of bestPath
, and another would be to create
a single method that determined both the number of spoons and the path, then
have spoons
and bestPath
call that method.
Last modified 2 November 2011