Merge branch 'TheAlgorithms:master' into master

This commit is contained in:
Maxim Smolskiy 2024-05-06 22:36:48 +03:00 committed by GitHub
commit 1e66d4be16
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 59 additions and 31 deletions

View File

@ -1,5 +1,6 @@
from __future__ import annotations from __future__ import annotations
from abc import abstractmethod
from math import pi from math import pi
from typing import Protocol from typing import Protocol
@ -8,6 +9,7 @@ import numpy as np
class FilterType(Protocol): class FilterType(Protocol):
@abstractmethod
def process(self, sample: float) -> float: def process(self, sample: float) -> float:
""" """
Calculate y[n] Calculate y[n]
@ -15,7 +17,6 @@ class FilterType(Protocol):
>>> issubclass(FilterType, Protocol) >>> issubclass(FilterType, Protocol)
True True
""" """
return 0.0
def get_bounds( def get_bounds(

View File

@ -1,4 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from abc import abstractmethod
from .number_theory.prime_numbers import next_prime from .number_theory.prime_numbers import next_prime
@ -173,6 +175,7 @@ class HashTable:
self.values[key] = data self.values[key] = data
self._keys[key] = data self._keys[key] = data
@abstractmethod
def _collision_resolution(self, key, data=None): def _collision_resolution(self, key, data=None):
""" """
This method is a type of open addressing which is used for handling collision. This method is a type of open addressing which is used for handling collision.

View File

@ -11,7 +11,7 @@ class QuadraticProbing(HashTable):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
def _collision_resolution(self, key, data=None): def _collision_resolution(self, key, data=None): # noqa: ARG002
""" """
Quadratic probing is an open addressing scheme used for resolving Quadratic probing is an open addressing scheme used for resolving
collisions in hash table. collisions in hash table.

View File

@ -76,11 +76,8 @@ max-complexity = 17 # default: 10
[tool.ruff.lint.per-file-ignores] [tool.ruff.lint.per-file-ignores]
"arithmetic_analysis/newton_raphson.py" = ["PGH001"] "arithmetic_analysis/newton_raphson.py" = ["PGH001"]
"audio_filters/show_response.py" = ["ARG002"]
"data_structures/binary_tree/binary_search_tree_recursive.py" = ["BLE001"] "data_structures/binary_tree/binary_search_tree_recursive.py" = ["BLE001"]
"data_structures/binary_tree/treap.py" = ["SIM114"] "data_structures/binary_tree/treap.py" = ["SIM114"]
"data_structures/hashing/hash_table.py" = ["ARG002"]
"data_structures/hashing/quadratic_probing.py" = ["ARG002"]
"data_structures/hashing/tests/test_hash_map.py" = ["BLE001"] "data_structures/hashing/tests/test_hash_map.py" = ["BLE001"]
"data_structures/heap/max_heap.py" = ["SIM114"] "data_structures/heap/max_heap.py" = ["SIM114"]
"graphs/minimum_spanning_tree_prims.py" = ["SIM114"] "graphs/minimum_spanning_tree_prims.py" = ["SIM114"]

View File

@ -11,11 +11,11 @@ They are synchronized with locks and message passing but other forms of
synchronization could be used. synchronization could be used.
""" """
from multiprocessing import Lock, Pipe, Process import multiprocessing as mp
# lock used to ensure that two processes do not access a pipe at the same time # lock used to ensure that two processes do not access a pipe at the same time
# NOTE This breaks testing on build runner. May work better locally # NOTE This breaks testing on build runner. May work better locally
# process_lock = Lock() # process_lock = mp.Lock()
""" """
The function run by the processes that sorts the list The function run by the processes that sorts the list
@ -29,8 +29,17 @@ resultPipe = the pipe used to send results back to main
""" """
def oe_process(position, value, l_send, r_send, lr_cv, rr_cv, result_pipe): def oe_process(
process_lock = Lock() position,
value,
l_send,
r_send,
lr_cv,
rr_cv,
result_pipe,
multiprocessing_context,
):
process_lock = multiprocessing_context.Lock()
# we perform n swaps since after n swaps we know we are sorted # we perform n swaps since after n swaps we know we are sorted
# we *could* stop early if we are sorted already, but it takes as long to # we *could* stop early if we are sorted already, but it takes as long to
@ -38,27 +47,23 @@ def oe_process(position, value, l_send, r_send, lr_cv, rr_cv, result_pipe):
for i in range(10): for i in range(10):
if (i + position) % 2 == 0 and r_send is not None: if (i + position) % 2 == 0 and r_send is not None:
# send your value to your right neighbor # send your value to your right neighbor
process_lock.acquire() with process_lock:
r_send[1].send(value) r_send[1].send(value)
process_lock.release()
# receive your right neighbor's value # receive your right neighbor's value
process_lock.acquire() with process_lock:
temp = rr_cv[0].recv() temp = rr_cv[0].recv()
process_lock.release()
# take the lower value since you are on the left # take the lower value since you are on the left
value = min(value, temp) value = min(value, temp)
elif (i + position) % 2 != 0 and l_send is not None: elif (i + position) % 2 != 0 and l_send is not None:
# send your value to your left neighbor # send your value to your left neighbor
process_lock.acquire() with process_lock:
l_send[1].send(value) l_send[1].send(value)
process_lock.release()
# receive your left neighbor's value # receive your left neighbor's value
process_lock.acquire() with process_lock:
temp = lr_cv[0].recv() temp = lr_cv[0].recv()
process_lock.release()
# take the higher value since you are on the right # take the higher value since you are on the right
value = max(value, temp) value = max(value, temp)
@ -94,39 +99,60 @@ def odd_even_transposition(arr):
>>> odd_even_transposition(unsorted_list) == sorted(unsorted_list + [1]) >>> odd_even_transposition(unsorted_list) == sorted(unsorted_list + [1])
False False
""" """
# spawn method is considered safer than fork
multiprocessing_context = mp.get_context("spawn")
process_array_ = [] process_array_ = []
result_pipe = [] result_pipe = []
# initialize the list of pipes where the values will be retrieved # initialize the list of pipes where the values will be retrieved
for _ in arr: for _ in arr:
result_pipe.append(Pipe()) result_pipe.append(multiprocessing_context.Pipe())
# creates the processes # creates the processes
# the first and last process only have one neighbor so they are made outside # the first and last process only have one neighbor so they are made outside
# of the loop # of the loop
temp_rs = Pipe() temp_rs = multiprocessing_context.Pipe()
temp_rr = Pipe() temp_rr = multiprocessing_context.Pipe()
process_array_.append( process_array_.append(
Process( multiprocessing_context.Process(
target=oe_process, target=oe_process,
args=(0, arr[0], None, temp_rs, None, temp_rr, result_pipe[0]), args=(
0,
arr[0],
None,
temp_rs,
None,
temp_rr,
result_pipe[0],
multiprocessing_context,
),
) )
) )
temp_lr = temp_rs temp_lr = temp_rs
temp_ls = temp_rr temp_ls = temp_rr
for i in range(1, len(arr) - 1): for i in range(1, len(arr) - 1):
temp_rs = Pipe() temp_rs = multiprocessing_context.Pipe()
temp_rr = Pipe() temp_rr = multiprocessing_context.Pipe()
process_array_.append( process_array_.append(
Process( multiprocessing_context.Process(
target=oe_process, target=oe_process,
args=(i, arr[i], temp_ls, temp_rs, temp_lr, temp_rr, result_pipe[i]), args=(
i,
arr[i],
temp_ls,
temp_rs,
temp_lr,
temp_rr,
result_pipe[i],
multiprocessing_context,
),
) )
) )
temp_lr = temp_rs temp_lr = temp_rs
temp_ls = temp_rr temp_ls = temp_rr
process_array_.append( process_array_.append(
Process( multiprocessing_context.Process(
target=oe_process, target=oe_process,
args=( args=(
len(arr) - 1, len(arr) - 1,
@ -136,6 +162,7 @@ def odd_even_transposition(arr):
temp_lr, temp_lr,
None, None,
result_pipe[len(arr) - 1], result_pipe[len(arr) - 1],
multiprocessing_context,
), ),
) )
) )