A bug in my simple python program of lcs - python

import numpy as np
def lcs(i, j):
global x, y, c
if i <= 0 or j <= 0:
return 0
else:
if c[i][j] < 0:
if x[i - 1] == y[j - 1]:
c[i][j] = lcs(i - 1, j - 1) + 1
else:
m = lcs(i - 1, j)
n = lcs(i, j - 1)
print m, n
c[i][j] = max(m, n)
else: return c[i][j]
c = np.zeros((8, 8), int)
c = c - 1
x = 'ABCBDAB'
y = 'BDCABA'
lcs(7, 6)
print c
the program has bugs so i lookup the 'm','n',
the print results come up with 'None'
ex:
0 0
0 None
0 None
0 None
None None
then the program occur an error:
TypeError: long() argument must be a string or a number, not 'NoneType'
i don't know where the 'None' comes
i'm a newer, thanks

i don't know where the 'None' comes
If you don't return anything, the return value of a python function is None.
In particular, you don't return anything in the if c[i][j] < 0: branch.

Related

Not able to append List to List Python ( N-Queen Problem )

I'm a beginner in Leetcode & Python and I tried to solve the N-Queen Problem. Below is the solution in Python which passed submission
class Solution:
def solveNQueens(self, n: int) -> List[List[str]]:
def isSafe(row, x_col):
# check row
for x in range(n):
if placed[row][x] is True and x != x_col:
return False
# check column
for x in range(n):
if placed[x][x_col] is True and x != row:
return False
# check diagnol
i, j = row, x_col
while i > 0 and j < n - 1:
if placed[i - 1][j + 1] is True:
return False
i -= 1
j += 1
i, j = row, x_col
while i < n - 1 and j < 0:
if placed[i + 1][j - 1] is True:
return False
i -= 1
j += 1
# #check offdiagnol
i, j = row, x_col
while i > 0 and j > 0:
if placed[i - 1][j - 1] is True:
return False
i -= 1
j -= 1
i, j = row, x_col
while i < n-1 and j < n-1:
if placed[i][j] is True:
return False
i += 1
j += 1
return True
def process(currconfig, matrix, n, row):
#base condition
if row == n:
curr = []
for x in range(n):
curr.append(currconfig[x])
totalconfig.append(currconfig)
return
for x_col in range(n):
if isSafe(row, x_col):
path = x_col * '.' + 'Q' + (n - x_col - 1) * '.'
currconfig.append(path)
matrix[row][x_col] = True
#process recursively called
process(currconfig, matrix, n, row + 1)
currconfig.pop()
matrix[row][x_col] = False
configuration = []
totalconfig = []
placed = [[False for _ in range(n)] for _ in range(n)]
process(configuration, placed, n, 0)
return totalconfig
a = Solution()
print(a.solveNQueens(4))
I only have a doubt about the base condition of the process function. In the process function's base condition I initially did this and got empty Lists appended to totalconfig no matter what, CASE I:
def process(currconfig, matrix, n, row):
if row == n:
totalconfig.append(currconfig)
return
so spent a few hours trying to get around the problem and weirdly enough for me this worked, CASE II :
def process(currconfig, matrix, n, row):
if row == n:
curr = []
for x in range(n):
curr.append(currconfig[x])
totalconfig.append(currconfig)
return
I don't get why the CASE I did not work but CASE II worked. What am I missing...How is "currconfig" in CASE I different from "curr" in CASE II
it looks like you are not using functions (methods) in classes correctly.
Basically, the first argument is the self which refers to itself. In your case, currconfig is self.
So presumably the function should have looked like this:
def process(self, currconfig, matrix, n, row): # <---added self
if row == n:
totalconfig.append(currconfig)
return

Number of subsets with a given sum . Recursion not tracing few branches of the tree

I have written this code in python and it is not yielding the right answer for the input wt[]=[2,3,5,6,8,10] in this order . It is giving right answer for few other combinations like wt[]=[3,2,6,10,8,5].I I have also tried tracing the recursive tree to debug accordingly but still cannot figure out why the code is not tracing some branches of the tree.
Kindly please help me figure out the problem.
Thank you!
n=6 #int(input())
m=10 #int(input())
wt=[2,3,5,6,8,10]
dp_table=[[-1 for i in range(n+1)]for j in range (m+1)]
total=[0]
def SS(m,n):
a=0
b=0
if m==0:
print(n-1)
total[0]=total[0]+1
return 0;
if n==0:
return 0;
else:
if wt[n-1]>m:
return (SS(m,n-1));
else:
if dp_table[m-wt[n-1]][n-1]==-1:
a=SS(m-wt[n-1],n-1) + wt[n-1]
if dp_table[m][n-1]==-1:
b=SS(m,n-1)
dp_table[m][n]=max(a,b)
return dp_table[m][n];
if m==0 or n==0:
print("Not Possible!")
if SS(m,n)==m:
print("Possible and the no of subsets with equal sum are: ",total[0])
else:
print("False")
You're storing results in dp_table but never using them (giving incorrect results). If the dp_table value of an entry isn't -1, you're ignoring the result (and assuming it's always 0).
Often it's better to do the cache-checks at the top of the function (or better yet, use functools.cache).
If you really want to keep the code structured as it is now, this will fix the issue:
def SS(m, n):
a = dp_table[m - wt[n - 1]][n - 1]
b = dp_table[m][n - 1]
if m == 0:
total[0] += 1
return 0
if n == 0:
return 0
else:
if wt[n - 1] > m:
dp_table[m][n] = b if b != -1 else SS(m, n - 1)
else:
if a == -1:
a = SS(m - wt[n - 1], n - 1)
a += wt[n - 1]
if b == -1:
b = SS(m, n - 1)
dp_table[m][n] = max(a, b)
return dp_table[m][n]
If you want to do the caching yourself, you can put cache checks at the top (a better approach), rather than putting a check (and an if-else statement) before every recursive call, like this:
def SS2(m, n):
if dp_table[m][n] != -1:
return dp_table[m][n]
if m == 0:
total[0] += 1
dp_table[m][n] = 0
elif n == 0:
dp_table[m][n] = 0
else:
if wt[n - 1] > m:
dp_table[m][n] = SS(m, n - 1)
else:
dp_table[m][n] = max(SS(m - wt[n - 1], n - 1) + wt[n - 1], SS(m, n - 1))
return dp_table[m][n]
But the most 'Pythonic' and least work alternative is to use the decorators built into the standard library. You can limit the total memory usage, and it might even be faster if your manual DP-table happens to have cache-unfriendly access patterns.
import functools
#functools.cache
def SS3(m, n):
if m == 0:
total[0] += 1
return 0
elif n == 0:
return 0
else:
if wt[n - 1] > m:
return SS(m, n - 1)
else:
return max(SS(m - wt[n - 1], n - 1) + wt[n - 1], SS(m, n - 1))

What's the recursion formula in the following code to solve the 3-Partition Problem in DP method

I have a python code which solves the 3-Partition problem using Dynamic Programming method. But I don't really understand how he utilizes the DP method. Could anyone tell me what is the recursion formula in this code and why it works? (Especially the middle loop part)
import sys
def partition3(A):
n = len(A)
if sum(A)%3 != 0:
return 0
W = sum(A)//3
value = [[[0 for x in range(W+1)] for y in range(W+1)] for z in range(len(A)+1)]
#print("dimension,n:",len(value[0][0]), len(A))
value[0][0][0] = 1
for idx in range(len(A)+1):
value[idx][0][0] = 1
for i in range(1, n+1):
for j in range(W+1):
for k in range(W+1):
value[i][j][k] = value[i-1][j][k]
if (j >= A[i-1] and value[i-1][j-A[i-1]][k]):
value[i][j][k] = 1
if (k >= A[i-1] and value[i-1][j][k-A[i-1]]):
value[i][j][k] = 1
for idx in range(n+1):
print(value[idx][0][:])
if(value[len(A)][W][W] == 1):
return 1
else:
return 0
if __name__ == '__main__':
input = sys.stdin.read()
n, *A = list(map(int, input.split()))
print(partition3(A))

python backtracking knapsack

This is the code I have thus far:
def frac_knapsack(n,size, profit,K):
if K <= 0:
return 0
for i in range(0,i):
if profit[i]/size[i]>profit[i-1]/size[i-1]:
profit.append[i] and size.append[i]
s = 0
p = 0
for i in range(n):
if s + size[i] <= K:
p += profit[i]
s += size[i]
else:
p += (K-s) * (profit[i]/size[i])
s = K
break
return p
def Knapsack(i, size):
if i > n or size <= 0:
print(x)
return
if x[j] == 1:
for j in range(0,i-1):
p+=P[j]
if x[j] == 1:
for j in range(0,i-1):
s+=S[j]
if x[i] == 1:
if s+size[i] <= K and (p + profit[i] + B) > MaxProfit:
B = fractional_Knapsack(n-(i+1), size[i+1:], profit[i+1:], T-size[i])
if p+profit[i] > MaxProfit:
MaxProfit=p+profit[i]
x=solution
Knapsack(i+1, T-size[i])
if x[i] == 0:
B = frac_Knapsack(n-(i+1), size[i+1:], profit[i+1:], T)
if (p + B) > MaxProfit:
Knapsack(i+1, T)
I have a problem with sorting in line 4. I have to sort it as weight-efficiency. do i need to use quick sort algorithm?
I want to make input for four things:
n,size,profit and K
do i need to use map? as size and profit is list?
You used
B = fractional_Knapsack(n-(i+1), size[i+1:], profit[i+1:], T)
your method is called
def frac_knapsack(n,size, profit,K):

Why does this code print None?

The Ackermann's Function had been tried to implement through the following code
def A(m, n):
if m == 0:
return n + 1
elif m > 0 and n == 1:
A(m - 1, 1)
elif m > 0 and n > 0:
A(m - 1, A(m, n - 1))
print A(4, 5)
Your function doesn't return anything for 2 of the 3 branches of the if statements; only if m == 0 do you explicitly return a value.
You need to return the results of recursive calls too:
def A(m, n):
if m == 0:
return n + 1
elif m > 0 and n == 1:
return A(m - 1, 1)
elif m > 0 and n > 0:
return A(m - 1, A(m, n - 1))
Without an explicit return, the function ends with the default return value of None.

Categories