diff --git a/dynamic_programming/FloydWarshall.py b/dynamic_programming/FloydWarshall.py new file mode 100644 index 000000000000..a4b6c6a82568 --- /dev/null +++ b/dynamic_programming/FloydWarshall.py @@ -0,0 +1,42 @@ +import math + + +class Graph: + def __init__(self, N=0): # a graph with Node 0,1,...,N-1 + self.N = N + self.W = [ + [math.inf for j in range(0, N)] for i in range(0, N) + ] # adjacency matrix for weight + self.dp = [ + [math.inf for j in range(0, N)] for i in range(0, N) + ] # dp[i][j] stores minimum distance from i to j + + def addEdge(self, u, v, w): + self.dp[u][v] = w + + def floyd_warshall(self): + for k in range(0, self.N): + for i in range(0, self.N): + for j in range(0, self.N): + self.dp[i][j] = min(self.dp[i][j], self.dp[i][k] + self.dp[k][j]) + + def showMin(self, u, v): + return self.dp[u][v] + + +if __name__ == "__main__": + graph = Graph(5) + graph.addEdge(0, 2, 9) + graph.addEdge(0, 4, 10) + graph.addEdge(1, 3, 5) + graph.addEdge(2, 3, 7) + graph.addEdge(3, 0, 10) + graph.addEdge(3, 1, 2) + graph.addEdge(3, 2, 1) + graph.addEdge(3, 4, 6) + graph.addEdge(4, 1, 3) + graph.addEdge(4, 2, 4) + graph.addEdge(4, 3, 9) + graph.floyd_warshall() + graph.showMin(1, 4) + graph.showMin(0, 3) diff --git a/dynamic_programming/coin_change.py b/dynamic_programming/coin_change.py index 2d7106f0cc6f..d8d0cecbd813 100644 --- a/dynamic_programming/coin_change.py +++ b/dynamic_programming/coin_change.py @@ -5,6 +5,10 @@ the given types of coins? https://www.hackerrank.com/challenges/coin-change/problem """ +<<<<<<< HEAD +from __future__ import print_function +======= +>>>>>>> upstream/master def dp_count(S, m, n): @@ -38,6 +42,11 @@ def dp_count(S, m, n): if __name__ == "__main__": +<<<<<<< HEAD + print(dp_count([1, 2, 3], 3, 4)) # answer 4 + print(dp_count([2, 5, 3, 6], 4, 10)) # answer 5 +======= import doctest doctest.testmod() +>>>>>>> upstream/master diff --git a/dynamic_programming/edit_distance.py b/dynamic_programming/edit_distance.py index 9df00eae96d7..c0c7a0b5502b 100644 --- a/dynamic_programming/edit_distance.py +++ b/dynamic_programming/edit_distance.py @@ -56,6 +56,14 @@ def solve(self, A, B): return self.__solveDP(len(A) - 1, len(B) - 1) +<<<<<<< HEAD +if __name__ == "__main__": + try: + raw_input # Python 2 + except NameError: + raw_input = input # Python 3 + +======= def min_distance_bottom_up(word1: str, word2: str) -> int: """ >>> min_distance_bottom_up("intention", "execution") @@ -88,16 +96,28 @@ def min_distance_bottom_up(word1: str, word2: str) -> int: if __name__ == "__main__": +>>>>>>> upstream/master solver = EditDistance() print("****************** Testing Edit Distance DP Algorithm ******************") print() +<<<<<<< HEAD + print("Enter the first string: ", end="") + S1 = raw_input().strip() + + print("Enter the second string: ", end="") + S2 = raw_input().strip() + + print() + print("The minimum Edit Distance is: %d" % (solver.solve(S1, S2))) +======= S1 = input("Enter the first string: ").strip() S2 = input("Enter the second string: ").strip() print() print("The minimum Edit Distance is: %d" % (solver.solve(S1, S2))) print("The minimum Edit Distance is: %d" % (min_distance_bottom_up(S1, S2))) +>>>>>>> upstream/master print() print("*************** End of Testing Edit Distance DP Algorithm ***************") diff --git a/dynamic_programming/fibonacci.py b/dynamic_programming/fibonacci.py index 923560b54d30..1007a3c64a67 100644 --- a/dynamic_programming/fibonacci.py +++ b/dynamic_programming/fibonacci.py @@ -39,13 +39,25 @@ def get(self, sequence_no=None): if __name__ == "__main__": print("\n********* Fibonacci Series Using Dynamic Programming ************\n") +<<<<<<< HEAD + try: + raw_input # Python 2 + except NameError: + raw_input = input # Python 3 + +======= +>>>>>>> upstream/master print("\n Enter the upper limit for the fibonacci sequence: ", end="") try: N = int(input().strip()) fib = Fibonacci(N) print( +<<<<<<< HEAD + "\n********* Enter different values to get the corresponding fibonacci sequence, enter any negative number to exit. ************\n" +======= "\n********* Enter different values to get the corresponding fibonacci " "sequence, enter any negative number to exit. ************\n" +>>>>>>> upstream/master ) while True: try: diff --git a/dynamic_programming/integer_partition.py b/dynamic_programming/integer_partition.py index ec8c5bf62d7d..7a25a2330673 100644 --- a/dynamic_programming/integer_partition.py +++ b/dynamic_programming/integer_partition.py @@ -1,3 +1,18 @@ +<<<<<<< HEAD +from __future__ import print_function + +try: + xrange # Python 2 +except NameError: + xrange = range # Python 3 + +try: + raw_input # Python 2 +except NameError: + raw_input = input # Python 3 + +======= +>>>>>>> upstream/master """ The number of partitions of a number n into at least k parts equals the number of partitions into exactly k parts plus the number of partitions into at least k-1 parts. Subtracting 1 from each part of a partition of n into k parts @@ -6,12 +21,21 @@ def partition(m): +<<<<<<< HEAD + memo = [[0 for _ in xrange(m)] for _ in xrange(m + 1)] + for i in xrange(m + 1): + memo[i][0] = 1 + + for n in xrange(m + 1): + for k in xrange(1, m): +======= memo = [[0 for _ in range(m)] for _ in range(m + 1)] for i in range(m + 1): memo[i][0] = 1 for n in range(m + 1): for k in range(1, m): +>>>>>>> upstream/master memo[n][k] += memo[n][k - 1] if n - k > 0: memo[n][k] += memo[n - k - 1][k] @@ -24,7 +48,11 @@ def partition(m): if len(sys.argv) == 1: try: +<<<<<<< HEAD + n = int(raw_input("Enter a number: ")) +======= n = int(input("Enter a number: ").strip()) +>>>>>>> upstream/master print(partition(n)) except ValueError: print("Please enter a number.") diff --git a/dynamic_programming/knapsack.py b/dynamic_programming/knapsack.py index aefaa6bade96..5a876373743a 100644 --- a/dynamic_programming/knapsack.py +++ b/dynamic_programming/knapsack.py @@ -35,6 +35,8 @@ def knapsack(W, wt, val, n): dp[i][w] = max(val[i - 1] + dp[i - 1][w - wt[i - 1]], dp[i - 1][w]) else: dp[i][w] = dp[i - 1][w] +<<<<<<< HEAD +======= return dp[n][W], dp @@ -89,11 +91,14 @@ def knapsack_with_example_solution(W: int, wt: list, val: list): "All weights must be integers but " f"got weight of type {type(wt[i])} at index {i}" ) +>>>>>>> upstream/master optimal_val, dp_table = knapsack(W, wt, val, num_items) example_optional_set = set() _construct_solution(dp_table, wt, num_items, W, example_optional_set) +<<<<<<< HEAD +======= return optimal_val, example_optional_set @@ -127,6 +132,7 @@ def _construct_solution(dp: list, wt: list, i: int, j: int, optimal_set: set): optimal_set.add(i) _construct_solution(dp, wt, i - 1, j - wt[i - 1], optimal_set) +>>>>>>> upstream/master if __name__ == "__main__": """ @@ -137,6 +143,10 @@ def _construct_solution(dp: list, wt: list, i: int, j: int, optimal_set: set): n = 4 w = 6 F = [[0] * (w + 1)] + [[0] + [-1 for i in range(w + 1)] for j in range(n + 1)] +<<<<<<< HEAD + print(knapsack(w, wt, val, n)) + print(MF_knapsack(n, wt, val, w)) # switched the n and w +======= optimal_solution, _ = knapsack(w, wt, val, n) print(optimal_solution) print(MF_knapsack(n, wt, val, w)) # switched the n and w @@ -148,3 +158,4 @@ def _construct_solution(dp: list, wt: list, i: int, j: int, optimal_set: set): assert optimal_subset == {3, 4} print("optimal_value = ", optimal_solution) print("An optimal subset corresponding to the optimal value", optimal_subset) +>>>>>>> upstream/master diff --git a/dynamic_programming/longest_common_subsequence.py b/dynamic_programming/longest_common_subsequence.py index a7206b221d96..8e7bc2e68aed 100644 --- a/dynamic_programming/longest_common_subsequence.py +++ b/dynamic_programming/longest_common_subsequence.py @@ -4,6 +4,15 @@ Example:"abc", "abg" are subsequences of "abcdefgh". """ +<<<<<<< HEAD +try: + xrange # Python 2 +except NameError: + xrange = range # Python 3 + + +def lcs_dp(x, y): +======= def longest_common_subsequence(x: str, y: str): """ @@ -28,6 +37,7 @@ def longest_common_subsequence(x: str, y: str): >>> longest_common_subsequence("computer", "food") (1, 'o') """ +>>>>>>> upstream/master # find the length of strings assert x is not None @@ -37,12 +47,25 @@ def longest_common_subsequence(x: str, y: str): n = len(y) # declaring the array for storing the dp values +<<<<<<< HEAD + L = [[None] * (n + 1) for i in xrange(m + 1)] + seq = [] + + for i in range(m + 1): + for j in range(n + 1): + if i == 0 or j == 0: + L[i][j] = 0 + elif x[i - 1] == y[j - 1]: + L[i][j] = L[i - 1][j - 1] + 1 + seq.append(x[i - 1]) +======= L = [[0] * (n + 1) for _ in range(m + 1)] for i in range(1, m + 1): for j in range(1, n + 1): if x[i - 1] == y[j - 1]: match = 1 +>>>>>>> upstream/master else: match = 0 @@ -70,6 +93,11 @@ def longest_common_subsequence(x: str, y: str): if __name__ == "__main__": +<<<<<<< HEAD + x = "AGGTAB" + y = "GXTXAYB" + print(lcs_dp(x, y)) +======= a = "AGGTAB" b = "GXTXAYB" expected_ln = 4 @@ -80,3 +108,4 @@ def longest_common_subsequence(x: str, y: str): import doctest doctest.testmod() +>>>>>>> upstream/master diff --git a/dynamic_programming/longest_increasing_subsequence.py b/dynamic_programming/longest_increasing_subsequence.py index 81b7f8f8ff17..7bd76ad560f8 100644 --- a/dynamic_programming/longest_increasing_subsequence.py +++ b/dynamic_programming/longest_increasing_subsequence.py @@ -7,6 +7,45 @@ 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 """ +<<<<<<< HEAD +from __future__ import print_function + + +def longestSub(ARRAY): # This function is recursive + + ARRAY_LENGTH = len(ARRAY) + if ( + ARRAY_LENGTH <= 1 + ): # If the array contains only one element, we return it (it's the stop condition of recursion) + return ARRAY + # Else + PIVOT = ARRAY[0] + isFound = False + i = 1 + LONGEST_SUB = [] + while not isFound and i < ARRAY_LENGTH: + if ARRAY[i] < PIVOT: + isFound = True + TEMPORARY_ARRAY = [element for element in ARRAY[i:] if element >= ARRAY[i]] + TEMPORARY_ARRAY = longestSub(TEMPORARY_ARRAY) + if len(TEMPORARY_ARRAY) > len(LONGEST_SUB): + LONGEST_SUB = TEMPORARY_ARRAY + else: + i += 1 + + TEMPORARY_ARRAY = [element for element in ARRAY[1:] if element >= PIVOT] + TEMPORARY_ARRAY = [PIVOT] + longestSub(TEMPORARY_ARRAY) + if len(TEMPORARY_ARRAY) > len(LONGEST_SUB): + return TEMPORARY_ARRAY + else: + return LONGEST_SUB + + +# Some examples + +print(longestSub([4, 8, 7, 5, 1, 12, 2, 3, 9])) +print(longestSub([9, 8, 7, 6, 5, 7])) +======= from typing import List @@ -54,3 +93,4 @@ def longest_subsequence(array: List[int]) -> List[int]: # This function is recu import doctest doctest.testmod() +>>>>>>> upstream/master diff --git a/dynamic_programming/longest_increasing_subsequence_O(nlogn).py b/dynamic_programming/longest_increasing_subsequence_O(nlogn).py new file mode 100644 index 000000000000..1df37af57e86 --- /dev/null +++ b/dynamic_programming/longest_increasing_subsequence_O(nlogn).py @@ -0,0 +1,42 @@ +from __future__ import print_function + +############################# +# Author: Aravind Kashyap +# File: lis.py +# comments: This programme outputs the Longest Strictly Increasing Subsequence in O(NLogN) +# Where N is the Number of elements in the list +############################# +def CeilIndex(v, l, r, key): + while r - l > 1: + m = (l + r) / 2 + if v[m] >= key: + r = m + else: + l = m + + return r + + +def LongestIncreasingSubsequenceLength(v): + if len(v) == 0: + return 0 + + tail = [0] * len(v) + length = 1 + + tail[0] = v[0] + + for i in range(1, len(v)): + if v[i] < tail[0]: + tail[0] = v[i] + elif v[i] > tail[length - 1]: + tail[length] = v[i] + length += 1 + else: + tail[CeilIndex(tail, -1, length - 1, v[i])] = v[i] + + return length + + +v = [2, 5, 3, 7, 11, 8, 10, 13, 6] +print(LongestIncreasingSubsequenceLength(v)) diff --git a/dynamic_programming/longest_sub_array.py b/dynamic_programming/longest_sub_array.py index 65ce151c33d6..1cf83ca17d58 100644 --- a/dynamic_programming/longest_sub_array.py +++ b/dynamic_programming/longest_sub_array.py @@ -6,6 +6,10 @@ The problem is : Given an array, to find the longest and continuous sub array and get the max sum of the sub array in the given array. """ +<<<<<<< HEAD +from __future__ import print_function +======= +>>>>>>> upstream/master class SubArray: diff --git a/dynamic_programming/matrix_chain_order.py b/dynamic_programming/matrix_chain_order.py index f88a9be8ac95..d1adb85776a9 100644 --- a/dynamic_programming/matrix_chain_order.py +++ b/dynamic_programming/matrix_chain_order.py @@ -12,6 +12,11 @@ def MatrixChainOrder(array): N = len(array) Matrix = [[0 for x in range(N)] for x in range(N)] Sol = [[0 for x in range(N)] for x in range(N)] +<<<<<<< HEAD + for i in range(1, N): + Matrix[i][i] = 0 +======= +>>>>>>> upstream/master for ChainLength in range(2, N): for a in range(1, N - ChainLength + 1): diff --git a/dynamic_programming/max_sub_array.py b/dynamic_programming/max_sub_array.py index 7350eaf373cb..a0617c83c123 100644 --- a/dynamic_programming/max_sub_array.py +++ b/dynamic_programming/max_sub_array.py @@ -1,7 +1,15 @@ """ author : Mayank Kumar Jha (mk9440) """ +<<<<<<< HEAD +from __future__ import print_function + +import time +import matplotlib.pyplot as plt +from random import randint +======= from typing import List +>>>>>>> upstream/master def find_max_sub_array(A, low, high): @@ -36,6 +44,11 @@ def find_max_cross_sum(A, low, mid, high): right_sum = summ max_right = i return max_left, max_right, (left_sum + right_sum) +<<<<<<< HEAD + + +if __name__ == "__main__": +======= def max_sub_array(nums: List[int]) -> int: @@ -76,6 +89,7 @@ def max_sub_array(nums: List[int]) -> int: import matplotlib.pyplot as plt from random import randint +>>>>>>> upstream/master inputs = [10, 100, 1000, 10000, 50000, 100000, 200000, 300000, 400000, 500000] tim = [] for i in inputs: @@ -86,7 +100,11 @@ def max_sub_array(nums: List[int]) -> int: tim.append(end - strt) print("No of Inputs Time Taken") for i in range(len(inputs)): +<<<<<<< HEAD + print((inputs[i], "\t\t", tim[i])) +======= print(inputs[i], "\t\t", tim[i]) +>>>>>>> upstream/master plt.plot(inputs, tim) plt.xlabel("Number of Inputs") plt.ylabel("Time taken in seconds ") diff --git a/other/dijkstra_bankers_algorithm.py b/other/dijkstra_bankers_algorithm.py new file mode 100644 index 000000000000..5c0ccaba40ca --- /dev/null +++ b/other/dijkstra_bankers_algorithm.py @@ -0,0 +1,221 @@ +# A Python implementation of the Banker's Algorithm in Operating Systems using +# Processes and Resources +# { +# "Author: "Biney Kingsley (bluedistro@github.io), bineykingsley36@gmail.com", +# "Date": 28-10-2018 +# } +''' +The Banker's algorithm is a resource allocation and deadlock avoidance algorithm +developed by Edsger Dijkstra that tests for safety by simulating the allocation of +predetermined maximum possible amounts of all resources, and then makes a "s-state" +check to test for possible deadlock conditions for all other pending activities, +before deciding whether allocation should be allowed to continue. +[Source] Wikipedia +[Credit] Rosetta Code C implementation helped very much. + (https://rosettacode.org/wiki/Banker%27s_algorithm) +''' + +import numpy as np +import time + + +class BankersAlgorithm: + + def __init__(self, claim_vector: list, allocated_resources_table: list, maximum_claim_table: list) -> None: + ''' + :param claim_vector: A nxn/nxm list depicting the amount of each resources + (eg. memory, interface, semaphores, etc.) available. + :param allocated_resources_table: A nxn/nxm list depicting the amount of each resource + each process is currently holding + :param maximum_claim_table: A nxn/nxm list depicting how much of each resource the system + currently has available + ''' + self.__claim_vector = claim_vector + self.__allocated_resources_table = allocated_resources_table + self.__maximum_claim_table = maximum_claim_table + + def __processes_resource_summation(self) -> list: + ''' + This method checks for allocated resources in line with each resource in the claim vector + ''' + allocated_resources = list() + for i in range(len(self.__allocated_resources_table[0])): + sum = 0 + for p_item in self.__allocated_resources_table: + sum += p_item[i] + allocated_resources.append(sum) + return allocated_resources + + def __available_resources(self) -> list: + ''' + This method checks for available resources in line with each resource in the claim vector + ''' + return np.array(self.__claim_vector) - np.array(self.__processes_resource_summation()) + + def __need(self) -> list: + ''' + This method implements safety checker by ensuring that + max_claim[i][j] - alloc_table[i][j] <= avail[j] + In order words, calculating for the needs + ''' + need = list() + for i in range(len(self.__allocated_resources_table)): + need.append(list(np.array(self.__maximum_claim_table[i]) + - np.array(self.__allocated_resources_table[i]))) + return need + + def __need_index_manager(self) -> dict: + ''' + This function builds an index control dictionary to track original ids/indices + of processes when altered during execution of method "main" + Return: {0: [a: int, b: int], 1: [c: int, d: int]} + >>> test_1_claim_vector = [8, 5, 9, 7] + >>> test_1_allocated_res_table = [[2, 0, 1, 1],[0, 1, 2, 1],[4, 0, 0, 3],[0, 2, 1, 0],[1, 0, 3, 0]] + >>> test_1_maximum_claim_table = [[3, 2, 1, 4],[0, 2, 5, 2],[5, 1, 0, 5],[1, 5, 3, 0],[3, 0, 3, 3]] + >>> BankersAlgorithm(test_1_claim_vector, test_1_allocated_res_table, test_1_maximum_claim_table)._BankersAlgorithm__need_index_manager() + {0: [1, 2, 0, 3], 1: [0, 1, 3, 1], 2: [1, 1, 0, 2], 3: [1, 3, 2, 0], 4: [2, 0, 0, 3]} + ''' + ni_manager = dict() + for i in self.__need(): + ni_manager.update({self.__need().index(i): i}) + return ni_manager + + def main(self, **kwargs) -> None: + ''' + This method utilized the various methods in this class to simulate the Banker's algorithm + Return: None + >>> test_1_claim_vector = [8, 5, 9, 7] + >>> test_1_allocated_res_table = [[2, 0, 1, 1],[0, 1, 2, 1],[4, 0, 0, 3],[0, 2, 1, 0],[1, 0, 3, 0]] + >>> test_1_maximum_claim_table = [[3, 2, 1, 4],[0, 2, 5, 2],[5, 1, 0, 5],[1, 5, 3, 0],[3, 0, 3, 3]] + >>> BankersAlgorithm(test_1_claim_vector, test_1_allocated_res_table, test_1_maximum_claim_table).main(describe=True) + Allocated Resource Table + P1 2 0 1 1 + + P2 0 1 2 1 + + P3 4 0 0 3 + + P4 0 2 1 0 + + P5 1 0 3 0 + + System Resource Table + P1 3 2 1 4 + + P2 0 2 5 2 + + P3 5 1 0 5 + + P4 1 5 3 0 + + P5 3 0 3 3 + + Current Usage by Active Processes: 8 5 9 7 + Initial Available Resources: 1 2 2 2 + __________________________________________________ + + Process 3 is executing. + Updated available resource stack for processes: 5 2 2 5 + The process is in a safe state. + + Process 1 is executing. + Updated available resource stack for processes: 7 2 3 6 + The process is in a safe state. + + Process 2 is executing. + Updated available resource stack for processes: 7 3 5 7 + The process is in a safe state. + + Process 4 is executing. + Updated available resource stack for processes: 7 5 6 7 + The process is in a safe state. + + Process 5 is executing. + Updated available resource stack for processes: 8 5 9 7 + The process is in a safe state. + + ''' + need_list = self.__need() + alloc_resources_table = self.__allocated_resources_table + available_resources = self.__available_resources() + need_index_manager = self.__need_index_manager() + for kw, val in kwargs.items(): + if kw and val is True: + self.__pretty_data() + print("{:_^50}".format("_")) + print() + while len(need_list) != 0: + safe = False + for each_need in need_list: + execution = True + for index, need in enumerate(each_need): + if need > available_resources[index]: + execution = False + break + + if execution: + safe = True + # get the original index of the process from ind_ctrl db + for original_need_index, need_clone in need_index_manager.items(): + if each_need == need_clone: + process_number = original_need_index + print('Process {} is executing.'.format(process_number + 1)) + # remove the process run from stack + need_list.remove(each_need) + # update available/freed resources stack + available_resources = np.array(available_resources) + \ + np.array(alloc_resources_table[process_number]) + print("Updated available resource stack for processes: {}" + .format(" ".join([str(x) for x in available_resources]))) + break + if safe: + print("The process is in a safe state.") + print() + else: + print("System in unsafe state. Aborting...") + print() + break + + def __pretty_data(self): + ''' + Properly align display of the algorithm's solution + ''' + print("{:>8}".format(" Allocated Resource Table")) + for item in self.__allocated_resources_table: + print("P{}".format(str(self.__allocated_resources_table.index(item) + 1)), end=" ") + for it in item: + print("{:^8}".format(it), end=" ") + print() + print() + + print("{:>8}".format(" System Resource Table")) + for item in self.__maximum_claim_table: + print("P{}".format(str(self.__maximum_claim_table.index(item) + 1)), end=" ") + for it in item: + print("{:^8}".format(it), end=" ") + print() + print() + + print("Current Usage by Active Processes: {:>11}" + .format(str(" ".join([str(x) for x in self.__claim_vector])))) + + print("Initial Available Resources: {:>15}" + .format(str(" ".join([str(x) for x in + self.__available_resources()])))) + time.sleep(1) + +if __name__ == "__main__": + import doctest + test_1_claim_vector = [8, 5, 9, 7] + test_1_allocated_res_table = [[2, 0, 1, 1], + [0, 1, 2, 1], + [4, 0, 0, 3], + [0, 2, 1, 0], + [1, 0, 3, 0]] + test_1_maximum_claim_table = [[3, 2, 1, 4], + [0, 2, 5, 2], + [5, 1, 0, 5], + [1, 5, 3, 0], + [3, 0, 3, 3]] + doctest.testmod(extraglobs={'m': BankersAlgorithm(test_1_claim_vector, test_1_allocated_res_table, + test_1_maximum_claim_table).main(describe=True)})