I was just testing Towers of Hanoi problem in Java and I ran the following code:
(I have removed sysouts
for convinience)
public class Util {
public static void main(String[] args) {
for (int i = 1; i <= 30; i++) {
long startTime = System.currentTimeMillis();
solveTowerOfHanoi(i, "A", "B", "C");
System.out.println("Time taken for " + i + ": "
+ (System.currentTimeMillis() - startTime));
}
}
public static void solveTowerOfHanoi(int n, String src, String inter,
String dest) {
if (n == 0) {
return;
}
solveTowerOfHanoi(n - 1, src, dest, inter);
solveTowerOfHanoi(n - 1, inter, src, dest);
}
}
I did an experiment and I tried disk sizes (indexes) from 1 to 35, ad I observed a very strange timing pattern, here is the output of the program:
Time taken for 1: 0
Time taken for 2: 0
Time taken for 3: 0
Time taken for 4: 0
Time taken for 5: 0
Time taken for 6: 0
Time taken for 7: 0
Time taken for 8: 1
Time taken for 9: 0
Time taken for 10: 0
Time taken for 11: 0
Time taken for 12: 0
Time taken for 13: 0
Time taken for 14: 0
Time taken for 15: 0
Time taken for 16: 0
Time taken for 17: 0
Time taken for 18: 3
Time taken for 19: 2
Time taken for 20: 11
Time taken for 21: 10
Time taken for 22: 39
Time taken for 23: 37
Time taken for 24: 158
Time taken for 25: 147
Time taken for 26: 603
Time taken for 27: 579
Time taken for 28: 2414
Time taken for 29: 2304
Time taken for 30: 9509
Time taken for 31: 9408
Time taken for 32: 38566
Time taken for 33: 37531
Time taken for 34: 152255
Time taken for 35: 148704
Question 1: The algorithm has exponential growth (2^n-1), then why do I see no gradual time growth from 1-20? But then sudden jumps from 20-35?
Question 2: Also another thing which amazes me even more is the equality of times in pairs. Starting from 19, (19,20), (21,22), (23,24), (25,26) etc.... have comparable times. I cannot understand this, if the growth rate of the algorithm is indeed exponential, why does two indexes give almost comparable times and then sudden jump at the next index?
Note: I repeated this program 2-3 times and got almost comparable timings so you can take it as an average run.
EDIT
Tried System.nanoTime()
and got following results:
Time taken for 1: 62644
Time taken for 2: 3500
Time taken for 3: 3500
Time taken for 4: 4200
Time taken for 5: 6300
Time taken for 6: 7350
Time taken for 7: 11549
Time taken for 8: 19948
Time taken for 9: 47245
Time taken for 10: 73142
Time taken for 11: 87491
Time taken for 12: 40246
Time taken for 13: 39196
Time taken for 14: 156784
Time taken for 15: 249875
Time taken for 16: 593541
Time taken for 17: 577092
Time taken for 18: 2318166
Time taken for 19: 2305217
Time taken for 20: 9468995
Time taken for 21: 9082284
Time taken for 22: 37747543
Time taken for 23: 37230646
Time taken for 24: 150416580
Time taken for 25: 145795297
Time taken for 26: 603730414
Time taken for 27: 578825875
Time taken for 28: 2409932558
Time taken for 29: 2399318129
Time taken for 30: 9777009489
Output is almost similar to the millisecs, but it does make the picture clear...answers my Question 1 may be, but Question 2 is still intriguing. And System.nanoTime()
raised one more question:
Question 3: Why does index 1 take more time than the next indexes (2,3...) etc ?