|
| 1 | +/* Ternary Search Implementations in JavaScript */ |
| 2 | + |
| 3 | + |
1 | 4 | /*
|
2 | 5 | Simple Ternary Search Implementation
|
3 | 6 |
|
4 | 7 | Find the maximum value in a strictly increasing and then strictly decreasing list
|
5 | 8 | N.B.- This method won't work if the list does not represent an unimodal function
|
6 | 9 | e.g. if the maximum value present in the first or last index of the list
|
7 | 10 | */
|
8 |
| -function simpleTernarySearch(itemList){ |
9 |
| - var left = 0, right = itemList.length - 1; |
10 |
| - |
11 |
| - var found = false; |
12 |
| - var precision = 3; |
13 |
| - |
14 |
| - while(left <= right){ |
15 |
| - if((right - left) < precision){ //Here 3 is the smallest range to divide the left and right value |
16 |
| - found = true; |
17 |
| - break; |
18 |
| - } |
19 |
| - |
20 |
| - var leftThird = left + Math.floor((right - left)/3); |
21 |
| - var rightThird = right - Math.floor((right - left)/3); |
22 |
| - |
23 |
| - //To find the minimum in an unimodal function change the following comparison to > |
24 |
| - if(itemList[leftThird] < itemList[rightThird]) |
25 |
| - left = leftThird; |
26 |
| - else |
27 |
| - right = rightThird; |
28 |
| - } |
29 |
| - |
30 |
| - return Math.floor((left + right)/2); |
| 11 | +function simpleTernarySearch(itemList) { |
| 12 | + var left = 0, |
| 13 | + right = itemList.length - 1; |
| 14 | + |
| 15 | + var found = false; |
| 16 | + var precision = 3; |
| 17 | + |
| 18 | + while (left <= right) { |
| 19 | + if ((right - left) < precision) { //Here 3 is the smallest range to divide the left and right value |
| 20 | + found = true; |
| 21 | + break; |
| 22 | + } |
| 23 | + |
| 24 | + var leftThird = left + Math.floor((right - left) / 3); |
| 25 | + var rightThird = right - Math.floor((right - left) / 3); |
| 26 | + |
| 27 | + //To find the minimum in an unimodal function change the following comparison to > |
| 28 | + if (itemList[leftThird] < itemList[rightThird]) |
| 29 | + left = leftThird; |
| 30 | + else |
| 31 | + right = rightThird; |
| 32 | + } |
| 33 | + |
| 34 | + return Math.floor((left + right) / 2); |
31 | 35 | }
|
32 | 36 |
|
33 | 37 | /*
|
34 | 38 | Find maximum of unimodal function func() within [left, right]
|
35 | 39 | To find the minimum, reverse the if/else statement or reverse the comparison.
|
36 | 40 | */
|
37 |
| -function ternarySearch(func, left, right, absolutePrecision){ |
38 |
| - while(true){ |
39 |
| - //left and right are the current bounds. the maximum is between them |
40 |
| - if(Math.abs(right - left) < absolutePrecision){ |
41 |
| - return Math.floor((left + right)/2); |
42 |
| - } |
43 |
| - |
44 |
| - var leftThird = left + (right - left)/3; |
45 |
| - var rightThird = right - (right - left)/3; |
46 |
| - |
47 |
| - if(func(leftThird) < func(rightThird)) |
48 |
| - left = leftThird; |
49 |
| - else |
50 |
| - right = rightThird; |
51 |
| - } |
| 41 | +function ternarySearch(func, left, right, absolutePrecision) { |
| 42 | + while (true) { |
| 43 | + //left and right are the current bounds. the maximum is between them |
| 44 | + if (Math.abs(right - left) < absolutePrecision) { |
| 45 | + return Math.floor((left + right) / 2); |
| 46 | + } |
| 47 | + |
| 48 | + var leftThird = left + (right - left) / 3; |
| 49 | + var rightThird = right - (right - left) / 3; |
| 50 | + |
| 51 | + if (func(leftThird) < func(rightThird)) |
| 52 | + left = leftThird; |
| 53 | + else |
| 54 | + right = rightThird; |
| 55 | + } |
52 | 56 | }
|
53 | 57 |
|
54 | 58 | /*
|
55 | 59 | Recursive Ternary Search Implementation
|
56 | 60 | */
|
57 | 61 |
|
58 |
| -function ternarySearchRecursive(func, left, right, absolutePrecision){ |
| 62 | +function ternarySearchRecursive(func, left, right, absolutePrecision) { |
59 | 63 |
|
60 |
| - //left and right are the current bounds. the maximum is between them |
61 |
| - if(Math.abs(right - left) < absolutePrecision) |
62 |
| - return Math.floor((left + right)/2); |
| 64 | + //left and right are the current bounds. the maximum is between them |
| 65 | + if (Math.abs(right - left) < absolutePrecision) |
| 66 | + return Math.floor((left + right) / 2); |
63 | 67 |
|
64 |
| - var leftThird = (2*left + right)/3; |
65 |
| - var rightThird = (left + 2*right)/3; |
| 68 | + var leftThird = (2 * left + right) / 3; |
| 69 | + var rightThird = (left + 2 * right) / 3; |
66 | 70 |
|
67 |
| - if(func(leftThird) < func(rightThird)) |
68 |
| - return ternarySearch(func, leftThird, right, absolutePrecision); |
69 |
| - else |
70 |
| - return ternarySearch(func, left, rightThird, absolutePrecision); |
| 71 | + if (func(leftThird) < func(rightThird)) |
| 72 | + return ternarySearch(func, leftThird, right, absolutePrecision); |
| 73 | + else |
| 74 | + return ternarySearch(func, left, rightThird, absolutePrecision); |
71 | 75 | }
|
72 | 76 |
|
73 | 77 |
|
74 | 78 |
|
75 |
| -/********************* Testing Ternary Search Implementation ***********************/ |
| 79 | +/********************* Testing Ternary Search Implementations ***********************/ |
76 | 80 |
|
77 | 81 | // This list must be sorted. If it is not given as sorted, sort it first, then call the binarySearch method
|
78 | 82 | var testList = [1, 50, 20, 10, 2, 1];
|
79 | 83 | var index = simpleTernarySearch(testList);
|
80 | 84 | console.log(testList[index]);
|
81 | 85 |
|
82 |
| -var func = function(x){ |
83 |
| - return (-1*1*x*x + 2*x +3); // (-a*x*x + b*x + c) is an unimodal function, here a = 1, b = 2, c = 3 |
| 86 | +var func = function(x) { |
| 87 | + return (-1 * 1 * x * x + 2 * x + 3); // (-a*x*x + b*x + c) is an unimodal function, here a = 1, b = 2, c = 3 |
84 | 88 | };
|
85 | 89 |
|
86 | 90 | result = ternarySearch(func, 0, 1, 1e-6);
|
|
0 commit comments