Fast hashing of 2-dimensional array - java

I'm building a Reversi player using the standard alpha beta pruning search algorithm. I'm trying to add a translation table to store previously calculated nodes in the search tree. So I need to hash a 2 dimensional array representing the game board (the state) and store a value for that.
I can't come up with anything better than a double for loop iterating over my arrays and adding all values together multiplying them with the offsets to get unique hash values.
#Override
public int hashCode() {
if (dirtyHash) {
int hash = 0;
for (int i = 0; i < Board.SIZEX; i++)
for (int j = 0; j < Board.SIZEY; j++)
hash += board[i][j] * (i + Board.SIZEY * j);
hashValue = hash;
dirtyHash = false;
}
return hashValue;
}
I suspect there must be a much smarter way to do this? Anyone got any ideas?

I would use java standard library as a first try:
int hash = java.util.Arrays.deepHashCode( board );
Once everything works well, profile your whole app, to check if the hashcode computation is really a performance bottleneck.

If you want to handle this yourself here is one way you could do it.
There are three values for each cell on the board: empty, black, white. That means you can use two bits per cell on the board. And since the board is 8x8 or 64 cells, you can encode the board in two long primitives. Maybe one of them tells you whether a particular cell is empty, and if it's not, the other tells you its color.
You do not even need to convert this representation into a 2D array. You can use bitwise operators on the longs directly in your methods to work with the board.
The hash value could then be the XOR of the two longs, or something like that.

You should be using a Zobrist hash for this. It is perfect for board games. It can also be updated incrementally as the board changes, instead of being recalculated from scratch every time. This makes it very efficient.
http://en.wikipedia.org/wiki/Zobrist_hashing

I'd suggest to following:
public int hashCode() {
int hash = 0;
for (int i = 0; i < Board.SIZEX; i++)
for (int j = 0; j < Board.SIZEY; j++)
hash = (hash) ^ ( (Math.pow(p,i)+Math.pow(p,j))* board[i][j]
return hashValue;
}
for p and q large 32-primes.
Why is that fast?
Calculatoin for a board is quite easy: the new can be calculated from the old with hash = (hash) ^ ( (Math.pow(p,i)+Math.pow(p,j))* board[i][j], iterating not over the whole board, but only the Changed stones. (if you add a black once with the hash for the black stone, if you change from black to white once with the black stone to remove it from the hash und once again with the white to add it)

Related

Summing over a N dimensional function - Monte Carlo Integration?

I wanted to evaluate a certain sum needed for a monte carlo method in N dimensions. In N dimensions I have N variables with M data points, meaning that I basically have M N-D vectors representing M sampling points. I have to hold one variable fixed while I sum over all other variables for M values. Currently my code is (assuming my mesh which has N columns and M rows is static):
public static double myFunction(int row, int col){
double checkMesh = mesh[row][col];
return myFunctionHelper(0,col,checkMesh);
}
public static double myFunctionHelper(int j, int col, double checkMesh){
//function is initialized with j=0
if (j >= mesh[0].length){
return 0;
}
double sum = 0;
for (int i=0 ; i<mesh.length ; i++){
sum += myFunctionHelper(j+1,col,checkMesh);
if (j==mesh[0].length-1){
if (mesh[0][col]==checkMesh){
sum += function(mesh[0]);
}
mesh = rotate(mesh,j);
}
}
if (j>=1){
mesh = rotate(mesh,j-1);
}
return sum;
}
Now this function works but it doesn't hold any variables fixed, instead it just sums over all possible combinations of variables. I was wondering if anyone had any suggestions on how I can alter this to make it work as I want it to. Currently the only workaround that I can think of is to remove the fixed column from my matrix, sum over the combinations of the altered matrix, and when the function gets evaluated make sure the fixed variable is included in the right spot of an altered list, except I want to avoid doing this as it requires more memory and isn't as clean. I'd appreciate the help :).
EDIT: The rotate function takes the mesh and rotates the j-th column by one vertically upwards movement. Also function takes a vector as an argument, where the vector is represented by an array.
(1) You are computing the sum recursively, through myFunctionHelper calling myFunctionHelper. This may work, but it makes the code more involved than necessary. Recursion is not really not suited for this kind of numeric computation. Rewrite your algorithm without recursion, as a double loop over row and columnd indices, and things will get much clearer.
(2) With mesh[0][col]==checkMesh you try to identify the fixed entry by value. Why not by column and row index?

Store 2D Array Index in ArrayList?

I'm coding a Battleship game and I need some way to track where the ships have been placed. I'm thinking the best way of doing this is with an ArrayList. If I store the indices that are contained in a placed ship, then I can iterate through the ArrayList to signify it's an invalid position. For example, if I have a loop like so:
for (int j = 1; j < SIZE; j++)
{
for (int k = 1; k < SIZE; k++)
{
if ((cell[j][k].contains(click)))
{
cell[j][k].setColor(Color.blue);
}
}
}
I'd like to store the cell [ j ] [ k ] position in an ArrayList, and when it's time for the user to place the ship, a for loop is run to determine whether or not that cell is occupied. The problem is when I try to add to the ArrayList, I'm adding the actual cell, not the index. I want the actual position (x, y) to be stored in the List, but right now I'm storing the actual element.
Storing a list of x and y values is an ideal situation to use Java's point class.
ArrayList<Point> shipPositions = new ArrayList<Point>();
shipPositions.add(new Point(0, 0));
The ArrayList of points can be easily modified and iterated through to add and remove ship positions.
You can make a separate object for each ship. You could make a rather simple class with an x and a y float (or a Point to keep it simple) and then just make an array of the ships like so
Ship[] ships = new Ship[n];
or
ArrayList<Ship> ships = new ArrayList<Ship>();
and then you could get the value at ships[n] (for the 1st example) or ships.get(n) (for the 2nd example).
This would allow you to use this array for more than just positions and minimize excess and unnecessary code. :)

Creating an even amount of randomness in an array

Let's say that you have an arbitrarily large sized two-dimensional array with an even amount of items in it. Let's also assume for clarity that you can only choose between two things to put as a given item in the array. How would you go about putting a random choice at a given index in the array but once the array is filled you have an even split among the two choices?
If there are any answers with code, Java is preferred but other languages are fine as well.
You could basically think about it in the opposite way. Rather than deciding for a given index, which value to put in it, you could select n/2 elements from the array and place the first value in them. Then place the 2nd value in the other n/2.
A 2-D A[M,N] array can be mapped to a vector V[M*N] (you can use a row-major or a column-major order to do the mapping).
Start with a vector V[M*N]. Fill its first half with the first choice, and the second half of the array with the second choice object. Run a Fisher-Yates shuffle, and convert the shuffled array to a 2-D array. The array is now filled with elements that are evenly split among the two choices, and the choices at each particular index are random.
The below creates a List<T> the size of the area of the matrix, and fills it half with the first choice (spaces[0]) and half with the second (spaces[1]). Afterward, it applies a shuffle (namely Fisher-Yates, via Collections.shuffle) and begins to fill the matrix with these values.
static <T> void fill(final T[][] matrix, final T... space) {
final int w = matrix.length;
final int h = matrix[0].length;
final int area = w * h;
final List<T> sample = new ArrayList<T>(area);
final int half = area >> 1;
sample.addAll(Collections.nCopies(half, space[0]));
sample.addAll(Collections.nCopies(half, space[1]));
Collections.shuffle(sample);
final Iterator<T> cursor = sample.iterator();
for (int x = w - 1; x >= 0; --x) {
final T[] column = matrix[x];
for (int y = h - 1; y >= 0; --y) {
column[y] = cursor.next();
}
}
}
Pseudo-code:
int trues_remaining = size / 2;
int falses_remaining = size / 2;
while (trues_remaining + falses_remaining > 0)
{
if (trues_remaining > 0)
{
if (falses_remaining > 0)
array.push(getRandomBool());
else
array.push(true);
}
else
array.push(false);
}
Doesn't really scale to more than two values, though. How about:
assoc_array = { 1 = 4, 2 = 4, 3 = 4, 4 = 4 };
while (! assoc_array.isEmpty())
{
int index = rand(assoc_array.getNumberOfKeys());
int n = assoc_array.getKeyAtIndex(index);
array.push(n);
assoc_array[n]--;
if (assoc_array[n] <= 0) assoc_array.deleteKey(n);
}
EDIT: just noticed you asked for a two-dimensional array. Well it should be easy to adapt this approach to n-dimensional.
EDIT2: from your comment above, "school yard pick" is a great name for this.
It doesn't sound like your requirements for randomness are very strict, but I thought I'd contribute some more thoughts for anyone who may benefit from them.
You're basically asking for a pseudorandom binary sequence, and the most popular one I know of is the maximum length sequence. This uses a register of n bits along with a linear feedback shift register to define a periodic series of 1's and 0's that has a perfectly flat frequency spectrum. At least it is perfectly flat within certain bounds, determined by the sequence's period (2^n-1 bits).
What does that mean? Basically it means that the sequence is guaranteed to be maximally random across all shifts (and therefore frequencies) if its full length is used. When compared to an equal length sequence of numbers generated from a random number generator, it will contain MORE randomness per length than your typical randomly generated sequence.
It is for this reason that it is used to determine impulse functions in white noise analysis of systems, especially when experiment time is valuable and higher order cross effects are less important. Because the sequence is random relative to all shifts of itself, its auto-correlation is a perfect delta function (aside from qualifiers indicated above) so the stimulus does not contaminate the cross correlation between stimulus and response.
I don't really know what your application for this matrix is, but if it simply needs to "appear" random then this would do that very effectively. In terms of being balanced, 1's vs 0's, the sequence is guaranteed to have exactly one more 1 than 0. Therefore if you're trying to create a grid of 2^n, you would be guaranteed to get the correct result by tacking a 0 onto the end.
So an m-sequence is more random than anything you'll generate using a random number generator and it has a defined number of 0's and 1's. However, it doesn't allow for unqualified generation of 2d matrices of arbitrary size - only those where the total number of elements in the grid is a power of 2.

Transpose matrix stored in a 1-dimensional array without using extra memory [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
In-place transposition of a matrix
Recently attended an Technical Written Interview. Came through the following question.
I have an array as say
testArray = {a1,a2,a3,...an,b1,b2,b3,....bn,c1,c2,c3,.....,cn}
I need to sort this array as `
testArray = {a1,b1,c1,a2,b2,c2,a3,b3,c3,.....,an,bn,cn}
Constraint is I should not use extra memory, should not use any inbuilt function.
Should write complete code, it can be in any language and can also use any data structure.
eg:
Input: {1,2,3,4,5,6,7,8,9}, n = 3
Output: {1,4,7,2,5,8,3,6,9}
I could not get any solution within the constraint, can anyone provide solution or suggestion?
This is just a matrix transpose operation. And there is even a problem and solution for in-place matrix transposition on Wikipedia.
No extra space is impossible, since you need to at least go through the array. O(1) additional memory is possible, with heavy penalty on the time complexity.
The solution is built on follow-the-cycle algorithm in the Wikipedia page: for each cell, we will find the cell with the smallest index in the cycle. If the cell with the smallest index is greater than or equal (>=) to the index of the current cell, we will perform chain swapping. Otherwise, we ignore the cell, since it has been swapped correctly. The (loosely analyzed) upper bound on time complexity can go as high as O((MN)2) (we go through M * N cells, and the cycle can only be as long as the total number of cells).
Impossibility
It is impossible to implement this algorithm without extra use of memory and an arbitrary length because you need a an iterator to traverse the list and that takes up space.
Finding the right indices to swap
For fixed lengths of the array and fixed n you can use a matrix transpose algorithm.
and in order to swap the elements y
The algorithm you are looking for is a matrix transpose algorithm.
so you have to swap every element exactly once iterating through it.
http://en.wikipedia.org/wiki/Transpose
basically you have to swap the m -th element in the n - th component with the n - th element in the m -th component. This can be done by a double loop.
m = length(array)/n;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
{
index_1 = i * m + j;
index_2 = j * m + i
swap(index_1, index_2);
}
Note: For fixed m and n this loop can be completely unrolled and therefore m, i, j can be replaced by a constant.
Swaping without Memory consumption
In order to swap every element without using extra space you can use the XOR swap algorithm as pointed out in the comments:
X := X XOR Y
Y := Y XOR X
X := X XOR Y
The simplest way to swap two numbers (a and b) without using a temporary variable is like this:
b = b + a;
a = b - a;
b = b - a;
If you write that in a function, then you're part of the way there. How you keep track of which variable to swap within the arrays without using a temporary variable eludes me right now.
Bear in mind voters: he doesn't actually need to sort the array, just swap the right values.
Edit: this will work with large values in Java (and in C/C++ unless you turn on some very aggressive compiler optimisations - the behaviour is undefined but defaults to sane). The values will just wrap around.
Second edit - some (rather untested) code to flip the array around, with I think 4 integers over the memory limit. It's while technically massively unthreadsafe, but it would be parallelisable just because you only access each array location once at most:
static int[] a = {1,2,3,4,
5,6,7,8,
9,10,11,12,
13,14,15,16};
static int n = 4;
public static void main(String[] args)
{
for(int i = 0; i < a.length/n; i++) // 1 integer
for(int j = 0; j < n; j++) // 1 integer
if(j > i)
swap(i*n+j, j*n+i);
}
static void swap(int aPos, int bPos) // 2 integers
{
if(a[aPos] != a[bPos])
{
a[bPos] = a[aPos] + a[bPos];
a[aPos] = a[bPos] - a[aPos];
a[bPos] = a[bPos] - a[aPos];
}
}
Apologies if this misunderstands the question; I read it carefully and couldn't work out what was needed other than this.
Take a look at Quicksort algorithm
For more information about available algorithms, go to Sorting algorithm page.

Sparse Matrix multiplication in Java

Hello I know there are a lot of questions on sparse matrix multiplication, but many of the answers say to just use libraries. I want to do it without using library functions. So far I've done the easy part, getting my matrices into the form of
element array
column array
row array.
What I need help with is the logic portion. If matrix A is M*N and matrix B is N*P, how do I do this? I considered iterating over the elements in matrix A and checking if it's rowA== colB, and if so if colA==rowB and if that's true then multiply. I currently know my version is wrong, but I can't think of a way to make it right.
for(int i = 0; i < rows; i++)
{
sum = 0;
for(int k = 0; k < cols; k++)
if (row_values.get(i) == col_valuesb.get(k))
if (col_values.get(i) == row_valuesb.get(k))
{
sum += (short) (elements.get(i)*elementsb.get(k));
}
elementsc.add(sum);
row_valuesc.add(row_values.get(i));
col_valuesc.add(col_values.get(k));
}
You said:
"I considered iterating over the elements in matrix A and checking if it's rowA== colB, >and if so if colA==rowB"
Well, since two matrices are, by definition, able to multiply if and only if colA==rowB, then shouldn't you modify
if (row_values.get(i) == col_valuesb.get(k)){
if (col_values.get(i) == row_valuesb.get(k))
{
and just make it
if (row_values.get(i) == col_valuesb.get(k)){
instead?

Categories