Best data structure to store and manipulate my data? - java

I am writing a simple Java program that will input a text file which will have some numbers representing a (n x n) matrix where numbers are separated by spaces. for ex:
1 2 3 4
5 6 7 8
9 1 2 3
4 5 6 7
I then want to store these numbers in a data structure that I will then use to manipulate the data (which will include, comparing adjecent numbers and also deleting certain numbers based on specific rules.
If a number is deleted, all the other numbers above it fall down the amount of spaces.
For the example above, if say i delete 8 and 9, then the result would be:
() 2 3 ()
1 6 7 4
5 1 2 3
4 5 6 7
so the numbers fall down in their columns.
And lastly, the matrix given will always be square (so always n x n, where n will be always given and will always be positive), therefore, the data structure has to be flexible to virtually accept any n-value.
I was originally implementing it in a 2-d array, but I was wandering if someone had an idea of a better data structure that I could use in order to improve efficiency (something that will allow me to more quickly access all the adjacent numbers in the matrix (rows and columns).
Ultimately, mu program will automatically check adjacent numbers against the rules, I delete numbers, re-format the matrix, and keep going, and in the end i want to be able to create an AI that will remove as many numbers from the matrix as possible in the least amount of moves as possible, for any n x n matrix.

In my opinion, you yo know the length of your array when you start, you are better off using an array. A simple dataType will be easier to navigate (direct access). Then again, using LinkedLists, you will be able to remove a middle value without having to re-arrange the data inside you matrix. This will leave you "top" value as null. in your example :
null 2 3 null
1 6 7 4
5 1 2 3
4 5 6 7
Hope this helps.

You could use one dimensional array with the size n*n.
int []myMatrix = new myMatrix[n * n];
To access element with coordinates (i,j) use myMatrix[i + j * n]. To fall elements use System.arraycopy to move lines.
Use special value (e.g. Integer.MIN_VALUE) as a mark for the () hole.
I expect it would be fastest and most memory efficient solution.

Array access is pretty fast. Accessing adjacent elements is easy, as you just increment the relevant index(s) (being cognizant of boundaries). You could write methods to encapsulate those operations that are well tested. Having elements 'fall down' though might get complicated, but shouldn't be too bad if you modularize it out by writing well tested methods.
All that said, if you don't need the absolute best speed, there are other options.
You also might want to consider a modified circularly linked list. When implementing a sudoku solver, I used the structure outlined here. Looking at the image, you will see that this will allow you to modify your 2d array as you want, since all you need to do is move pointers around.
I'll post a screen shot of relevant picture describing the datastructure here, although I would appreciate it if someone will warn me if I am violating some sort of copy right or other rights of the author, in which case I'll take it down...

Try a Array of LinkedLists.

If you want the numbers to auto-fall, I suggest you to use list for the coloumns.

Related

Finding LIS in an array of user defined objects based on more than one field

Cracking The Coding Interview(5th ed): Chp 11, Ques 7
Question: A circus is designing a tower routine consisting of people standing atop one another's shoulders. For practical and aesthetic reasons, each person must be both shorter and lighter than the person below him or her. Given the height and weights of each person in the circus, write a method to compute the largest possible number of people in such a tower.
My doubt:
In the solution given in the book it is clearly mentioned in the text
that sorting the elements will make the solution too trivial then why
elements have been sorted initially in the code?
If the elements do not need to stay in the same(relative) order, then
we would simply sort the array. This makes the problem too trivial, so
let's assume that the elements need to stay in the same relative
order.
Here is the code from the book where sorting has been done(First three lines of the code):
ArrayList<HtWt> getIncreasingSequence(ArrayList<HtWt> items)
{
Collections.sort(items);
return longestIncreaingSequence(items);
}
The proposed solution is composed of 2 steps:
sort by weight
find the longest increasing subsequence on the heights
The quoted sentence is not relative to the first step, but to the second step (finding the longest increasing subsequence) and it is explaining that we can't just sort the heights because we can't change their order since they are already sorted by their weights.
Take a look at this example with 5 people:
weights: 4 5 1 7 2
heights: 6 3 5 4 1
Result after step 1 (sorting by weight):
weights: 1 2 4 5 7
heights: 5 1 6 3 4
Now, looking at the heights we can see that the longest increasing subsequence is 1 3 4 which tell us that the solution is composed of 3 people. To obtain that result we can't just sort by heights because since they are already sorted by their weight...
... the elements need to stay in the same relative order.
So we need to use a longest increasing subsequence algorithm instead.

Java: Reduce array to specific number of averages

The main issue which needs to be solved is:
Let's say I have an array with 8 numbers, e.g. [2,4,8,3,5,4,9,2] and I use them as values for my x axis in an coordinate system to draw a line. But I can only display 3 of this points.
What I need to do now is do reduce the number of points (8) to 3, without manipulating the line too much - so using an average should be an option.
I am NOT looking for the average of the array in a whole - I still need 3 points of the amount of 8 in total.
For an array like [2,4,2,4,2,4,2,4] and 4 numbers out of that array, I could simply use the average "3" of each pair - but that's not possible if the number is uneven.
But how would I do that? Do you know how this process is called in a mathematical way?
To give you some more realistic details about this issue: I have an x axis, which is 720px long and let's say I get 1000 points. Now I have to reduce this 1000 points (2 arrays, one for x and one for y values) to a maximum of 720 points.
Thought about interpolation and stuff like that, but I'm still not quite sure if this is what I am looking for.
Interpolation is good idea. You input your points and get a polynomial function as an output. Then you can use it to draw your line. Check more here : Interpolation over an array (or two)
I would recommend that you fit all the points you have in some fashion and then evaluate at the particular points you need for the display.
There are a myriad of choices for fitting:
Least squares
Piecewise using polynomials or splines
You should consult a text or find a library to help you - something like Apache Commons Math.
It sounds like you are looking for a more advanced mathematical function than a simple average.
I would suggest trying to identify potential algorithms via Mathematica Stack Exchange and then trying to find a Java library that implements any of the potential choices (maybe a new question here).
since its for an X-axis, why not use the
MIN, MAX and (MIN+MAX)/2
for your three points?

Programmatically determine whether an array could be the result of a Weighted Quick Union algorithm on a set of 10 items?

I'd like to be able to programmatically examine an array and determine whether or not it could have been the result of a Weighted Quick Union algorithm. For those of us who need a refresher, a java implementation of Weighted Quick Union is here.
The basic idea of the weighted quick union algorithm is that is always connects the smaller tree to the larger one in order to minimize height, thus optimizing any traversal functions.
For example, an array that looks like 8 4 8 8 8 3 8 3 9 7 could not be the result of Weighted Quick Union because it contains a cycle, 9->7->3->8->9
An array like 8 0 9 3 6 6 0 4 8 0 cannot be a weighted quick union because the height of the trees together is 4, which is more than log(N) (where N is 10, the size of the initial array).
However, an array like 0 1 2 8 4 1 1 7 8 9 could have been the result of a weighted quick union.
I'd like to write a Java function like this:
public static boolean canBeResultOfWeightedQuickUnion(int[] id){
//returns whether or not the given array of ints could have been the result of a weighted quick union
}
How could I go about writing a method like this, ideally using the data structure available here?
"An array like *** cannot be a weighted quick union because the height of the trees together is 4, which is more than log(N) (where N is 10, the size of the initial array)."
In fact the maximum height in this case is ceil(log_2(N)), which is 4. To check this, just keep merging trees with the same height from the start
This property remains for all subtrees, and it is a very good answer for your question since you can just check this property.
The question that stills is how can you do this with most efficiency. I suppose that you just received an array and is checking it. So no other info is available. If this is the case, you can just create a auxiliary array for the height. Then you must go throught the id array, find the leafs and in a second step recursively go from the leafs to the roots updating the values of the heights and comparing to the number of elements in the subtree.

Card Program in Java

For this project I'm attempting I need to check if a hand of 5 cards, given as an array of 5 integers, is a straight. Right now I'm not sure how to check this as the array is not ordered and we are not allowed to use the Arrays.sort() method to sort it. The only way I can think of right now is to manually sort them using loops but I think this would be inefficient. Any input would be appreciated.
Does it have to be sorted? How about iterating all your cards, storing the lowest and highest one, and checking whether they are 5 apart? (max - min + 1).
I wouldn't bother about efficiency at this stage. Not to mention for an array of 5 integers.

8 puzzle: Solvability and shortest solution

I have built a 8 puzzle solver using Breadth First Search. I would now want to modify the code to use heuristics. I would be grateful if someone could answer the following two questions:
Solvability
How do we decide whether an 8 puzzle is solvable ? (given a starting state and a goal state )
This is what Wikipedia says:
The invariant is the parity of the permutation of all 16 squares plus
the parity of the taxicab distance (number of rows plus number of
columns) of the empty square from the lower right corner.
Unfortunately, I couldn't understand what that meant. It was a bit complicated to understand. Can someone explain it in a simpler language?
Shortest Solution
Given a heuristic, is it guaranteed to give the shortest solution using the A* algorithm? To be more specific, will the first node in the open list always have a depth ( or the number of movements made so fat ) which is the minimum of the depths of all the nodes present in the open list?
Should the heuristic satisfy some condition for the above statement to be true?
Edit : How is it that an admissible heuristic will always provide the optimal solution? And how do we test whether a heuristic is admissible?
I would be using the heuristics listed here
Manhattan Distance
Linear Conflict
Pattern Database
Misplaced Tiles
Nilsson's Sequence Score
N-MaxSwap X-Y
Tiles out of row and column
For clarification from Eyal Schneider :
I'll refer only to the solvability issue. Some background in permutations is needed.
A permutation is a reordering of an ordered set. For example, 2134 is a reordering of the list 1234, where 1 and 2 swap places. A permutation has a parity property; it refers to the parity of the number of inversions. For example, in the following permutation you can see that exactly 3 inversions exist (23,24,34):
1234
1432
That means that the permutation has an odd parity. The following permutation has an even parity (12, 34):
1234
2143
Naturally, the identity permutation (which keeps the items order) has an even parity.
Any state in the 15 puzzle (or 8 puzzle) can be regarded as a permutation of the final state, if we look at it as a concatenation of the rows, starting from the first row. Note that every legal move changes the parity of the permutation (because we swap two elements, and the number of inversions involving items in between them must be even). Therefore, if you know that the empty square has to travel an even number of steps to reach its final state, then the permutation must also be even. Otherwise, you'll end with an odd permutation of the final state, which is necessarily different from it. Same with odd number of steps for the empty square.
According to the Wikipedia link you provided, the criteria above is sufficient and necessary for a given puzzle to be solvable.
The A* algorithm is guaranteed to find the (one if there are more than one equal short ones) shortest solution, if your heuristic always underestimates the real costs (In your case the real number of needed moves to the solution).
But on the fly I cannot come up with a good heuristic for your problem. That needs some thinking to find such a heuristic.
The real art using A* is to find a heuristic that always underestimates the real costs but as little as possible to speed up the search.
First ideas for such a heuristic:
A quite pad but valid heuristic that popped up in my mind is the manhatten distance of the empty filed to its final destination.
The sum of the manhatten distance of each field to its final destination divided by the maximal number of fields that can change position within one move. (I think this is quite a good heuristic)
For anyone coming along, I will attempt to explain how the OP got the value pairs as well as how he determines the highlighted ones i.e. inversions as it took me several hours to figure it out. First the pairs.
First take the goal state and imagine it as a 1D array(A for example)
[1,2,3,8,0,4,7,5]. Each value in that array has it's own column in the table(going all the way down, which is the first value of the pair.)
Then move over 1 value to the right in the array(i + 1) and go all the way down again, second pair value. for example(State A): the first column, second value will start [2,3,8,0,4,7,5] going down. the second column, will start [3,8,0,4,7,5] etc..
okay now for the inversions. for each of the 2 pair values, find their INDEX location in the start state. if the left INDEX > right INDEX then it's an inversion(highlighted). first four pairs of state A are: (1,2),(1,3),(1,8),(1,0)
1 is at Index 3
2 is at Index 0
3 > 0 so inversion.
1 is 3
3 is 2
3 > 2 so inversion
1 is 3
8 is 1
3 > 2 so inversion
1 is 3
0 is 7
3 < 7 so No inversion
Do this for each pairs and tally up the total inversions.
If both even or both odd (Manhattan distance of blank spot And total inversions)
then it's solvable. Hope this helps!

Categories

Resources