Manipulating adjacent matrix - java

I have a network graph with nodes and edges and i managed to construct an adjacent matrix of my graph.
sample adjacent matrix with edge weight
Nodes -> {A, B, C, D}
Edges -> {[A->B = 2] , [A->D = 5] , [C->A = 1] , [C->B = 4] , [D->B = ] , [D->C = 2]}
my adjacent network is like this
0 2 0 2
0 0 0 0
4 4 0 0
0 6 6 0
so i want to change the adjacent matrix to be like this with labels of the nodes and average of each column by considering non zero cells
A B C D
A 0 2 0 2
B 0 0 0 0
C 4 4 0 0
D 0 6 6 0
X 4 4 6 2 <- Mean of non zero column
here is my the code i used to create adjacent matrix,
Node.java
public class Node
{
public char label;
public Node(char l)
{
this.label=l;
}
}
Graph.java
public class Graph
{
public ArrayList nodes=new ArrayList();
public double[][] adjacentMatrix;
int size;
public void addNode(Node n)
{
nodes.add(n);
}
public void addEdge(Node start,Node end,int weight)
{
if(adjacentMatrix==null)
{
size=nodes.size();
adjacentMatrix=new double[size][size];
}
int startIndex=nodes.indexOf(start);
int endIndex=nodes.indexOf(end);
adjacentMatrix[startIndex][endIndex]=weight;
}
public static void printAdjacentMatrix(double matrix[][]) {
for (int row = 0; row < matrix.length; row++) {
for (int column = 0; column < matrix[row].length; column++) {
System.out.print(matrix[row][column] + " ");
}
System.out.println();
}
}
}
Main.java
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
//Defining nodes
Node nA=new Node('A');
Node nB=new Node('B');
Node nC=new Node('C');
Node nD=new Node('D');
//Creating adjacent matrix
Graph g=new Graph();
g.addNode(nA);
g.addNode(nB);
g.addNode(nC);
g.addNode(nD);
g.addEdge(nA, nB, 2);
g.addEdge(nA, nD, 2);
g.addEdge(nC, nA, 4);
g.addEdge(nC, nB, 4);
g.addEdge(nD, nB, 6);
g.addEdge(nD, nC, 6);
g.printAdjacentMatrix(g.adjacentMatrix);
}
}
so i ask for help to display the second matrix with average and labels...Thank you in advance

Not a very nice solution but that will do.
public class Graph {
public ArrayList nodes = new ArrayList();
public int[][] adjacentMatrix;
int size;
public void addNode(Node n) {
nodes.add(n);
}
public void addEdge(Node start, Node end, int weight) {
if (adjacentMatrix == null) {
size = nodes.size();
adjacentMatrix = new int[size][size];
}
int startIndex = nodes.indexOf(start);
int endIndex = nodes.indexOf(end);
adjacentMatrix[startIndex][endIndex] = weight;
}
public static void printAdjacentMatrix(int matrix[][]) {
for (int row = 0; row < matrix.length; row++) {
for (int column = 0; column < matrix[row].length; column++) {
System.out.print(matrix[row][column] + " ");
}
System.out.println();
}
}
public static void convertMatrix(int matrix[][]) {
int row = matrix.length + 2;
int column = matrix[0].length + 1;
String newMatrix[][] = new String[row][column];
initializeFirstRow(newMatrix);
initializeFirstColumn(newMatrix);
copyMatrix(matrix, newMatrix);
addMean(matrix, newMatrix);
printAdjacentMatrix(newMatrix);
}
private static void initializeFirstColumn(String[][] newMatrix) {
newMatrix[1][0] = "A";
newMatrix[2][0] = "B";
newMatrix[3][0] = "C";
newMatrix[4][0] = "D";
newMatrix[5][0] = "X";
}
private static void printAdjacentMatrix(String[][] newMatrix) {
for (int row = 0; row < newMatrix.length; row++) {
for (int column = 0; column < newMatrix[row].length; column++) {
System.out.print(newMatrix[row][column] + " ");
}
System.out.println();
}
}
private static void addMean(int[][] matrix, String[][] newMatrix) {
int mean = 0;
int sum = 0;
int divident = 0;
for (int j = 0; j < matrix[0].length; j++) {
sum = 0;
divident = 0;
for (int i = 0; i < matrix.length; i++) {
if (matrix[i][j] != 0) {
sum += matrix[i][j];
divident++;
}
}
if (sum != 0) {
mean = sum / divident;
}
newMatrix[5][j + 1] = "" + mean;
}
}
private static void copyMatrix(int[][] matrix, String[][] newMatrix) {
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
newMatrix[i + 1][j + 1] = "" + matrix[i][j];
}
}
}
private static void initializeFirstRow(String[][] newMatrix) {
newMatrix[0][0] = " ";
newMatrix[0][1] = "A";
newMatrix[0][2] = "B";
newMatrix[0][3] = "C";
newMatrix[0][4] = "D";
}
}
Also add following line in Main.java
g.convertMatrix(g.adjacentMatrix);

Related

Value in the method changes which I didn't expect to happen

so I'm trying to make a program that rotates a cube shaped grid 90 degree to the right.
The problem I encountered is that temp values (temp1, temp2, temp3, temp4) that I declared in the method keep changes during the process of method.
Assume there is a cube grid,
1 2 3
4 5 6
7 8 9
as I declared
int[] temp1 = grid[0]; in the method
temp1 should be fixed as {1, 2, 3}.
However, when this part of code executes,
//rotate 90 degree to right
//row 0 ==
for (int i = 0; i < grid[0].length; i++)
{
grid[0][i] = temp2[i];
}
temp1's value changes as {7, 4, 1} which I didn't not expect
It is really confusing because temp value usually don't change.
Can anyone give me advice to fix this issue?
import java.util.Scanner;
public class a
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
int numLine = Integer.parseInt(input.nextLine());
int[][] grid = new int[numLine][numLine];
String[] lines = null;
for (int i = 0; i < numLine; i++)
{
lines = input.nextLine().split(" ");
for (int j = 0; j < numLine; j++)
{
grid[i][j] = Integer.parseInt(lines[j]);
}
}
rotate(grid);
for (int[] i : grid)
{
for (int j : i)
{
System.out.print(j + " ");
}
System.out.println("");
}
input.close();
}
public static void rotate(int[][] grid)
{
//row 0
int[] temp1 = grid[0];
//column 0
int[] temp2 = new int[grid[0].length];
int c = 0;
for (int i = grid[0].length-1; i >= 0; i--)
{
temp2[c] = grid[i][0];
c++;
}
c = 0;
//row last
int[] temp3 = grid[grid[0].length-1];
//column last
int[] temp4 = new int[grid[0].length];
for (int i = grid[0].length-1; i >= 0; i--)
{
temp4[c] = grid[i][grid[0].length-1];
c++;
}
c = 0;
//rotate 90 degree to right
//row 0 ==
for (int i = 0; i < grid[0].length; i++)
{
grid[0][i] = temp2[i];
}
//column last ==
for (int i = 0; i < grid[0].length; i++)
{
grid[i][grid[0].length-1] = temp1[i];
}
//row last ==
for (int i = 0; i < grid[0].length; i++)
{
grid[grid[0].length-1][i] = temp4[i];
}
//column 0 ==
for (int i = 0; i < grid[0].length; i++)
{
grid[i][0] = temp3[i];
}
}
}

Issues with calculating the determinant of a matrix (in Java). It is alwys 0

I want to calculoate the determinant of a given NxN Matrix using the Laplace-Method. I already tried differnt approaches which always return a 0.
The class I used:
package Matrix;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Scanner;
public class Matrix
{
double[][] array;
public static void init(Matrix a,int row , int column)
{
a.array = new double [row] [column];
for (int i = 0; i < row; i++)
{
for(int k = 0; k < column; k++)
{
a.array[i][k] = 0;
}
}
}
public static int getNRows(Matrix a)
{
return a.array.length;
}
public static int getNColumns(Matrix a)
{
return a.array[0].length;
}
public static void print(Matrix a)
{
for(int i = 0; i < getNRows(a);i++ )
{
for (int k = 0; k < getNColumns(a); k++)
{
System.out.print(a.array[i][k] + "\t");
}
System.out.println();
}
}
public static double det(Matrix a)
{
double det = 0;
det = a.array[0][0] * a.array[1][1] * a.array[2][2] + a.array[1][0] * a.array[2][1] * a.array[0][2] + a.array[2][0] * a.array[0][1] * a.array[1][2] - a.array[2][0] * a.array[1][1] * a.array[0][2] - a.array[1][0] * a.array[0][1] * a.array[2][2] - a.array[0][0] * a.array[2][1] * a.array[1][2];
return det;
public static Matrix transpose(Matrix a)
{
Matrix transposed = new Matrix();
Matrix.init(transposed, getNRows(a), getNColumns(a));
for(int i = 0; i < getNRows(a); i++)
{
for(int j = 0; j < getNColumns(a); j++)
{
transposed.array[j][i] = a.array[i][j];
}
}
return transposed;
}
public static Matrix subMatrix(Matrix a, int exclRow, int exclCol)
{
Matrix subMatrix = new Matrix();
Matrix.init(subMatrix, getNRows(a) - 1, getNColumns(a) - 1);
for(int i = 0; i < getNRows(a) - 1; i++)
{
for(int j = 0; j < getNColumns(a) - 1; j++)
{
if(i != exclRow && j != exclCol)
{
subMatrix.array[i][j] = a.array[i][j];
}
}
}
return subMatrix;
}
public static Matrix loadMatrix(String filename) throws Exception
{
Scanner sc = new Scanner(new BufferedReader(new FileReader(filename)));
Matrix result = new Matrix();
int row = 0;
int col = 0;
String[] line = sc.nextLine().trim().split("\t");
row = Integer.parseInt(line[0]);
col = Integer.parseInt(line[1]);
init(result, row, col);
int currentRow = 0;
while(sc.hasNextLine())
{
String[] line2 =sc.nextLine().trim().split("\t");
for(int i = 0; i < col; i++)
{
result.array[currentRow][i] = Double.parseDouble(line2[i]);
}
currentRow++;
}
return result;
}
/*public static double detN(Matrix a)
{
int colOfA = getNColumns(a);
int rowOfA = getNRows(a);
double value = 1;
if(colOfA != rowOfA)
{
return 0;
}
if(colOfA == 1 && rowOfA == 1)
{
return a.array[0][0];
}
else
{
for(int row = 0; row < rowOfA; row++)
{
value += Math.pow(-1, row) * a.array[row][0] * detN(subMatrix(a, row, 0));
}
}
return value;
}*/
public static double detN(Matrix a)
{
int colOfA = getNColumns(a);
int rowOfA = getNRows(a);
if(colOfA != rowOfA)
{
return 0;
}
if(rowOfA <= 3)
{
return det(a);
}
double value = 0;
for(int row = 0; row < rowOfA; row++)
{
if(row % 2 == 0)
{
value += a.array[row][0] * detN(subMatrix(a, row, 0));
}
else
{
value -= a.array[row][0] * detN(subMatrix(a, row, 0));
}
}
return value;
}
public static Matrix adjointN(Matrix a)
{
int rowOfA = getNRows(a);
int colOfA = getNColumns(a);
Matrix ret = new Matrix();
Matrix.init(ret, rowOfA, colOfA);
for(int row = 0; row < rowOfA; row++)
{
for(int col = 0; col < colOfA; col++)
{
ret.array[row][col] = detN(subMatrix(a, row, col));
}
ret = transpose(ret);
return ret;
}
return ret;
}
public static Matrix inverseN(Matrix a)
{
Matrix inverse = new Matrix();
Matrix.init(inverse, getNRows(a), getNColumns(a));
double pre = 1/detN(a);
inverse = adjointN(a);
for(int i = 0; i < getNRows(a); i++)
{
for(int j = 0; j < getNColumns(a); j++)
{
inverse.array[j][i] = inverse.array[i][j] * pre;
}
}
return inverse;
}
}
I have two versions for detN, which both yield the same result.
This isn't the entire class, because there are some functions that don't belong to this particular question
Here is an approach you could consider(the code is not fully debugged so take with a grain of salt). Finding the determinant is a recursive concept since you are always finding the determinant of a smaller matrix to get the final answer.
//Recursive base function
public static double det(int[][] matrix) {
if(matrix.length == 2)
return ((matrix[0][0] * matrix[1][1]) - (matrix[0][1] * matrix[1][0]));
double determinant = 0;
int mlength = matrix.length - 1;
int[][] newM = new int[mlength][mlength];
for(int i = 0; i < mlength + 1; i++) {
newM = newMatrix(matrix, i);
determinant = determinant + (Math.pow(-1, i) * matrix[0][i]) * det(newM);
}
return determinant;
}
//Format smaller matrix to use in further iteration of above det(int[][]) function
public static int[][] newMatrix(int[][] m, int column) {
int length = m.length - 1;
int[][] newMat = new int[length][length];
for(int i = 1; i < m.length; i++) {
for(int j = 0; j < column; j++)
newMat[i - 1][j] = m[i][j];
for(int k = column + 1; k < m.length; k++)
newMat[i - 1][k - 1] = m[i][k];
}
return newMat;
}
You can adapt to however your Matrix class works.
subMatrix is not really excluding the given row and column - it is just making them zero (not copying) and removing the last row and column...
Printing the matrix will help debug that.
one way: use additional indices for the destination matrix (the sub matrix). Only increment this if a value is really copied. Example: sub.array[k++][l++] = a.array[i][j] inside the if
loop over original matrix
Alternative: if one index is greater than or equal to the index that must be skipped, add 1 to the reading index:
var k = (i>=exclRow) ? i+1 : i;
var l = (j>=exclCol) ? j+1 : j;
sub.array[i][j = a.array[k][l];
code not intended to be complete, just ideas how to solve the problem

My omitRow function omits the wrong row

This project involves three classes. Star creates the stars, Starfield creates a matrix of stars, and StarfieldSimualation is the runner
When I omit row 0, it omits the bottom row, instead of the top one. But, it works for rows 1-4. Thanks in advance for the help.
Starfield Code
public class Starfield
{
private Star[][] Sky;
public Starfield(int rows, int cols)
{
if(rows < 0 || cols < 0)
{
rows = cols = 1;
}
Sky = new Star[rows][cols];
}
public String toString()
{
String S = "";
for (Star[] row: Sky)
{
for(Star X: row)
{
if(X != null)
{
S+= X.getImage() + "\t";
}
else
{
S += "- \t";
}
}
S += "\n";
}
return S;
}
public void addStar(String Image, String Constellation, int row, int col)
{
if(row < 0 || row >= Sky.length || col < 0 || col >= Sky[0].length)
{
return;
}
Sky[row][col] = new Star(Image, Constellation, row, col);
}
public Star[][] omitRow(int r)
{
int i, j, k;
k = 0;
Star[][] rowless = new Star[Sky.length - 1][Sky[0].length];
for(i = 0; i < Sky.length-1; i++)
{
for(j = 0; j < Sky[0].length; j++)
{
k++;
}
}
Star[] ans = new Star[k];
k = 0;
for(i = 0; i < Sky.length; i++)
{
for(j = 0; j < Sky[0].length; j++)
{
if(i != r)
{
ans[k] = Sky[i][j];
k++;
}
}
}
k = 0;
for(i = 0; i < rowless.length; i++)
{
for(j = 0; j < rowless[0].length; j++)
{
if(i != r)
{
rowless[i][j] = ans[k];
k++;
}
}
}
return rowless;
}
Star Code
public class Star
{
private Star[][] Sky;
private String Image, Constellation;
private int row, col;
public Star(String I, String C, int r, int c)
{
Image = I;
Constellation = C;
row = r;
col = c;
}
public String getImage()
{
return Image;
}
public String getConstellation()
{
return Constellation;
}
public int getRow()
{
return row;
}
public int getCol()
{
return col;
}
}
Starfield Simluation Code
public class StarFieldSimulation
{
public static void main(String[] args)
{
Starfield theSky = new Starfield(5,4);
theSky.addStar("*", "Orion", 2, 3);
theSky.addStar("*", "Orion", 2, 2);
theSky.addStar("*", "Orion", 2, 1);
theSky.addStar("*", "Orion", 2, 0);
theSky.addStar("*", "Orion", 1, 3);
System.out.println("IT'S THE SKY EVERYONE");
System.out.println(theSky.toString());
Star[][] minusrow = new Star[4][4];
minusrow = theSky.omitRow(4);
System.out.println("A row has been removed");
System.out.println();
for(Star[] row: minusrow)
{
for(Star X: row)
{
if(X != null)
{
System.out.print(X.getImage() + "\t");
}
else
{
System.out.print("-\t");
}
}
System.out.println();
}
System.out.println();
System.out.println("It's the sky again");
System.out.println(theSky.toString());
}

How can I speed up my n*n sudoku grid generator?

This is my code for a Sudoku-style grid generator. It generates every possible different n*n grid where there cannot be the same number in a certain column or row (like a sudoku) and also counts how many different combinations there are. E.g. one example of a 3*3 grid could be:
[ 3, 2, 1 ]
[ 1, 3, 2 ]
[ 2, 1, 3 ]
Unfortunately, for anything past 4*4 grids, it takes too long to do this, therefore, could anybody help me edit this slightly so that it is much faster?
import java.util.Arrays;
public class GridN {
public static final int SIZE = 3;
public static int count;
public static void main(String[] args) {
int[][] grid = new int[SIZE][SIZE];
count = 0;
bruteSolve(0, 0, grid);
}
public static void bruteSolve(int num1, int num2, int[][] grid) {
for (int i = 1; i < SIZE + 1; i++) {
grid[num1][num2] = i;
if (num2 == SIZE - 1 && num1 == SIZE - 1) {
if (isValid(grid)) {
count++;
System.out.println(Arrays.deepToString(grid));
System.out.println(count);
}
} else if (num2 == SIZE - 1) {
bruteSolve(num1 + 1, 0, grid);
} else {
bruteSolve(num1, num2 + 1, grid);
}
}
}
public static boolean isValid(int[][] grid) {
int factorial = 1;
int fibonacci = 0;
int totalX1 = 1;
int totalY1 = 1;
int totalX2 = 0;
int totalY2 = 0;
for (int i = SIZE; i > 0; i--) {
factorial = factorial * i;
}
for (int i = SIZE; i > 0; i--) {
fibonacci = fibonacci + i;
}
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
totalY1 = totalY1 * grid[i][j]; // checks all columns
totalX1 = totalX1 * grid[j][i]; // checks all rows
totalX2 = totalX2 + grid[j][i];
totalY2 = totalY2 + grid[i][j];
}
if (totalX1 != factorial || totalY1 != factorial
|| totalX2 != fibonacci || totalY2 != fibonacci) {
return false;
}
totalX1 = 1;
totalY1 = 1;
totalX2 = 0;
totalY2 = 0;
}
return true;
}
}

How do you add adjacent cells in a 2d array?

I need to have each cell in the firstArray become the sum of all adjacent cells then dump that answer into secondArray.
Example:
Initial array with random numbers:
3 5 11
5 9 14
1 2 8
Computed array:
19 42 41
20 49 48
33 62 44
3 spot([0][0]) is 5 + 9 + 5 = 19, and so on. Here's what I have:
public class ProcessArray {
private int rows;
private int columns;
private int [][] firstArray;
private int [][] secondArray;
public ProcessArray(int rows, int columns) {
this.rows=rows;
this.columns=columns;
firstArray = new int[rows][columns];
secondArray = new int[rows][columns];
initializeArray(firstArray, secondArray);
randomlyFillArray(firstArray);
System.out.println("Initial array with random numbers: ");
printArray(firstArray, secondArray, rows, columns);
getFirstArray(firstArray);
System.out.println("Computed array:");
computeArrayValues(firstArray);
}
private void initializeArray(int firstArray[][], int secondArray[][]){
for(int i = 0; i <firstArray.length; i++){
for (int j =0; j<firstArray[i].length; j++){
firstArray[i][j] = (0);
}
}
for(int i = 0; i <secondArray.length; i++){
for (int j =0; j<secondArray[i].length; j++){
secondArray[i][j] = (0);
}
}
}
public void randomlyFillArray(int firstArray[][]){
for(int i = 0; i <firstArray.length; i++){
for (int j =0; j<firstArray[i].length; j++){
firstArray[i][j] = (int)(Math.random()*15);
}
}
}
//here's where I try to have it add, I don't know what loop to have it run to go to each spot in the `firstArray`:
public void computeArrayValues(int firstArray[][]){
int x=1;
int y=1;
int sum;
int topLeft = firstArray[x-1][y-1];
int top = firstArray[x][y-1];
int topRight = firstArray[x+1][y-1];
int midLeft = firstArray[x-1][y];
int midRight = firstArray[x+1][y];
int botLeft = firstArray[x-1][y+1];
int bot = firstArray[x][y+1];
int botRight = firstArray[x+1][y+1];
secondArray[0][0]= (bot+botRight+midRight);
for (x=0; x<firstArray.length; x++){
for(y=0; y<firstArray.length; y++){
secondArray[x][y] = (topLeft+top+topRight+midLeft+midRight+botLeft+bot+botRight);
}
}
System.out.println(secondArray[x][y]);
}
public void printArray(int firstArray[][], int secondArray[][], int rows, int columns){
for (int i = 0; i < rows; i++){
for (int j = 0; j < columns; j++){
System.out.printf(String.format("%4s", firstArray[i][j]));
}
System.out.println();
}
}
public int[][] getFirstArray(int array[][]){
array = firstArray;
return array;
}
public int[][] getSecondArray(int array[][]){
array = secondArray;
return array;
}
}
Presuming you are looking for suggestions on alternative approaches, I would suggest encapsulating cell coordinates and using streams of cells instead of iteration. This assumes java 8 (naturally):
class Cell {
private final int row;
private final int col;
private Cell(int row, int col) {
this.row = row;
this.col = col;
}
public static Stream<Cell> streamCells(int rows, int cols) {
return IntStream.range(0, rows)
.flatMap(row -> IntStream.range(0, cols)
.flatMap(col -> new Cell(row, col)));
}
public Stream<Cell> streamAdjacentCells(int rows, int cols) {
return IntStream.range(row - 1, row + 1)
.flatMap(row -> IntStream.range(col - 1, col + 1)
.flatMap(col -> new Cell(row, col)))
.filter(cell -> cell.row >= 0 && cell.col >= 0)
.filter(cell -> cell.row < rows && cell.col < cols)
.filter(cell -> cell.row != this.row && cell.col != this.col);
}
public int getValue(int[][] array) {
return array[row][col];
}
public void setValue(int[][] array, int value) {
array[row][col] = value;
}
}
Then the code to set adjacent values quite simple:
int[][] destination = new int[rows][cols];
Cell.streamCells(rows, cols)
.forEach(cell -> setValue(
destination,
cell.streamAdjacentCells(rows, cols)
.mapToInt(adj -> getValue(source, adj))
.sum()));
This will fulfill the stated requirement, but running the program with the example data will output:
19 42 28
20 49 35
16 37 25
That would be the correct output for a sum of all adjacent cells (let me know if I misunderstood the question).
public class ArraySum {
static int[][] sum(int array[][]) {
// Asuming square arrays
int size = array.length;
int result[][] = new int[size][size];
// For every cell in the table
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
// Iterate the neighbors
for (int n = -1; n <= 1; n++) {
for (int m = -1; m <= 1; m++) {
// Discard the cell
if (n == 0 && m == 0) {
continue;
}
int ii = i - n;
int jj = j - m;
// Check if the neighbor coordinates are
// inside of the array bounds
if (ii >= 0 && ii < size && jj >= 0 && jj < size) {
result[i][j] += array[ii][jj];
}
}
}
}
}
return result;
}
public static void main(String... args) {
int a[][] = { {3, 5, 11},
{5, 9, 14},
{1, 2, 8} };
int r[][] = sum(a);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
System.out.printf("%d ", r[i][j]);
}
System.out.println();
}
}
}

Categories

Resources