Find all subset sum using dynamic programming - python

I want to use dynamic programming to find all subset of an array that sums to a target,like:
arr = [1,3,2,4]
target = 6
output:
[1,3,2],[2,4]
How can i modify the code to get solution? thanks
def CheckSubsetSum(S, M):
n = len(S)
subset = np.array([[True]*(M+1)]*(n+1))
for i in range(0,n):
subset[i,0] = True
for j in range(1,M+1):
subset[0,j] =False
for i in range(1,n+1):
for j in range(1,M+1):
if j<S[i-1]:
subset[i,j] = subset[i-1,j]
else:
subset[i,j] = subset[i-1,j] or subset[i-1,j-S[i-1]]
print(subset)
CheckSubsetSum([1,3,2,4],6)

Related

How to implement a moving average?

I've got a distribution of numbers in an array called predictions and I wanted a moving average. I am new to Python, so I've not used numpy here, just ordinary arrays. My question is there a more graceful way of doing this?
Here is the code:
predictions = [] #Already filled with 7001 values
movingaverage = []
pmean = []
n=-1
count = 0
sumpm = 0
for z in range(40000):
n+=1
count+=1
pmean.append(predictions[n])
if(count == 5):
for j in range(5):
sumpm+=pmean[j]
sumpm=sumpm/5
movingaverage.append(sumpm)
n=n-5
pmean = []
sumpm=0
count = -1
The size of predictions array is 7001 or can use len(predictions).
Here is something I wrote in the past
def moving_average(a: list, n: int) -> list:
"""
:param a: array of numbers
:param n: window of the moving average
:return: the moving average sequence
"""
moving_sum = sum(a[:n])
moving_averages = [moving_sum/n]
for i in range(n, len(a)):
moving_sum += a[i] - a[i - n]
moving_averages.append(moving_sum / n)
return moving_averages

How could I shuffle a list to this rule?

I am trying to make an algorithm to shuffle a list and then make a new list of all the combinations according to this rule:
You are only allowed to swap one pair. For example:
array = [1, 2, 3]
[3, 2, 1] #number at index 0 switched with number at index 2
Any thoughts on how to write it?
Edit:
Saschas code worked well. I wrote this code before asking the question:
sols = []
for i in range(len(a)):
for j in range(len(a)):
a[i] = a[j]
a[j] = a[i]
sols_perm.append(a)
I was aware that I would get some identical elements in the list because of unordered pairs but it just created a list full of identical elements. Any thoughts why?
sols = []
for i in range(len(array)):
for j in range(i+1, len(array)): # symmetry-reduction -> ordered pairs
sol = array[:] # copy list
sol[i], sol[j] = sol[j], sol[i] # swap
sols.append(sol)
Try the function below:
def swap(inlist):
n = len(inlist)
res = [x for x in inlist]
for i in range(n):
for j in range(i+1, n):
tmp = res[i]
res[i] = res[j]
res[j] = tmp
return res

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))

python error - "IndexError: list index out of range"

I'm really new at Python so I apologize in advance if this is a really dumb question. Pretty much, I'm writing a longest common subsequence algorithm with dynamic programming.
Whenever I try to run it, I get the IndexError: list index out of range, and I don't know why because the array I'm adding values to never changes in size. Code snippet for clarity:
def LCS(sequence1, sequence2):
n = len(sequence1)
m = len(sequence2)
D = [[0 for num in range(0,n)]for number in range(0, m)]
for i in range(1, n):
for j in range(1, m):
if(sequence1[i] == sequence2[j]):
D[i][j] = D[i-1][j-1] + 1
else:
D[i][j] = max(D[i-1][j], D[i][j-1])
print D[n][m]
There seem to be two problems:
In the definition of D, you should swap n and m
D = [[0 for num in range(0, m)] for number in range(0, n)]
You have to print (or better: return) the last element of the matrix
return D[n-1][m-1] # or just D[-1][-1]
The issue is with total rows and columns of the matrix(D). Size should be (m+1)*(n+1) and then loop over the matrix. Otherwise you need to return D[m-1][n-1].
def LCS(sequence1, sequence2):
n = len(sequence1)
m = len(sequence2)
D = [[0 for num in range(0,n+1)]for number in range(0, m+1)]
for i in range(1, n+1):
for j in range(1, m+1):
if(sequence1[i-1] == sequence2[j-1]):
D[i][j] = D[i-1][j-1] + 1
else:
D[i][j] = max(D[i-1][j], D[i][j-1])
print D[n][m]
LCS('abcdef' , 'defjkl')

Knapsack algorithm dynamic programming .(incorrect output) here is what I have so far

I wrote this code for dynamic programming implementation of the knapsack problem.
#B = maximum weight
#n = number of items
#p = list of weights
#a = list of values
#p[i] = weight with value a[i]
def maximum_attractiveness(n, B, p, a):
f = [i for i in range(n+1)]
m = [f for i in range(B+1)]
m[0] = [0 for i in range(len(m[0]))]
for i in m:
i[0] = 0
print(m)
for j in range(n):
for w in range(B):
if (p[j]) > (w):
m[w][j] = m[w][j-1]
else:
m[w][j] = max(m[w][j-1],m[w-p[j]][j-1]+a[j])
return m[B][n]
I get an incorrect output for this algorithm. where did I go wrong?
f = [i for i in range(n+1)]
m = [f for i in range(B+1)]
This uses the same array f for every position m, so for example if you change m[1][k], you also change m[i][k] for every i. You probably meant to do
m = [[i for i in range(n+1)] for i in range(B+1)]
There might be some other bugs I think, so maybe you should print out the intermediate arrays at some points to check out where the results are not what you'd expect them to be.
UPDATE:
Your initialization seems strange to me. I think it should be just m = [[0]*n for i in range(B+1)] because you need a matrix of zeroes.
it should be for w in range(B+1)
you should not return m[B][n], but max(m[j][n] for j in range(B+1)).
My attempt, which avoids the the matrix altogether and only uses a single array:
m = [0]*(B+1)
for j in range(n):
for w in range(B,p[j]-1,-1):
m[w] = max(m[w], m[w-p[j]] + a[j])
return max(m)

Categories