Algorithm with ceil(n/2) comparisons

  • Context: MHB 
  • Thread starter Thread starter evinda
  • Start date Start date
  • Tags Tags
    Algorithm
Click For Summary

Discussion Overview

The discussion revolves around designing an algorithm to find the minimum element in a strictly alternating sequence of numbers using at most $\lceil \frac{n}{2} \rceil$ comparisons. Participants explore various approaches, code implementations, and justifications for their methods, focusing on algorithm efficiency and comparison counts.

Discussion Character

  • Technical explanation
  • Mathematical reasoning
  • Debate/contested

Main Points Raised

  • One participant describes the properties of strictly alternating sequences and provides an initial algorithm that does not meet the $\lceil \frac{n}{2} \rceil$ comparison requirement.
  • Another participant suggests that instead of storing values, indices should be stored, proposing a method to determine the minimum index based on comparisons between elements.
  • Several participants reiterate the importance of tracking indices rather than values, with examples illustrating how to initialize and update the minimum index during the search.
  • There is a discussion about the number of comparisons required, with participants attempting to derive the total based on different initial conditions for the minimum index.
  • A later reply proposes a simplification in the algorithm that allows for a consistent number of comparisons, regardless of the initial conditions, and provides a mathematical breakdown of the comparison counts based on whether $n$ is even or odd.

Areas of Agreement / Disagreement

Participants generally agree on the need to optimize the algorithm for fewer comparisons, but there are multiple competing views on the best approach to achieve this, and the discussion remains unresolved regarding the most efficient implementation.

Contextual Notes

Some participants express uncertainty about the exact number of comparisons needed and how to demonstrate that the algorithm meets the $\lceil \frac{n}{2} \rceil$ requirement, indicating that assumptions about the sequence and the algorithm's behavior may affect the analysis.

evinda
Gold Member
MHB
Messages
3,741
Reaction score
0
Hello! (Wave)

I am looking at the following exercise:

We say that a sequence of numbers $A=(a_1,a_2, \dots, a_n) , n \geq 3$, is strictly alternating if for each $i$, with $2 \leq i \leq n-1$, one of the following conditions stands:

  • $a_{i-1}< a_i$ and $a_i>a_{i+1}$
    $$$$
  • $a_{i-1}>a_i$ and $a_i<a_{i+1}$

For example, the sequences $(2,10,5,6,3,11,-1,7,4)$ and $(2,-7,4,3,6,0,33,2)$ are alternating, but the sequnce $(5,6,7,3,4,-2,7,10)$ isn't.

Design an algorithm, that, given an alternating sequence of numbers $A$, executes at most $\lceil \frac{n}{2} \rceil$ comparisons, in order to calculate the minimum element of $A$. Justify your answer.

I wrote the following code:

Code:
#include <stdio.h>

int main()
{
int n,i,min,position_min;
printf("Give n: \n");
scanf("%d",&n);
while (n<3){
   printf("	Give an other value for n: \n");
   scanf("%d", &n);
}
int A[n];
for (i=0; i<n; i++){
     printf("Give the value of the %dth position of the array: \n",i+1);
     scanf("%d",&A[i]);
}
min=A[0];
position_min=0;
if (A[1]<min) {
    min=A[1];
    position_min=1;
}
for (i=position_min+2; i<n; i+=2){
    if (A[i]<min){
       min=A[i];
       position_min=i;
    }
}
printf("min=%d \n ",min);
return 0;
}

So, we need $2 \left ( \frac{n-\text{position_min}-2+1}{2} \right )=n-\text{position_min}-1$ comparisons..But.. we don't need $\lceil \frac{n}{2} \rceil$ comparisons, at the algorithm I wrote.. (Sweating)

How could I do it otherwise? :confused:
 
Technology news on Phys.org
If the first number is smaller than the second then you have the indecies are even. Otherwise they are odd.

You don't need to store the value of the element but rather you store the index.

For example :

Code:
A = {4,6,5,7,3,8,2}  
Then min is initialized to 0 since 4 <6.  counter =2;
Since A[min]<A[counter] , min stays 0;
Counter = counter+2 = 4;
Since A[min]>A[counter] min=4;
Counter = counter+2=6;
Since A[min]>A[counter] min=6;
Counter = counter+2=8 > length(A)
Hence min = 6 and the minimum is A[6]=2;

Since each time we travel almost to the end of the array and we skip one element at a time we expect the complexity to be $$\frac{n}{2}$$.Fore the case were the first element is greater than the second initialize min=1 and counter = 3.
 
ZaidAlyafey said:
If the first number is smaller than the second then you have the indecies are even. Otherwise they are odd.

You don't need to store the value of the element but rather you store the index.

For example :

Code:
A = {4,6,5,7,3,8,2}  
Then min is initialized to 0 since 4 <6.  counter =2;
Since A[min]<A[counter] , min stays 0;
Counter = counter+2 = 4;
Since A[min]>A[counter] min=4;
Counter = counter+2=6;
Since A[min]>A[counter] min=6;
Counter = counter+2=8 > length(A)
Hence min = 6 and the minimum is A[6]=2;

Since each time we travel almost to the end of the array and we skip one element at a time we expect the complexity to be $$\frac{n}{2}$$.Fore the case were the first element is greater than the second initialize min=1 and counter = 3.

So, at this for loop:

Code:
for (i=position_min+2; i<n; i+=2){
    if (A[i]<min){
       min=A[i];
       position_min=i;
    }
}

we don't need to write the command:
Code:
position_min=i;
, right? (Thinking)

So,should it be like that? :confused:

Code:
#include <stdio.h>

int main()
{
int n,i,min,j;
printf("Give n: \n");
scanf("%d",&n);
while (n<3){
   printf("	Give an other value for n: \n");
   scanf("%d", &n);
}
int A[n];
for (i=0; i<n; i++){
     printf("Give the value of the %dth position of the array: \n",i+1);
     scanf("%d",&A[i]);
}
min=A[0];
j=0;
if (A[1]<min) {
    min=A[1];
    j=1;
}
for (i=j+2; i<n; i+=2){
    if (A[i]<min){
       min=A[i];
    }
}
printf("min=%d \n ",min);
return 0;
}
 
Generally we are not interested in the element but rather the index so we have

Code:
if(A[0] < A[1])
    min=0;
else
    min=1;

for(counter = min+2; counter < n ; counter+=2)
    if(A[counter] < A[min])
          min = counter;

printf("The minimum is %d ", A[min]);
 
ZaidAlyafey said:
Generally we are not interested in the element but rather the index so we have

Code:
if(A[0] < A[1])
    min=0;
else
    min=1;

for(counter = min+2; counter < n ; counter+=2)
    if(A[counter] < A[min])
          min = counter;

printf("The minimum is %d ", A[min]);

So, we need $n-min-2+1=n-min-1=\left\{\begin{matrix}
\frac{n-1}{2} &, min=0 \\
\\
\frac{n-2}{2} & ,min=1
\end{matrix}\right.$ comparisons, right? (Thinking)

But.. how can we show that we need $ \lceil \frac{n}{2} \rceil$ comparisons? :confused:
 
Just don't bother only checking the last element if min = 0, do it every time. It doesn't affect correctness, and makes your code simpler to analyze, because in that case you simply have this number of comparisons:

$$1 + \left ( \left \lfloor \frac{n}{2} \right \rfloor - 1 \right ) + (n \bmod 2) = \left \lfloor \frac{n}{2} \right \rfloor + (n \bmod 2)$$

Where the first $1$ is the initial comparison, the second term is the for loop (note that you must subtract $1$ because you've already processed the first two elements) and the final $n \bmod 2$ is because we need one more comparison if $n$ is odd for the last element.

If $n$ is even, then this gives:

$$\frac{n}{2} = \left \lceil \frac{n}{2} \right \rceil$$

And if $n$ is odd, then this gives:

$$\frac{n - 1}{2} + 1 = \frac{n + 1}{2} = \left \lceil \frac{n}{2} \right \rceil$$

And so you are done. Sometimes it pays off to not be too clever :)
 

Similar threads

  • · Replies 9 ·
Replies
9
Views
2K
  • · Replies 1 ·
Replies
1
Views
2K
Replies
7
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 2 ·
Replies
2
Views
1K
  • · Replies 17 ·
Replies
17
Views
2K
  • · Replies 6 ·
Replies
6
Views
6K
Replies
9
Views
3K
  • · Replies 3 ·
Replies
3
Views
1K
Replies
47
Views
5K