How to find the saddle points in a 2D array? - c

I'm trying to write pseudocode to find all the saddle points in a 2D array. The saddle points are the spots where the value is the minimum in its row, but maximum in its column, or the maximum in its row and minimum in its column.
I'm having trouble wrapping my head around how to store where these values occur, especially if there are 2 saddle points in the same row or column. I'm also not sure if I'm even approaching this correctly, maybe it can be done in a more efficient way?
The array is given by A[x][y] where x is the row and y is the column.
So far my (very basic) pseudocode is
for r=0 to y-1 // iterates through every row
for c=0 to x-1 //iterates through every element in row r
min=min(A[c][r]) //finds the minimum value in row r
for p=0 to y-1 //iterates through every element in col c
max=max(A[c][p]) //finds max in col c
if min==max
saddle point=A[c][p]

You seem to have two major problems with your pseudocode.
1) You have swapped the raws and colums
2) Passing an array element (aka value) to min/max does not make much sense. You probably should pass a row number instead and have the function to return the column number.
A simple way is to find the index of the column holding the minimum value in row r. Then find the index of the row holding the maximum value in that column.
If the two row index are the same, you have a saddle point.
Something like:
for r=0 to x-1 // iterates through every row
// Check min-max combination
c = min_in_row(r) //find index of the column holding the minimum value in row r
r2 = max_in_column(c) //find index of the row holding the maximum value in column c
if (r == r2)
{
// Saddle point found
printf("r=%d c=%d value %d is a saddle point\n", r, c, A[r][c]);
}
// Repeat the same for the max-min combination

Any saddle point can be stored with (row, column). In C:
struct Saddle { int row, col; };
If the maximum number of expected saddle points is known a result array may be used:
/* max. number of saddle points */
#define MAX_FOUND 16
/* row/col. of found saddle points */
struct Saddle found[MAX_FOUND];
/* number of found saddle points */
int nFound = 0;
To store a new result:
found[nFound].row = r;
found[nFound].col = c;
++nFound;
If the number of expected saddle points is unknown two options come in mind:
make the array size x * y (Hmm.)
allocate storage for array using malloc.
For the 2nd option malloc/realloc can be used.
There is often a trick used: If the storage runs out of memory, the realloc is used to allocate new space for multiple additional elements. Thus, the number of re-allocations is reduced because realloc is counted as "expensive" operation. In this case, two count variables are used: one for the size of allocated array, another for the numbers of actually used elements. Of course, the second must always be less or equal to the first.

Related

splitting an array and find maximal |max (L) -max (R)|

I have a general question in programming.
Suppose I have an array, I need to find the index K that divides the array into two parts L, R so that the value
|max (L) -max (R)| Is maximal.
max(L) is the highest number in the L part
K points to the first member in R
This seems to be a problem that reduces to only 2 viable candidates for a solution: either K splits off the first value from the rest, or the last value from the rest, giving you a small part of just one value, and a large part with the remaining values, including the maximum value.
Suppose the maximum value in the array can be found at index M, then one of the two parts will have that value and it will be Max(Part). The other part should have a maximum value that is as small as possible. Consequently that part should be reduced to just one value: adding one more value to that part could never decrease its maximum value.
If the overall maximum value is at one of the ends of the array, then there is no choice, and the small part will be chopped off the array at the other end of it.
When the overall maximum value is not at an end of the array, there are two possibilities: choose the one where the chopped off value will be the lowest. In other words, K will be either 1 or n-1 (in zero-based indexing), and this can be determined in constant time, i.e. O(1).
Actually to solve this question we can do it in constant time.
1.Since the list must be divided in two either list A or list B will contain the leftmost or rightmost element.
Adding values to our list can only increase the maximum element of a list, so it is never desirable to have a list of size larger than 1
So all we need to do is look at the head and tail, take the smallest A, and make the rest of the list B
For example consider 6,7,7,3,2,6,4
A = [4], (smallest head/tail), B = [6,7,7,3,2,6]
You can solve it in O(n) with some preparation:
Make two arrays, maxL[] and maxR[] equal in size to the original array
Walk the original array starting from the left, setting maxL[i] to the max value so far
Walk the original array again starting from the right, setting maxR[i] to the max value so far
Now walk both maxL[] and maxR[] in any direction, looking for k such that the value of ABS(maxL[k] - maxR[k]) is maximized; return k.

accessing unallocatted memory after changing matrix size

I won't bother you with all the dry details of what is the assignment and the problem I'm trying to solve, I'll cut right to the chase.
I need to fill a matrix with data. the matrix is square and everything is zero except the first 2 diagonals (meaning M[i][i] for i between 0 and n-1 and M[i][i+1] for i between 0 and n-2 are already filled)
We want to fill the matrix using this a bit complex formula.
M[i][j]=max(a+min(M[i+2][j],M[i+1][j-1]) , b+min(M[i+1][j-1],M[i][j-2]))
The result is an upper triangular matrix. You can see from the above formula that to compute the k'th diagonal, we need the k-2 diagonal. And I said the first 2 are given.
I wrote a code to fill the matrix and it is working as intended.
Here is my problem:
Since it is an upper triangular matrix, the lower half is all zero. so there is no point in wasting memory and saving it. So I thought to myself instead of allocating an n by n matrix, I will allocate n rows, and to the first row ill allocate n spaces, to the second n-1, to the third n-2 and so on...
But since we changed the dimensions of the matrix, the formula I wrote above to compute M[i][j] is different now. In my opinion, we moves all the values in the i'th row, i columns to the left. in row 0 nothing changed. in row 1, we pulled all the values 1 column to the left, etc. So if I understand correctly:
M[i][j]=M'[i][j-i]
Where M' is our new matrix. And so plugging that in the formula above:
M'[i][j]=max(a+min(M'[i+2][j-i],M'[i+1][j-1-i]) , b+min(M'[i+1][j-1-i],M'[i][j-2-i]))
However now the program to fill the matrix is not working correctly. It is filling the matrix with garbage.
Here is the code to fill the matrix:
void fill_matrix() //fills the matrix with data of optimal path, we use memoization rather than recursion, so this step is necessary.
{ //first step is to allocate the matrix. we can assume right_index==size-1 since this is the first thing we do after generating the array
int i,j;
optimum_matrix=(int**)malloc((right_index+1)*sizeof(int**));
for(j=0;j<=right_index;j++)
optimum_matrix[j]=(int*)malloc((right_index+1-j)*sizeof(int*)); //matrix allocated. upper triangular matrix. no need to allocate n^2 spaces. //to fix indices, M[i][j]=M'[i][j-i+1]. subtract i and add 1 to each column, since we moved each entry in row i, i-1 columns back.
for(i=0;i<=right_index;i++) //first diagonal
optimum_matrix[i][0]=data_array[i];
for(i=0;i<right_index;i++) //second diagonal
optimum_matrix[i][1]=get_max(data_array[i],data_array[i+1]);
for(i=0;i<=right_index;i++)
{
for(j=2;j<=right_index-i;j++)
optimum_matrix[i][j]=get_max(data_array[i]+get_min(optimum_matrix[i+2][j-i],optimum_matrix[i+1][j-i-1]),data_array[j]+get_min(optimum_matrix[i+1][j-i-1],optimum_matrix[i][j-i-2])); //here is the problem
}
}
And this is the code to print the matrix
void print_matrix()
{
int i,j,k;
for(i=0;i<=right_index;i++)
{
for(k=0;k<i;k++)
printf("0 ");
for(j=0;j<=right_index-i;j++)
printf("%d ",optimum_matrix[i][j]);
printf("\n");
}
}
Even on the first iteration of filling the third diagonal, when it enters the for loop where it says "here is the problem", if i type printf("%d",optimum_matrix[i+2][j-i]); it will print garbage. And I don't understand why since the formula agrees.
Would appreciate help. Thank you.
optimum_matrix=(int**)malloc((right_index+1)*sizeof(int**));
That isn't the right way to allocate a double array. It's allocating only one dimension of the double array. It's hard for me to follow your logic on how big you want each row and column to be. So below may not be the exact right dimensions you want. But hopefully it does illustrate how to more correctly allocate the double array.
int **optimum_matrix = malloc((right_index+1)*sizeof(int*));
for (i = 0; i < (right_index+1); i++) {
optium_matrix[i] = malloc((right_index+1)*sizeof(int));
}
BTW, I left out the check of the malloc return value for brevity. And your original code also doesn't check the return value of malloc. That should always be done.

Largest 3 numbers c language [duplicate]

I have an array
A[4]={4,5,9,1}
I need it would give the first 3 top elements like 9,5,4
I know how to find the max element but how to find the 2nd and 3rd max?
i.e if
max=A[0]
for(i=1;i<4;i++)
{
if (A[i]>max)
{
max=A[i];
location=i+1;
}
}
actually sorting will not be suitable for my application because,
the position number is also important for me i.e. I have to know in which positions the first 3 maximum is occurring, here it is in 0th,1th and 2nd position...so I am thinking of a logic
that after getting the max value if I could put 0 at that location and could apply the same steps for that new array i.e.{4,5,0,1}
But I am bit confused how to put my logic in code
Consider using the technique employed in the Python standard library. It uses an underlying heap data structure:
def nlargest(n, iterable):
"""Find the n largest elements in a dataset.
Equivalent to: sorted(iterable, reverse=True)[:n]
"""
if n < 0:
return []
it = iter(iterable)
result = list(islice(it, n))
if not result:
return result
heapify(result)
for elem in it:
heappushpop(result, elem)
result.sort(reverse=True)
return result
The steps are:
Make an n length fixed array to hold the results.
Populate the array with the first n elements of the input.
Transform the array into a minheap.
Loop over remaining inputs, replacing the top element of the heap if new data element is larger.
If needed, sort the final n elements.
The heap approach is memory efficient (not requiring more memory than the target output) and typically has a very low number of comparisons (see this comparative analysis).
You can use the selection algorithm
Also to mention that the complexity will be O(n) ie, O(n) for selection and O(n) for iterating, so the total is also O(n)
What your essentially asking is equivalent to sorting your array in descending order. The fastest way to do this is using heapsort or quicksort depending on the size of your array.
Once your array is sorted your largest number will be at index 0, your second largest will be at index 1, ...., in general your nth largest will be at index n-1
you can follw this procedure,
1. Add the n elements to another array B[n];
2. Sort the array B[n]
3. Then for each element in A[n...m] check,
A[k]>B[0]
if so then number A[k] is among n large elements so,
search for proper position for A[k] in B[n] and replace and move the numbers on left in B[n] so that B[n] contains n large elements.
4. Repeat this for all elements in A[m].
At the end B[n] will have the n largest elements.

Delete a column from a double array

I'm stuck here. I've got a matrix of size NxN stored in a double array. Then I want to delete a given column, lets say the first column. So I created a new double array of size NxN-1 and copy the values from the first matrix to the second one, except the 1st column of course. But then I want to set the first array to be the second array. I am blanking here.
double matrix[N][N]
//fill up the matrix code here...
// remove first column of array
double newMatrix[N][N-1];
for(i = 0; i < N; i++){
for(j = 1; j < N; j++){
newMatrix[i][j-1] = matrix[i][j];
}
}
matrix = newMatrix; // how do I set this correctly? Do I need to realloc the first array?
You cannot assign arrays in C, which I assume that your compiler tells you. To do such dynamic memory management, you will need to use pointers instead of arrays. I suggest you read up on how malloc() and free() work so that you can do what you want.
Edit:
Another solution comes to mind if you are only removing columns (or rows): keep track of the number of rows and columns used in the array. Then you can remove a row or column within the original array without creating a copy first. Just move the data past the delete column (or row) to the left (or up) then decrement your size counters. (I hope this make sense. If not let me know and I'll elaborate.)
like Code-guru said malloc() and free() should help alot, but if u simply wanted to delete the last column the you wouldn't need two arrays:
double matrix[2][3] = {1,2,3,4,5,6}; //declaring a 2 by 3 matrix
for (i=0;i<2;i++) //rows
{
for (j=0;j<3-1;j++) //columns - 1
{
printf("%.1f ",matrix[i][j]); //I chose to display matrix...
}
printf("\n");
}
Instead of accessing elements from array[i][j], one might opt to access elements from array + stride_x[x] + stride_y[y]; where array is originally introduced as double matrix[N*N]; or double *matrix = malloc(sizeof(double)*N*N);.
The stride_y[x] would originally contain offsets of columns for all rows: 0 1 2 3 4 ... N-1 and stride_y[y] would contain similar offsets multiplied with original row width 0 N 2*N 3*N..
From these 1-D arrays one can more effortlessly delete or exchange complete rows and columns, which may come handy in eg. recursive implementation of determinant calculation / Gauss Jordan elimination.

How to identify the duplicated number, in an array, with minimum compexity?

There is an array of size 10,000. It store the number 1 to 10,000 in randomly order.
Each number occurs one time only.
Now if any number is removed from that array and any other number is duplicated into array.
How can we identify the which number is duplicated, with minimum complexity?
NOTE : We can not use another array.
The fastest way is an O(N) in-place pigeonhole sort.
Start at the first location of the array, a[0]. Say it has the value 5. You know that 5 belongs at a[4], so swap locations 0 and 4. Now a new value is in a[0]. Swap it to where it needs to go.
Repeat until a[0] == 1, then move on to a[1] and swap until a[1] == 2, etc.
If at any point you end up attempting to swap two identical values, then you have found the duplicate!
Runtime: O(N) with a very low coefficient and early exit. Storage required: zero.
Bonus optimization: count how many swaps have occurred and exit early if n_swaps == array_size. This resulted in a 15% improvement when I implemented a similar algorithm for permuting a sequence.
Compute the sum and the sum of the squares of the elements (you will need 64 bit values for the sum of the squares). From these you can recover which element was modified:
Subtract the expected values for the unmodified array.
If x was removed and y duplicated you get the difference y - x for the sum and y2 - x2 = (y + x) (y - x) for the sum of squares.
From that it is easy to recover x and y.
Edit: Note that this may be faster than pigeonhole sort, because it runs linearly over the array and is thus more cache friendly.
Why not simply using a second array or other data structure like hash table (hash table if you like, depending on the memory/performance tradeoff). This second array would simply store the count of a number in the original array. Now just add a +/- to the access function of the original array and you have your information immediately.
ps when you wrote "we can not use another array" - I assume, you can not change the ORIGINAL data structure. However the use of additional data structures is possible....
Sort the array, then iterate through until you hit two of the same number in a row.

Resources