def warnsdoffs_algo(graph: Graph[T], rows:int = 4, cols:int = 4) -> List[List[int]]: chess: List[List[int]] = empty_2d_array(rows, cols, fill_default=-999) visited: Set[str] = set() step = 1 curr_vertex = graph.vertices[0][1] # data_vertex_mapping: Dict[T, Vertex[T]] = {data: vertex for (data, vertex) in graph.vertices} # curr_vertex = data_vertex_mapping['4,9'] indices: List[T] = curr_vertex.data.split(',') chess[int(indices[0])][int(indices[1])] = step while curr_vertex.data not in visited: visited.add(curr_vertex.data) rank, curr_vertex = get_adjacent_vertex_with_min_rank_via_Ira_Pohl(curr_vertex, visited) if curr_vertex is None: break step += 1 indices: List[T] = curr_vertex.data.split(',') chess[int(indices[0])][int(indices[1])] = step display(chess) import time time.sleep(.1) return chess
def coin_change(coins, max_total_sum): """ Formulae - table[row][col] = table[row-1][col] + table[row][col-row], Where `row` denotes `coin`, `col` denotes `sum`. :param coin_max_denomination: :param max_total_sum: :return: """ rows = len(coins) + 1 cols = max_total_sum + 1 table = empty_2d_array(rows, cols) # Number of ways to get the total_sum = 0 by using coin(s) of denomination [0] is 1. table[0][0] = 1 # Number of ways to get the total_sum(>0) by using coin(s) of denomination [0] is 0. for first_row_elt in xrange(1, max_total_sum + 1): table[0][first_row_elt] = 0 for i_coin in xrange(1, rows): for s in xrange(0, cols): coin_val = coins[i_coin - 1] excl_coin = table[i_coin - 1][s] if coin_val > s: table[i_coin][s] = excl_coin else: incl_coin = table[i_coin][s - coin_val] table[i_coin][s] = excl_coin + incl_coin #print table return table[rows - 1][cols - 1]
def sparse_matrix(self): self._vertices = list( map(lambda _: _.strip(), input("Enter vertices (comma-separated): ").split(','))) self._sparse_matrix = empty_2d_array(len(self._vertices), len(self._vertices), fill_default=0) for i in range(0, self.num_edges): print("Enter edge: {} ".format(i + 1), end=', ') from_to = list( map( lambda _: _.strip(), input("from v1 to v2 (comma-separated, e.g. v1,v2): "). split(","))) from_vertex = from_to[0] to_vertex = from_to[1] print("{} --> {}".format(from_vertex, to_vertex)) is_bi_directional_edge = True if input( "Is this edge bi-directional ? (y/n): ").lower( ) == 'y' else False try: i_from_vertex = self._vertices.index(from_vertex) i_to_vertex = self._vertices.index(to_vertex) self._sparse_matrix[i_from_vertex][i_to_vertex] = 1 if is_bi_directional_edge: self._sparse_matrix[i_to_vertex][i_from_vertex] = 1 except ValueError as ve: print("Invalid vertices! Can't create an edge. Try again") self.num_edges += 1 return self._sparse_matrix
def subset_sum_dp(elt_set, total_sum): rows = len(elt_set) + 1; cols = total_sum + 1 table = empty_2d_array(rows, cols) # Set each cell in first col as `True`, because total_sum = 0 can be formed if we have 0 in subset. for row in xrange(0, rows): table[row][0] = True # Except (0, 0), set each cell in first row as `False`, because using subset {0} we can't form total_sum>0 for col in xrange(1, cols): table[0][col] = False for i_elt in xrange(1, rows): for s in xrange(1, cols): elt = elt_set[i_elt-1] excl_elt = table[i_elt-1][s] # If current elt > current sum, we can't include current elt in subset. if elt > s: table[i_elt][s] = excl_elt else: incl_elt = table[i_elt-1][s-elt] table[i_elt][s] = excl_elt or incl_elt #print table return table[rows-1][cols-1]
def subset_sum_dp(elt_set, total_sum): rows = len(elt_set) + 1 cols = total_sum + 1 table = empty_2d_array(rows, cols) # Set each cell in first col as `True`, because total_sum = 0 can be formed if we have 0 in subset. for row in xrange(0, rows): table[row][0] = True # Except (0, 0), set each cell in first row as `False`, because using subset {0} we can't form total_sum>0 for col in xrange(1, cols): table[0][col] = False for i_elt in xrange(1, rows): for s in xrange(1, cols): elt = elt_set[i_elt - 1] excl_elt = table[i_elt - 1][s] # If current elt > current sum, we can't include current elt in subset. if elt > s: table[i_elt][s] = excl_elt else: incl_elt = table[i_elt - 1][s - elt] table[i_elt][s] = excl_elt or incl_elt #print table return table[rows - 1][cols - 1]
def lcs_dp(p, q): rows = len(p)+1; cols = len(q)+1 table = empty_2d_array(rows, cols) for row in xrange(0, rows): for col in xrange(0, cols): if row == 0 or col == 0: # If either of 2 sequence is empty, lcs is 0. table[row][col] = 0 continue if p[row-1] == q[col-1]: table[row][col] = table[row-1][col-1] + 1 else: table[row][col] = max(table[row-1][col], table[row][col-1]) #print table lcs_seq = get_lcs_seq(p, q, table) return table[rows-1][cols-1], lcs_seq
def lrs_dp(p): rows = cols = len(p) + 1 table = empty_2d_array(rows, cols) for row in xrange(0, rows): for col in xrange(0, cols): if row == 0 or col == 0: # If either of 2 sequence is empty, lcs is 0. table[row][col] = 0 continue if p[row-1] == p[col-1] and row != col: table[row][col] = table[row-1][col-1] + 1 else: table[row][col] = max(table[row-1][col], table[row][col-1]) #print table lrs_seq = get_lrs_seq(p, p, table) return table[rows-1][cols-1], lrs_seq
def knapsack_dp(weights, values, w_limit): n = len(weights) # Number of items. table = empty_2d_array(n+1, w_limit+1) for w in xrange(0, n+1): for sow in xrange(0, w_limit+1): # sow stands for sum of weights # Max value we can get is 0 when either of `w` or `sow` is 0. `w` represents current weight. if w == 0 or sow == 0: table[w][sow] = 0 elif w > sow: table[w][sow] = table[w-1][sow] else: table[w][sow] = max ( table[w-1][sow], # excluding the current weight `w` values[w-1] + table[w-1][sow-weights[w-1]] # including the current weight `w` ) return table[n][w_limit]
def square_sub_matrix_with_max_ones(matrix=[]): """ Algorithm - 1) Construct a sum matrix S[R][C] for the given M[R][C]. And initialize max_size, max_i, max_j to 0. a) Copy first row and first columns as it is from M[][] to S[][] b) For other entries, use following expressions to construct S[][] If M[i][j] is 1 then S[i][j] = min(S[i][j-1], S[i-1][j], S[i-1][j-1]) + 1 Else If M[i][j] is 0 S[i][j] = 0 c) Update max_size, max_i, max_j (if required) as follows - If S[i][j] > max_size: max_size = S[i][j] max_i = i; max_j = j 2) Using the max_size and coordinates(max_i, max_j) of maximum entry in S[i], print sub-matrix of M[][] :param matrix: :return: """ rows = len(matrix) cols = len(matrix[0]) if rows > 0 else 0 # Sum matrix sum_matrix = empty_2d_array(rows, cols) max_i = max_j = max_size = 0 for row in xrange(0, rows): for col in xrange(0, cols): # Copy first row & first col as it is from `matrix` to `sum_matrix`. if row == 0 or col == 0: sum_matrix[row][col] = matrix[row][col] continue elif matrix[row][col] == 1: sum_matrix[row][col] = min(sum_matrix[row][col - 1], sum_matrix[row - 1][col], sum_matrix[row - 1][col - 1]) + 1 elif matrix[row][col] == 0: sum_matrix[row][col] = 0 if sum_matrix[row][col] > max_size: max_size = sum_matrix[row][col] max_i = row max_j = col #print sum_matrix return max_size, (max_i, max_j)
def knapsack_dp(weights, values, w_limit): n = len(weights) # Number of items. table = empty_2d_array(n + 1, w_limit + 1) for w in xrange(0, n + 1): for sow in xrange(0, w_limit + 1): # sow stands for sum of weights # Max value we can get is 0 when either of `w` or `sow` is 0. `w` represents current weight. if w == 0 or sow == 0: table[w][sow] = 0 elif w > sow: table[w][sow] = table[w - 1][sow] else: table[w][sow] = max( table[w - 1][sow], # excluding the current weight `w` values[w - 1] + table[w - 1] [sow - weights[w - 1]] # including the current weight `w` ) return table[n][w_limit]
def square_sub_matrix_with_max_ones(matrix=[]): """ Algorithm - 1) Construct a sum matrix S[R][C] for the given M[R][C]. And initialize max_size, max_i, max_j to 0. a) Copy first row and first columns as it is from M[][] to S[][] b) For other entries, use following expressions to construct S[][] If M[i][j] is 1 then S[i][j] = min(S[i][j-1], S[i-1][j], S[i-1][j-1]) + 1 Else If M[i][j] is 0 S[i][j] = 0 c) Update max_size, max_i, max_j (if required) as follows - If S[i][j] > max_size: max_size = S[i][j] max_i = i; max_j = j 2) Using the max_size and coordinates(max_i, max_j) of maximum entry in S[i], print sub-matrix of M[][] :param matrix: :return: """ rows = len(matrix) cols = len(matrix[0]) if rows > 0 else 0 # Sum matrix sum_matrix = empty_2d_array(rows, cols) max_i = max_j = max_size = 0 for row in xrange(0, rows): for col in xrange(0, cols): # Copy first row & first col as it is from `matrix` to `sum_matrix`. if row == 0 or col == 0: sum_matrix[row][col] = matrix[row][col] continue elif matrix[row][col] == 1: sum_matrix[row][col] = min(sum_matrix[row][col-1], sum_matrix[row-1][col], sum_matrix[row-1][col-1]) + 1 elif matrix[row][col] == 0: sum_matrix[row][col] = 0 if sum_matrix[row][col] > max_size: max_size = sum_matrix[row][col] max_i = row max_j = col #print sum_matrix return max_size, (max_i, max_j)
def max_profit_dp(prices, rod_len): rows = len(prices) + 1; cols = rod_len + 1 table = empty_2d_array(rows, cols) for piece_len in xrange(0, rows): for r_len in xrange(0, cols): if piece_len == 0 or r_len == 0: table[piece_len][r_len] = 0 continue excl = table[piece_len-1][r_len] if piece_len > r_len: table[piece_len][r_len] = excl else: incl = prices[piece_len-1] + table[piece_len][r_len-piece_len] table[piece_len][r_len] = max(excl, incl) print table return table[rows-1][cols-1]
def floyd_warshalls_all_pairs_shortest_path(graph: Graph[T]): """ Considers every vertex one-by-one as source, while every other vertex as middle vertex. e.g. vertices: 1, 2, 3, 4 For vertex 1 consider 2, 3, 4 as middle vertex. e.g. distance from 1 -> 4 while considering 2 as middle vertex will be: D[1, 4] = MIN(D[1, 4], (D[1, 2] + D[2, 4])) D[i, j] = MIN(D[i, j], (D[i, k], D[k, j])) where k is a middle vertex i.e distance from i to j via k. :param graph: :return: """ vertex_idx_mapping: Dict[Vertex[T], int] = { vertex: i for i, (data, vertex) in enumerate(graph.vertices) } num_vertices: int = len(vertex_idx_mapping) distance_matrix: List[List[int]] = empty_2d_array(num_vertices, num_vertices, fill_default=maxsize) # populating distance from vertex u to v if there is any direct edge between them. for edge in graph.edges: idx_u: int = vertex_idx_mapping[edge.vertex1] idx_v: int = vertex_idx_mapping[edge.vertex2] distance_matrix[idx_u][idx_v] = edge.weight for i in range(0, num_vertices): # Diagonals...distance from a vertex to itself will be 0. distance_matrix[i][i] = 0 for k in range( 0, num_vertices ): # distance between i, j while considering k as middle vertex. for i in range(0, num_vertices): for j in range(0, num_vertices): if distance_matrix[i][k] == maxsize or distance_matrix[k][ j] == maxsize: continue else: distance_matrix[i][j] = min( distance_matrix[i][j], distance_matrix[i][k] + distance_matrix[k][j]) return distance_matrix, vertex_idx_mapping
def is_subset_sum_dp(arr, n, half_sum): rows = half_sum + 1 cols = n + 1 table = empty_2d_array(rows, cols) # initialize first row as True for col in range(0, cols): table[0][col] = True # initialize first column as False, except table[0][0] for row in range(1, rows): table[row][0] = False for row in xrange(1, rows): for col in xrange(1, cols): table[row][col] = table[row][col-1] or table[row - arr[col-1]][col-1] return table[half_sum][n]
def max_profit_dp(prices, rod_len): rows = len(prices) + 1 cols = rod_len + 1 table = empty_2d_array(rows, cols) for piece_len in range(0, rows): for r_len in range(0, cols): if piece_len == 0 or r_len == 0: table[piece_len][r_len] = 0 continue excl = table[piece_len - 1][r_len] if piece_len > r_len: table[piece_len][r_len] = excl else: incl = prices[piece_len - 1] + table[piece_len][r_len - piece_len] table[piece_len][r_len] = max(excl, incl) print(table) return table[rows - 1][cols - 1]
def is_subset_sum_dp(arr, n, half_sum): rows = half_sum + 1 cols = n + 1 table = empty_2d_array(rows, cols) # initialize first row as True for col in range(0, cols): table[0][col] = True # initialize first column as False, except table[0][0] for row in range(1, rows): table[row][0] = False for row in xrange(1, rows): for col in xrange(1, cols): table[row][col] = table[row][col - 1] or table[row - arr[col - 1]][col - 1] return table[half_sum][n]
if row >= n: return True for col in range(0, n): found_safe = True for queen in range(0, row): position = positions[queen] r = position[0] c = position[1] if c == col or r+c == row + col or r-c == row-col: found_safe = False break if found_safe: positions[row] = (row, col) if place_queens_v2(positions, n , row+1): return True return False if __name__ == '__main__': n = 4 print "\n********** V1 **********\n" board = empty_2d_array(n, n, fill_default=0) place_queens_v1(board, n) print board print "\n********** V2 **********\n" positions = empty_1d_array(n) place_queens_v2(positions, n) print positions
if row >= n: return True for col in range(0, n): found_safe = True for queen in range(0, row): position = positions[queen] r = position[0] c = position[1] if c == col or r + c == row + col or r - c == row - col: found_safe = False break if found_safe: positions[row] = (row, col) if place_queens_v2(positions, n, row + 1): return True return False if __name__ == '__main__': n = 4 print "\n********** V1 **********\n" board = empty_2d_array(n, n, fill_default=0) place_queens_v1(board, n) print board print "\n********** V2 **********\n" positions = empty_1d_array(n) place_queens_v2(positions, n) print positions