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));
// ...
Related
I have n inputs.
these inputs are numbers from 1 to 100.
I want to output the number that appears less than the other ones; also if there are two numbers with the same amount of appearance, I want to output the number that is less than the other one.
I wrote this code but it doesn't work!
Scanner scanner = new Scanner(System.in);
int n=scanner.nextInt(), max=0 , ans=-1;
int[] counter = new int[n];
for(int i=0; i<n; i++)
counter[scanner.nextInt()]+=1;
for(int j=1; j<=100; j++){
if(counter[j]>max)
max=counter[j];
}
for (int i=1; i<=max; i++){
if(counter[i]>0)
if(ans==-1 || counter[ans]>counter[i] || (counter[ans] == counter[i] && i<ans))
ans=i;
}
System.out.print(ans);
There’s a couple of problems with your code, but the main one is the last for loop: You are trying to find the first (ie lowest) number whose counter is equal to max, so your loop should be from 1 to n, not 1 to max.
Another problem is if you are using the number, which is in the range 1-n, as your array index, you need an array of size n+1, not n.
I pinched this from another question regarding the title of yours:
i = input.nextInt (); while (i != 0) { counts [i]++; i = input.nextInt (); } That method increments the number at the position of the user input in the counts array, that way the array holds the number of times a number occurs in a specific index, e.g. counts holds how often 3 occurs.
counter array should contain frequency values for the numbers from 1 to 100 inclusive.
That is, either a shift by 1 should be used when counting the frequency:
int[] counter = new int[100];
for (int i = 0; i < n; i++) {
counter[scanner.nextInt() - 1]++;
}
or 101 may be used as the length of counter array thus representing values in the range [0..100], without shifting by 1.
int[] counter = new int[101];
for (int i = 0; i < n; i++) {
counter[scanner.nextInt()]++;
}
The minimal least frequent number can be found in a single loop (assuming that the counter length is 101).
int minFreq = 101, answer = -1;
for(int j = 1; j <= 100; j++) {
if (counter[j] > 0 && counter[j] < minFreq) { // check valid frequency > 0
minFreq = counter[j];
answer = j;
}
}
System.out.println(answer);
For a wider range of input values (e.g. including negative values) of a relatively small count it is better to use a hashmap instead of a large sparse array.
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);
}
I started to read the famous "cracking the Coding Interview" book and I want to do the following exercice.
Write an algorithm such that if an element in an MxN matrix is 0, its entire row and column is set to 0.
Here is the author's solution :
public static void setZeros(int[][] matrix) {
int[] row = new int[matrix.length];
int[] column = new int[matrix[0].length];
// Store the row and column index with value 0
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length;j++) {
if (matrix[i][j] == 0) {
row[i] = 1;
column[j] = 1;
}
}
}
// Set arr[i][j] to 0 if either row i or column j has a 0
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
if ((row[i] == 1 || column[j] == 1)) {
matrix[i][j] = 0;
}
}
}
}
I agree with the author about the main idea. We don't have to store the position of '0' in the matrix but only the position of the rows and columns that are concernerd. But what I found a little "strange" in her solution is that at the end, she did a loop on all the cells of the matrix, which is not necessary in my opinion.
Here is my solution :
static int[][] replaceMatrix(int[][] matrix){
int M = matrix.length;
int N = matrix[0].length;
boolean[] row = new boolean[M] ;
boolean[] column = new boolean[N];
for (int i =0; i< M; i++) {
for (int j = 0; j<N; j++ ){
if (matrix[i][j] == 0) {
row[i] = true;
column[j] = true;
}
}
}
for (int i =0; i<M; i++){
if (row[i]){
for (int k =0; k<N; k++){
matrix[i][k]=0;
}
}
}
for (int j =0; j<N; j++){
if (column[j]){
for (int k =0; k<M; k++){
matrix[k][j]=0;
}
}
}
I'am newbie in programmation so I'm not totaly sure about this. But in my solution, if we except the first step which is to store the 0 positions, my second part of my programme have a time complexity of O(M+N) while her solution has a complexity of O(M*N).
The problem is that the general complexity will be the same O(M*N + (M+N)) is the same that having the complexity O(2*M*N), no? (I'm not totally sure).
For example, if it's a matrix with M=N, so the two complexity of the two programs will be O(M^2).
I really want to know if there is a difference or not about complexity in this case?
ps : I read that the space complexity can be improved with a bit vector. But I really didn't understand. Can you just give me a general idea about it (in Java)?
Time complexity of your last two for loops is still O(M*N) as in worst case inner for loop will be running maximum value of k times.
There is technically no difference in your and the author's solution because both of you have traversed the entire matrix.So both codes are same ** if we have to consider big O notation**
In fact the author's code is a little bit( by little bit I do not mean a different time complexity) better. Here is the reason:
Suppose in your boolean array of rows, all rows are set true. Then in your case you will go through all rows and through each element of every row which is basically traversing the entire matrix.
Suppose in your boolean array of columns, all columns are set true. Then in your case you will go through all columns and through each element of every column which is basically traversing the entire matrix.
So you will in effect traverse the entire matrix twice. But the time complexity of the codes is the same because O(M*N) and O(2*M*N) is same.
You have already done saving space, since you used boolean data type.
This is technically a code challenge.
I was asked an interesting question at an interview and am hoping for some insight as the best answer I could come up with was O(2n^2) - n-squared category, but still pretty much brute force.
Let's say you have a matrix that's M by N size ( an array of arrays (int[][]) )
1 2 4 3 1
0 5 3 7 7
5 8 9 2 8
6 7 0 8 9
If a cell contains a Zero, then set that entire row and column to zero.
Making the result:
0 2 0 3 1
0 0 0 0 0
0 8 0 2 8
0 0 0 0 0
What is the fastest and/or best way to do this?
My own answer is to iterate the entire array of arrays, keep track of rows and columns to zero out, and then zero them out.
public void zeroOut(int[][] myArray){
ArrayList<Integer> rowsToZero = new....
ArrayList<Integer> columnsToZero = new....
for(int i=0; i<myArray.length; i++){ // record which rows and columns will be zeroed
for(int j=0; j<myArray[i].length; i++){
if(myArray[i][j] == 0){
if(!rowsToZero.contains(i)) rowsToZero.add(i);
if(!columnsToZero.contains(j)) columnsToZero.add(j);
}
}
}
for(int row : rows){ // now zero the rows
myArray[row] = int[myArray.length];
}
for(int i=0; i<myArray.length; i++){
for(int column: columns){ // now zero the columns
myArray[i][column] = 0;
}
}
}
Is there a better algorithm? Is there a better data-structure to represent this matrix?
you can do this by taking two int but the only condition is the no of rows and cols should less than or equal to 32. You can do the same with greater than 32 but you have to take array of ints.
So the logic is :
take two ints i.e. row and col
traverse the matrix if matrix[i][j] = 0 than set the corresponding bits in the row and col
after traversal traverse again and set the matrix[i][j] = 0 if corresponding bit of either row or column is set.
The time complexity is same O(N^2) but it is memory efficient. Please find my code below .
Check whether the array[row][col] == 0 if 0 than set the corresponding bit in r and c.
int r = 0, c = 0;
for (int row = 0; row < 5; row++) {
for (int col = 0; col < 7; col++) {
if (array[row][col] == 0) {
r = r | (1<<row);
c = c | (1<<col);
}
}
}
Now if either of the bit is set than make the cell to 0.
for (int row = 0; row < 5; row++) {
for (int col = 0; col <7; col++) {
if (((c&(1<<col))!=0) || ((r&(1<<row))!=0)) {
array[row][col] = 0;
}
}
}
What about splitting the matrices into equal smaller matrice parts and calculate the deteriminant, so that you can predict that there is a zero within this matric part.
And then only use the brute force mechanism to this preselected matrices to determin
in wich row or column the zero is.
The determinant is just a suggestion maybe you can use some other kind of linear algebraic
algorithms and rules to predict a zero value
UPDATE:
if you use Quicksort concept to organize temporay every row. Then you have just to loop until the first none zero element occurs.
You need to remember during sorting process which column index was associated with the 0
Means
1 2 6 0 3
Quciksort (
0 1 2 4 6
When you remember the column index you now directly know which row to fill with 0 and which column,
Average of Quicksort ist O(n log n) Worstcase n * n
Maybe this already improves the overall complexisitiy.
Seems no one really came up with a significantly faster/better algorithm so far, so this one seems to be it. Thanks for your input everyone.
public void zeroOut(int[][] myArray){
ArrayList<Integer> rowsToZero = new....
ArrayList<Integer> columnsToZero = new....
for(int i=0; i<myArray.length; i++){ // record which rows and columns will be zeroed
for(int j=0; j<myArray[i].length; i++){
if(myArray[i][j] == 0){
if(!rowsToZero.contains(i)) rowsToZero.add(i);
if(!columnsToZero.contains(j)) columnsToZero.add(j);
}
}
}
for(int row : rows){ // now zero the rows
myArray[row] = int[myArray.length];
}
for(int i=0; i<myArray.length; i++){
for(int column: columns){ // now zero the columns
myArray[i][column] = 0;
}
}
}
I just came across this question and have developed a solution for it.
I am hoping I can get some feedback for the code about how it's better/worse and it's runtime.
Pretty new to all this :)
public static void zeroMatrix(int[][] arr1)
{
ArrayList<Integer> coord = new ArrayList<>();
int row = arr1.length;
int column = arr1[0].length;
for(int i=0; i < row; i++)
{
for(int j=0; j < column; j++)
{
if(arr1[i][j]==0)
{
coord.add((10*i) + j);
}
}
}
for(int n : coord)
{
int j=n%10;
int i=n/10; int k=0;
int l=0;
while(k<row)
{
arr1[k][j]=0;
k++;
}
while(l<column)
{
arr1[i][l]=0;
l++;
}
}
}
I have used HashMap.See if this can help in any way
import java.util.*;
class ZeroMatrix
{
public static void main(String args[])
{
int mat[][]=new int[][]{{0,2,3,4},{1,2,3,4},{1,2,3,4},{1,2,3,4},{1,2,3,0}};
HashMap<Integer,Integer> ht=new HashMap<Integer,Integer>();
for(int i=0;i<5;i++)
{
for(int j=0;j<4;j++)
{
if(mat[i][j]==0)
ht.put(i,j);
}
}
//Set the Respected Rows and colums to Zeros
Set set=ht.entrySet();
Iterator itr=set.iterator();
while(itr.hasNext())
{
Map.Entry m=(Map.Entry)itr.next();
int i=(Integer)m.getKey();
int k=(Integer)m.getValue();
for(int j=0;j<4;j++)
{
mat[i][j]=0;
}
for(int j=0;j<5;j++)
{
mat[j][k]=0;
}
}
//Printing the Resultant Zero Matrix
for(int i=0;i<5;i++)
{
for(int j=0;j<4;j++)
{
System.out.print(mat[i][j]);
}
System.out.println();
}
}
}
I'm trying to create a method that will search through a 2d array of numbers. If the numbers add up to a certain sum, those numbers should remain and all of the other numbers should be changed to a 0. For example, if the desired sum is 7 and a row contains 2 5 1 2, the result should be 2 5 0 0 after the method is implemented. I have everything functioning but instead of keeping all of the numbers that add up to the sum, only the last number is retained. So, I am left with 0 5 0 0 . I think I need another array somewhere but not sure exactly how to go about implementing it. Any ideas?
public static int[][] horizontalSums(int[][] a, int sumToFind) {
int[][] b = new int[a.length][a[0].length];
int columnStart = 0;
while (columnStart < a[0].length) {
for (int row = 0; row < a.length; row++) {
int sum = 0;
for (int column = columnStart; column < a[row].length; column++) {
sum += a[row][column];
if (sum == sumToFind) {
b[row][column] = a[row][column];
}
}
}
columnStart++;
}
return b;
}
In your example you use 2 5 1 1, would 0 5 1 1 also be a valid response? Or do you just need to find any combination? A recursive function may be the best solution.
If you just need to scan through the array and add up the numbers until the sum is reached then just add a for loop to copy the previous values from the array to the new array when the sum is found. Something like:
if (sum == sumToFind)
{
for (int i= 0; i<= columnStart; i++)
{
b[row][i] = a[row][i];
}
}
if (sum == sumToFind)
{
for (int i= columnStart; i<= column; i++)
{
b[row][i] = a[row][i];
}
}
A minor tweak was all it needed. If you have columnStart and column like in the other answer, it only finds the first number of the series.