From e30925666d1179e9af84de4365e8bbe4d8e6cc6a Mon Sep 17 00:00:00 2001 From: Rejoan Sardar Date: Thu, 6 Mar 2025 01:47:48 +0530 Subject: [PATCH 1/3] feat: added maximum_subarray_sum --- .../linear_data_structures/algorithms.rst | 4 +- .../linear_data_structures/__init__.py | 3 +- .../linear_data_structures/algorithms.py | 61 ++++++++++++++++++- .../tests/test_algorithms.py | 2 +- .../utils/tests/test_code_quality.py | 2 +- 5 files changed, 67 insertions(+), 5 deletions(-) diff --git a/docs/source/pydatastructs/linear_data_structures/algorithms.rst b/docs/source/pydatastructs/linear_data_structures/algorithms.rst index 7ab521cfd..073cc28cc 100644 --- a/docs/source/pydatastructs/linear_data_structures/algorithms.rst +++ b/docs/source/pydatastructs/linear_data_structures/algorithms.rst @@ -45,4 +45,6 @@ Algorithms .. autofunction:: pydatastructs.jump_search -.. autofunction:: pydatastructs.intro_sort \ No newline at end of file +.. autofunction:: pydatastructs.intro_sort + +.. autofunction:: pydatastructs.maximum_subarray_sum \ No newline at end of file diff --git a/pydatastructs/linear_data_structures/__init__.py b/pydatastructs/linear_data_structures/__init__.py index 057adc169..87e4574a7 100644 --- a/pydatastructs/linear_data_structures/__init__.py +++ b/pydatastructs/linear_data_structures/__init__.py @@ -47,6 +47,7 @@ jump_search, selection_sort, insertion_sort, - intro_sort + intro_sort, + maximum_subarray_sum ) __all__.extend(algorithms.__all__) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 792bce855..71323d329 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -30,7 +30,8 @@ 'jump_search', 'selection_sort', 'insertion_sort', - 'intro_sort' + 'intro_sort', + 'maximum_subarray_sum' ] def _merge(array, sl, el, sr, er, end, comp): @@ -1850,3 +1851,61 @@ def partition(array, lower, upper): intro_sort(array, start=p+1, end=upper, maxdepth=maxdepth-1, ins_threshold=ins_threshold) return array + +def maximum_subarray_sum(array, **kwargs): + """ + Finds the maximum subarray sum of the given array. + Parameters + ========== + array: OneDimensionalArray + The array for which the maximum subarray sum + has to be found. + start: int + The starting index of the portion + which is to be considered. + Optional, by default 0 + end: int + The ending index of the portion which + is to be considered. + Optional, by default the index + of the last position filled. + comp: lambda/function + The comparator which is to be used + for performing comparisons. + Optional, by default, less than or + equal to is used for comparing two + values. + backend: pydatastructs.Backend + The backend to be used. + Optional, by default, the best available + backend is used. + Returns + ======= + output: int + The maximum subarray sum. + Examples + ======== + >>> from pydatastructs import OneDimensionalArray as ODA, maximum_subarray_sum + >>> arr = ODA(int, [-2, 1, -3, 4, -1, 2, 1, -5, 4]) + >>> maximum_subarray_sum(arr) + 6 + >>> arr = ODA(int, [1, 2, 3, 4, 5]) + >>> maximum_subarray_sum(arr) + 15 + References + ========== + .. [1] https://en.wikipedia.org/wiki/Maximum_subarray_problem + """ + raise_if_backend_is_not_python( + maximum_subarray_sum, kwargs.get('backend', Backend.PYTHON)) + start = kwargs.get('start', 0) + end = kwargs.get('end', len(array) - 1) + comp = kwargs.get('comp', lambda u, v: u <= v) + + max_sum = array[start] + max_ending_here = array[start] + for i in range(start + 1, end + 1): + max_ending_here = max(array[i], max_ending_here + array[i]) + max_sum = max(max_sum, max_ending_here) + + return max_sum diff --git a/pydatastructs/linear_data_structures/tests/test_algorithms.py b/pydatastructs/linear_data_structures/tests/test_algorithms.py index 46609544b..52b570db2 100644 --- a/pydatastructs/linear_data_structures/tests/test_algorithms.py +++ b/pydatastructs/linear_data_structures/tests/test_algorithms.py @@ -5,7 +5,7 @@ cocktail_shaker_sort, quick_sort, longest_common_subsequence, is_ordered, upper_bound, lower_bound, longest_increasing_subsequence, next_permutation, prev_permutation, bubble_sort, linear_search, binary_search, jump_search, - selection_sort, insertion_sort, intro_sort, Backend) + selection_sort, insertion_sort, intro_sort, maximum_subarray_sum, Backend) from pydatastructs.utils.raises_util import raises import random diff --git a/pydatastructs/utils/tests/test_code_quality.py b/pydatastructs/utils/tests/test_code_quality.py index eafa80be1..215d453f2 100644 --- a/pydatastructs/utils/tests/test_code_quality.py +++ b/pydatastructs/utils/tests/test_code_quality.py @@ -174,7 +174,7 @@ def _apis(): pyds.Trie, pyds.TrieNode, pyds.SkipList, pyds.RangeQueryStatic, pyds.RangeQueryDynamic, pyds.SparseTable, pyds.miscellaneous_data_structures.segment_tree.OneDimensionalArraySegmentTree, pyds.bubble_sort, pyds.linear_search, pyds.binary_search, pyds.jump_search, - pyds.selection_sort, pyds.insertion_sort, pyds.quick_sort, pyds.intro_sort] + pyds.selection_sort, pyds.insertion_sort, pyds.quick_sort, pyds.intro_sort, pyds.maximum_subarray_sum] def test_public_api(): pyds = pydatastructs From b2a2dc6d9425691b5863b1dad9900dd9e1d1dc73 Mon Sep 17 00:00:00 2001 From: Rejoan Sardar Date: Thu, 6 Mar 2025 02:14:54 +0530 Subject: [PATCH 2/3] feat: added maximum_subarray_sum --- .../linear_data_structures/algorithms.rst | 2 +- .../linear_data_structures/__init__.py | 2 +- .../linear_data_structures/algorithms.py | 29 +++++++++++-------- .../tests/test_algorithms.py | 2 +- .../utils/tests/test_code_quality.py | 2 +- 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/docs/source/pydatastructs/linear_data_structures/algorithms.rst b/docs/source/pydatastructs/linear_data_structures/algorithms.rst index 073cc28cc..ae1e2db74 100644 --- a/docs/source/pydatastructs/linear_data_structures/algorithms.rst +++ b/docs/source/pydatastructs/linear_data_structures/algorithms.rst @@ -47,4 +47,4 @@ Algorithms .. autofunction:: pydatastructs.intro_sort -.. autofunction:: pydatastructs.maximum_subarray_sum \ No newline at end of file +.. autofunction:: pydatastructs.maximum_subarray_sum_1 \ No newline at end of file diff --git a/pydatastructs/linear_data_structures/__init__.py b/pydatastructs/linear_data_structures/__init__.py index 87e4574a7..000001b5a 100644 --- a/pydatastructs/linear_data_structures/__init__.py +++ b/pydatastructs/linear_data_structures/__init__.py @@ -48,6 +48,6 @@ selection_sort, insertion_sort, intro_sort, - maximum_subarray_sum + maximum_subarray_sum_1 ) __all__.extend(algorithms.__all__) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 71323d329..5e00d26e7 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -31,7 +31,7 @@ 'selection_sort', 'insertion_sort', 'intro_sort', - 'maximum_subarray_sum' + 'maximum_subarray_sum_1' ] def _merge(array, sl, el, sr, er, end, comp): @@ -1852,9 +1852,10 @@ def partition(array, lower, upper): return array -def maximum_subarray_sum(array, **kwargs): +def maximum_subarray_sum_1(array, **kwargs): """ - Finds the maximum subarray sum of the given array. + Finds the maximum subarray sum of the given array using a brute force approach. + Parameters ========== array: OneDimensionalArray @@ -1879,33 +1880,37 @@ def maximum_subarray_sum(array, **kwargs): The backend to be used. Optional, by default, the best available backend is used. + Returns ======= output: int The maximum subarray sum. + Examples ======== - >>> from pydatastructs import OneDimensionalArray as ODA, maximum_subarray_sum + >>> from pydatastructs import OneDimensionalArray as ODA, maximum_subarray_sum_1 >>> arr = ODA(int, [-2, 1, -3, 4, -1, 2, 1, -5, 4]) - >>> maximum_subarray_sum(arr) + >>> maximum_subarray_sum_1(arr) 6 >>> arr = ODA(int, [1, 2, 3, 4, 5]) - >>> maximum_subarray_sum(arr) + >>> maximum_subarray_sum_1(arr) 15 + References ========== .. [1] https://en.wikipedia.org/wiki/Maximum_subarray_problem """ raise_if_backend_is_not_python( - maximum_subarray_sum, kwargs.get('backend', Backend.PYTHON)) + maximum_subarray_sum_1, kwargs.get('backend', Backend.PYTHON)) start = kwargs.get('start', 0) end = kwargs.get('end', len(array) - 1) comp = kwargs.get('comp', lambda u, v: u <= v) - max_sum = array[start] - max_ending_here = array[start] - for i in range(start + 1, end + 1): - max_ending_here = max(array[i], max_ending_here + array[i]) - max_sum = max(max_sum, max_ending_here) + max_sum = float('-inf') + for i in range(start, end + 1): + curr_sum = 0 + for j in range(i, end + 1): + curr_sum += array[j] + max_sum = max(max_sum, curr_sum) return max_sum diff --git a/pydatastructs/linear_data_structures/tests/test_algorithms.py b/pydatastructs/linear_data_structures/tests/test_algorithms.py index 52b570db2..fb19c76b0 100644 --- a/pydatastructs/linear_data_structures/tests/test_algorithms.py +++ b/pydatastructs/linear_data_structures/tests/test_algorithms.py @@ -5,7 +5,7 @@ cocktail_shaker_sort, quick_sort, longest_common_subsequence, is_ordered, upper_bound, lower_bound, longest_increasing_subsequence, next_permutation, prev_permutation, bubble_sort, linear_search, binary_search, jump_search, - selection_sort, insertion_sort, intro_sort, maximum_subarray_sum, Backend) + selection_sort, insertion_sort, intro_sort, maximum_subarray_sum_1, Backend) from pydatastructs.utils.raises_util import raises import random diff --git a/pydatastructs/utils/tests/test_code_quality.py b/pydatastructs/utils/tests/test_code_quality.py index 215d453f2..14dfe1949 100644 --- a/pydatastructs/utils/tests/test_code_quality.py +++ b/pydatastructs/utils/tests/test_code_quality.py @@ -174,7 +174,7 @@ def _apis(): pyds.Trie, pyds.TrieNode, pyds.SkipList, pyds.RangeQueryStatic, pyds.RangeQueryDynamic, pyds.SparseTable, pyds.miscellaneous_data_structures.segment_tree.OneDimensionalArraySegmentTree, pyds.bubble_sort, pyds.linear_search, pyds.binary_search, pyds.jump_search, - pyds.selection_sort, pyds.insertion_sort, pyds.quick_sort, pyds.intro_sort, pyds.maximum_subarray_sum] + pyds.selection_sort, pyds.insertion_sort, pyds.quick_sort, pyds.intro_sort, pyds.maximum_subarray_sum_1] def test_public_api(): pyds = pydatastructs From e0c3df16be1375036105ccd62549540e739eafe1 Mon Sep 17 00:00:00 2001 From: Rejoan Sardar Date: Thu, 6 Mar 2025 02:32:13 +0530 Subject: [PATCH 3/3] feat: added maximum_subarray_sum --- pydatastructs/linear_data_structures/algorithms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydatastructs/linear_data_structures/algorithms.py b/pydatastructs/linear_data_structures/algorithms.py index 5e00d26e7..0f2661201 100644 --- a/pydatastructs/linear_data_structures/algorithms.py +++ b/pydatastructs/linear_data_structures/algorithms.py @@ -1807,7 +1807,7 @@ def intro_sort(array, **kwargs) -> Array: intro_sort, kwargs.get('backend', Backend.PYTHON)) # Always sorts in increasing order, this is because of - # heapsort's limitation + # heapsort's limitatio comp = lambda u, v: u <= v lower = kwargs.get('start', 0) upper = kwargs.get('end', len(array) - 1)