I am trying to perform dynamic programming for approximate pattern matching in this code.Once the matrix is created,I am trying to trace back to my answer using the function trace.But when I run the program,the trace function is not returning any result and the program isn't getting terminated.
class Structure :
def __init__(self):
self.vertical =[]
self.horizontal =[]
self.diagnol=[]
def merge(self, s):
for i in s.vertical :
self.vertical.append(i)
for i in s.horizontal :
self.horizontal.append(i)
for i in s.diagonal:
self.diagonal.append(i)
def __str__(self):
return "horizontal \n"+str(self.horizontal) +"\n vertical \n"+str(self.vertical)+"\n diagonal"+str(self.diagonal)
def posList(pattern, text): #determine the positions in the matrix
retList = list()
textList = [x for x in text.strip()]
for i, char1 in enumerate(pattern):
textPos = [j for j, char2 in enumerate(textList) if char1==char2]
for j in textPos:
retList.append((i+1,j+1))
return retList
def trace(M,text,pattern,k) :
positions=posList(pattern,text)
struct = Structure()
for i in range(0,2):
for j in range(0,7):
while M[i,j]<=k and M[2,j]!=0:
if M[i,j] == M[i,j-1]+1:
struct.horizontal.append(j)
j -= 1
elif M[i,j] == M[i-1,j]+1:
struct.vertical.append(i)
i -= 1
elif (i+1,j+1)in positions and M[i,j]==M[i-1,j-1] :
struct.diagonal.append((i,j))
i -= 1
j -= 1
elif (i+1,j+1) not in positions and M[i,j]==M[i-1,j-1]+1 and M[i,j]==M[i-1,j]+1:
struct.vertical.append(i)
i-=1
print "error"
elif (i+1,j+1) not in positions and M[i,j]==M[i-1,j-1]+1 and M[i,j]==M[i,j-1]+1:
struct.horizontal.append(j)
j-=1
elif M[i,j]==M[i-1,j]+1 and M[i,j]==M[i,j-1]+1:
struct.vertical.append(i)
elif M[i,j]==M[i-1,j]+1 and M[i,j]==M[i,j-1]+1 and M[i,j]==M[i-1,j-1]+1:
struct.vertical.append(i)
i-=1
else :
pass
return struct
text='ACAGCAG'
pattern='GC'
n = len(pattern)
m = len(text)
text1=list(text)
pattern1=list(pattern)
M = [[0 0 0 0 0 0 0 0],[1 1 1 1 0 1 1 0],[2 2 1 2 1 0 1 1]]
#perform traceback
s= trace(M,text,pattern,1)
print s
s = trace(M, w, seq, max, 0, n-1)
print str(s)
print seq
result=real_string(s)
print "".join(result)
Can anyone suggest me where I maybe going wrong in the function ?
Related
So I tried coding a program to solve NQueen problem in python. It is only outputing correct response for n as 1 or 5. It doesn't throw an error or anything for the rest of numbers.
Here is the code:
import numpy as np
def isSafe(arr, row, col, n):
for ind in range(row):
if(arr[ind][col] == 1):
return False
x = row
y = col
while x >= 0 and y >= 0:
if arr[x][y] == 1:
return False
x -= 1
y -= 1
x = row
y = col
while x >= 0 and y < n:
if arr[x][y] == 1:
return False
x -= 1
y += 1
return True
def nQueen(arr, row, n):
if row >= n:
return True
for col in range(n):
if isSafe(arr,row,col,n) == True:
arr[row][col] = 1
if nQueen(arr, row+1, n) == True:
return True
return False
def main():
n = int(input("Enter the size of board: "))
arr = np.zeros((n,n)).astype(int)
if nQueen(arr, 0, n):
for x in range(n):
for y in range(n):
print(arr[x][y], end='\t')
print("\n")
else:
print("No Solution: ")
if __name__ == '__main__':
main()\
Using Lists:
import numpy as np
def isSafe(arr, row, col, n):
for ind in range(row):
if(arr[ind][col] == 1):
return False
x = row
y = col
while x >= 0 and y >= 0:
if arr[x][y] == 1:
return False
x -= 1
y -= 1
x = row
y = col
while x >= 0 and y < n:
if arr[x][y] == 1:
return False
x -= 1
y += 1
return True
def nQueen(arr, row, n):
if row >= n:
return True
for col in range(n):
if isSafe(arr,row,col,n) == True:
arr[row][col] = 1
if nQueen(arr, row+1, n) == True:
return True
return False
def main():
n = int(input("Enter the size of board: "))
arr = [[0]*n]*n
if nQueen(arr, 0, n):
for x in range(n):
for y in range(n):
print(arr[x][y], end='\t')
print("\n")
else:
print("No Solution: ")
if __name__ == '__main__':
main()
I tried using every single integer from 0 to 20 but only 1 and 5 seemed to output something while any other number just outputted "No Solution".
Also, The lists one doesnt even output an answer for 5, just 1
When you determine that an assignment arr[row][col] is not safe, you never reset it for future tests.
def nQueen(arr, row, n):
if row >= n:
return True
for col in range(n):
if isSafe(arr,row,col,n) == True:
arr[row][col] = 1 # Put a queen here
if nQueen(arr, row+1, n) == True:
return True
arr[row][col] = 0 # Take it back; it didn't work here
return False
I have to design an algorithm to sort a list of orders by selection time (t selection, finding the good in the warehouse and bringing it to the surface) plus shipping time (t shipping, constant). The customer orders can be retrieved (in the same order as placed) from a server database. You should expect between 100-10K elements.
The program takes as input a data-set of orders where the id, t selection, and t shipping are of type unsigned int, n is the number of orders and a space character.
id1, t selection1, t shipping1; ...; idn, t selectionn, t shippingn \n
The expected output is a space-separated list of the ids, sorted by t selection + t shipping and terminated by a new line \n.
Input: 1, 500, 100; 2, 700, 100; 3, 100, 100\n
Output: 3 1 2\n
I am trying to do it with merge sort, however my program returns
1 2 3/n instead of 3 1 2/n
I have provided my code below, could anyone help me out?
#!/usr/bin/env python3
import sys
class Order:
def __init__(self, id: int, selection_time: int, shipping_time: int):
self.id: int = id
self.selection_time: int = selection_time
self.shipping_time: int = shipping_time
def merge(left, right):
if not len(left) or not len(right):
return left or right
result = []
i, j = 0, 0
while len(result) < len(left) + len(right):
if left[i].shipping_time + left[i].selection_time < right[j].shipping_time + right[j].selection_time:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
if i == len(left) or j == len(right):
result.extend(left[i:] or right[j:])
break
return result
def sort(list):
if len(list) < 2:
return list
middle = int(len(list) / 2)
left = sort(list[:middle])
right = sort(list[middle:])
return merge(left, right)
if __name__ == '__main__':
'''
Retrieves and splits the input
'''
data = input()
data = data.split('; ')
order_list = []
for d in data:
id, selection_t, shipping_t = d.split(', ', 2)
order: Order = Order(int(id), int(selection_t), int(shipping_t))
order_list.append(order)
sort(order_list)
for order in order_list:
sys.stdout.write(str(order.id))
sys.stdout.write(" ")
The simplest (and probably least efficient) sorting algorithm is the Bubble sort. But the question says nothing about performance so it can be simplified like this:
class Order:
def __init__(self, ident, selection_time, shipping_time):
self._ident = ident
self._selection_time = selection_time
self._shipping_time = shipping_time
#property
def selection_time(self):
return self._selection_time
#property
def shipping_time(self):
return self._shipping_time
#property
def ident(self):
return self._ident
def merge(lst):
def comboval(order):
return order.selection_time + order.shipping_time
if len(lst) > 1:
mid = len(lst) // 2
left = lst[:mid]
right = lst[mid:]
merge(left)
merge(right)
i = j = k = 0
while i < len(left) and j < len(right):
if comboval(left[i]) < comboval(right[j]):
lst[k] = left[i]
i += 1
else:
lst[k] = right[j]
j += 1
k += 1
for _i in range(i, len(left)):
lst[k] = left[_i]
k += 1
for _j in range(j, len(right)):
lst[k] = right[_j]
k += 1
return lst
inval = '1, 500, 100; 2, 700, 100; 3, 100, 100'
orderlist = []
for order in inval.split(';'):
orderlist.append(Order(*map(int, order.split(','))))
print(*[order.ident for order in merge(orderlist)])
Output:
3 1 2
Note:
This is an in-place sort
I tried to implement merge-sort in Python. Somehow this piece of code runs correctly (and pretty fast), but I don't know why: There is no return-statement in mergeSort()
from sys import stdin
def mergeSort(A):
if len(A) > 1:
m = int(len(A)/2)
L = A[:m]
R = A[m:]
mergeSort(L)
mergeSort(R)
l = 0
r = 0
a = 0
while l < len(L) and r < len(R):
if L[l] < R[r]:
A[a] = L[l]
l += 1
else:
A[a] = R[r]
r += 1
a += 1
while l < len(L):
A[a] = L[l]
l += 1
a += 1
while r < len(R):
A[a] = R[r]
r += 1
a += 1
def main():
A = []
for line in stdin:
A.append(int(line))
mergeSort(A)
print(A)
if __name__ == "__main__":
main()
I am following Cormen Leiserson Rivest Stein (clrs) book and came across "kmp algorithm" for string matching. I implemented it using Python (as-is).
However, it doesn't seem to work for some reason. where is my fault?
The code is given below:
def kmp_matcher(t,p):
n=len(t)
m=len(p)
# pi=[0]*n;
pi = compute_prefix_function(p)
q=-1
for i in range(n):
while(q>0 and p[q]!=t[i]):
q=pi[q]
if(p[q]==t[i]):
q=q+1
if(q==m):
print "pattern occurs with shift "+str(i-m)
q=pi[q]
def compute_prefix_function(p):
m=len(p)
pi =range(m)
pi[1]=0
k=0
for q in range(2,m):
while(k>0 and p[k]!=p[q]):
k=pi[k]
if(p[k]==p[q]):
k=k+1
pi[q]=k
return pi
t = 'brownfoxlazydog'
p = 'lazy'
kmp_matcher(t,p)
This is a class I wrote based on CLRs KMP algorithm, which contains what you are after. Note that only DNA "characters" are accepted here.
class KmpMatcher(object):
def __init__(self, pattern, string, stringName):
self.motif = pattern.upper()
self.seq = string.upper()
self.header = stringName
self.prefix = []
self.validBases = ['A', 'T', 'G', 'C', 'N']
#Matches the motif pattern against itself.
def computePrefix(self):
#Initialize prefix array
self.fillPrefixList()
k = 0
for pos in range(1, len(self.motif)):
#Check valid nt
if(self.motif[pos] not in self.validBases):
self.invalidMotif()
#Unique base in motif
while(k > 0 and self.motif[k] != self.motif[pos]):
k = self.prefix[k]
#repeat in motif
if(self.motif[k] == self.motif[pos]):
k += 1
self.prefix[pos] = k
#Initialize the prefix list and set first element to 0
def fillPrefixList(self):
self.prefix = [None] * len(self.motif)
self.prefix[0] = 0
#An implementation of the Knuth-Morris-Pratt algorithm for linear time string matching
def kmpSearch(self):
#Compute prefix array
self.computePrefix()
#Number of characters matched
match = 0
found = False
for pos in range(0, len(self.seq)):
#Check valid nt
if(self.seq[pos] not in self.validBases):
self.invalidSequence()
#Next character is not a match
while(match > 0 and self.motif[match] != self.seq[pos]):
match = self.prefix[match-1]
#A character match has been found
if(self.motif[match] == self.seq[pos]):
match += 1
#Motif found
if(match == len(self.motif)):
print(self.header)
print("Match found at position: " + str(pos-match+2) + ':' + str(pos+1))
found = True
match = self.prefix[match-1]
if(found == False):
print("Sorry '" + self.motif + "'" + " was not found in " + str(self.header))
#An invalid character in the motif message to the user
def invalidMotif(self):
print("Error: motif contains invalid DNA nucleotides")
exit()
#An invalid character in the sequence message to the user
def invalidSequence(self):
print("Error: " + str(self.header) + "sequence contains invalid DNA nucleotides")
exit()
You might want to try out my code:
def recursive_find_match(i, j, pattern, pattern_track):
if pattern[i] == pattern[j]:
pattern_track.append(i+1)
return {"append":pattern_track, "i": i+1, "j": j+1}
elif pattern[i] != pattern[j] and i == 0:
pattern_track.append(i)
return {"append":pattern_track, "i": i, "j": j+1}
else:
i = pattern_track[i-1]
return recursive_find_match(i, j, pattern, pattern_track)
def kmp(str_, pattern):
len_str = len(str_)
len_pattern = len(pattern)
pattern_track = []
if len_pattern == 0:
return
elif len_pattern == 1:
pattern_track = [0]
else:
pattern_track = [0]
i = 0
j = 1
while j < len_pattern:
data = recursive_find_match(i, j, pattern, pattern_track)
i = data["i"]
j = data["j"]
pattern_track = data["append"]
index_str = 0
index_pattern = 0
match_from = -1
while index_str < len_str:
if index_pattern == len_pattern:
break
if str_[index_str] == pattern[index_pattern]:
if index_pattern == 0:
match_from = index_str
index_pattern += 1
index_str += 1
else:
if index_pattern == 0:
index_str += 1
else:
index_pattern = pattern_track[index_pattern-1]
match_from = index_str - index_pattern
Try this:
def kmp_matcher(t, d):
n=len(t)
m=len(d)
pi = compute_prefix_function(d)
q = 0
i = 0
while i < n:
if d[q]==t[i]:
q=q+1
i = i + 1
else:
if q != 0:
q = pi[q-1]
else:
i = i + 1
if q == m:
print "pattern occurs with shift "+str(i-q)
q = pi[q-1]
def compute_prefix_function(p):
m=len(p)
pi =range(m)
k=1
l = 0
while k < m:
if p[k] <= p[l]:
l = l + 1
pi[k] = l
k = k + 1
else:
if l != 0:
l = pi[l-1]
else:
pi[k] = 0
k = k + 1
return pi
t = 'brownfoxlazydog'
p = 'lazy'
kmp_matcher(t, p)
KMP stands for Knuth-Morris-Pratt it is a linear time string-matching algorithm.
Note that in python, the string is ZERO BASED, (while in the book the string starts with index 1).
So we can workaround this by inserting an empty space at the beginning of both strings.
This causes four facts:
The len of both text and pattern is augmented by 1, so in the loop range, we do NOT have to insert the +1 to the right interval. (note that in python the last step is excluded);
To avoid accesses out of range, you have to check the values of k+1 and q+1 BEFORE to give them as index to arrays;
Since the length of m is augmented by 1, in kmp_matcher, before to print the response, you have to check this instead: q==m-1;
For the same reason, to calculate the correct shift you have to compute this instead: i-(m-1)
so the correct code, based on your original question, and considering the starting code from Cormen, as you have requested, would be the following:
(note : I have inserted a matching pattern inside, and some debug text that helped me to find logical errors):
def compute_prefix_function(P):
m = len(P)
pi = [None] * m
pi[1] = 0
k = 0
for q in range(2, m):
print ("q=", q, "\n")
print ("k=", k, "\n")
if ((k+1) < m):
while (k > 0 and P[k+1] != P[q]):
print ("entered while: \n")
print ("k: ", k, "\tP[k+1]: ", P[k+1], "\tq: ", q, "\tP[q]: ", P[q])
k = pi[k]
if P[k+1] == P[q]:
k = k+1
print ("Entered if: \n")
print ("k: ", k, "\tP[k]: ", P[k], "\tq: ", q, "\tP[q]: ", P[q])
pi[q] = k
print ("Outside while or if: \n")
print ("pi[", q, "] = ", k, "\n")
print ("---next---")
print ("---end for---")
return pi
def kmp_matcher(T, P):
n = len(T)
m = len(P)
pi = compute_prefix_function(P)
q = 0
for i in range(1, n):
print ("i=", i, "\n")
print ("q=", q, "\n")
print ("m=", m, "\n")
if ((q+1) < m):
while (q > 0 and P[q+1] != T[i]):
q = pi[q]
if P[q+1] == T[i]:
q = q+1
if q == m-1:
print ("Pattern occurs with shift", i-(m-1))
q = pi[q]
print("---next---")
print("---end for---")
txt = " bacbababaabcbab"
ptn = " ababaab"
kmp_matcher(txt, ptn)
(so this would be the correct accepted answer...)
hope that it helps.
I am not sure why do i get this error from the console:
<<
print stirngp[state[i][j]]
^
SyntaxError: invalid syntax
<<
Furthermore it seems that the IDE put a red close on the following code line
line = raw_input("Enter:")
I am not sure what did i do wrong, the following code is as shown below
def isTerminal(state):
stateT = zip(*state)
for i in range(3):
if all(state[i][0] == j for j in state[i]) and state[i][0] != 0:
return state[i][0]
if all(stateT[i][0] == j for j in stateT[i]) and stateT[i][0] != 0:
return stateT[i][0]
if (state[0][0] == state[1][1] == state[2][2]) or \
(state[0][2] == state[1][1] == state[2][0]):
if state[1][1] != 0:
return state[1][1]
for i in range(3):
if 0 in state[i]:
return None
return 0
def succ(state):
# print state
countX = 0
countO = 0
for i in range(3):
for j in range(3):
if state[i][j] == 1: countX = countX + 1
if state[i][j] == -1: countO = countO + 1
if countX > countO:
player = "MIN"
else:
player = "MAX"
succList = []
v = {"MIN":-1,"MAX":1}
for i in range(3):
for j in range(3):
if state[i][j] == 0:
succ = [k[:] for k in state]
succ[i][j] = v[player]
succList = succList + [succ]
# print succList
return succList
def nextplay(player):
if player == "MIN":
return "MAX"
else:
return "MIN"
def minimax(state,alpha,beta,player):
value = isTerminal(state)
if value != None:
# print "TERMINAL:", state, value, player
return value
if player == "MIN":
for y in succ(state):
beta = min(beta, minimax(y,alpha,beta,"MAX"))
if beta <= alpha: return alpha
return beta
if player == "MAX":
for y in succ(state):
alpha = max(alpha, minimax(y,alpha,beta,"MIN"))
if alpha >= beta: return beta
return alpha
def printing(state):
p = {-1:"O",0:".",1:"X"}
for i in range(3):
for j in range(3):
print p[state[i][j]],
print ""
print ""
def main():
state = [[0,0,0],
[0,0,0],
[0,0,0]]
val = isTerminal(state)
while val == None:
line = raw_input("Enter:")
x = line.split(",")
a = int(x[0]); b = int(x[1])
state[a][b] = 1
if isTerminal(state) != None:
printing(state)
return
# determine which successive state is better
succList = succ(state)
succValList = []
for i in succList:
succValList = succValList + [(minimax(i,-1,1,"MAX"),i)]
succValList.sort(key=lambda x:x[0])
state = succValList[0][1] # can also randomly choose other states of the same minimax value
printing(state)
val = isTerminal(state)
if __name__ == '__main__':
main()
As far as i know you can't use raw_input() in Python 3. It's been changed to just input()
http://docs.python.org/dev/whatsnew/3.0.html
also what is stringp? is it an existing list?
if so then state[i][j] MUST return an integer so you can retrieve the item at that index of stringp[]