How to create a function to generate a matrix where numbers progessivley get smaller columnwise? [closed] - arrays

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 months ago.
Improve this question
Basically I have been trying to come up with a 2D array loop in Matlab. It will create a 5 column array for example that starts of with full 100's and removes the 5th column by an interval of 10 until it hits zero and then moves onto the 4th column and starts at 90, then the 5th column (starting at 90) goes down to zero. This repeats until all the numbers have become zero. Im looking for some sort of loop that creates something like this:
100 100 100 100 90
100 100 100 100 80
100 100 100 100 70 .....
100 100 100 90 90 .....
100 100 100 90 80
100 0 0 0 0 ....
0 0 0 0 0
But I am really struggling to come up with a simple loop for it.
If anyone has an ideas on how to create this I would really appreciate it.

Here's a simple loop-approach that does what you want. You have to make minor adjustments for it to work with the steps you want, but that should be simple:
c = 4; % number of columns
n = 3; % starting number
x = zeros(n*c+1, c); % Initial matrix of zeros
for ii = 1:c
last_idx(ii) = ((n*c+1)-n)-(ii-1)*n;
x(1:last_idx(ii),ii) = n;
x(last_idx(ii)+[1:n-1], ii) = [n-1:-1:1];
end
x =
3 3 3 3
3 3 3 2
3 3 3 1
3 3 3 0
3 3 2 0
3 3 1 0
3 3 0 0
3 2 0 0
3 1 0 0
3 0 0 0
2 0 0 0
1 0 0 0
0 0 0 0

The following should get you started. Its a very nice application possibility of the Kronecker Tensor Product to get a fully vectorized solution without loop.
Parameters:
step = 20;
nrows = 3;
nsteps = 5;
As one-liner:
A = cumsum(kron(fliplr(eye(nrows)),step*ones(nsteps,1)),1,'reverse');
with explanation:
basepattern = fliplr(eye(nrows)); % general matrix design
subpattern = step*ones(nsteps,1); % pattern to repeat
a = kron(basepattern, subpattern); % kronecker delta to repeat pattern
A = cumsum(a,1,'reverse'); % cumulative sum upwards
% optional: filter out lines:
A(nsteps+1:nsteps:end,:) = [];
% optional: pad zeros at the end
A(end+1,:) = 0
Result
A =
100 100 100
100 100 80
100 100 60
100 100 40
100 100 20
100 80 0
100 60 0
100 40 0
100 20 0
80 0 0
60 0 0
40 0 0
20 0 0
0 0 0

Related

Hungarian Algorithm - Wikipedia method doesn't work for this example

I'm trying to implement a Hungarian Algorithm in C.
I have the matrix:
35 0 0 0
0 30 0 5
55 5 0 10
0 45 30 45
And I'm up to the stage where I have to find the minimum amount of lines to cover all zeroes (making as many assignments as possible). Obviously, by inspection this is columns 1 and 3 and row 1.
Wikipedia suggests the following method:
Row 1 has three zeroes: pick any (I pick the first one) and assign it
Row 2: Assign the first zero
Row 3: Assign the 3rd zero
Row 4 is unassigned (since the only zero is in a col that already has an assigned zero)
If I follow this for my matrix above, I get:
35 0' 0 0
0' 30 0 5
55 5 0' 10
0 45 30 45
Where zero prime is the assigned zero. Then, following Wikipedia's instructions below, I mark row 4 (unassigned zero), column 1 (col with the unassigned zero), then row 2 (row with a zero in a marked col).
So that would suggest that the min lines to hit all zeroes are:
+--------
|
+--------
|
But this doesn't hit the zero at (2, 3). Relevant C code:
for (i = 0; i < M->size; i++) {
for (j = 0; j < M->size; j++) {
if (M->values[i][j] == 0) {
if (assigned_cols[j] == 0) {
assigned_cols[j] = 1; // We've assigned something in this col
assigned_rows[i] = 1; // We've assigned something in this row.
marked_rows[i] = 0;
total--;
break; // Go to the next row
} else {
marked_cols[j] = 1; // Then there exists a zero in this col in an unassigned row
mark_col(M, j); // marks all elements in column j
total++;
}
}
}
}
This code chooses which zeroes are zero prime (assigns zeroes).
Then this code marks all rows having assignments in newly-marked columns:
for (i = 0; i < M->size; i++) {
if (marked_cols[i] == 1) {
for (j = 0; j < M->size; j++) {
//iterating through rows
if (M->values[j][i] == 0) {
// then (j,i) is a zero in a marked col
// mark the row
if (marked_rows[j] != 1) {
total++;
marked_rows[j] = 1;
}
break; // no need to continue more
}
}
}
}
But this (and the wikipedia explanation) fails for my matrix above. How come?
Wikipedia is lacking explanation on the algorithm, the assignments will be done in the last step!
STEP 0
35 0 0 0
0 30 0 5
55 5 0 10
0 45 30 45
STEP 1-2
all rows-columns have at least one 0 so step 1 leaves array the same
35 0 0 0
0 30 0 5
55 5 0 10
0 45 30 45
STEP 3
All zeros in the matrix must be covered by marking as few rows and/or columns as possible
- - - -
| |
| |
| |
Note that no assignments are done thus far and you need to cover all zeros. Your cover left zero (2,3) uncovered!!
Now take min element that is not covered e.g 5 (take the 5 at position (2,4))
-Reduce (by 5) all elements that where not covered.
-Increase (by 5) all elements crossed by two lines.
-Rest remain same
So the array:
40 0 5 0
0 25 0 0
55 0 0 5
0 40 30 40
Now check again for min required lines: now you need 4 lines (equal to size n=4 of rows of array, so we stop).
Finally assignment:
Start from lines with only one zero this will surely be assigned:
40 0 5 _
0 25 _ 0
55 _ 0 5
_ 40 30 40
Multiple assignments exist (I use _ for assignment).
More specifically two assignments we get: (one stated above with total cost 5) and:
40 _ 5 0
0 25 0 _
55 0 _ 5
_ 40 30 40
With also cost 5!
EDIT
Based on comment it seems that I didn't get the exact part that op was asking so I will answer this specific part keeping the general description of the algorithm above.
The mistake (due to bad Wikipedia description) is here:
Where zero prime is the assigned zero. Then, following Wikipedia's
instructions below, I mark row 4 (unassigned zero), column 1 (col with
the unassigned zero), then row 2 (row with a zero in a marked col).
Totally agree till now but...it's not complete!!!
When correctly marking row2 you need to go to step 2 (of Wikipedia)
and check again for columns with zeros in this case column 3 should
also been marked, this also causes the row 3 to be marked as well (due to assigned zero in the newly marked column 3) and
there you stop (no other rows or columns should be marked)!!
So overall the marked columns and rows:
+ +
35 0' 0 0
0' 30 0 5 +
55 5 0' 10 +
0 45 30 45 +
And the lines you get by choosing the marked columns and unmarked lines:
- - - -
| |
| |
| |
which is the right one as described in the first part of answer and leads to right results in next stages (also explained above).
One very similar post that states literally same thing can be found on mathstackexchange:
finding the minimum number of lines to cover all zeros in an assignment probem

Finding or arranging all combinations of given numbers [duplicate]

This question already has answers here:
Find all combinations of a given set of numbers
(9 answers)
Closed 8 years ago.
I hope all you are doing great.
I have an interesting question, which has stuck me. Its about generating combinations in a precise order.
For example i have 4 variables(can be vary) and these 4 variables has some limit to increase for example in this case 2. so i want to generate 2d matrix in a order as:
0 0 0 0
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
1 1 0 0
1 0 1 0
1 0 0 1
0 1 1 0
0 1 0 1
0 0 1 1
1 1 1 0
0 1 1 1
1 1 1 1
2 0 0 0
0 2 0 0
0 0 2 0
0 0 0 2
2 1 0 0
2 0 1 0
......
......
and so on.
the number of variables ( in this case 4 ) can be varied and also the maximum limit ( in this case 4) can be varied.
Even i have also find all possible combinations but i am not able to arrange them in this sequence.
it would be great if somebody gives an answer.
cheers!
I'm going to assume you've got n variables, each of which is allowed to range from 0 to b-1. What you want is just counting n-digit numbers in base b. For example, if n = 2 and b = 3, then the sequence you want to produce is
00
01
02
10
11
12
20
21
22
To implement this, write a loop something like the following: (warning: untested code)
def inc(v, b):
for i in range(len(v)):
v[i] = v[i] + 1
if v[i] < b:
break
v[i] = 0
def is_zero(v):
for i in range(len(v)):
if v[i] != 0:
return False
return True
v = [0, 0, 0]
b = 3
while True:
print(v)
inc(v, b)
if is_zero(v):
break
If you look carefully at how this works, you should see how to generalize it if your variables have different upper bounds.

How to populate binary matrices with all the combinations?

I want to have 2^n matrices with all the combinations of 0 and 1 in them. For example, for n=6 (n=#rows x #columns) array{1}=[0 0 0; 0 0 0],array{2}=[0 0 0; 0 0 1]... array{64}=[1 1 1;1 1 1]. I am using MATLAB and I came across with combn.m (M = COMBN(V,N) returns all combinations of N elements of the elements in vector V. M has the size (length(V).^N)-by-N.), dec2bin() but I can't get it quite right. Another idea of mine was to create a large matrix and then split it into 2^n matrices. For instance,for n=6( 2 x 3), i did this M=combn([0 1],3) which gives me:
M =
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
Then, use this M to create a larger matrix like this M2=combn(M,2), but this produces the wrong results. However, if i concatenate M row like this:
M=combn([000;010;100;001;110;011;101;111],2)' I get something closer to what I expect i.e
M =
Columns 1 through 21
0 0 0 0 0 0 0 0 10 10 10 10 10 10 10 10 100 100 100 100 100
0 10 100 1 110 11 101 111 0 10 100 1 110 11 101 111 0 10 100 1 110
Columns 22 through 42
100 100 100 1 1 1 1 1 1 1 1 110 110 110 110 110 110 110 110 11 11
11 101 111 0 10 100 1 110 11 101 111 0 10 100 1 110 11 101 111 0 10
Columns 43 through 63
11 11 11 11 11 11 101 101 101 101 101 101 101 101 111 111 111 111 111 111 111
100 1 110 11 101 111 0 10 100 1 110 11 101 111 0 10 100 1 110 11 101
Column 64
111
111
where I can get each column and convert it separately into 64 matrices.So, for example column 1 would be converted from [0;0] to [0 0 0;0 0 0] etc. However, i believe it is a much easier problem which it can be solved in less time, elegantly.
Using dec2bin:
r = 2; %// nunber of rows
c = 3; %// number of columns
M = dec2bin(0:2^(r*c)-1)-'0'; %// Or: M = de2bi(0:2^(r*c)-1);
M = reshape(M.',r,c,[]);
M is a 3D-array of size r x c x 2^(r*c), such that M(:,:,1) is the first matrix, M(:,:,2) is the second etc.
How it works:
dec2bin gives a binary string representation of a number. So dec2bin(0:2^(r*c)-1) gives all numbers from 0 to 2^(r*c)-1 expressed in binary, each in one row. The -'0' part just turns the string into a numeric vector of 0 and 1 values. Then reshape puts each of those rows into a r x c form, to make up each of the the desired matrices.

Navigation of matrix from left top to right bottom, only moving to the right or downwards?

actual problem is like this which I got from an Online competition. I solved it but my solution, which is in C, couldn't produce answer in time for large numbers. I need to solve it in C.
Given below is a word from the English dictionary arranged as a matrix:
MATHE
ATHEM
THEMA
HEMAT
EMATI
MATIC
ATICS
Tracing the matrix is starting from the top left position and at each step move either RIGHT or DOWN, to reach the bottom right of the matrix. It is assured that any such tracing generates the same word. How many such tracings can be possible for a given word of length m+n-1 written as a matrix of size m * n?
1 ≤ m,n ≤ 10^6
I have to print the number of ways S the word can be traced as explained in the problem statement. If the number is larger than 10^9+7, I have to print S mod (10^9 + 7).
In the testcases, m and n can be very large.
Imagine traversing the matrix, whatever path you choose you need to take exatcly n+m-2 steps to make the word, among of which n-1 are down and m-1 are to the right, their order may change but the numbers n-1 and m-1 remain same. So the problem got reduced to only select n-1 positions out of n+m-2, so the answer is
C(n+m-2,n-1)=C(n+m-2,m-1)
How to calculate C(n,r) for this problem:
You must be knowing how to multiply two numbers in modular arithmetics, i.e.
(a*b)%mod=(a%mod*b%mod)%mod,
now to calculate C(n,r) you also need to divide, but division in modular arithmetic can be performed by using modular multiplicative inverse of the number i.e.
((a)*(a^-1))%mod=1
Ofcourse a^-1 in modular arithmetic need not equal to 1/a, and can be computed using Extended Euclidean Algorithm, as in your case mod is a prime number therefore
(a^(-1))=a^(mod-2)%mod
a^(mod-2) can be computed efficiently using repetitive squaring method.
I would suggest a dynamic programming approach for this problem since calculation of factorials of large numbers shall involve a lot of time, especially since you have multiple queries.
Starting from a small matrix (say 2x1), keep finding solutions for bigger matrices. Note that this solution works since in finding the solution for bigger matrix, you can use the value calculated for smaller matrices and speed up your calculation.
The complexity of the above soltion IMO is polynomial in M and N for an MxN matrix.
Use Laplace's triangle, incorrectly named also "binomial"
1 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1 1 0 0 0
1 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1 1 1 0 0
1 2 0 0 0
1 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1 1 1 1 0
1 2 3 0 0
1 3 0 0 0
1 0 0 0 0
0 0 0 0 0
1 1 1 1 1
1 2 3 4 0
1 3 6 0 0
1 4 0 0 0
1 0 0 0 0
1 1 1 1 1
1 2 3 4 5
1 3 6 10 0
1 4 10 0 0
1 5 0 0 0
1 1 1 1 1
1 2 3 4 5
1 3 6 10 15
1 4 10 20 0
1 5 15 0 0
1 1 1 1 1
1 2 3 4 5
1 3 6 10 15
1 4 10 20 35
1 5 15 35 0
1 1 1 1 1
1 2 3 4 5
1 3 6 10 15
1 4 10 20 35
1 5 15 35 70
Got it? Notice, that elements could be counted as binomial members. The diag members are here: C^1_2, C^2_4,C^3_6,C^4_8, and so on. Choose which you need.

Algorithm: Find smallest contiguous array containing K 0's in array of 1's and 0's

I have array of 1's and 0's only. Now I want to find smallest contiguous subset/subarray which contains at least K 0's.
Example
Array is 1 1 0 1 1 0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 1 0 0 1 0 0 0
and K(6) should be 0 0 1 0 1 1 0 0 0 or 0 0 0 0 1 0 1 1 0....
My Solution
Array: 1 1 0 1 1 0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 1 0 0
Index: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
Sum: 1 2 2 3 4 4 5 6 6 6 6 6 7 7 8 9 9 9 9 10 11 11 11
Diff(I-S): 0 0 1 1 1 2 2 2 3 4 5 6 6 7 7 7 8 9 10 10 10 11 12
For K(6)
Start with 9-15 = Store difference in diff.
Next increase difference
8-15(Difference in index)
8-14(Compare Difference in index)
So on keep moving to find element with least elements...
I am looking for better algorithm for this solution.
I believe you could do it with a rolling window like:
In the given array, find the first occurance of 0 (say at index i).
Keep on scanning until you've k 0's included in your window (say, the window ends at index j) Record the window Length(say j-i+1=L).
Now, discard the left-most 0 at index i, and keep scanning till you get next 0 (say at index i'
Extend the right-end of the window situated at j to j' to make the count of 0's = k again.
If the new window-length L'=j'-i'+1 is smaller update it.
Keep on repeating the above procedure till j hits the end of array.
No extra space needed and It's O(N) time-complexity, as an element would be scanned at max twice.
With extra O(k) memory , you can do it in O(n) time.Here is the java code.What you are doing is , if a[i]==0 then you check where the queue's first element points to.and if the differnce in positions is less than minimum, then you update the answer.
Queue<Integer> queue =new LinkedList<Integer>();
int i=0;
while(queue.size()<k&&i<n)
{
if(a[i]==0)
{
queue.add(i);
}
i++;
}
if(i==n&&queue.size()<k)
System.out.println("Insufficient 0''s");
int ans=i-1-queue.peek();
for(int j=i;j<n;j++)
{
if(a[i]==0)
{
queue.poll();
queue.add(i);
ans=Math.min(ans,i-queue.peek());
}
}
System.out.println(ans);
EDIT :Explanation
We maintain a queue which consist of all the positions which have a 0 and we limit the queue size to be k. So initially in the while loop we fill the queue with the first k indexes. If ofcourse the queue size is less than k after seeing all elements , then it's impossible. After that , we keep going to all the left over elements .Each time we see a 0 , we calcualte the length of the subsequence ,(i-queue.peek()) and find the minimum .Also we remove the first element , and add the latest index again maintaining the queue size
fully working python code:
>>> A = "1 1 0 1 1 0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 1 0 0".split()
>>> A = map(int, A)
>>> zero_positions = [i for i, x in enumerate(A) if x == 0]
>>> k = 3
>>> containing_k_zeros_intervals = zip(zero_positions, zero_positions[k:])
>>> min(b - a for a, b in containing_k_zeros_intervals)
3
Scan the array from the starting to find the index till which we get k zeros.
Have two pointers.
Now ptr1 is at the index where first zero is seen.
start = ptr1
ptr2 is at the index where we have found k 0's.
end = ptr2;
a)increment ptr1.
b ) find the index from ptr2+1 until we find k 0's.
c) Say at ptr3 we find K 0's. If ptr3-ptr1 < (end-start) update indexes start and end.
Repeat steps a -c until the end of the list.
At the end, start and end will have indexes where there are k 0's.

Resources