The aim of this program is to build a 3x3 matrix which then reduces additional rows, but, for some reason, after the second row is added to M in the while loop, it replaces it with the new row, rather than adding a third row, and, then, reducing additional (most likely 3) vectors after that. Here's the code:
from sympy import *
init_printing(use_unicode= True)
A = []
def reduceOneRow(M):
k = 0
for i in range(k,min(M.shape)-1):
if M[i,i]!=0 or i ==2:
for j in range(k,min(M.shape)-1):
T = Matrix([M.row(j+1)-(M[j+1,i]/M[i,i])*M.row(i)])
A.append(M[j+1]/M[i,i])
M.row_del(j+1)
M = M.row_insert(j+1,T)
k = k+1
else:
i = i+1
return M
# M = Matrix([[1,1,1],[1,4,7],[3,2,5]])
# reduceOneRow(M)
# A
#The following block of code generates a list of monomials, but not in reverse
#lexicagraphical order. This can be fixed later. Ultimately, I'd like to
#make it it's own function
sigma = symbols('x1:4')
D = [1]
for d in D:
for s in sigma:
if s*d not in D:
D.append(s*d)
if len(D) > 20:
break
# print(D)
# print(D[9].subs([('x1',4),('x2',2),('x3',3)]))
#We begin with the set up described in C1
P = [(1,2,3),(4,5,6),(7,8,9)]
G = []
Q = []
S = []
L = [1]
M = Matrix([])
#Here we being step C2.
while L != []:#what follows this while statement is the loop C2-C5 and back
t = L[0]
L.remove(L[0])
K = Matrix([]) #K is a kind of bucket matrix
if t==1: #this block generates the firs line in M. It had to be separate
for j in range(len(P)):#because of the way sympy works. 1 is int, rather
K = K.col_insert(j,Matrix([1])) #than a symbol
else: #here we generate all other rows of M, using K for the name of the rows
for p in P:
K = K.col_insert(0,Matrix([t.subs([(sigma[0],p[0]),(sigma[1],p[1]),(sigma[2],p[2])])]))
# K = K.col_insert(i,Matrix([t.subs([(sigma[0],p[0]),(sigma[1],p[1]),(sigma[2],p[2])]))
M = M.row_insert(min(M.shape)+1,K) #K gets added to M
M
A = []
reduceOneRow(M)#row reduces M and produces the ai in C3
sum = 0
for n in range(len(A)):
sum = sum + A[n]*S[n]
V = M.row(-1)
if V == zeros(1,len(V)):
G.append(t - sum)
M.row_del(-1)
else:
S.append(t-sum)
Q.append(t)
for i in range(1,4):
#if not t*D[i] == Q[0]:
L.append(t*D[i])
L
print('G =',' ',G,' ','Q =',Q)
I figure it out. I changed 'reduceRowOne(M)' to 'M = reduceRowOne'. Ugh.
Thank you all who took a look at this!
Related
I have this code, which runs an algorithm called Tomkins-Paige algorithm. The algorithm creates permutations of a sequence.
The problem is that the code prints the different permutations p, but when i try to append it to a list, it only appends the initial p, i.e. p = [1,2,3,4].
import numpy as np
n = 4
p = [i for i in range(1,n+1)]
c = [1 for i in range(1,n+1)]
i = 2
print(p)
listp = []
while i <= n:
shift = np.roll(p[:i],-1)
for k in range(len(shift)):
p[k] = shift[k]
if c[i-1] < i:
c[i-1] += 1
i = 2
print(p, c, i )
listp.append(p)
else:
c[i-1] = 1
i += 1
more information about the algorithm: https://en.wikipedia.org/wiki/Tompkins%E2%80%93Paige_algorithm
Thanks in advance :)
How to solve set cover if each group and each element has its own cost.
I came up with a greedy algorithm for this, but it does not work in all cases. Need an accurate algorithm.
That's all I could find on this topic:
this and this
But there the algorithm does not work considering the cost of the groups, and the cost of each element separately.
Please tell me what I can use to solve this problem.
from queue import PriorityQueue
N = int(input())
dct = {}
groups = PriorityQueue()
for i in range(N):
a,c = [int(j) for j in input().split()]
dct[a] = c
M = int(input())
for i in range(M):
k,c = [int(j) for j in input().split()]
s = 0
tmp = []
for j in input().split():
j_=int(j)
if j_ in dct:
s+=dct[j_]
tmp.append(j_)
d = c-s
if d<0:
groups.put([d, c, tmp])
s = 0
while not groups.empty():
#print(dct)
#for i in groups.queue:
# print(i)
g = groups.get()
if g[0]>0:
break
#print('G',g)
#print('-------')
for i in g[2]:
if i in dct:
del(dct[i])
s += g[1]
groups_ = PriorityQueue()
for i in range(len(groups.queue)):
g_ = groups.get()
s_ = 0
tmp_ = []
for i in g_[2]:
if i in dct:
s_+=dct[i]
tmp_.append(i)
d = g_[1]-s_
groups_.put([d, g_[1], tmp_])
groups = groups_
for i in dct:
s+=dct[i]
print(s)
Im trying to solve the following Codewars problem: https://www.codewars.com/kata/sum-of-pairs/train/python
Here is my current implementation in Python:
def sum_pairs(ints, s):
right = float("inf")
n = len(ints)
m = {}
dup = {}
for i, x in enumerate(ints):
if x not in m.keys():
m[x] = i # Track first index of x using hash map.
elif x in m.keys() and x not in dup.keys():
dup[x] = i
for x in m.keys():
if s - x in m.keys():
if x == s-x and x in dup.keys():
j = m[x]
k = dup[x]
else:
j = m[x]
k = m[s-x]
comp = max(j,k)
if comp < right and j!= k:
right = comp
if right > n:
return None
return [s - ints[right],ints[right]]
The code seems to produce correct results, however the input can consist of array with up to 10 000 000 elements, so the execution times out for large inputs. I need help with optimizing/modifying the code so that it can handle sufficiently large arrays.
Your code inefficient for large list test cases so it gives timeout error. Instead you can do:
def sum_pairs(lst, s):
seen = set()
for item in lst:
if s - item in seen:
return [s - item, item]
seen.add(item)
We put the values in seen until we find a value that produces the specified sum with one of the seen values.
For more information go: Referance link
Maybe this code:
def sum_pairs(lst, s):
c = 0
while c<len(lst)-1:
if c != len(lst)-1:
x= lst[c]
spam = c+1
while spam < len(lst):
nxt= lst[spam]
if nxt + x== s:
return [x, nxt]
spam += 1
else:
return None
c +=1
lst = [5, 6, 5, 8]
s = 14
print(sum_pairs(lst, s))
Output:
[6, 8]
This answer unfortunately still times out, even though it's supposed to run in O(n^3) (since it is dominated by the sort, the rest of the algorithm running in O(n)). I'm not sure how you can obtain better than this complexity, but I thought I might put this idea out there.
def sum_pairs(ints, s):
ints_with_idx = enumerate(ints)
# Sort the array of ints
ints_with_idx = sorted(ints_with_idx, key = lambda (idx, num) : num)
diff = 1000000
l = 0
r = len(ints) - 1
# Indexes of the sum operands in sorted array
lSum = 0
rSum = 0
while l < r:
# Compute the absolute difference between the current sum and the desired sum
sum = ints_with_idx[l][1] + ints_with_idx[r][1]
absDiff = abs(sum - s)
if absDiff < diff:
# Update the best difference
lSum = l
rSum = r
diff = absDiff
elif sum > s:
# Decrease the large value
r -= 1
else:
# Test to see if the indexes are better (more to the left) for the same difference
if absDiff == diff:
rightmostIdx = max(ints_with_idx[l][0], ints_with_idx[r][0])
if rightmostIdx < max(ints_with_idx[lSum][0], ints_with_idx[rSum][0]):
lSum = l
rSum = r
# Increase the small value
l += 1
# Retrieve indexes of sum operands
aSumIdx = ints_with_idx[lSum][0]
bSumIdx = ints_with_idx[rSum][0]
# Retrieve values of operands for sum in correct order
aSum = ints[min(aSumIdx, bSumIdx)]
bSum = ints[max(aSumIdx, bSumIdx)]
if aSum + bSum == s:
return [aSum, bSum]
else:
return None
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)
I am having difficulty getting this scoring function to work. The objective of my program is to make a t x n matrix and find a consensus sequence.
I keep getting a error :
TypeError: 'int' object is not subscriptable.
Any help would be appreciated.
def Score(s, i, l, dna):
t = len(dna) # t = number of dna sequences
# Step 1: Extract the alignment corresponding to starting positions in s
alignment = []
for j in range(0, i):
alignment.append(dna[j][s[j]:s[j]+l])
# Step 2: Create the corresponding profile matrix
profile = [[],[],[],[]] # prepare an empty 4 x l profile matrix first
for j in range(0, 4):
profile[j] = [0] * l
for c in range(0, l): # for each column number c
for r in range(0, i): # for each row number r in column c
if alignment[r][c] == 'a':
profile[0][c] = profile[0][c] + 1
elif alignment[r][c] == 't':
profile[1][c] = profile[1][c] + 1
elif alignment[r][c] == 'g':
profile[2][c] = profile[2][c] + 1
else:
profile[3][c] = profile[3][c] + 1
# Step 3: Compute the score from the profile matrix
score = 0
for c in range(0, l):
score = score + max([profile[0][c], profile[1][c], profile[2][c], profile[3][c]])
return score
Is your variable dna a dictionary,
if so use def Score(s, i, l, **dna)
If it is int variable, you can't access it as dna[j][s[j]:s[j]+l]