mirror of
https://github.com/TheAlgorithms/Python.git
synced 2025-01-18 08:17:01 +00:00
Fix sphinx/build_docs warnings for dynamic_programming (#12484)
* Fix sphinx/build_docs warnings for dynamic_programming * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix * Fix * Fix * Fix * Fix * Fix --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
493a7c153c
commit
7fa9b4bf1b
|
@ -9,8 +9,9 @@ from __future__ import annotations
|
|||
def all_construct(target: str, word_bank: list[str] | None = None) -> list[list[str]]:
|
||||
"""
|
||||
returns the list containing all the possible
|
||||
combinations a string(target) can be constructed from
|
||||
the given list of substrings(word_bank)
|
||||
combinations a string(`target`) can be constructed from
|
||||
the given list of substrings(`word_bank`)
|
||||
|
||||
>>> all_construct("hello", ["he", "l", "o"])
|
||||
[['he', 'l', 'l', 'o']]
|
||||
>>> all_construct("purple",["purp","p","ur","le","purpl"])
|
||||
|
|
|
@ -1,22 +1,23 @@
|
|||
"""
|
||||
Question:
|
||||
You are given an array of distinct integers and you have to tell how many
|
||||
different ways of selecting the elements from the array are there such that
|
||||
the sum of chosen elements is equal to the target number tar.
|
||||
You are given an array of distinct integers and you have to tell how many
|
||||
different ways of selecting the elements from the array are there such that
|
||||
the sum of chosen elements is equal to the target number tar.
|
||||
|
||||
Example
|
||||
|
||||
Input:
|
||||
N = 3
|
||||
target = 5
|
||||
array = [1, 2, 5]
|
||||
* N = 3
|
||||
* target = 5
|
||||
* array = [1, 2, 5]
|
||||
|
||||
Output:
|
||||
9
|
||||
9
|
||||
|
||||
Approach:
|
||||
The basic idea is to go over recursively to find the way such that the sum
|
||||
of chosen elements is “tar”. For every element, we have two choices
|
||||
The basic idea is to go over recursively to find the way such that the sum
|
||||
of chosen elements is `target`. For every element, we have two choices
|
||||
|
||||
1. Include the element in our set of chosen elements.
|
||||
2. Don't include the element in our set of chosen elements.
|
||||
"""
|
||||
|
|
|
@ -3,11 +3,12 @@
|
|||
|
||||
def fizz_buzz(number: int, iterations: int) -> str:
|
||||
"""
|
||||
Plays FizzBuzz.
|
||||
Prints Fizz if number is a multiple of 3.
|
||||
Prints Buzz if its a multiple of 5.
|
||||
Prints FizzBuzz if its a multiple of both 3 and 5 or 15.
|
||||
Else Prints The Number Itself.
|
||||
| Plays FizzBuzz.
|
||||
| Prints Fizz if number is a multiple of ``3``.
|
||||
| Prints Buzz if its a multiple of ``5``.
|
||||
| Prints FizzBuzz if its a multiple of both ``3`` and ``5`` or ``15``.
|
||||
| Else Prints The Number Itself.
|
||||
|
||||
>>> fizz_buzz(1,7)
|
||||
'1 2 Fizz 4 Buzz Fizz 7 '
|
||||
>>> fizz_buzz(1,0)
|
||||
|
|
|
@ -11,7 +11,7 @@ def mf_knapsack(i, wt, val, j):
|
|||
"""
|
||||
This code involves the concept of memory functions. Here we solve the subproblems
|
||||
which are needed unlike the below example
|
||||
F is a 2D array with -1s filled up
|
||||
F is a 2D array with ``-1`` s filled up
|
||||
"""
|
||||
global f # a global dp table for knapsack
|
||||
if f[i][j] < 0:
|
||||
|
@ -45,22 +45,24 @@ def knapsack_with_example_solution(w: int, wt: list, val: list):
|
|||
the several possible optimal subsets.
|
||||
|
||||
Parameters
|
||||
---------
|
||||
----------
|
||||
|
||||
W: int, the total maximum weight for the given knapsack problem.
|
||||
wt: list, the vector of weights for all items where wt[i] is the weight
|
||||
of the i-th item.
|
||||
val: list, the vector of values for all items where val[i] is the value
|
||||
of the i-th item
|
||||
* `w`: int, the total maximum weight for the given knapsack problem.
|
||||
* `wt`: list, the vector of weights for all items where ``wt[i]`` is the weight
|
||||
of the ``i``-th item.
|
||||
* `val`: list, the vector of values for all items where ``val[i]`` is the value
|
||||
of the ``i``-th item
|
||||
|
||||
Returns
|
||||
-------
|
||||
optimal_val: float, the optimal value for the given knapsack problem
|
||||
example_optional_set: set, the indices of one of the optimal subsets
|
||||
|
||||
* `optimal_val`: float, the optimal value for the given knapsack problem
|
||||
* `example_optional_set`: set, the indices of one of the optimal subsets
|
||||
which gave rise to the optimal value.
|
||||
|
||||
Examples
|
||||
-------
|
||||
--------
|
||||
|
||||
>>> knapsack_with_example_solution(10, [1, 3, 5, 2], [10, 20, 100, 22])
|
||||
(142, {2, 3, 4})
|
||||
>>> knapsack_with_example_solution(6, [4, 3, 2, 3], [3, 2, 4, 4])
|
||||
|
@ -104,19 +106,19 @@ def _construct_solution(dp: list, wt: list, i: int, j: int, optimal_set: set):
|
|||
a filled DP table and the vector of weights
|
||||
|
||||
Parameters
|
||||
---------
|
||||
----------
|
||||
|
||||
dp: list of list, the table of a solved integer weight dynamic programming problem
|
||||
|
||||
wt: list or tuple, the vector of weights of the items
|
||||
i: int, the index of the item under consideration
|
||||
j: int, the current possible maximum weight
|
||||
optimal_set: set, the optimal subset so far. This gets modified by the function.
|
||||
* `dp`: list of list, the table of a solved integer weight dynamic programming
|
||||
problem
|
||||
* `wt`: list or tuple, the vector of weights of the items
|
||||
* `i`: int, the index of the item under consideration
|
||||
* `j`: int, the current possible maximum weight
|
||||
* `optimal_set`: set, the optimal subset so far. This gets modified by the function.
|
||||
|
||||
Returns
|
||||
-------
|
||||
None
|
||||
|
||||
``None``
|
||||
"""
|
||||
# for the current item i at a maximum weight j to be part of an optimal subset,
|
||||
# the optimal value at (i, j) must be greater than the optimal value at (i-1, j).
|
||||
|
|
|
@ -1,15 +1,19 @@
|
|||
"""
|
||||
Longest Common Substring Problem Statement: Given two sequences, find the
|
||||
longest common substring present in both of them. A substring is
|
||||
necessarily continuous.
|
||||
Example: "abcdef" and "xabded" have two longest common substrings, "ab" or "de".
|
||||
Therefore, algorithm should return any one of them.
|
||||
Longest Common Substring Problem Statement:
|
||||
Given two sequences, find the
|
||||
longest common substring present in both of them. A substring is
|
||||
necessarily continuous.
|
||||
|
||||
Example:
|
||||
``abcdef`` and ``xabded`` have two longest common substrings, ``ab`` or ``de``.
|
||||
Therefore, algorithm should return any one of them.
|
||||
"""
|
||||
|
||||
|
||||
def longest_common_substring(text1: str, text2: str) -> str:
|
||||
"""
|
||||
Finds the longest common substring between two strings.
|
||||
|
||||
>>> longest_common_substring("", "")
|
||||
''
|
||||
>>> longest_common_substring("a","")
|
||||
|
|
|
@ -4,11 +4,13 @@ Author : Mehdi ALAOUI
|
|||
This is a pure Python implementation of Dynamic Programming solution to the longest
|
||||
increasing subsequence of a given sequence.
|
||||
|
||||
The problem is :
|
||||
Given an array, to find the longest and increasing sub-array in that given array and
|
||||
return it.
|
||||
Example: [10, 22, 9, 33, 21, 50, 41, 60, 80] as input will return
|
||||
[10, 22, 33, 41, 60, 80] as output
|
||||
The problem is:
|
||||
Given an array, to find the longest and increasing sub-array in that given array and
|
||||
return it.
|
||||
|
||||
Example:
|
||||
``[10, 22, 9, 33, 21, 50, 41, 60, 80]`` as input will return
|
||||
``[10, 22, 33, 41, 60, 80]`` as output
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
@ -17,6 +19,7 @@ from __future__ import annotations
|
|||
def longest_subsequence(array: list[int]) -> list[int]: # This function is recursive
|
||||
"""
|
||||
Some examples
|
||||
|
||||
>>> longest_subsequence([10, 22, 9, 33, 21, 50, 41, 60, 80])
|
||||
[10, 22, 33, 41, 60, 80]
|
||||
>>> longest_subsequence([4, 8, 7, 5, 1, 12, 2, 3, 9])
|
||||
|
|
|
@ -1,42 +1,48 @@
|
|||
"""
|
||||
Find the minimum number of multiplications needed to multiply chain of matrices.
|
||||
Reference: https://www.geeksforgeeks.org/matrix-chain-multiplication-dp-8/
|
||||
| Find the minimum number of multiplications needed to multiply chain of matrices.
|
||||
| Reference: https://www.geeksforgeeks.org/matrix-chain-multiplication-dp-8/
|
||||
|
||||
The algorithm has interesting real-world applications. Example:
|
||||
1. Image transformations in Computer Graphics as images are composed of matrix.
|
||||
2. Solve complex polynomial equations in the field of algebra using least processing
|
||||
The algorithm has interesting real-world applications.
|
||||
|
||||
Example:
|
||||
1. Image transformations in Computer Graphics as images are composed of matrix.
|
||||
2. Solve complex polynomial equations in the field of algebra using least processing
|
||||
power.
|
||||
3. Calculate overall impact of macroeconomic decisions as economic equations involve a
|
||||
3. Calculate overall impact of macroeconomic decisions as economic equations involve a
|
||||
number of variables.
|
||||
4. Self-driving car navigation can be made more accurate as matrix multiplication can
|
||||
4. Self-driving car navigation can be made more accurate as matrix multiplication can
|
||||
accurately determine position and orientation of obstacles in short time.
|
||||
|
||||
Python doctests can be run with the following command:
|
||||
python -m doctest -v matrix_chain_multiply.py
|
||||
Python doctests can be run with the following command::
|
||||
|
||||
Given a sequence arr[] that represents chain of 2D matrices such that the dimension of
|
||||
the ith matrix is arr[i-1]*arr[i].
|
||||
So suppose arr = [40, 20, 30, 10, 30] means we have 4 matrices of dimensions
|
||||
40*20, 20*30, 30*10 and 10*30.
|
||||
python -m doctest -v matrix_chain_multiply.py
|
||||
|
||||
matrix_chain_multiply() returns an integer denoting minimum number of multiplications to
|
||||
multiply the chain.
|
||||
Given a sequence ``arr[]`` that represents chain of 2D matrices such that the dimension
|
||||
of the ``i`` th matrix is ``arr[i-1]*arr[i]``.
|
||||
So suppose ``arr = [40, 20, 30, 10, 30]`` means we have ``4`` matrices of dimensions
|
||||
``40*20``, ``20*30``, ``30*10`` and ``10*30``.
|
||||
|
||||
``matrix_chain_multiply()`` returns an integer denoting minimum number of
|
||||
multiplications to multiply the chain.
|
||||
|
||||
We do not need to perform actual multiplication here.
|
||||
We only need to decide the order in which to perform the multiplication.
|
||||
|
||||
Hints:
|
||||
1. Number of multiplications (ie cost) to multiply 2 matrices
|
||||
of size m*p and p*n is m*p*n.
|
||||
2. Cost of matrix multiplication is associative ie (M1*M2)*M3 != M1*(M2*M3)
|
||||
3. Matrix multiplication is not commutative. So, M1*M2 does not mean M2*M1 can be done.
|
||||
4. To determine the required order, we can try different combinations.
|
||||
1. Number of multiplications (ie cost) to multiply ``2`` matrices
|
||||
of size ``m*p`` and ``p*n`` is ``m*p*n``.
|
||||
2. Cost of matrix multiplication is not associative ie ``(M1*M2)*M3 != M1*(M2*M3)``
|
||||
3. Matrix multiplication is not commutative. So, ``M1*M2`` does not mean ``M2*M1``
|
||||
can be done.
|
||||
4. To determine the required order, we can try different combinations.
|
||||
|
||||
So, this problem has overlapping sub-problems and can be solved using recursion.
|
||||
We use Dynamic Programming for optimal time complexity.
|
||||
|
||||
Example input:
|
||||
arr = [40, 20, 30, 10, 30]
|
||||
output: 26000
|
||||
``arr = [40, 20, 30, 10, 30]``
|
||||
output:
|
||||
``26000``
|
||||
"""
|
||||
|
||||
from collections.abc import Iterator
|
||||
|
@ -50,12 +56,13 @@ def matrix_chain_multiply(arr: list[int]) -> int:
|
|||
Find the minimum number of multiplcations required to multiply the chain of matrices
|
||||
|
||||
Args:
|
||||
arr: The input array of integers.
|
||||
`arr`: The input array of integers.
|
||||
|
||||
Returns:
|
||||
Minimum number of multiplications needed to multiply the chain
|
||||
|
||||
Examples:
|
||||
|
||||
>>> matrix_chain_multiply([1, 2, 3, 4, 3])
|
||||
30
|
||||
>>> matrix_chain_multiply([10])
|
||||
|
@ -66,8 +73,7 @@ def matrix_chain_multiply(arr: list[int]) -> int:
|
|||
722
|
||||
>>> matrix_chain_multiply(list(range(1, 100)))
|
||||
323398
|
||||
|
||||
# >>> matrix_chain_multiply(list(range(1, 251)))
|
||||
>>> # matrix_chain_multiply(list(range(1, 251)))
|
||||
# 2626798
|
||||
"""
|
||||
if len(arr) < 2:
|
||||
|
@ -93,8 +99,10 @@ def matrix_chain_multiply(arr: list[int]) -> int:
|
|||
def matrix_chain_order(dims: list[int]) -> int:
|
||||
"""
|
||||
Source: https://en.wikipedia.org/wiki/Matrix_chain_multiplication
|
||||
|
||||
The dynamic programming solution is faster than cached the recursive solution and
|
||||
can handle larger inputs.
|
||||
|
||||
>>> matrix_chain_order([1, 2, 3, 4, 3])
|
||||
30
|
||||
>>> matrix_chain_order([10])
|
||||
|
@ -105,8 +113,7 @@ def matrix_chain_order(dims: list[int]) -> int:
|
|||
722
|
||||
>>> matrix_chain_order(list(range(1, 100)))
|
||||
323398
|
||||
|
||||
# >>> matrix_chain_order(list(range(1, 251))) # Max before RecursionError is raised
|
||||
>>> # matrix_chain_order(list(range(1, 251))) # Max before RecursionError is raised
|
||||
# 2626798
|
||||
"""
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
def max_product_subarray(numbers: list[int]) -> int:
|
||||
"""
|
||||
Returns the maximum product that can be obtained by multiplying a
|
||||
contiguous subarray of the given integer list `nums`.
|
||||
contiguous subarray of the given integer list `numbers`.
|
||||
|
||||
Example:
|
||||
|
||||
>>> max_product_subarray([2, 3, -2, 4])
|
||||
6
|
||||
>>> max_product_subarray((-2, 0, -1))
|
||||
|
|
|
@ -5,6 +5,7 @@ import sys
|
|||
def minimum_squares_to_represent_a_number(number: int) -> int:
|
||||
"""
|
||||
Count the number of minimum squares to represent a number
|
||||
|
||||
>>> minimum_squares_to_represent_a_number(25)
|
||||
1
|
||||
>>> minimum_squares_to_represent_a_number(37)
|
||||
|
|
|
@ -1,23 +1,25 @@
|
|||
"""
|
||||
Regex matching check if a text matches pattern or not.
|
||||
Pattern:
|
||||
'.' Matches any single character.
|
||||
'*' Matches zero or more of the preceding element.
|
||||
|
||||
1. ``.`` Matches any single character.
|
||||
2. ``*`` Matches zero or more of the preceding element.
|
||||
|
||||
More info:
|
||||
https://medium.com/trick-the-interviwer/regular-expression-matching-9972eb74c03
|
||||
"""
|
||||
|
||||
|
||||
def recursive_match(text: str, pattern: str) -> bool:
|
||||
"""
|
||||
r"""
|
||||
Recursive matching algorithm.
|
||||
|
||||
Time complexity: O(2 ^ (|text| + |pattern|))
|
||||
Space complexity: Recursion depth is O(|text| + |pattern|).
|
||||
| Time complexity: O(2^(\|text\| + \|pattern\|))
|
||||
| Space complexity: Recursion depth is O(\|text\| + \|pattern\|).
|
||||
|
||||
:param text: Text to match.
|
||||
:param pattern: Pattern to match.
|
||||
:return: True if text matches pattern, False otherwise.
|
||||
:return: ``True`` if `text` matches `pattern`, ``False`` otherwise.
|
||||
|
||||
>>> recursive_match('abc', 'a.c')
|
||||
True
|
||||
|
@ -48,15 +50,15 @@ def recursive_match(text: str, pattern: str) -> bool:
|
|||
|
||||
|
||||
def dp_match(text: str, pattern: str) -> bool:
|
||||
"""
|
||||
r"""
|
||||
Dynamic programming matching algorithm.
|
||||
|
||||
Time complexity: O(|text| * |pattern|)
|
||||
Space complexity: O(|text| * |pattern|)
|
||||
| Time complexity: O(\|text\| * \|pattern\|)
|
||||
| Space complexity: O(\|text\| * \|pattern\|)
|
||||
|
||||
:param text: Text to match.
|
||||
:param pattern: Pattern to match.
|
||||
:return: True if text matches pattern, False otherwise.
|
||||
:return: ``True`` if `text` matches `pattern`, ``False`` otherwise.
|
||||
|
||||
>>> dp_match('abc', 'a.c')
|
||||
True
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""
|
||||
This module provides two implementations for the rod-cutting problem:
|
||||
1. A naive recursive implementation which has an exponential runtime
|
||||
2. Two dynamic programming implementations which have quadratic runtime
|
||||
1. A naive recursive implementation which has an exponential runtime
|
||||
2. Two dynamic programming implementations which have quadratic runtime
|
||||
|
||||
The rod-cutting problem is the problem of finding the maximum possible revenue
|
||||
obtainable from a rod of length ``n`` given a list of prices for each integral piece
|
||||
|
@ -20,18 +20,21 @@ def naive_cut_rod_recursive(n: int, prices: list):
|
|||
Runtime: O(2^n)
|
||||
|
||||
Arguments
|
||||
-------
|
||||
n: int, the length of the rod
|
||||
prices: list, the prices for each piece of rod. ``p[i-i]`` is the
|
||||
---------
|
||||
|
||||
* `n`: int, the length of the rod
|
||||
* `prices`: list, the prices for each piece of rod. ``p[i-i]`` is the
|
||||
price for a rod of length ``i``
|
||||
|
||||
Returns
|
||||
-------
|
||||
The maximum revenue obtainable for a rod of length n given the list of prices
|
||||
|
||||
The maximum revenue obtainable for a rod of length `n` given the list of prices
|
||||
for each piece.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
>>> naive_cut_rod_recursive(4, [1, 5, 8, 9])
|
||||
10
|
||||
>>> naive_cut_rod_recursive(10, [1, 5, 8, 9, 10, 17, 17, 20, 24, 30])
|
||||
|
@ -54,28 +57,30 @@ def top_down_cut_rod(n: int, prices: list):
|
|||
"""
|
||||
Constructs a top-down dynamic programming solution for the rod-cutting
|
||||
problem via memoization. This function serves as a wrapper for
|
||||
_top_down_cut_rod_recursive
|
||||
``_top_down_cut_rod_recursive``
|
||||
|
||||
Runtime: O(n^2)
|
||||
|
||||
Arguments
|
||||
--------
|
||||
n: int, the length of the rod
|
||||
prices: list, the prices for each piece of rod. ``p[i-i]`` is the
|
||||
---------
|
||||
|
||||
* `n`: int, the length of the rod
|
||||
* `prices`: list, the prices for each piece of rod. ``p[i-i]`` is the
|
||||
price for a rod of length ``i``
|
||||
|
||||
Note
|
||||
----
|
||||
For convenience and because Python's lists using 0-indexing, length(max_rev) =
|
||||
n + 1, to accommodate for the revenue obtainable from a rod of length 0.
|
||||
.. note::
|
||||
For convenience and because Python's lists using ``0``-indexing, ``length(max_rev)
|
||||
= n + 1``, to accommodate for the revenue obtainable from a rod of length ``0``.
|
||||
|
||||
Returns
|
||||
-------
|
||||
The maximum revenue obtainable for a rod of length n given the list of prices
|
||||
|
||||
The maximum revenue obtainable for a rod of length `n` given the list of prices
|
||||
for each piece.
|
||||
|
||||
Examples
|
||||
-------
|
||||
--------
|
||||
|
||||
>>> top_down_cut_rod(4, [1, 5, 8, 9])
|
||||
10
|
||||
>>> top_down_cut_rod(10, [1, 5, 8, 9, 10, 17, 17, 20, 24, 30])
|
||||
|
@ -94,16 +99,18 @@ def _top_down_cut_rod_recursive(n: int, prices: list, max_rev: list):
|
|||
Runtime: O(n^2)
|
||||
|
||||
Arguments
|
||||
--------
|
||||
n: int, the length of the rod
|
||||
prices: list, the prices for each piece of rod. ``p[i-i]`` is the
|
||||
---------
|
||||
|
||||
* `n`: int, the length of the rod
|
||||
* `prices`: list, the prices for each piece of rod. ``p[i-i]`` is the
|
||||
price for a rod of length ``i``
|
||||
max_rev: list, the computed maximum revenue for a piece of rod.
|
||||
* `max_rev`: list, the computed maximum revenue for a piece of rod.
|
||||
``max_rev[i]`` is the maximum revenue obtainable for a rod of length ``i``
|
||||
|
||||
Returns
|
||||
-------
|
||||
The maximum revenue obtainable for a rod of length n given the list of prices
|
||||
|
||||
The maximum revenue obtainable for a rod of length `n` given the list of prices
|
||||
for each piece.
|
||||
"""
|
||||
if max_rev[n] >= 0:
|
||||
|
@ -130,18 +137,21 @@ def bottom_up_cut_rod(n: int, prices: list):
|
|||
Runtime: O(n^2)
|
||||
|
||||
Arguments
|
||||
----------
|
||||
n: int, the maximum length of the rod.
|
||||
prices: list, the prices for each piece of rod. ``p[i-i]`` is the
|
||||
---------
|
||||
|
||||
* `n`: int, the maximum length of the rod.
|
||||
* `prices`: list, the prices for each piece of rod. ``p[i-i]`` is the
|
||||
price for a rod of length ``i``
|
||||
|
||||
Returns
|
||||
-------
|
||||
The maximum revenue obtainable from cutting a rod of length n given
|
||||
|
||||
The maximum revenue obtainable from cutting a rod of length `n` given
|
||||
the prices for each piece of rod p.
|
||||
|
||||
Examples
|
||||
-------
|
||||
--------
|
||||
|
||||
>>> bottom_up_cut_rod(4, [1, 5, 8, 9])
|
||||
10
|
||||
>>> bottom_up_cut_rod(10, [1, 5, 8, 9, 10, 17, 17, 20, 24, 30])
|
||||
|
@ -168,12 +178,11 @@ def _enforce_args(n: int, prices: list):
|
|||
"""
|
||||
Basic checks on the arguments to the rod-cutting algorithms
|
||||
|
||||
n: int, the length of the rod
|
||||
prices: list, the price list for each piece of rod.
|
||||
* `n`: int, the length of the rod
|
||||
* `prices`: list, the price list for each piece of rod.
|
||||
|
||||
Throws ValueError:
|
||||
|
||||
if n is negative or there are fewer items in the price list than the length of
|
||||
Throws ``ValueError``:
|
||||
if `n` is negative or there are fewer items in the price list than the length of
|
||||
the rod
|
||||
"""
|
||||
if n < 0:
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
def subset_combinations(elements: list[int], n: int) -> list:
|
||||
"""
|
||||
Compute n-element combinations from a given list using dynamic programming.
|
||||
|
||||
Args:
|
||||
elements: The list of elements from which combinations will be generated.
|
||||
n: The number of elements in each combination.
|
||||
* `elements`: The list of elements from which combinations will be generated.
|
||||
* `n`: The number of elements in each combination.
|
||||
|
||||
Returns:
|
||||
A list of tuples, each representing a combination of n elements.
|
||||
A list of tuples, each representing a combination of `n` elements.
|
||||
|
||||
>>> subset_combinations(elements=[10, 20, 30, 40], n=2)
|
||||
[(10, 20), (10, 30), (10, 40), (20, 30), (20, 40), (30, 40)]
|
||||
>>> subset_combinations(elements=[1, 2, 3], n=1)
|
||||
|
|
|
@ -11,9 +11,11 @@ def viterbi(
|
|||
"""
|
||||
Viterbi Algorithm, to find the most likely path of
|
||||
states from the start and the expected output.
|
||||
|
||||
https://en.wikipedia.org/wiki/Viterbi_algorithm
|
||||
sdafads
|
||||
|
||||
Wikipedia example
|
||||
|
||||
>>> observations = ["normal", "cold", "dizzy"]
|
||||
>>> states = ["Healthy", "Fever"]
|
||||
>>> start_p = {"Healthy": 0.6, "Fever": 0.4}
|
||||
|
@ -27,97 +29,78 @@ def viterbi(
|
|||
... }
|
||||
>>> viterbi(observations, states, start_p, trans_p, emit_p)
|
||||
['Healthy', 'Healthy', 'Fever']
|
||||
|
||||
>>> viterbi((), states, start_p, trans_p, emit_p)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: There's an empty parameter
|
||||
|
||||
>>> viterbi(observations, (), start_p, trans_p, emit_p)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: There's an empty parameter
|
||||
|
||||
>>> viterbi(observations, states, {}, trans_p, emit_p)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: There's an empty parameter
|
||||
|
||||
>>> viterbi(observations, states, start_p, {}, emit_p)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: There's an empty parameter
|
||||
|
||||
>>> viterbi(observations, states, start_p, trans_p, {})
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: There's an empty parameter
|
||||
|
||||
>>> viterbi("invalid", states, start_p, trans_p, emit_p)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: observations_space must be a list
|
||||
|
||||
>>> viterbi(["valid", 123], states, start_p, trans_p, emit_p)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: observations_space must be a list of strings
|
||||
|
||||
>>> viterbi(observations, "invalid", start_p, trans_p, emit_p)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: states_space must be a list
|
||||
|
||||
>>> viterbi(observations, ["valid", 123], start_p, trans_p, emit_p)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: states_space must be a list of strings
|
||||
|
||||
>>> viterbi(observations, states, "invalid", trans_p, emit_p)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: initial_probabilities must be a dict
|
||||
|
||||
>>> viterbi(observations, states, {2:2}, trans_p, emit_p)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: initial_probabilities all keys must be strings
|
||||
|
||||
>>> viterbi(observations, states, {"a":2}, trans_p, emit_p)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: initial_probabilities all values must be float
|
||||
|
||||
>>> viterbi(observations, states, start_p, "invalid", emit_p)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: transition_probabilities must be a dict
|
||||
|
||||
>>> viterbi(observations, states, start_p, {"a":2}, emit_p)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: transition_probabilities all values must be dict
|
||||
|
||||
>>> viterbi(observations, states, start_p, {2:{2:2}}, emit_p)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: transition_probabilities all keys must be strings
|
||||
|
||||
>>> viterbi(observations, states, start_p, {"a":{2:2}}, emit_p)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: transition_probabilities all keys must be strings
|
||||
|
||||
>>> viterbi(observations, states, start_p, {"a":{"b":2}}, emit_p)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: transition_probabilities nested dictionary all values must be float
|
||||
|
||||
>>> viterbi(observations, states, start_p, trans_p, "invalid")
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: emission_probabilities must be a dict
|
||||
|
||||
>>> viterbi(observations, states, start_p, trans_p, None)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
|
@ -213,7 +196,6 @@ def _validation(
|
|||
... "Fever": {"normal": 0.1, "cold": 0.3, "dizzy": 0.6},
|
||||
... }
|
||||
>>> _validation(observations, states, start_p, trans_p, emit_p)
|
||||
|
||||
>>> _validation([], states, start_p, trans_p, emit_p)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
|
@ -242,7 +224,6 @@ def _validate_not_empty(
|
|||
"""
|
||||
>>> _validate_not_empty(["a"], ["b"], {"c":0.5},
|
||||
... {"d": {"e": 0.6}}, {"f": {"g": 0.7}})
|
||||
|
||||
>>> _validate_not_empty(["a"], ["b"], {"c":0.5}, {}, {"f": {"g": 0.7}})
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
|
@ -267,12 +248,10 @@ def _validate_not_empty(
|
|||
def _validate_lists(observations_space: Any, states_space: Any) -> None:
|
||||
"""
|
||||
>>> _validate_lists(["a"], ["b"])
|
||||
|
||||
>>> _validate_lists(1234, ["b"])
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: observations_space must be a list
|
||||
|
||||
>>> _validate_lists(["a"], [3])
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
|
@ -285,7 +264,6 @@ def _validate_lists(observations_space: Any, states_space: Any) -> None:
|
|||
def _validate_list(_object: Any, var_name: str) -> None:
|
||||
"""
|
||||
>>> _validate_list(["a"], "mock_name")
|
||||
|
||||
>>> _validate_list("a", "mock_name")
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
|
@ -294,7 +272,6 @@ def _validate_list(_object: Any, var_name: str) -> None:
|
|||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: mock_name must be a list of strings
|
||||
|
||||
"""
|
||||
if not isinstance(_object, list):
|
||||
msg = f"{var_name} must be a list"
|
||||
|
@ -313,7 +290,6 @@ def _validate_dicts(
|
|||
) -> None:
|
||||
"""
|
||||
>>> _validate_dicts({"c":0.5}, {"d": {"e": 0.6}}, {"f": {"g": 0.7}})
|
||||
|
||||
>>> _validate_dicts("invalid", {"d": {"e": 0.6}}, {"f": {"g": 0.7}})
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
|
@ -339,7 +315,6 @@ def _validate_dicts(
|
|||
def _validate_nested_dict(_object: Any, var_name: str) -> None:
|
||||
"""
|
||||
>>> _validate_nested_dict({"a":{"b": 0.5}}, "mock_name")
|
||||
|
||||
>>> _validate_nested_dict("invalid", "mock_name")
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
|
@ -367,7 +342,6 @@ def _validate_dict(
|
|||
) -> None:
|
||||
"""
|
||||
>>> _validate_dict({"b": 0.5}, "mock_name", float)
|
||||
|
||||
>>> _validate_dict("invalid", "mock_name", float)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
|
|
Loading…
Reference in New Issue
Block a user