I have a question regarding implementing priority queue for Dijkstra's algorithm, because this is a hw so I couldn't create another class, so I'm trying to find a way to add nodes(integer)in priority queue but I want the queue to sort the weight inside the node, but not the node itself.
For example,I have 3 nodes(0,1,2) and node 0 has a weight of 10, node 1 has 15, and node 2 has 5.
Queue<Integer> queue = new PriorityQueue<Integer>();
queue.add(0);
queue.add(1);
queue.add(2);
while(!queue.isEmpty()){
System.out.println(queue.poll());
}
This should give me a output of 2,0,1.
Is this possible without creating another class? Or is there a different approach I could use besides priority queue?
Thanks in advance!!!!!! any help would be much appreciated!
One solution I could think of is sorting a normal queue every time I add a node into it, so if I have node 2,0,1 in the queue and I want to add node 3 which has a weight of 8, I would need to compare the weight with the top element of queue until it fits into the queue, so it would be 2,3,0,1 in queue, but this is kindda inefficient tho.
You have two options:
Create your own Node class, and make it implement the Comparable<Node> interface. The class will have a weight attribute, and it could compare Nodes based on their weight. This will create a natural ordering of Nodes that PriorityQueue will use.
Create the priority queue with the PriorityQueue(Comparator<? super E> comparator) constructor. It takes a comparison function (Comparator) for comparing two items. You can therefore have that function compare using the node's weights (which don't have to be kept in the same queue - the might be calculated dynamically or be kept in some separate data structure).
Related
I am currently studying about Algorithms & Data Structures and while I was reading over the Book of Algorithms 4th edition, I discovered the Bag data-structure together with the Stack and Queue.
After reading the the explanation of it, it is still unclear to me why would I prefer using a Bag (which has no remove() method) over other data-structures such as Stack, Queue, LinkedList or a Set?
As far as I can understand from the Book, the implementation of a Bag, is the same as for a Stack, just replacing the name of push() to add() and remove the pop() method.
So the idea of a Bag is basically having the ability to collect items and then iterate through the collected items, check if a bag is empty and find the number of items in it.
But under which circumstances I would better using a Bag over one of the mentioned above Collections? And why a Bag doesn't have a remove() method basically? is there a specific reason for it?
Thanks in advance.
Stack is ADT of the collection of elements with specific remove order = LIFO (last-in-first-out), allows duplicates,
Queue is ADT of the collection of elements with specific remove order = FIFO (first-in-first-out), allows duplicates,
LinkedList is implementation of the list,
Set is ADT of the collection of elements which disallows duplicates,
Bag is ADT of the collection of elements which allows duplicates.
In general, anything that holds an elements is Collection.
Any collection which allows duplicates is Bag, otherwise it is Set.
Any bag which access elements via index is List.
Bag which appends new element after the last one and has a method to remove element from the head (first index) is Queue.
Bag which appends new element after the last one and has a method to remove element from the tail (last index) is Stack.
Example: In Java, LinkedList is a collection, bag, list, queue and also you can work with it as it was a stack since it support stack operations (add~addLast~push, peekLast, removeLast~pop), so you can call it also stack. The reason, why it does not implement Stack interface is, that peek method is reserved by Queue implementation which retrieves the head of the list (first element). Therefore in case of LinkedList, the "stack methods" are derived from Deque.
Whether Bag contains remove(Object) or not may depend on the implementation e. g. you can implement your own Bag type which supports this operation. Also you can implement get(int) operation to access object on specified index. Time complexity of the get(int) would depend on your implementation e. g. one can implement Bag via linked-list so the complexity would be at average O(n/2), other one via resizable array (array-list) with direct access to the element via index, so the complexity would be O(1).
But the main idea of the Bag is, that it allows duplicates and iteration through this collection. Whether it supports another useful operations depends on implementator's design decision.
Which one of the collection type to use dependes on your needs, if duplicates are not desired, you would use Set instead of Bag. Moreover, if you care about remove order you would pick Stack or Queue which are basically Bags with specific remove order. You can think of Bag as super-type of the Stack and Queue which extends its api by specific operations.
Most of the time, you just need to collect objects and process them in some way (iteration + element processing). So you will use the most simple Bag implementation which is one directional linked-list.
Bag is an unordered collection of values that may have duplicates. When comparing a stack to a bag, the first difference is that for stacks,
order matters.
Bag only supports the add and iterate operations. You cannot remove items from a bag-it’s possible to remove elements from a stack.-. After checking if the container is actually empty, clients can iterate through its elements; since the actual order is unspecified by definition, clients must not rely on it.
Bags are useful when you need to collect objects and process them as a whole set rather than individually. For example, you could collect samples and then, later, compute statistics on them, such as average or standard deviation—the order is
irrelevant in that case.
in terms of priority queues, a bag is a Priority queue for which element
removal (top()-Returns and extracts the element with the highest priority. ) is disabled. Priority Queue api has, top, peek,insert,remove and update methods. it’s possible to peek one element at a time, and the
priority of each element is given by a random number from a uniform distribution. Priorities also change at every iteration.
This is straight from the Java Docs:
This class and its iterator implement all of the optional methods of the Collection and Iterator interfaces. The Iterator provided in method iterator() is not guaranteed to traverse the elements of the priority queue in any particular order. If you need ordered traversal, consider using Arrays.sort(pq.toArray()).
So basically, my PriorityQueue works fine, but printing it out to the screen using its own built in toString() method caused me to see this anomaly in action, and was wondering if someone could explain why it is that the iterator provided (and used internally) does not traverse the PriorityQueue in its natural order?
Because the underlying data structure doesn't support it. A binary heap is only partially ordered, with the smallest element at the root. When you remove that, the heap is reordered so that the next smallest element is at the root. There is no efficient ordered traversal algorithm so none is provided in Java.
PriorityQueues are implemented using binary heap.
A heap is not a sorted structure and it is partially ordered. Each element has a “priority” associated with it. Using a heap to implement a priority queue, it will always have the element of highest priority in the root node of the heap. so in a priority queue, an element with high priority is served before an element with low priority. If two elements have the same priority, they are served according to their order in the queue. Heap is updated after each removal of elements to maintain the heap property
At first guess, it's probably traversing the data in the order in which it's stored. To minimize the time to insert an item in the queue, it doesn't normally store all the items in sorted order.
Well, as the Javadoc says, that's how it's been implemented. The priority queue probably uses a binary heap as the underlying data structure. When you remove items, the heap is reordered to preserve the heap property.
Secondly, it's unwise to tie in a specific implementation (forcing a sorted order). With the current implementation, you are free to traverse it in any order and use any implementation.
Binary heaps are an efficient way of implementing priority queues. The only guarantee about order that a heap makes is that the item at the top has the highest priority (maybe it is the "biggest" or "smallest" according to some order).
A heap is a binary tree that has the properties:
Shape property: the tree fills up from top to bottom left to right
Order prperty: the element at any node is bigger (or smaller if smallest has highest priority) than its two children nodes.
When the iterator visits all the elements it probably does so in a level-order traversal, i.e. it visits each node in each level in turn before going on to the next level. Since the only guarantee about order that is made that a node has a higher priority than its children, the nodes in each level will be in no particular order.
I'm just studying for exams right now, and came across this question in the sample exam:
Block Implementation of a Priority Queue
If we know in advance that a priority queue will only ever need to cater for a small number of discrete priorities (say 10), we can implement all operations of the priority queue in constant time by representing the priority queue as an array of queues - each queue storing the elements of a single priority. Note that while an operation may be linear in the number of priorities in the priority queue, the operation is still constant with respect to the size of the overall data structure.
The Objects stored in this priority queue is not comparable.
I have attempted it but I am lost as to how I am supposed to assign priority with a array implementation priority queue.
I have also tried looking for solutions, but all I've managed to find are examples that used Comparable, which we did not learn in this course.
Question: http://imgur.com/3mlBoW7
Each of the arrays will correspond to a different priority. Your lowest level priority array will deal only with objects of that priority level. Your highest level priority array will deal with objects of highest priority level, and so on. When you receive a new object, you place it into the array that corresponds to its priority.
It doesn't matter, then, that objects are not comparable since they are sorted by priority based on the stratification of the arrays. Then, when you are looking for next elements to execute, you check the highest priority array and see if there are any elements; if not, move to the next priority, and so on through each array.
I'm hoping I understood the problem and your question correctly; let me know if you have any additional questions in regards to my answer.
Following on Imcphers' answer, this would be a simple implementation in Java. Note that you do not need Comparable because enqueue takes an extra parameter, namely the discrete priority of the newly-added element:
public class PQueue<T> {
public static final int MAX_PRIORITIES = 10;
private ArrayList<ArrayDeque<T> > queues = new ArrayList<>();
public PQueue() {
for (int i=0; i<MAX_PRIORITIES; i++) {
queues.add(new ArrayDeque<T>());
}
}
public void enqueue(int priority, T element) {
// ... add element to the end of queues[priority]
}
public T dequeue() {
// ... find first non-empty queue and pop&return its first element
}
// ... other methods
}
Here, enqueue() and dequeue() are both O(1), because you know in advance how many priorities there can be, and what their values are (0 to MAX_PRIORITIES-1) so that no sorting is required, and search of a non-empty queue is constant-time (at most, MAX_PRIORITIES queues will have to be tested for emptyness). If these parameters are not known, the best implementation would use
private TreeSet<ArrayDeque<T extends Comparable> > queues
= new TreeSet<>(CustomComparator);
Where the CustomComparator asks queues to sort themselves depending on the natural order of their first elements, and which needs to keep these internal queues sorted after each call to enqueue --- this ups the complexity of enqueue/dequeue to O(log p), where p is the number of distinct priorities (and therefore, internal queues).
Note that Java's PriorityQueue belongs to the same complexity class, but avoids all that object overhead contributed by the TreeSet / ArrayDeque wrappers by implementing its own internal priorty heap.
So I am playing with the source code of the java.util.PriorityQueue. You can check it here: http://kickjava.com/src/java/util/PriorityQueue.java.htm
I am in need to peek the tail of the queue. This class only offers peeking the head of the queue. Is there an easy way that I can modify this class to allow me to pick the tail?
I am looking for any change / smart hack in this class to allow me to do that. My first try was to peek queue[size] but it did not work.
Java's PriorityQueue, like most priority queues, is implemented with a heap.
A heap is a data structure that maintains only the property that all parents are less than their children, or all parents are greater than their children. There is no inherent ordering among children.
Thus, the only way to find the tail would be to do a linear search among the bottom layer, which costs O(n) time for a size n priority queue.
Yes, but the at the cost of extra space complexity:
PriorityQueue<Integer> pqNew = new PriorityQueue<>(java.util.Collections.reverseOrder());
Now add the elements of your PriorityQueue into this pqNew.
Therefore, pqNew.peek() will give you the required answer i.e. the tail element of your original PriorityQueue.
How about use toArray() method and access the last position?
PriorityQueue<Integer> pq = new PriorityQueue<>(3);
pq.offer(1); pq.offer(2); pq.offer(3);
System.out.println((int) pq.toArray()[pq.size()-1]);
I was wondering which Java collection types are traversed fastest. Collections I am most interested in are...
array
LinkedList
Queue
PriorityLinkedList
HashMap
Actually among concrete classes of Collection interface , traversing will be fast through array. Its because as you know it traverse with the index of the element.Since it follows the index pattern so,traversing through index it makes our traversing fast. Why not others? Let me explain one by one..
1.LinkedList : LinkedList follows the insertion order.If you traverse the data and searching for elements,for every element it will search from beginning. So traversing becomes slow.
2.Queue : LinkedList and PriorityQueue are two concrete classes of Queue. The elements of the priority queue are ordered according to their natural ordering, or by a Comparator provided at queue construction time, depending on which constructor is used.It's not guaranteed to traverse the elements of the priority queue in any particular order.If you need ordered traversal, consider using Arrays.sort(pq.toArray()). So it becomes useless for traversing provided if you traverse without sorting it explicitly.
3.HashMap: If you use Map instead of Collection , traversing is not guaranteed here because it works on hashcode of the key element. So here again traversing becomes useless. You can directly search the element by providing key-value of the element.
4.PriorityLinkedList: This class does not exist in Java APIs.