简体   繁体   中英

Optimal Search Tree Using Python - Code Analysis

First of all, sorry about the naive question. But I couldn't find help elsewhere

I'm trying to create an Optimal Search Tree using Dynamic Programing in Python that receives two lists (a set of keys and a set of frequencies) and returns two answers:

1 - The smallest path cost.

2 - The generated tree for that smallest cost.

I basically need to create a tree organized by the most accessed items on top (most accessed item it's the root), and return the smallest path cost from that tree, by using the Dynamic Programming solution.

I've the following implemented code using Python:

def optimalSearchTree(keys, freq, n):
    #Create an auxiliary 2D matrix to store results of subproblems
    cost = [[0 for x in xrange(n)] for y in xrange(n)]

    #For a single key, cost is equal to frequency of the key
    #for i in xrange (0,n):
    #    cost[i][i] = freq[i]

    # Now we need to consider chains of length 2, 3, ... .
    # L is chain length.
    for L in xrange (2,n):
        for i in xrange(0,n-L+1):
            j = i+L-1
            cost[i][j] = sys.maxint
            for r in xrange (i,j):
                if (r > i):
                    c = cost[i][r-1] + sum(freq, i, j)
                elif (r < j):
                    c = cost[r+1][j] + sum(freq, i, j)
                elif (c < cost[i][j]):
                    cost[i][j] = c

    return cost[0][n-1]

def sum(freq, i, j):
    s = 0
    k = i
    for k in xrange (k,j):
        s += freq[k]
    return s

keys = [10,12,20]
freq = [34,8,50]
n=sys.getsizeof(keys)/sys.getsizeof(keys[0])
print(optimalSearchTree(keys, freq, n))

I'm trying to output the answer 1. The smallest cost for that tree should be 142 (the value stored on the Matrix Position [0][n-1], according to the Dynamic Programming solution). But unfortunately it's returning 0. I couldn't find any issues in that code. What's going wrong?

You have several very questionable statements in your code, definitely inspired by C/Java programming practices. For instance,

keys = [10,12,20]
freq = [34,8,50]
n=sys.getsizeof(keys)/sys.getsizeof(keys[0])

I think you think you calculate the number of items in the list. However, n is not 3:

sys.getsizeof(keys)/sys.getsizeof(keys[0])

3.142857142857143

What you need is this:

n = len(keys)

One more find: elif (r < j) is always True , because r is in the range between i (inclusive) and j (exclusive). The elif (c < cost[i][j]) condition is never checked. The matrix c is never updated in the loop - that's why you always end up with a 0.

Another suggestion: do not overwrite the built-in function sum() . Your namesake function calculates the sum of all items in a slice of a list:

sum(freq[i:j])
import sys
def optimalSearchTree(keys, freq):
#Create an auxiliary 2D matrix to store results of subproblems
n = len(keys)
cost = [[0 for x in range(n)] for y in range(n)]
storeRoot = [[0 for i in range(n)] for i in range(n)]

#For a single key, cost is equal to frequency of the key
for i in range (0,n):
    cost[i][i] = freq[i]

# Now we need to consider chains of length 2, 3, ... .
# L is chain length.
for L in range (2,n+1):
    for i in range(0,n-L+1):
        j = i + L - 1
        cost[i][j] = sys.maxsize
        for r in range (i,j+1):
            c = (cost[i][r-1] if r > i else 0)
            c += (cost[r+1][j] if r < j else 0)
            c += sum(freq[i:j+1])
            if (c < cost[i][j]):
                cost[i][j] = c
                storeRoot[i][j] = r
return cost[0][n-1], storeRoot

if __name__ == "__main__" :

keys = [10,12,20]
freq = [34,8,50]
print(optimalSearchTree(keys, freq))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM