Create 2D array with 2 int arrays - java

I want to build a 2D matrix with sum of 2 input arrays(by adding row & column elements).
For example, if a is {1,3,5} and b is {4,8}, I want to build my matrix as so: [{1,3,5}, {4,7,9}, {8,11,13}].
Some more explanation here: [{1,3,5} (this is a), {4,7,9} (4 from b, 7=3+4) (9= 5+4), {8,11,13}]. (8 from b again, then 11= 3+8) (13=5+8). If you draw the first row with a, then draw b as the column aligned with a[0], you could add row element with column element to get the sum matrix.
Is there a more efficient way to do so? I tried to write 2 for-loops which gives a large time and space complexity.
public void BuildMatrix (int[] a, int[] b) {
int rows = b.length+1;
int columns = a.length;
int[][] matrix = new int[b.length+1][a.length];
for (int i = 0; i < columns-1; i++) {
matrix[0][i] = a[i];
for (int j = 1; j < rows; j++) {
matrix[j][0] = b[j-1];
matrix[j][i+1] = b[j-1] + a[i+1];
}
} }

Are input arrays to be of any possible size? If you know size ahead of time you can optimize that.
You are computing rows and columns twice:
int rows = b.length+1;
int columns = a.length;
int[][] matrix = new int[b.length+1][a.length];
so why not:
int rows = b.length+1;
int columns = a.length;
int[][] matrix = new int[rows][columns];
likewise you can factor out b[j-1] here (but compiler likely does the same anyway):
matrix[j][0] = b[j-1];
matrix[j][i+1] = b[j-1] + a[i+1];
Those are extremely minor bits though.
You should look into the broader picture and try parallelizing BuildMatrix calls if it's called a lot. You would then prepare a set of inputs for multiple BuildMatrix calls, and run them all on multiple processor cores (in parallel).

Related

What is the quickest way to arrange numbers to 3 dimensional array?

I need to arrange numbers of a given size (provided by user at runtime), to 3 dimensional array to represent these numbers in real 3D space.
For example if user enters 7 then I need to create an array of size 2,2,2 and arrange the first 7 numbers given by user into the array starting from position 0,0,0 .
The cube should always be smallest possible for example cube of size 2 can contain 2*2*2 = 8 values. And need a function that can take input numbers and return 3D integer array with values inserted from input array (input[0] will become result[0][0][0] and so on).
int input[7] ;
int[][][] result = bestFunction(int[] input) {...}
I have implemented with 3 nested for loops by checking each value at a time.
Is there a better or faster approach to implement it?
Do a Math.floor(Math.cbrt(val)) to get the dimension size.
I think we can reduce it to level 1 nesting, or using two loops, using a string input for the z-axis values.
for(int i = 0; i<size; i++)
for(int j = 0;j<size;j++)
arr[i][j]= Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
where Scanner sc = new Scanner(System.in); if you're taking in user input.
Three for loops would be O(n) as long as you break right after the last element of the input is put in.
int[][][] func(int[] input) {
int size = (int) Math.ceil(Math.cbrt(input.length));
int[][][] result = new int[size][size][size];
int x = 0;
loop: for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
for (int k = 0; k < size; k++) {
result[i][j][k] = input[x++];
if (x == input.length)
break loop; //Finish processing
}
}
}
return result;
}

Matrix manipulation: logic not fetching correct answer for higher order NXN matrix data

I came across below problem related to Matrix Manipulation.
problem statement
There is a NxN matrix,divided into N * N cells. Each cell has a predefined value. Which would be given as an input. Iteration has to happen K number of times which is also given in the test input. We have to make sure that we pick the optimum/min value of rows/columns at each iteration. Final output is the cumulative sum of optimum value saved at the end of each iteration.
Steps 1. Sum up the individual row and column and find the min sum of rows and columns, (it could be a row or a column, just need the minimum row or a column)
Step 2. Store the sum found above separately
Step 3.
Increment elements of the min. sum row or column. by 1
Repeat steps 1,2,3 from 1 to Kth value
add the sum at each iteration(specified in step2)
output is the sum obtained on on the Kth iteration.
Sample data
2 4
1 3
2 4
Output data
22
I was able to write a code (in java) and tested the same for some sample test cases. The output worked fine. The code works fine for sample data matrix of lower order, say, 2x2,4x4,even till 44x40 (that has less iteration). However, when the matrix size is increased to 100X100 (complex iteration), I see the expected output output values differ at 10s and hundreds place of the digit from the actual output and its random. Since I am not able to find a correct pattern of output vs input. Now, it is taking a toll on me to really debugging 500th loop to identify the issue. Is there any better way or approach to solve such problem related to huge matrix manipulation. Has anyone come across issues similar to this and solved it.
I am mainly interested in knowing the correct approach to solve given matrix problem. What Data structure to use in java. At present, I am using primitive DS and arrays int[] or long[] to solve this problem. Appreciate any help in this regard.
Which data structure?
What you need here is a data structure which allows you to efficiently query and update the minimum sum line. The most commonly used for this is a heap https://en.wikipedia.org/wiki/Heap_(data_structure).
For your purposes it's probably best to just implement the simplest kind, an array-based binary heap:
See here: https://en.wikipedia.org/wiki/Binary_heap
And here: http://courses.cs.washington.edu/courses/cse373/11wi/homework/5/BinaryHeap.java
..for implementation details.
Procedure:
Initialize your heap to size M + N where M, N are the number of rows and columns.
Before the loop, pre-compute the sum of each row and column, and add them as objects to the heap. Also add two arrays A, B which store the row and columon objects separately.
Now heapify the heap array with respect to the line sum attribute. This ensures the heap follows the criterion of the binary heap structure (parent always > children). Read the sources to find out more about how to implement this (quite easy for a fixed array)
For each iteration, look at the first element in the heap array. This is always the one with the smallest line sum. If this is a row object, then increment the sum attribute by N (no. of columns), and increment each object in B (list of columns) by 1. Do the same if it's a column.
After this, always heapify before the next iteration.
At the end, just return the first element's attribute.
Time complexity:
The original naive solution (looping through all columns and rows every time) is .
Using a heap, the heapify operation at each step is (for a binary heap).
This means the total complexity is , FAR smaller. The max term is to compensate for the fact that at each iteration it may be either rows or columns which are incremented.
As a side note, there are other heap structure types which have even better time complexity than the binary heap, e.g. binomial trees, Fibonacci heaps etc. These however are far more complicated, and have higher constant-factor overheads as a result. Thus for your project I feel they are not necessary, as many of them need phenomenal data set sizes to justify for the constant factor overhead.
Besides, they all support the same external operations as the binary heap, as defined by the Abstract Data Structure of Heap.
(heapify is an internal operation specific to the binary heap structure. Quite a few of the other ones are theoretically superior as they do this operation implicitly and "lazily")
O(KN + N*N) Solution:
You can just work with sum of columns and rows, and not store or manipulate them directly.
First sum all the columns and rows, in a 2*N array, first row being sum of columns, a[0][0] is sum of first column, a[0][1] is sum of second column, and second row is sum of rows, a[1][0] sum of first row, etc...
Then do the following for iterating:
Find min in array a .
Add it to the answer.
Add N to the min of row or column selected.
If the min is row add one to all cols and if it is a column add one to all rows.
If needed any further explanation, don't hesitate to comment.
I am doing like this for solving the above problem...
void matrixManipulation() throws IOException {
int N = Reader.nextInt();
int[][] matrix = new int[N][N];
int K = Reader.nextInt();
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
matrix[i][j] = Reader.nextInt();
}
}
// System.out.println("********Inital position**********");
// for (int i = 0; i < N; i++) {
// for (int j = 0; j < N; j++) {
// System.out.print(matrix[i][j]);
// }
// System.out.println();
// }
// System.out.println("********Inital position**********");
CalculateSum calculateSum = new CalculateSum();
int[] row = new int[N];
int[] row_clone = new int[N];
int[] col = new int[N];
int[] col_clone = new int[N];
int test =0;
for (int kk = 0; kk < K; kk++) {
row = calculateSum.calculateRowSum(matrix, N);
row_clone = row.clone();
/* just sort it either Arrarys sort or any other ---starts here*/
// for (int i = 1; i < row.length; i++) {
// row_orignial[i] = row[i];
// }
// Arrays.sort(row);
Node root1 = insert(null, row[0], 0, row.length);
for (int i = 1; i < row.length; i++) {
insert(root1, row[i], 0, row.length);
}
sortArrayInOrderTrvsl(root1, row, 0);
/* just sort it either Arrarys sort or any other ---ends here*/
col = calculateSum.calculateColumnSum(matrix, N);
col_clone = col.clone();
/* just sort it either Arrarys sort or any other ---starts here*/
// for (int i = 1; i < col.length; i++) {
// col_orignial[i] = col[i];
// }
// Arrays.sort(col);
Node root2 = insert(null, col[0], 0, col.length);
for (int i = 1; i < row.length; i++) {
insert(root2, col[i], 0, col.length);
}
sortArrayInOrderTrvsl(root2, col, 0);
/* just sort it either Arrary.sort or any other---ends here */
int pick = 0;
boolean rowflag = false;
int rowNumber = 0;
int colNumber = 0;
if (row[0] < col[0]) {
pick = row[0];// value
rowflag = true;
for (int i = 0; i < N; i++) {
if (pick == row_clone[i])
rowNumber = i;
}
} else if (row[0] > col[0]) {
pick = col[0];// value
rowflag = false;
for (int i = 0; i < N; i++) {
if (pick == col_clone[i])
colNumber = i;
}
} else if(row[0] == col[0]){
pick = col[0];
rowflag = false;
for (int i = 0; i < N; i++) {
if (pick == col_clone[i])
colNumber = i;
}
}
test= test + pick;
if (rowflag) {
matrix = rowUpdate(matrix, N, rowNumber);
} else {
matrix = columnUpdate(matrix, N, colNumber);
}
System.out.println(test);
// System.out.println("********Update Count"+kk+" position**********");
// for (int i = 0; i < N; i++) {
// for (int j = 0; j < N; j++) {
// System.out.print(matrix[i][j]);
// }System.out.println();
// }
// System.out.println("********Update Count"+kk+" position**********");
}
// System.out.println("********Final position**********");
// for (int i = 0; i < N; i++) {
// for (int j = 0; j < N; j++) {
// System.out.print(matrix[i][j]);
// }System.out.println();
// }
// System.out.println("********Final position**********");
// System.out.println(test);
}

Java - Two-Dimensional Arrays - Plotting Points

I have an assignment for a JAVA class I am taking. We are discussing two-dimensional arrays, however on this particular assignment, I can not figure out how to return back specific points and set those points with a specific value. Here is the assignment:
Write a method called create2DArray that will fill, create, and return
a 10 x 10 2d array with random numbers in the range of 1 to 100. Write
a method called print2DArray that will print a 10 x 10 2D array in row
column fashion. Write a method called createCoords that will search
the 2D array looking for any value that is evenly divisible by 3.
Once you have found a number you should log the row, column location.
This means when your method finishes it should produce a list of
coordinates that I can use to plot my graph. This method must also
return the number of coordinates that are divisible by 3 so that I
know how many points there are to plot. I am not particular as to how
the coordinates are returned back as long as I get a list of the row,
column locations. So, I will leave it to you to work out a mechanism
for returning the values. To test that you have logged the
coordinates create another function called fillLocations that will
fill the locations in the array you have logged with
-1. So, your program should flow in this order
create2DArray
print2DArray
createCoords
fillLocations
print2DArray
I understand and have completed create2DArray and print2DArray, but I can not figure out createCoords and fillLocations. Here is what I have so far, but it does not work and there are errors present:
public int createCoords(int row1, int col1){
int[][] coords = new int[row1][col1];
int[][] count = new int[0][0];
int co = 0;
for(int row = 0; row < 10; row++)
{
for(int col = 0; col < 10; col++)
{
if(coords[row][col] % 3 == 0)
co++;
return count[row][col];
}
}
return co;}
public int fillLocations(int[][] count){
int x = 0;
int y = 0;
for(int row = 0; row < 10; row++)
{
for(int col = 0; col < 10; col++)
{
if(count[row][col] % 3 == 0)
x = row;
y = col;
break;
}
}
return (x, y);}
As a programmer you'll nearly always need to research for doing different things. This research will be easier when you divide your problem to smaller problems.
For example you need to generate random numbers? So search on google that and you'll find this: How do I generate random integers within a specific range in Java?.
You need to create and return a 2D array? Google and see Syntax for creating a two-dimensional array
And with your art, put the pieces of the puzzle together in a way that gives your desired result.
public int[][] create2DArray() {
int[][] newArray = new int[10][10];
Random random = new Random();
int range = 100;
for(int i = 0; i < 10; i++)
{
for(int j = 0;j<arr[0].length;j++)
{
newArray[i][j]= (random.nextInt(range) + 1);
}
}
return newArray;
}
This method, creates and returns a 10*10 2D array filled with random generated numbers between 1-100. I'm sure you can write the rest of your program and enjoy from it by yourself.

Constraint choco

I am using choco API to solve a problem. What I need is coding a constraint that make the sum of all my variables equal to 1.
This code keeps a sum of rows equal 1:
IntegerVariable[][] rows;
int n; //number of rows
for(int i=0; i<n; i++)
model.addConstraint(eq(sum(rows[i], 1));
But what I need is programming a code that keeps the sum of all my element's matrix (sum of rows) to be equaled to 1 and not the sum of each row = 1.
If I understand you correctly you want to ensure that the sums of the full matrix is equal to 1.
Then you can use an ArrayList ("all") to collect all the IntegerVariables into one list and then add a constraint to "all". Your example is not complete, e.g. the number of columns, so I assume that there are n columns and that it is a 0/1 matrix. Here's an example:
// ...
ArrayList<IntegerVariable> all = new ArrayList<IntegerVariable>();
int n = 5; // number of rows and columns
IntegerVariable[][] rows = new IntegerVariable[n][n];
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
rows[i][j] = makeIntVar("rows["+i+","+j+"]", 0, 1);
all.add(rows[i][j]);
}
}
// convert ArrayList all to an array
model.addConstraint(eq(sum(all.toArray(new IntegerVariable[1])),1));
// ...

addition of combinations of two-dimensional array list

So the problem I'm working on solving involves an array list of array list of integers
. What is known: The number of elements in each ArrayList of integers. What is NOT known: How many ArrayList of Integers there actually are. I need suggestions for an algorithm that would sum the (ordered) elements of these arrays in every combination possible OF the arrays. In order to clarify what I mean by this let me give an example:
AoA = [[1,0,1,0],[0,1,0,1],[1,1,1,1],[0,0,0,0]];
Sum the elements of AoA[0] + AoA[1]; AoA[0]+AoA[2]; AoA[0]+AoA[3]; AoA[1]+AoA[2]; AoA[1]+AoA[3]; AoA[2]+AoA[3];
(4 choose 2)
So if anyone could code this simple version I'd be grateful as I'm struggling to do it. If anyone could code the more complex example where there's an unknown number of arrays in the AoA (so N choose 2), you'd be my hero.
TL;DR/edit
I need an algorithm to take n-choose-2 arrays from an array of arrays; sum the arrays (e.g. [1,2,3] + [1,2,3] = [2,4,6]); put the add the new summed array into an array of arrays.
If the 2 is fixed then the easiest thing I can think about is just generating the new array with N*(N-1)/2 rows, one for each sum and then using two variables to iterate through the original array with something like:s
int c = 0;
for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
for (int k = 0; k < M; k++) {
sums[c][k] = AoA[i][k] + AoA[j][k];
}
c++;
}
}
Here's what I've got, took me a while but this will do what I was looking for:
it takes each combination of the arrays (t1, t2, t3, t4) and adds their elements and returns whatever combinatorial you choose for n, (in this example i left it as 3).
If there's any more optimizations you can see please feel free to add it. I'm a perl guy so making this work at all in Java was a real task.
import java.util.ArrayList;
public class testnCk {
public static void main(String[] args) {
ArrayList<int[]> sums = new ArrayList<int[]>();
int [] t1 = {1,1,0,0};
int [] t2 = {1,0,0,1};
int [] t3 = {0,0,0,0};
int [] t4 = {0,0,1,1};
ArrayList<int[]> testing = new ArrayList<int[]>();
testing.add(t1);
testing.add(t2);
testing.add(t3);
testing.add(t4);
int n = 3;
int i = -1;
int[] array = new int[4];
ArrayList<int[]> whatever = nCk(testing, sums, array, i, n);
for (int[] test1 : whatever)
{
for (int j = 0; j < test1.length; j++) {
System.out.print(test1[j]);
}
System.out.println();
}
}
public static ArrayList<int[]> nCk (ArrayList<int[]> arrayOfDiffPatterns, ArrayList<int[]> solutions, int[] tempsums, int i, int n)
{
n--;
for (int j=i+1; j<arrayOfDiffPatterns.size(); j++){
int[] array = tempsums.clone();
for (int k=0; k<arrayOfDiffPatterns.get(0).length; k++){
array[k] += arrayOfDiffPatterns.get(j)[k];
}
if(n>0){
nCk(arrayOfDiffPatterns, solutions, array, j, n);
}
else{
solutions.add(array);
}
}
return solutions;
}
}

Categories