I've written code for a 100 x 100 adjacency matrix that represents the following directed graph:
I'm attempting to use a Floyd-Warshall algorithm to find the shortest path for all pairs of blue nodes in the graph. How do you only find the all pairs shortest path for the selected nodes? Here's the code I've written thus far:
public class AdjacencyMatrix
{
public static final int NUM_NODES = 100;
public static final int INF = Integer.MAX_VALUE;
public static boolean even(int num)
{
return num%2==0;
}
public static boolean odd(int num)
{
return num%2==1;
}
public static void initialize(int [][] adjMat, int N)
{
for(int i = 0; i < N; i++)
for(int j = 0; j <N; j++)
adjMat[i][j]=INF;
for(int x = 0; x<N; x++)
{
int row = x/10;
int column = x%10;
if (even(row)) {
if (column!=9)
adjMat[x][x+1]=1;
}
if (odd(row)) {
if (column!=0)
adjMat[x][x-1]=1;
}
if (even(column)){
if (row!=9)
adjMat[x][x+10]=1;
}
if (odd(column)) {
if (row!=0)
adjMat[x][x-10]=1;
}
}
}
public void floydWarshall(int[][] adjMat, int N)
{
adjMat = new int[N][N];
initialize(adjMat, NUM_NODES);
for(int k = 0; k < N; ++k) {
for(int i = 0; i < N; ++i) {
for(int j = 0; j < N; ++j) {
adjMat[i][j] = Math.min(adjMat[i][j], adjMat[i][k] + adjMat[k][j]);
}
}
}
}
public static void main(String[] args)
{
int adjMat[][] = new int[NUM_NODES][NUM_NODES];
initialize(adjMat, NUM_NODES);
int A,B,C,D,E,F,G,H,I,W;
A = 20;
B = 18;
C = 47;
D = 44;
E = 53;
F = 67;
G = 95;
H = 93;
I = 88;
W = 66;
System.out.println(adjMat[A][B]);
System.out.println();
}
}
First of all, you should not assign new value to adjMat parameter in floydWarshall(), because the value will not be saved after exiting the method.
The next step is to check adjMat[i][k] and adjMat[k][j] for equality to INF and continue the loop if so:
for(int k = 0; k < N; ++k) {
for(int i = 0; i < N; ++i) {
for(int j = 0; j < N; ++j) {
if (adjMat[i][k] != INF && adjMat[k][j] != INF) {
adjMat[i][j] = Math.min(adjMat[i][j], adjMat[i][k] + adjMat[k][j]);
}
Shortest Floyd-Warshall algo implemenation:
for(int k = 0; k < N; ++k) {
for(int i = 0; i < N; ++i) {
for(int j = 0; j < N; ++j) {
adjMat[i][j] = Math.min(adjMat[i][j], adjMat[i][k] + adjMat[k][j]);
}
}
}
After running this piece of cade adjMat will contain shortest distances between every pair of nodes.
Update: to avoid integer overflow, fill the matrix with Integer.MAX_VALUE / 2. In general case, it's dangerous to set the maximum possible value to variable as infinity, because you can't perform addition operation with it.
Related
I feel like I'm really close with this implementation of a memoized matrix chain algorithm in Java, but I'm getting an array out of bounds error on line 45 and 53. These, for some reason, really seem to mess me up. Maybe there's something I'm continually messing up with, but I dunno, obviously. Can anyone help me out?
public class Lab2 {
//fields
static int p[];
static int m[][];
final static int INFINITY = 999999999;
public Lab2() {
//
}
public static void main(String[] args) {
Lab2 lab2 = new Lab2();
Lab2.m = new int[7][7];
Lab2.p = new int[7];
Lab2.p[0] = 20;
Lab2.p[1] = 8;
Lab2.p[2] = 4;
Lab2.p[3] = 25;
Lab2.p[4] = 30;
Lab2.p[5] = 5;
Lab2.p[6] = 10;
int n = Lab2.p.length-1;
//initialize m array to infinity
for (int i = 1; i <= n; i++){
for (int j = i; j <= n; j++){
Lab2.m[i][j]= INFINITY;
}
}
lab2.lookUpChain(m, p, 1, n);
for (int i = 0; i < 8; i++){
for (int j = 0; j < 8; j++){
System.out.println(m[i][j]);
}
}
}
//
public int lookUpChain(int m[][], int p[], int i, int j ){
if (m[i][j]<INFINITY){
return m[i][j];
}
if (i == j){
m[i][j] = 0;
}
else{
for (int k = i; k <= j; i++){
int q = (lookUpChain(m,p,i,k)) + (lookUpChain(m,p,k+1,j)) + (p[i]*p[k]*p[j]);
if (q < m[i][j]){
m[i][j] = q;
}
}
}
return m[i][j];
}
}
else{
for (int k = i; k <= j; i++)
Change to:
else{
for (int k = i; k <= j; k++) // change i to k
I have a class with three fields:
public class CCTest {
public double f;
public double[][][] x;
public double counter;
}
I am trying to assign a random number to it. I have the method below for random data generation:
public static double[][][] getRandomX(int x, int y, int z) {
double[][][] result = new double[x][y][z];
Random r = new Random();
for (int i = 0; i < z; i++) {
for (int j = 0; j < y; j++) {
for (int k = 0; k < x; k++) {
result[k][j][i] = r.nextDouble();
}
}
}
// System.out.println(Arrays.deepToString(result));
return result;
}
As for the issue. I have for example an array with 5 CCTest-objects:
CCTest[] cls = new CCTest[5];
How can I assign a random number to each of the 5 CCTest-objects?
I tried this:
for (int i = 0; i < Size =5; i++) {
cls[i].x = new double[this.c][this.D][this.Size];
for (int j = 0; j < this.D; j++) {
cls[i].X= getRandomX(this.c, this.D, this.Size);
}
The result should have following structure:
X(:,:,1) =
0.8909 0.5472
0.9593 0.1386
X(:,:,2) =
0.1493 0.8407
0.2575 0.2543
But the code did not produce it. Could anyone guide me to a solution, please?
The problem is that you haven't made any CCTest-instances.
So after you make the CCTest[] cls = new CCTest[5]; the five CCTest-objects are null. You should create them if they don't exist yet:
CCTest[] cls = new CCTest[5];
for (int i = 0; i < (Size = 5); i++) {
// We create a new CCTest-instance if it doesn't exist yet:
if(cls[i] == null){
cls[i] = new CCTest();
}
cls[i].x = new double[this.c][this.D][this.Size];
for (int j = 0; j < this.D; j++) {
cls[i].x = getRandomX(this.c, this.D, this.Size);
}
}
Alternatively, you could create them first, and then do the for-loop to assign the random doubles:
CCTest[] cls = new CCTest[5];
for (int i = 0; i < cls.length; i++) {
cls[i] = new CCTest();
}
for (int i = 0; i < (Size = 5); i++) {
cls[i].x = new double[this.c][this.D][this.Size];
for (int j = 0; j < this.D; j++) {
cls[i].x = getRandomX(this.c, this.D, this.Size);
}
}
I am trying to create a method that calculates (N choose R) using dynamic programming but I get an array out of bounds exception:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 7
at BinomialCoefficients.method5(BinomialCoefficients.java:127)
at BinomialCoefficients.main(BinomialCoefficients.java:50)
I am using a 2 dimensional array. Here is my code,
protected static long method5(long lN, long lR)
{
long lArray[][] = new long[(int) (lN+1)][(int) (lR+1)];
for(int i = 0; i <= lN; i++)
{
lArray[i][0] = 1;
}
for(int i = 0; i <= lN; i++)
{
lArray[i][i] = 1;
}
for(int i = 0; i <= lN; i++)
{
for(int j = i; j <= i; j++)
{
lArray[i][j] = lArray[i-1][j-1] + lArray[i-1][j];
}
}
/*for(int i = 0; i <= lN; i++)
{
for(int j = 0; j <= i; j++)
{
System.out.print(String.format("%5d", lArray[i][j]));
}
System.out.println();
}*/
return lArray[(int) lN][(int) lR];
}
Can somebody tell me what is wrong with it?
This code looks suspicious
for(int i = 0; i <= lN; i++)
{
lArray[i][i] = 1;
}
considering lArray was initialized using two potentially different values:
long lArray[][] = new long[(int) (lN+1)][(int) (lR+1)];
I think you should have an inner loop here, such as:
for(int i = 0; i <= lN; i++) {
for (int j=0; j<=lR; j++) {
lArray[i][j] = 1;
}
}
I see the indexing error has already been corrected. But will point out that you're allocating a square array when you only need one row. You're also not taking advantage of symmetry. Consider something like this:
public class Binomial {
public static long n_choose_r(int n, int r) {
r = Math.min(r, n - r);
long [] a = new long[r + 1];
a[0] = 1;
for (int i = 1; i <= n; ++i) {
if (i <= r) {
a[i] = 1;
}
for (int j = Math.min(r, i - 1); j > 0; --j) {
a[j] += a[j - 1];
}
}
return a[r];
}
public static void main(String [] args) {
System.out.println(n_choose_r(6, 4));
}
}
My 2D FFT algorithm is outputting the correct values, but they are in the wrong order. For example, for input:
1050.0 1147.0 1061.0 1143.0
1046.0 1148.0 1118.0 1073.0
1072.0 1111.0 1154.0 1101.0
1078.0 1101.0 1106.0 1062.0
Taking the FFT, and then inverse FFT results in:
1050.0 1143.0 1061.0 1147.0
1078.0 1062.0 1106.0 1101.0
1072.0 1101.0 1154.0 1111.0
1046.0 1073.0 1118.0 1148.0
You can see that if you flip the last 3 columns horizontally, then the last 3 rows vertically, the data will be correct. As far as I can tell this is true for all input sizes so it's an easy (albeit hacky) fix. I am however worried about about computational time of the fix because I may have to perform this on 1024x1024 or even 2048x2048 images in the future.
I am fairly confident that my 1D FFT algorithm doFFT() is correct, and I am getting the expected values for the forward 2D FFT. It is just the inverse 2D FFT that is causing me trouble.
Does anyone see where my error is?
Code
private static double[] cose;
private static double[] sin;
public static void main(String[] args) {
float[][] img = new float[][]{
{ 1050.0f, 1147.0f, 1061.0f, 1143.0f},
{ 1046.0f, 1148.0f, 1118.0f, 1073.0f},
{ 1072.0f, 1111.0f, 1154.0f, 1101.0f},
{ 1078.0f, 1101.0f, 1106.0f, 1062.0f}
};
int size = img.length;
System.out.println("Image");
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
System.out.print(img[i][j] + "\t");
}
System.out.println();
}
Complex[][] fft = fft2D(toComplex(img), false);
Complex[][] inverse = fft2D(fft, true);
System.out.println("\nInverse");
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
System.out.print(inverse[i][j].getReal() + "\t");
}
System.out.println();
}
}
public static Complex[][] fft2D(Complex[][] pixels, boolean inverse){
int size = pixels.length;
computeCosSin(size);
Complex[][] data = transpose(pixels.clone());
Complex[] temp;
// FFT of rows
for (int i = 0; i < size; i++)
{
temp = doFFT(data[i], size);
data[i] = temp;
}
// FFT of columns
for (int i = 0; i < size; i++)
{
temp = new Complex[size];
for (int j = 0; j < size; j++)
{
temp[j] = data[j][i];
}
Complex[] temp2 = doFFT(temp, size);
for (int j = 0; j < size; j++)
{
data[j][i] = temp2[j];
}
}
if (!inverse)
{
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
data[i][j] = data[i][j].divide(size*size);
}
}
}
return data;
}
public static Complex[] doFFT(Complex[] data, int size){
Complex[] temp = new Complex[size];
int j = 0;
for (int i = 0; i < size; i++) {
temp[i] = data[j];
int k = size / 2;
while ((j >= k) && (k > 0)) {
j -= k;
k /= 2;
}
j += k;
}
Complex n,m,h,f;
for(int i=0; i<size;i+=4){
n = temp[i].add(temp[i+1]);
m = temp[i+2].add(temp[i+3]);
h = temp[i].subtract(temp[i+1]);
f = temp[i+2].subtract(temp[i+3]);
Complex mult = h.add(f.multiply(Complex.I));
Complex sub = h.subtract(f.multiply(Complex.I));
temp[i] = n.add(m);
temp[i+2] = n.subtract(m);
temp[i+1] = sub;
temp[i+3] = mult;
}
int u;
for(int i=4; i< size;i<<=1){
int v = size/(i <<1);
for(int c=0; c< size;c +=i<<1){
for(int x=0; x < i; x++){
u = v*x;
double calc = temp[i+c+x].getReal()*cose[u] - temp[i+c+x].getImaginary()*sin[u];
double calc2 = temp[i+c+x].getReal()*sin[u] + temp[i+c+x].getImaginary()*cose[u];
Complex fftArray = new Complex(calc,calc2);
temp[(i+c+x)] =temp[(c+x)].subtract(fftArray);
temp[(c+x)] = temp[(c+x)].add(fftArray);
}
}
}
return temp;
}
public static Complex[][] toComplex(float[][] arr)
{
Complex[][] newArr = new Complex[arr.length][arr.length];
for (int i = 0; i < arr.length; i++)
{
for (int j = 0; j < arr.length; j++)
{
newArr[i][j] = new Complex(arr[i][j], 0.0);
}
}
return newArr;
}
public static Complex[][] transpose(Complex[][] array)
{
for (int i = 0; i < array.length; i++)
{
for (int j = i+1; j < array[i].length; j++)
{
Complex temp = array[i][j];
array[i][j] = array[j][i];
array[j][i] = temp;
}
}
return array;
}
public static void computeCosSin(int size){
double num = (2.0*Math.PI)/size;
double cos = Math.cos(num);
double sine = Math.sin(num);
cose = new double[size];
sin = new double[size];
cose[0] =1.0;
for(int i=1; i<size;i++){
cose[i] = cos*cose[i-1] + sine*sin[i-1];
sin[i] = cos*sin[i-1] - sine*cose[i-1];
}
}
}
This doesn't solve the root problem, but it does change the data I'm getting to the data I expect so it will serve my purpose for now. I do worry it will be incredibly slow on large arrays.
This function swaps row i with row N-i and then swaps every column i with column N-i, for 0 < i < N, (Assuming a square, power of 2 input array)
public Complex[][] inverseFix(Complex[][] array)
{
int size = array.length;
// Swap rows
Complex[] temp;
for (int i = 1; i < size/2; i++)
{
temp = array[i];
array[i] = array[size-i];
array[size-i] = temp;
}
// Swap columns
Complex temp2;
for (int i = 0; i < size; i++)
{
for (int j = 1; j < size/2; j++)
{
temp2 = array[i][j];
array[i][j] = array[i][size-j];
array[i][size-j] = temp2;
}
}
return array;
}
i'm currently working on a small towerdefense project in Java and i got stuck with the pathfinding.
I read a lot about A* dijkstra and such things but i decided that it is probably the best to use Floyd-Warshall for pathfinding (at least it seems to me as its solving the all pair shortest path problem).
Anyway i tried to implement it on my own but it doesn't exactly work as it should.
i used the code on wikipedia as a start http://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm
So here's my Code:
public class MyMap {
public class MyMapNode {
// list of neighbour nodes
public List<MyMapNode> neighbours;
// Currently no need for this :)
public int cellX, cellY;
// NodeIndex for pathreconstruction
public int index;
// this value is checked by units on map to decide wether path needs
// reconstruction
public boolean isFree = true;
public MyMapNode(int cellX, int cellY, int index) {
this.cellX = cellX;
this.cellY = cellY;
this.index = index;
neighbours = new ArrayList<MyMapNode>();
}
public void addNeighbour(MyMapNode neighbour) {
neighbours.add(neighbour);
}
public void removeNeighbour(MyMapNode neighbour) {
neighbours.remove(neighbour);
}
public boolean isNeighbour(MyMapNode node) {
return neighbours.contains(node);
}
}
//MapSize
public static final int CELLS_X = 10;
public static final int CELLS_Y = 10;
public MyMapNode[][] map;
public MyMap() {
//Fill Map with Nodes
map = new MyMapNode[CELLS_X][CELLS_Y];
for (int i = 0; i < CELLS_X; i++) {
for (int j = 0; j < CELLS_Y; j++) {
map[i][j] = new MyMapNode(i, j, j + i * CELLS_Y);
}
}
//-------------------------------------------------
initNeighbours();
recalculatePath();
}
public void initNeighbours() {
//init neighbourhood without diagonals
for (int i = 0; i < CELLS_X; i++) {
for (int j = 0; j < CELLS_Y; j++) {
int x, y;// untere Grenze
if (j == 0)
y = 0;
else
y = -1;
if (i == 0)
x = 0;
else
x = -1;
int v, w;// obere Grenze
if (j == CELLS_Y - 1)
w = 0;
else
w = 1;
if (i == CELLS_X - 1)
v = 0;
else
v = 1;
for (int h = x; h <= v; h++) {
if (h != 0)
map[i][j].addNeighbour(map[i + h][j]);
}
for (int g = y; g <= w; g++) {
if (g != 0)
map[i][j].addNeighbour(map[i][j + g]);
}
}
}
}
//AdjacencyMatrix
public int[][] path = new int[CELLS_X * CELLS_Y][CELLS_X * CELLS_Y];
//for pathreconstruction
public MyMapNode[][] next = new MyMapNode[CELLS_X * CELLS_Y][CELLS_X
* CELLS_Y];
public void initAdjacency() {
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[0].length; j++) {
path[i][j] = 1000;
List<MyMapNode> tmp = map[i][j].neighbours;
for (MyMapNode m : tmp) {
path[m.index][map[i][j].index] = 1;
path[map[i][j].index][m.index] = 1;
}
}
}
}
public void floydWarshall() {
int n = CELLS_X * CELLS_Y;
for (int k = 0; k < n; k++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (path[i][k] + path[k][j] < path[i][j]) {
path[i][j] = path[i][k] + path[k][j];
next[i][j] = getNodeWithIndex(k);
}
}
}
}
}
public void recalculatePath() {
initAdjacency();
floydWarshall();
}
public MyMapNode getNextWayPoint(MyMapNode i, MyMapNode j) {
if (path[i.index][j.index] >=1000)
return null;
MyMapNode intermediate = next[i.index][j.index];
if (intermediate == null)
return j; /* there is an edge from i to j, with no vertices between */
else
return getNextWayPoint(i, intermediate);
}
public MyMapNode getNodeWithIndex(int k) {
//for testing purpose,this can be done faster
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[0].length; j++) {
if (map[i][j].index == k)
return map[i][j];
}
}
return null;
}
public void removeMapNode(MyMapNode m) {
//for testing purpose,this can be done faster
m.isFree = false;
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[0].length; j++) {
if (map[i][j].neighbours.contains(m)) {
map[i][j].neighbours.remove(m);
}
}
}
}
}
the Floyd-Warshall algorithm is designed to work on a graph so i create one where every node knows its neighbours (which are the nodes it is connected to).
I actually don't now where it goes wrong but it somehow does.
but at least it looks like the initialization of the adjacency matrix works.
in the floydwarshall function i hoped to get the index of the next node in the next[][] but i only get null or 10/11;
So my question is what am i doing wrong or is my approach wrong at all?
i hope someone can help me.
if you need any further information please ask
p.S. sorry for my bad english ;)
I don't have Java available but it seems like your initAdjacency() function is flawed. path[][] is of dimension [CELL_X * CELLS_Y][CELLS_X * CELLS_Y] while you're iterating over the dimensions of map which are [CELL_X][CELL_Y] so you're not setting all the elements without edges to the default value of 1000 and they end up being 0.
Try adding
for (int i = 0; i < CELLS_X * CELLS_Y; i++)
for (int j = 0; j < CELLS_X * CELLS_Y; j++)
path[i][j] = 1000;
to the beginning of the initAdjacency() function, before your loop, to initialize it properly.
You may also want to do
for (int i = 0; i < CELLS_X * CELLS_Y) path[i][i] = 0;
after that just in case, I'm not sure this affects the algorithm.