Reluctant Search
April 3, 2015
Wednesday was April Fools’ Day, and I was feeling frisky, so I implemented the reluctant search algorithm from Pessimal Algorithms and Simplexity Analysis by Andrei Broder and Jorge Stolfi. Their algorithm takes time O(2n), which is worse than the naive brute force O(n), to find the index of a target x in a sorted array. We looked at a different algorithm that paper in a previous exercise. I’ll leave it to you to fetch the paper and enjoy the sincerity of the authors’ pessimality.
Your task is to implement the reluctant search algorithm. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.
In Python.
Surely an O(2n) algorithm is also O(n), at least if I understand the definition of big-O correctly. What is more, you can make linear search take 2n time by running it twice, discarding the first result.
@JohnCowan: Your understanding of big-O notation is correct. Read the article for their definition of pessimal. Basically, it’s cheating to do things like run a calculation twice or include a useless loop that takes up time; the algorithm must make progress toward its goal at every step.
My first attempt was slow enough, but did not produce the correct result. This version seems to work better.
public class ReluctantSearch {
public static void main(String[] args) {
int[] input = new int[] {1, 2, 3, 4, 5, 6};
System.out.println(“Position “+research(3, input, 0, input.length-1));
System.out.println(“Position “+research(7, input, 0, input.length-1));
}
private static int research(int x, int[] input, int i, int j) {
if(i > j) return -1;
if(i == j)
if(x == input[i])
return i;
else return -1;
int m = (i+j)/2;
if(x <= input[m]) {
int k = research(x, input, (m+1), j);
if (k==-1) {
return research(x, input, i, m);
} else return k;
} else {
int k = research(x, input, i, m);
if(k==-1) {
return research(x, input, (m+1), j);
} else return k;
}
}
}
To achieve optimal pessimality, I have transformed the algorithm into non-recursive form with an explicit stack (and done what is effectively the obvious tail recursion elimination):