I'm trying to generate a 8 by 8 matrix. Each element of matrix needs to have a value of 1 except one element on each column which is set as 0, that one element is chosen by generating a random int between 0-7.
What I get when I run the code:
1 1 1 1 1 1 1 1
1 1 1 0 1 1 1 1
1 1 0 1 1 1 1 1
1 0 1 1 1 1 1 1
1 0 1 1 1 1 1 1
1 0 0 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 0 1 1
My matrix should look like this:
1 1 1 1 1 1 1 1
1 1 0 1 1 1 1 1
1 1 1 1 1 0 1 0
0 1 1 1 1 1 1 1
1 1 1 0 1 1 0 1
1 0 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 0 1 1 1
code
for (int[] row: grid)
Arrays.fill(row, 1);
for (int i=0; i<grid.length; i++) {
int j = getRandom();
grid[i][j] = 0;
}
// print matrix
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++)
System.out.format("%2s%2d%2s", " ", Main.grid[i][j], " ");
System.out.println();
}
In your nested loop, both initialization and nulling of cells are in the innermost loop. This will cause both to run once per cell, but nulling is only done once per column.
If we change the order that the cells are initialized in from row after row to column after column, we can move the nulling logic out to the outermost loop.
for (int c = 0; c < 8; c++) {
for (int r = 0; r < 8; r++) {
Main.grid[r][c] = 1;
}
Main.grid[getRandom()][c] = 0; // assuming your getRandom() is within range
}
Firstly let's make the matrix all 1s:
//fill however you like
int[][] matrix = IntStream.range(0, 8).mapToObj(i
-> IntStream.range(0, 8).map(i -> 1).toArray());
Then, based on your question, it seems like you want a unique row per column to have a zero. So just shuffle your column indexes:
List<Integer> rows = IntStream.range(0, 8).collect(Collectors.toList());
Collections.shuffle(rows); //random rows per 0-8 column
AtomicInteger column = new AtomicInteger();
//iterate columns, and select random row
rows.forEach(i -> matrix[i][column.getAndIncrement()] = 0);
This'll disperse the random 0s to be unique per row (and column), and there's not really any RNG involved so it's O(n)
First of all, use the Arrays.fill api, it will make your code much cleaner and concise.
int[][] matrix = new int[m][n];
// Fill each row with 1
for (int[] row: matrix)
Arrays.fill(row, 1);
Then, for each row, pick a column number at random and insert '0' thereby replacing the 1.
for(int i=0; i<matrix.length; i++) {
int j = Math.Random(0,matrix[0].length); // Or any other api for random number generation
matrix[i][j] = 0;
}
Related
So far I have developed a program that uses an adjacency matrix to build a graph using linked implementation.
I'm stuck on how I can read a text file containing an adjacency matrix, and using that data instead of manually inputting the adjacency matrix.
For example, a text file containing the following:
4
0 1 1 0
1 1 1 1
1 0 0 0
1 1 0 1
6
0 1 0 1 1 0
1 0 0 1 1 0
0 0 1 0 0 1
0 0 0 0 1 0
1 0 0 0 0 0
0 0 1 0 0 1
3
0 1 1
1 0 1
1 1 0
You can use this method to read matrix data from file. This method returns a 2d array of bytes containing zeroes and ones.
public static void main(String[] args) throws IOException {
byte[][] matrix = getMatrixFromFile("matrix.txt");
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
System.out.print(matrix[i][j] + ((j + 1) == matrix[i].length ? "" : " "));
}
System.out.println();
}
}
public static byte[][] getMatrixFromFile(String filename) throws IOException {
List<String> lines = Files.readAllLines(Paths.get(filename));
int size = Byte.parseByte(lines.get(0));
byte[][] matrix = new byte[size][size];
for (int i = 1; i < lines.size(); i++) {
String[] nums = lines.get(i).split(" ");
for (int j = 0; j < nums.length; j++) {
matrix[i - 1][j] = Byte.parseByte(nums[j]);
}
}
return matrix;
}
Here I am assuming the file will contain data for one matrix, like following, but my code can easily be extended to read data for multiple matrices and return a list of 2d byte array.
4
0 1 1 0
1 1 1 1
1 0 0 0
1 1 0 1
I am trying to understand this code from the book.
int[][] grade = {
{ 1, 0, 1 },
{ 0, 1, 0 },
{ 1, 0, 1 }
};
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (i == j)
System.out.print(grade[i][j] + grade[j][i] + " ");
else
System.out.print(grade[i][j] * grade[j][i] + " ");
}
System.out.println(" ");
}
I understand the logic of a two-dimensional arrays being rows and columns. I just don’t understand how the answer came to be this.
2 0 1
0 2 0
1 0 2
It loops through the 2 dimensional array.
If i is equal to j, e.g ( 0,0 1,1 2,2 ) then it adds grade[i][j] with grade[j][i]. Since i and j are equal it adds the location with itself.
When i is not equal to j it multiplies grade[i][j] with grade[j][i].
Since they are not equal it multiplies 2 different positions in the grid.
e.g.
grade [3][1] is multiplied by grade[1][3], not by itself.
If you changed grade[1][3] to 2, then all corners would be output as 2
The input:
1 0 2
0 1 0
1 0 1
would output:
2 0 2
0 2 0
2 0 2
It basically loops through the two dimensional array and if it sees that the column and row number (i and j) are the same it will add it with itself. i.e. times the diagonal by two. And for the rest of the entries it will multiply with itself.
I've been struggling on this for some time and I'm really confused on how to solve this problem.
I've found something that works with MatLab but it's not what I need.
Here's my scenario:
private int[][] c = {{1,1,1,1,1,1,1},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0}
};
c is a matrix in which I can have only one value set to 1 in each column.
This means that a configuration like
private int[][] c = {{0,1,0,1,1,0,0},
{1,0,0,0,0,1,1},
{0,0,1,0,0,0,0}
};
is valid, while
private int[][] c = {{1,0,1,1,0,1,1},
{0,0,1,0,0,0,0},
{0,0,0,0,1,0,0}
};
is not.
What I need is to generate a Set containing all the valid combinations for this matrix, but I've no idea on how to start.
I don't know if it's just because it's late and I'm half asleep but I can't think of a good way to do this.
Do you have any ideas?
There are many possible ways of actually implementing this. But you basically have to count from 0 to 37, and create one matrix for each number.
Imagine each possible column of the matrix as one number:
1
0 = 0
0
0
1 = 1
0
0
0 = 2
1
Then, the matrices can be represented by numbers in 3-ary form. The number 0000000 will correspond to the matrix
1 1 1 1 1 1 1
0 0 0 0 0 0 0
0 0 0 0 0 0 0
The number 0000001 will correspond to the matrix
1 1 1 1 1 1 0
0 0 0 0 0 0 1
0 0 0 0 0 0 0
and so on.
Then, you can compute the total number of matrices, count up from 0 to this number, convert each number into a string in 3-ary form, and fill the matrix based on this string.
The 895th matrix will have the number 1020011, which is one of your example matrices:
0 1 0 1 1 0 0
1 0 0 0 0 1 1
0 0 1 0 0 0 0
A simple implementation:
public class MatrixCombinations
{
public static void main(String[] args)
{
int cols = 7;
int rows = 3;
int count = (int)Math.pow(rows, cols);
for (int i=0; i<count; i++)
{
String s = String.format("%"+cols+"s",
Integer.toString(i, rows)).replaceAll(" ", "0");
int[][] matrix = createMatrix(rows, cols, s);
System.out.println("Matrix "+i+", string "+s);
printMatrix(matrix);
}
}
private static int[][] createMatrix(int rows, int cols, String s)
{
int result[][] = new int[rows][cols];
for (int c=0; c<cols; c++)
{
int r = s.charAt(c) - '0';
result[r][c] = 1;
}
return result;
}
private static void printMatrix(int matrix[][])
{
for (int r=0; r<matrix.length; r++)
{
for (int c=0; c<matrix[r].length; c++)
{
System.out.printf("%2d", matrix[r][c]);
}
System.out.println();
}
}
}
So I got this 2D Array that is a 5x5 array and I have to subtract or add 1 to one of the rows that the user chooses to change. All is fine when the user inputs to change the first row, but with the higher rows, for example 2, it adds more than 1.
The array values are
1 -2 1 0 0
-1 0 4 2 0
0 -4 1 -1 0
0 1 -1 -1 -2
0 -3 1 -1 0
And the method I used to add 1 is the following
public static void plusRow (int i){
for(int row = 0; row < board.length; row++){
int[] rows = board[i];
for(int col = 0; col < board.length; col++){
rows[col] = rows[col] + 1;
System.out.print(board[row][col] + " ");
}
System.out.println("");
}
}
My output value for example with 2 comes out like this
1 -2 1 0 0
1 2 6 4 2
0 -4 1 -1 0
0 1 -1 -1 -2
0 -3 1 -1 0
When it should be
1 -2 1 0 0
0 1 5 3 1
0 -4 1 -1 0
0 1 -1 -1 -2
0 -3 1 -1 0
The problem is that your nested for loop runs as many times as the function input int "i"
Your algorithm is very inefficient- you don't need to do a nested loop here. Break your ouput and your math into 2 different loops.
for(int j =0; j<boards[i].length; j++){
boards[i][j] += 1;
}
Then write a double loop to ouput board. In fact, that should be a separate function
How to padarray in java that is add row and column to a existing array in front and back with a given number.
For example :-
let x = 1 2 3
4 5 6
7 8 9
and now want to 2 rows and columns of zeros in this:
x = 0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 1 2 3 0 0
0 0 4 5 6 0 0
0 0 7 8 9 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
So, i want to know that is there a existing method or way to do this in java like it is available in matlab using the predefined method called padarray(x,[r,c]).
You can never add rows or columns to 2 dimensional arrays at all. Arrays are fixed size. You could use a dynamic data structure such as List<List<Integer>>.
What you also can do is create a new array (that is bigger or smaller than your current one) using the Arrays.copyOf(int[] original, int newLength); method.
You array x is like:
int[][] x = new int[][]{{1,2,3}, {4,5,6}, {7,8,9}};
There is no one-liner (I know of) to transform it to your desired format. You have to create a method that creates a new 2 dimensional array and place your values at the correct indexes.
Here is some code that takes the 2D array you want padded, what you want it to be padded with, and how many pads to surround the array with (yours would be 2 because you want your array surrounded with 2 layers of 0's).
public static int[][] padArray(int[][] arr, int padWith, int numOfPads) {
int[][] temp = new int[arr.length + numOfPads*2][arr[0].length + numOfPads*2];
for (int i = 0; i < temp.length; i++) {
for (int j = 0; j < temp[i].length; j++) {
temp[i][j] = padWith;
}
}
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
temp[i+numOfPads][j+numOfPads] = arr[i][j];
}
}
return temp;
}