def _knapsack(W, wt, val): # Get numbers of rows on the table n = len(val) # Create a table to store values that are used to solve shortest problems k = table_utils.initialize(n + 1, W + 1, 0) # Iterate over all rows for i in range(n + 1): # Iterate over all columns j = 1 while j < (W + 1): if i == 0 or j == 0: k[i][j] = 0 elif wt[i - 1] <= j: k[i][j] = max(val[i - 1] + k[i - 1][j - wt[i - 1]], k[i - 1][j]) else: k[i][j] = k[i - 1][j] j += 1 return k[n][W]
def _dijkstra(source, input): # Extract number of vertices from square adjacency matrix number_of_vertices = len(input) # Result array with shortest distance from src to i # Initialized with infinite value and source with 0 # (table.initialize returns 2d array. we want only row 0) distances = table_utils.initialize(1, number_of_vertices, float("inf"))[0] distances[source] = 0 # Array to keep track which vertices were already marked as seen # Initialized with False # (table.initialize returns 2d array. we want only row 0) vertices_processed = table_utils.initialize(1, number_of_vertices, False)[0] # For every vertex for _ in range(number_of_vertices): # Choose the vertex with minimum distance to source and that # has not been finalized yet. Note that on first iteration, # source will be chosen vertex = _shortest_distance(distances, vertices_processed) # Mark it as processed vertices_processed[vertex] = True # Update distances of all adjacent vertices # to the chosen vertex for a_vertex in range(number_of_vertices): # Only update if (1) a_vertex hasn't be processed # (2) there is an edge from vertex to a_vertex and # (3) it's worth updating (distance from source to # a_vertex through vertex is small than current distance # to a_vertex) if vertices_processed[a_vertex] == False and \ input[vertex][a_vertex] is not None and \ distances[vertex] + input[vertex][a_vertex] < distances[a_vertex]: distances[ a_vertex] = distances[vertex] + input[vertex][a_vertex] return distances
def _edit_distance(str1, str2, m, n): """ Calculate the edit distance between two strings using dynamic programming """ # Initialize table to store solution of sub problems # with length1 + 1 rows and length2 + 1 columns table = table_utils.initialize(m + 1, n + 1) _fill_table(table, str1, str2, m, n) return table[m][n]
def _matrix_chain_mult(dims): num = len(dims) table = table_utils.initialize(num, num, 0) for c_len in range(2, num): for i in range(1, num - c_len + 1): j = i + c_len - 1 table[i][j] = sys.maxsize for k in range(i, j): mult = table[i][k] + table[k + 1][j] + dims[i - 1] * dims[j] * dims[k] table[i][j] = mult if mult < table[i][j] else table[i][j] return table[1][num - 1]
def _subset_sum_problem(subset, sum): rows = len(subset) + 1 cols = sum + 1 table = table_utils.initialize(rows, cols, False) table[0][0] = True for r in range(1, rows): table[r][0] = True for c in range(1, cols): if table[r - 1][c] or (c - subset[r - 1]) < 0: table[r][c] = table[r - 1][c] else: table[r][c] = table[r - 1][c - subset[r - 1]] return table[rows - 1][cols - 1]
def _kruskal_minimum_spanning_tree(graph, num_verts): tree = [] num_edges = len(graph) sorted_graph = sorted(graph, key=lambda tup: tup[0]) subset = table_utils.initialize(num_verts, 2, 0) for i in range(num_verts): subset[i][0] = i for edge in sorted_graph: v1 = _find_subset(subset, edge[1]) v2 = _find_subset(subset, edge[2]) if v1 != v2: tree.append(edge) _union(subset, v1, v2) if len(tree) >= num_edges - 1: break return tree
def _longest_common_subsequence(seq, sub): seq_len = len(seq) + 1 sub_len = len(sub) + 1 table = table_utils.initialize(seq_len, sub_len, 0) for r in range(1, seq_len): r_bk = r - 1 for c in range(1, sub_len): c_bk = c - 1 if (seq[r_bk] == sub[c_bk]): table[r][c] = table[r_bk][c_bk] + 1 else: r_val = table[r_bk][c] c_val = table[r][c_bk] table[r][c] = r_val if r_val > c_val else c_val return table[seq_len - 1][sub_len - 1]
def _coin_change(total_change, coins): # Initialize table. Rows for change and columns for index of which # coins should be included (cumulative effect, including previous set) # {c1}, {c1,c2}, {c1, c2, c3} # 0 # 1 # 2 table = table_utils.initialize(total_change + 1, len(coins), 0) # Fill entries for the first row with 1, as for 0 change we can always # find a solution (not giving any coins) for coin in range(len(coins)): table[0][coin] = 1 # Fill table in a bottom up manner, iterating over all coin possibilities # for a fixed change, starting from change 0 for change in range(1, total_change + 1): # For all indices of coins for coin in range(len(coins)): # If there were other (smaller) coins, solutions # with this coin should be at least the same if (coin >= 1): without_this_coin = table[change][coin - 1] else: without_this_coin = 0 # If we can include this coin: if change - coins[coin] >= 0: # Then take number of solutions with this same coin, but # for (change - value of this coin) with_this_coin = table[change - coins[coin]][coin] else: with_this_coin = 0 # Add number of solutions without and with this coin table[change][coin] = without_this_coin + with_this_coin # Return last element return table[total_change][len(coins) - 1]
def _binomial_coefficient(n, k): if (n >= k) and (k >= 0): # Create a table to store values that are used to solve shortest problems c = table_utils.initialize(1, k + 1, 0)[0] # Set the first position with 1 c[0] = 1 for i in range(1, n + 1): # Calculate the current row of pascal triangle using the previous column j = min(i, k) while j > 0: c[j] = c[j] + c[j - 1] j -= 1 return c[k] else: return -1