I am using adjacency matrix to represent all the vertex of my weighted unidirectional large graph. In this graph no edge connects a vertex to itself. This makes all the diagonal elements of my adjacency matrix null. As my graph is large so in adjacency matrix i need not to save any elements in left triangle. Below is a small sample graph with adjacency matrix.
In an unidirectional graph left triangle is just mirror image of right triangle. i.e. adjacency_matrix[i][j], adjacency_matrix[j][i] are same. so why to store the left triangle. for a large graph this trick can save so much memory. At the same time diagonal elements are also zero since no edge connects a vertex to itself. i.e. adjacency_matrix[i][i] are zero.
But how can i implement this? can 2D array be used here?
Java doesn't really have 2D arrays, although there is syntatic sugar for allocating an array of arrays.
You probably just want:
int[][] weight = new int[N][];
for (int i = 0; i < N; i++) weight[i] = new int[N-1-i];
That will allocate the triangle you want. Then just index row r, col c at weight[r][c-r-1].
The other option is just to use a single array with
int[] weight = new int[N*(N-1)/2];
The indexing can be a bit more complicated to compute, but less allocation and pointer overhead.
You can use a jagged array.
int[][] matrix = new int[N][];
for (int i = 1; i <= N; i++) {
matrix[i] = new int[N - i + 1];
for (int j = 1; j <= N - i + 1; j++)
matrix[i][j] = edgeValue;
}
Basically you allocate for each row as much as you need.
P.S Maybe I messed up some boundaries here, but you should still get the main point:)
Related
I'm kind of at a roadblock while trying to assign 3D grid points as vertices to Cells.
The Cells should just contain 8 points as corner vertices.
I have created the grid without any issues, but cant seem to figure out how to sort the points to their according cells.
This sketch illustrates how the points are indexed:
One cube with 8 corner points would correspond to a Cell (ex. Cell0 would include points 0,1,3,4,6,7,9,10 as corner points).
The code should be something like this:
public class Cell
{
public int[] Index =new int[8];
}
public void makeCells()
{
numCells = (xSize - 1) * (zSize - 1) * (ySize - 1);
Cells = new Cell[numCells];
for ( int i = 0, j = 0; i < numCells; i++)
{
Cells[i] = new Cell();
for ( int k = 0; k <8; k++, j ++)
{
Cells[i].Index[k] = j;
}
}
}
I can't seem to get how to increment the indices properly so that they coordinate with the correct points.
Any form of help would be appreciated!
I managed to index all of my vertices using the algorithm above. If anyone needs any further explanation please feel free to ask.
Why we use matrices instead of just arrays?
If I create an array of vertices of a 3d model and I want to move each vertex left well
ArrayList<Vertex> vertex = fillVertecis();
for(Vertex vertex: vertices){
vertex.x += 2;
}
//or avoiding creating all those objects
float[] vertices = fillVertecis();
//asumming we arrange the array like so [x1,y1,z1,x2,y2,z2....]
int x = 0;
int y = 1;
int z = 2;
for(int i = 0; i < vertices.lenght/3; i+= 3){
vertices[i+x] += 1;
}
sure I'm looping through all vertex but don't we have to do the same using matrices?
What advantages do we have using matrices instead of arrays?
What advantages do we have using matrices instead of arrays?
Clarity of purpose.
Ease of manipulation.
Abstraction of implementation.
...
Try applying rotation or scaling to your vertices and you'll see the benefit of 4x4 matrices and homogeneous transformations over arrays.
I have two containers: a 2-dimensional NxN matrix and a 1-dimensional array which is the transposed 1D "version" of the matrix (so for a 5x5 array, I will have a 25 element array with the same values). I want to implement a query function that will take 2D coordinates as arguments but will be doing work on the equivalent 1D array.
In order to keep algorithm efficiency strictly non-quadratic I want to access only the array and not the matrix.
I've checked other questions but they all talk about converting the whole matrix to an array through nested for-loops. I don't want to do this, as that would take quadratic time to run. Instead, I want the conversion to be on-demand for a given coordinate through a query function/method. In other words for a given number of N columns/rows:
transpose(int i, int j) {
int result;
result = i * N + j;
return result;
}
This is the formula I'm using but it is not correct. For example if I want to access the element in the {5,5} position the result would be 5*5 + 5 = 30, which is greater than 25 (which would be the total number of elements for 5x5 matrix).
Thanks in advance.
If you have a 2d array and a 1d array having same elements,then the following will be true
2d[i][j]=1d[i*number_of_columns+j]
I am assuming from your post that you already have created a 1d array out of a 2d one.
Note i and j are indices and rememeber indices begin from 0
EDIT:If you are accessing an element at [5][5] (as last element)it means your array is of order 6 by 6 and not 5 by 5.So your 1d array will have 6*6=36 elements and not 25.
You can use the deepToString() method to output a 2D array to a String. This can make it easier to do things such as sort() for example.
Assuming a declared int mat2d[m][n]; with m rows and n columns, you can convert it like
int * mat1d = new int[m * n];
int k = 0;
for (int i = 0; i < m; ++i)
for (int j = 0; j < n; ++i)
mat1d[k++] = mat2d[i][j];
If you just want to convert between 1D and 2D coordinates, serve yourself and make functions from this:
const int width = 10;
// from 1D coordinate to 2D coordinate
int coord_1d = 25;
int coord_x = coord_1d % width;
int coord_y = coord_1d / width;
// from 2D coordinate to 1D coordinate
coord_1d = coord_x + coord_y * width;
Your question is quite confusing, you said that you don't want nested loops, here is a just-one-loop conversion
int[][] a={
{1,2,3,4,5,6},
{4,5,6,7,8,9},
{7,8,9,1,2,3},
{1,2,3,4,5,6}
};
int[]b=new int[a.length*a[0].length];
int x=0;
for(int i=0, j=0;i<a.length&&j<a[0].length;i=(j==a[0].length-1?i+1:i),j=(j+1)%a[0].length)
b[x++]=a[i][j];
System.out.println(Arrays.toString(b));
If you want the conversion to be based on coordinates, by changing i and j values in the for loop to such coordinates will allow you to convert to array only a subset of your matrix
I am making a Pac-Man game and I am currently working on the ghosts AI. I am planning on using Dijkstra's algorithm for the pathfinding. My problem is that when my game is loaded the vertices for the graph are stored in a matrix. I am trying to assign each vertex all of its edges like this
for(int x = 0; x<40; x++)
{
for(int y = 0; y<40; y++)
{
Vertex vertex = map[x][y];
vertex.adjacencies = new Edge[]{new Edge(map[x-1][y], 1), new Edge(map[x+1][y], 1), new Edge(map[x][y-1], 1), new Edge(map[x][y+1], 1)};
}
}
the problem is that it sometimes throws an array out of bounds exception. How would I fix this without putting in tons of if statements to check if the current vertex is on the edge of the graph?
One easy way is to include a non-traversable border around the edges.
For example, if your actual map is 40x40, you can declare a 42x42 array. Rows 0 and n would be non-traversable, as would be columns 0 and n.
You'd still need to handle cylindrical travel of the pacman between left and right sides.
You should start your loop with a "border" of 1, like this:
for(int x = 1; x < 39; x++)
because, when you create your edges with map[x-1][y] with a x started to 0, it take -1 as array index, so it throw an Array Out of Bounds exception.
I'm working on an OpenGL project in Java, and it has come to point where I'd like to create the transformation matrices in my own code, so i can use them to do world-to-screen point transformations, and vice versa. I've created a Matrix class with support for transformations, and that is all working quite nicely. However, I'm having trouble actually figuring out how to create an inverse transform.
So my question is this:
Given an arbitrary affine (4x4) transformation matrix, how do you create the inverse transformation matrix? Are some matrices uninvertible? What are the limitations and caveats of inverting a transformation matrix?
From my research, I've heard various methods of doing so, with the simplest being to transpose then negate the matrix. However, this doesn't seem to be actually working. I've heard that this method doesn't work on some matrices, and even that some matrices are uninvertible.
I'm looking for more than just a "plug in this equation" answer, because I'd actually like to understand what's going on when I invert a matrix. This also excludes "just use this library" answers. I might move to a matrix library in the future, but for now I'd like to create it myself.
Edit: Before anyone asks, this is NOT homework. This is a personal project.
Edit: Apparently there's a whole list of strategies for calculating inverse matrices here: http://en.wikipedia.org/wiki/Invertible_matrix
Here is some code that I used in my Computer Graphics course, basically I used the Gauss Jordan elimination for calculating the inverse of a matrix. For a matrix to be invertible its determinant value must be not equal to zero. I have not handled that case in my code though, I am not going to do it all for you.
Matrix4* Matrix4::FindInverse(Matrix4 &a){
int n = R;
int i = 0;
int j = 0;
float pivot = 0;
Matrix4* invA = NULL;
//TODO: Check whether the matrix is invertible.Else Return
invA = new Matrix4();
invA->SetMatrix4(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1);
for(i = 0; i < n; i++){
pivot = a.v[i][i];
if(pivot != 1.0 and pivot != 0){
for(int t = i; t < n; t++){
a.v[i][t] = a.v[i][t]/pivot;
invA->v[i][t] = invA->v[i][t]/pivot;
}
}
//Update to the new pivot which must be 1.0
pivot = a.v[i][i];
for(j = 0; j < n; j++){
if( j==i ){
continue;
}
else{
float l = a.v[j][i]/pivot;
for(int m = 0; m < n; m++){
a.v[j][m] = a.v[j][m] - l * a.v[i][m];
invA->v[j][m] = invA->v[j][m] - (l * invA->v[i][m]);
}
}
}
}
return invA;
}