Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update ternary_search.py #3055

Open
wants to merge 2 commits into
base: master
from
Open

Update ternary_search.py #3055

wants to merge 2 commits into from

Conversation

@zyrch
Copy link

@zyrch zyrch commented Oct 8, 2020

Describe your change:

Reduces the overall complexity of the algorithm for discrete searches (like in a list)

  • Add an algorithm?
  • Fix a bug or typo in an existing algorithm?
  • Documentation change?

Checklist:

  • I have read CONTRIBUTING.md.
  • This pull request is all my own work -- I have not plagiarized.
  • I know that pull requests will not be merged if they fail the automated tests.
  • This PR only changes one algorithm file. To ease review, please open separate PRs for separate algorithms.
  • All new Python files are placed inside an existing directory.
  • All filenames are in all lowercase characters with no spaces or dashes.
  • All functions and variable names follow Python naming conventions.
  • All function parameters and return values are annotated with Python type hints.
  • All functions have doctests that pass the automated testing.
  • All new algorithms have a URL in its comments that points to Wikipedia or other similar explanation.
  • If this pull request resolves one or more open issues then the commit message contains Fixes: #{$ISSUE_NO}.
Copy link

@peteryao7 peteryao7 left a comment

The changes don't make the functions ternary search anymore.

oneThird = (left + right) / 3 + 1
twoThird = 2 * (left + right) / 3 + 1
oneThird = (left + right) / 2 - 1
twoThird = (left + right) / 2 + 1

This comment has been minimized.

@peteryao7

peteryao7 Oct 8, 2020

Ternary search is a divide and conquer algorithm like binary search that's supposed to split the search space into three equal portions. Here, you're splitting it into two halves and the middle element as the second third.

Using floating point division / over integer division // is causing an entirely different bug, but the index calculations themselves are fine.

Another way to calculate oneThird and twoThird that prevents overflow problems in other languages is by doing it this way:
oneThird = left + (right - left) // 3
twoThird = right - (right - left) // 3

This comment has been minimized.

@zyrch

zyrch Oct 8, 2020
Author

By dividing the search space into three in ternary search we are able to find the minimum or maximum of convex functions, (if it is not convex then binary search is directly applicable). Now comparing three values in the search space allows us to eliminate one portion at a time. Now to increase the efficiency of the program we can decrease the distance two intervals and still get the same result, this method is also known as dichotomous search.

This comment has been minimized.

@peteryao7

peteryao7 Oct 8, 2020

Binary and ternary search are examples of dichotomous search. What ternary search lets you do over binary search is omit two sections, or 2/3, of the search space on each iteration (as opposed to 1/2 in binary search), which is correctly done at the end of the loop:

elif target < A[oneThird]:
    right = oneThird - 1
elif A[twoThird] < target:
    left = twoThird + 1
else:
    left = oneThird + 1
    right = twoThird - 1

The goal of the function is simply to find a specified value, so binary search will suffice, but by changing how the boundaries are calculated and changing the time complexity to O(log2(n)), you implemented binary search, not ternary search.

Also, even though they're very similar, O(log2(n)) is less efficient than O(log3(n)).

This comment has been minimized.

@zyrch

zyrch Oct 8, 2020
Author

You are correct I just realized we are searching in a sorted array, and my method is a better only in the case when ternary search is used to min or max of convex functions or data sets.

oneThird = (left + right) / 3 + 1
twoThird = 2 * (left + right) / 3 + 1
oneThird = (left + right) / 2 - 1
twoThird = (left + right) / 2 + 1

This comment has been minimized.

@peteryao7

peteryao7 Oct 8, 2020

Same as the iterative change above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

2 participants
You can’t perform that action at this time.