Skip to content

Commit 427a9d4

Browse files
committed
Ternary search code added
1 parent 02825e3 commit 427a9d4

File tree

3 files changed

+97
-0
lines changed

3 files changed

+97
-0
lines changed

Searching/Ternary Search/README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Ternary Search
2+
3+
**Ternary search** algorithm is a technique in computer science for finding the minimum or maximum of a [unimodal](https://en.wikipedia.org/wiki/Unimodality) function. A ternary search determines either that the minimum or maximum cannot be in the first third of the domain or that it cannot be in the last third of the domain, then repeats on the remaining two-thirds.
4+
Unimodal functions are functions that, have a single highest value.
5+
6+
7+
#### Binary Search vs. Ternary Search
8+
Binary search looks a zero or a specific value in case of monotonic(Non-increasing or non-decreasing) input; ternary search is used to locate an extremum for unimodal(Having a single extremum) inputs.
9+
10+
11+
#### Complexity Analysis
12+
- Average Case - O(logn)
13+
14+
15+
### More on this topic
16+
- https://en.wikipedia.org/wiki/Ternary_search
17+
- https://www.hackerearth.com/practice/algorithms/searching/ternary-search/tutorial/

Searching/Ternary Search/search.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
def simpleTernarySearch(item_list):
2+
"""
3+
Find the maximum value in a strictly increasing and then strictly decreasing list
4+
N.B.- This method won't work if the list does not represent an unimodal function
5+
e.g. if the maximum value present in the first or last index of the list
6+
"""
7+
left, right = 0, len(item_list) - 1
8+
9+
found = False
10+
11+
while left <= right:
12+
if (right - left) < 3: #Here 3 is the smallest range to divide the left and right value
13+
found = True
14+
break
15+
16+
leftThird = left + (right - left) // 3
17+
rightThird = right - (right - left) // 3
18+
19+
#To find the minimum in an unimodal function change the following comparison to >
20+
if item_list[leftThird] < item_list[rightThird]:
21+
left = leftThird
22+
else:
23+
right = rightThird
24+
25+
return (left + right) // 2
26+
27+
28+
def ternarySearch(func, left, right, absolutePrecision):
29+
"""
30+
Find maximum of unimodal function func() within [left, right]
31+
To find the minimum, reverse the if/else statement or reverse the comparison.
32+
"""
33+
while True:
34+
#left and right are the current bounds; the maximum is between them
35+
if abs(right - left) < absolutePrecision:
36+
return (left + right)/2
37+
38+
leftThird = left + (right - left)/3
39+
rightThird = right - (right - left)/3
40+
41+
if func(leftThird) < func(rightThird):
42+
left = leftThird
43+
else:
44+
right = rightThird
45+
46+
47+
def ternarySearchRecursive(func, left, right, absolutePrecision):
48+
"""
49+
left and right are the current bounds. the maximum is between them
50+
"""
51+
if abs(right - left) < absolutePrecision:
52+
return (left + right)/2
53+
54+
leftThird = (2*left + right)/3
55+
rightThird = (left + 2*right)/3
56+
57+
if func(leftThird) < func(rightThird):
58+
return ternarySearch(func, leftThird, right, absolutePrecision)
59+
else:
60+
return ternarySearch(func, left, rightThird, absolutePrecision)

Searching/Ternary Search/test.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from search import *
2+
3+
def main():
4+
# This list must be sorted. If it is not given as sorted, sort it first, then call the binarySearch method
5+
testlist = [1, 50, 20, 10, 2, 1]
6+
index = simpleTernarySearch(testlist)
7+
print(testlist[index])
8+
9+
result = ternarySearch(func, 0, 1, 1e-6)
10+
print(func(result))
11+
12+
result = ternarySearchRecursive(func, 0, 1, 1e-6)
13+
print(func(result))
14+
15+
16+
def func(x):
17+
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
18+
19+
if __name__ == '__main__':
20+
main()

0 commit comments

Comments
 (0)