How can we achieve Circular buffer implementation in Android?
Is there a way we can re-use a pre-defined method if exists? or do we have support for C standard libraries in Android?
In Android development first preference is to use Java rather than C for implementing these things. Ofcourse you can do that in C (using JNI) but that requires certain overheads i.e. you need to implement your own garbage collection logic along with the code of circular buffer whereas in Java this can be achieved automatically. . See below class if it works for your case..
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
public class CustomCircularBuffer<T> {
private T[] buffer;
private int tail;
private int head;
public CustomCircularBuffer(int n) {
buffer = (T[]) new Object[n];
tail = 0;
head = 0;
}
public void add(T toAdd) {
if (head != (tail - 1)) {
buffer[head++] = toAdd;
} else {
throw new BufferOverflowException();
}
head = head % buffer.length;
}
public T get() {
T t = null;
int adjTail = tail > head ? tail - buffer.length : tail;
if (adjTail < head) {
t = (T) buffer[tail++];
tail = tail % buffer.length;
} else {
throw new BufferUnderflowException();
}
return t;
}
public String toString() {
return "CustomCircularBuffer(size=" + buffer.length + ", head=" + head + ", tail=" + tail + ")";
}
}
Here are some other useful links which can give necessary explanations ..
Example
Another Example
In Depth Article
I just realized that ArrayDeque would be a good implementation for this.
There is also CircularArray from Android support.
CircularArray is a generic circular array data structure that provides
O(1) random read, O(1) prepend and O(1) append. The CircularArray
automatically grows its capacity when number of added items is over
its capacity.
I can't tell its performance, but from a quick glance at the Javadocs, it seems to be designed with efficiency in mind. Not so sure anymore.
Related
I have a BinaryTree and I want to get all nodes of a specific level. Order does not matter. I want to try to do this with recursion . My method looks like this:
public List<T> getNodesOnLevel(int i){
int recursionTool = i
//to do
recursionTool-=1
}
I tried to while(recursionTool != 0){ method.... and then recursionTool -1}
But I ended up getting all nodes until the wanted level.
My Node looks like this:
class Node<T>{
T val;
Node<T> left;
Node<T> right;
Node(T v){
val = v;
left = null;
right = null;
}
It is possible to implement this as a pure functional algorithm by concatenating the lists returned by recursive calls. Unfortunately, that is rather inefficient in Java because all retrieved values are copied by list creation or concatenation once at each recursion level.
If you are willing to use mutation, here is a solution that avoids the copying (assuming that this is a Node<T>):
private void getNodesOnLevel(int level, List<T> list) {
if (node == null) return;
if (level == 0) {
list.add(this.val);
} else {
this.left.getNodesOnLevel(level - 1, list);
this.right.getNodesOnLevel(level - 1, list);
}
}
The above method needs to be called with an empty (mutable) list as the 2nd argument, so we need another method:
public List<T> getNodesOnLevel(int level) {
List<T> list = new ArrayList<>();
this.getNodesOnLevel(level, list);
return list;
}
(In complexity terms, the pure functional solution is O(LN) where L is the level and N is the number of nodes at that level. My solution is O(N). Each value in the list will be copied twice on average, due to the way that ArrayList.append implements list resizing. The resizing could be avoided by creating the list with a capacity of 2level.)
This may help you. I had used this method to print nodes but you can change it.
public void printGivenLevel(TNode root, int level) {
if (root == null)
return;
if (level == 1 && root.getValue() != null) {
// here, add root.getValue() to list
} else if (level > 1) {
printGivenLevel(root.getLeft(), level - 1);
printGivenLevel(root.getRight(), level - 1);
}
}
I am trying to implement a Ring (circular queue) of Chars in Java and I'm having a difficult time thinking through how to detect if the buffer isEmpty without using the .size() method on the array.
Because if the Ring Buffer is full read pointer == write pointer but also if the Ring Buffer is empty, read pointer == write pointer so I'm not sure how to check for isEmpty() correctly. I know that I can do it with .size() but I'm trying to figure out if it's possible to implement it without.
I know that I will need to waste a space at the end of the array but I'm not sure how to check it. Would the check be as simple as if (head != (tail - 1))?
Also, I am trying to write the flush() method and I think I can do so with a for each loop looking like this:
for(char c : items){
c = (Character) null;
}
But eclipse yells at me for null pointer access requiring auto boxing and unboxing.
Any help would be very much appreciated. The full class is below for reference:
public class RingBuffer {
private char[] items;
private int front;
private int rear;
private int last;
public RingBuffer(int capacity){
items = new char[capacity +1];
front = 0;
rear = 0;
last = capacity;
}
public void flush(){
for(char c : items){
c = (Character) null;
}
}
public boolean isEmpty(){
return false;
}
}
You can read more about Full/Empty Buffer Distinction on Wikipedia
http://en.wikipedia.org/wiki/Circular_buffer#Full_.2F_Empty_Buffer_Distinction
There are multiple workarounds described. I would point out the one you mentioned and maybe the easiest one to understand.
Always keep one slot open
The buffer will never be full to the last item, but there will be always one slot empty. That means you can distinguish full from empty like this:
public boolean isEmpty() {
return head == tail;
}
public boolean isFull() {
// don't forget about the modulo here
return head == ((tail - 1) % capacity);
}
When flushing (I would name it rather clear()) you don't have to overwrite the data in array or allocate a new one. You can just set pointers to the beginning of the array.
public void clear() {
head = 0;
tail = 0;
}
And that means the buffer will be considered empty. No matter what data are really written in memory they will be ignored and then overwritten.
If you liked this answer please mark it as accepted. Thank you.
I need some help with my A* algorithm implementation.
When I run the algorithm it does find the goal, but the path is definately not the shortest :-P
Here is my code, please help me spot the bugs!
I think it might be the reconstruct path that is my problem but I'm not sure.
public class Pathfinder {
public List<Node> aStar(Node start, Node goal, WeightedGraph graph) {
Node x, y;
int tentative_g_score;
boolean tentative_is_better;
FScoreComparator comparator = new FScoreComparator();
List<Node> closedset = new ArrayList<Node>();
Queue<Node> openset = new PriorityQueue<Node>(10, comparator);
openset.add(start);
start.g_score = 0;
start.h_score = heuristic_cost_estimate(start, goal);
start.f_score = start.h_score;
while (!openset.isEmpty()) {
x = openset.peek();
if (x == goal) {
return reconstruct_path(goal);
}
x = openset.remove();
closedset.add(x);
for (Edge e : graph.adj(x)) {
if (e.v == x) {
y = e.w;
} else {
y = e.v;
}
if (closedset.contains(y) || y.illegal) {
continue;
}
tentative_g_score = x.g_score + e.weight;
if (!openset.contains(y)) {
openset.add(y);
tentative_is_better = true;
} else if (tentative_g_score < y.g_score) {
tentative_is_better = true;
} else {
tentative_is_better = false;
}
if (tentative_is_better) {
y.g_score = tentative_g_score;
y.h_score = heuristic_cost_estimate(y, goal);
y.f_score = y.g_score + y.h_score;
y.parent = x;
}
}
}
return null;
}
private int heuristic_cost_estimate(Node start, Node goal) {
return Math.abs(start.x - goal.x) + Math.abs(start.y - goal.y);
}
private List<Node> reconstruct_path(Node current_node) {
List<Node> result = new ArrayList<Node>();
while (current_node != null) {
result.add(current_node);
current_node = current_node.parent;
}
return result;
}
private class FScoreComparator implements Comparator<Node> {
public int compare(Node n1, Node n2) {
if (n1.f_score < n2.f_score) {
return 1;
} else if (n1.f_score > n2.f_score) {
return -1;
} else {
return 0;
}
}
}
}
Thanks to everyone for all the great answers!
My A* algorithm now works perfectly thanks to you guys! :-)
This was my first post and this forum is really amazing!
You are changing the priority of an element in the PriorityQueue after having inserted it. This isn't supported, as the priority queue isn't aware that an object has changed. What you can do is remove and re-add the object when it changes.
The priority is changed in the line: y.f_score = y.g_score + y.h_score;. This line happens after adding y to the priority queue. Note that simply moving the line openset.add(y); to after calculating the cost won't be enough, since y may have been added in a previous iteration.
It also isn't clear from your code whether the heuristic you used is admissible. If it isn't it will also cause you to get suboptimal paths.
Finally, a performance note: The contains method on ArrayList and PriorityQueue takes linear time to run, which will make the running time of your implememtation non-optimal. You can improve this by adding boolean properties to the nodes to indicate if they are in the closed/open sets, or by using a set data structure.
Priority queue does not update position of item when you change its priority.
Therefore heap property does not hold.
Changed priority affect additions/removals of other items, but it does not repair heap property.
therefore you does not get best item from open -> you don't find shortest path.
You can:
1) write your own heap and maintain index into it
2) add another object into PQ and mark the old one as invalid (you must instead of node put some object with validity flag and referencing node into queue).
2) have worse performance and I advise against it, but some navigation software use this approach (or at least few years back it used).
edit: Best practice is, insert immutable (or at least with imutable parts that means priority) objects into PriorityQueue
For my data structures class our homework is to create a generic heap ADT. In the siftUp() method I need to do comparison and if the parent is smaller I need to do a swap. The problem I am having is that the comparison operators are not valid on generic types. I believe I need to use the Comparable interface but from what I read it’s not a good idea to use with Arrays. I have also search this site and I have found good information that relates to this post none of them helped me find the solution
I removed some of the code that wasn’t relevant
Thanks
public class HeapQueue<E> implements Cloneable {
private int highest;
private Integer manyItems;
private E[] data;
public HeapQueue(int a_highest) {
data = (E[]) new Object[10];
highest = a_highest;
}
public void add(E item, int priority) {
// check to see is priority value is within range
if(priority < 0 || priority > highest) {
throw new IllegalArgumentException
("Priority value is out of range: " + priority);
}
// increase the heaps capacity if array is out of space
if(manyItems == data.length)
ensureCapacity();
manyItems++;
data[manyItems - 1] = item;
siftUp(manyItems - 1);
}
private void siftUp(int nodeIndex) {
int parentIndex;
E tmp;
if (nodeIndex != 0) {
parentIndex = parent(nodeIndex);
if (data[parentIndex] < data[nodeIndex]) { <-- problem ****
tmp = data[parentIndex];
data[parentIndex] = data[nodeIndex];
data[nodeIndex] = tmp;
siftUp(parentIndex);
}
}
}
private int parent(int nodeIndex) {
return (nodeIndex - 1) / 2;
}
}
Technically you're using the comparable interface on on item, not an array. One item in the array specifically. I think the best solution here is to accept, in the constructor, a Comparator that the user can pass to compare his generic objects.
Comparator<E> comparator;
public HeapQueue(int a_highest, Comparator<E> compare)
{
this.comparator = compare;
Then, you would store that comparator in a member function and use
if (comparator.compare(data[parentIndex],data[nodeIndex]) < 0)
In place of the less than operator.
If I am reading this right, E simply needs to extend Comparable and then your problem line becomes...
if (data[parentIndex].compareTo(ata[nodeIndex]) < 0)
This is not breaking any bet-practice rules that I know of.
I need to use a FIFO structure in my application. It needs to have at most 5 elements.
I'd like to have something easy to use (I don't care for concurrency) that implements the Collection interface.
I've tried the LinkedList, that seems to come from Queue, but it doesn't seem to allow me to set it's maximum capacity. It feels as if I just want at max 5 elements but try to add 20, it will just keep increasing in size to fit it. I'd like something that'd work the following way:
XQueue<Integer> queue = new XQueue<Integer>(5); //where 5 is the maximum number of elements I want in my queue.
for (int i = 0; i < 10; ++i) {
queue.offer(i);
}
for (int i = 0; i < 5; ++i) {
System.out.println(queue.poll());
}
That'd print:
5
6
7
8
9
Thanks
Create your own subclass of the one you want, and override the add method so that it
checks if the new object will fit, and fails if not
calls super.add()
(and the constructors).
If you want it to block when inserting if full, it is a different matter.
I haven't seen any limitation like that in the API. You can use ArrayList by changing the behavior of the add method with anonymous class feature:
new ArrayList<Object>(){
public boolean add(Object o){ /*...*/ }
}
Looks like what you want is a limited size FIFO structure, that evicts oldest items when new ones are added. I recommend a solution based on a cyclic array implementation, where you should track the index of the queue tail and queue head, and increase them (in cyclic manner) as needed.
EDIT:
Here is my implementation (note that it IS a Collection). It works fine with your test scenario.
public class XQueue <T> extends AbstractQueue<T>{
private T[] arr;
private int headPos;
private int tailPos;
private int size;
#SuppressWarnings("unchecked")
public XQueue(int n){
arr = (T[]) new Object[n];
}
private int nextPos(int pos){
return (pos + 1) % arr.length;
}
#Override
public T peek() {
if (size == 0)
return null;
return arr[headPos];
}
public T poll(){
if (size == 0)
return null;
size--;
T res = arr[headPos];
headPos = nextPos(headPos);
return res;
}
#Override
public boolean offer(T e) {
if (size < arr.length)
size++;
else
if (headPos == tailPos)
headPos = nextPos(headPos);
arr[tailPos] = e;
tailPos = nextPos(tailPos);
return true;
}
#Override
public Iterator<T> iterator() {
return null; //TODO: Implement
}
#Override
public int size() {
return size;
}
}
Perhaps an ArrayBlockingQueue might do the trick. Look here. Try something like this:
BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(5);
for (int i = 0; i < 10; i++) {
while (!queue.offer(i)) {
queue.poll();
}
}
for (int i = 0; i < 5; i++) {
System.out.println(queue.poll());
}
You have three choices
1) Subclass an Abstract Collection
2) Limit the size to five and do the logic around the code where you are doing the insert.
3) Use LinkedListHashMap The removeEldestEntry(Map.Entry) method may be overridden to impose a policy for removing stale mappings automatically when new mappings are added to the map. (You would then use an Iterator to get the values - which will be returned in order of insertion)
Your best bet is #1 - It is real easy if you look at the link.
Did you have a look at the Apache Commons Collections library? The BoundedFifoBuffer should exactly meet your needs.
If I remember correctly, I've done exactly what you want using a LinkedList.
What you need to do is check the size of the List, if it's 5 and you want to add objects, just delete the first element and keep doing so if the size is 5.