Exemple #1
0
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]
Exemple #2
0
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
Exemple #3
0
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]
Exemple #4
0
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]
Exemple #5
0
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]
Exemple #6
0
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
Exemple #7
0
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]
Exemple #8
0
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]
Exemple #9
0
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