increment 1

This commit is contained in:
Alex Brown 2018-10-19 07:48:28 -05:00
parent 718b99ae39
commit 564179a0ec
131 changed files with 16252 additions and 0 deletions

View File

@ -0,0 +1,38 @@
import numpy as np
import math
import cv2
def Representational(r,g,b):
return (0.299*r+0.287*g+0.114*b)
def calculate(img):
b,g,r = cv2.split(img)
pixelAt = Representational(r,g,b)
return pixelAt
def main():
#Loading images (orignal image and compressed image)
orignal_image = cv2.imread('orignal_image.png',1)
compressed_image = cv2.imread('compressed_image.png',1)
#Getting image height and width
height,width = orignal_image.shape[:2]
orignalPixelAt = calculate(orignal_image)
compressedPixelAt = calculate(compressed_image)
diff = orignalPixelAt - compressedPixelAt
error = np.sum(np.abs(diff) ** 2)
error = error/(height*width)
#MSR = error_sum/(height*width)
PSNR = -(10*math.log10(error/(255*255)))
print("PSNR value is {}".format(PSNR))
if __name__ == '__main__':
main()

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

View File

@ -0,0 +1,33 @@
import math
def bisection(function, a, b): # finds where the function becomes 0 in [a,b] using bolzano
start = a
end = b
if function(a) == 0: # one of the a or b is a root for the function
return a
elif function(b) == 0:
return b
elif function(a) * function(b) > 0: # if none of these are root and they are both positive or negative,
# then his algorithm can't find the root
print("couldn't find root in [a,b]")
return
else:
mid = (start + end) / 2
while abs(start - mid) > 0.0000001: # until we achieve precise equals to 10^-7
if function(mid) == 0:
return mid
elif function(mid) * function(start) < 0:
end = mid
else:
start = mid
mid = (start + end) / 2
return mid
def f(x):
return math.pow(x, 3) - 2*x - 5
print(bisection(f, 1, 1000))

View File

@ -0,0 +1,16 @@
import math
def intersection(function,x0,x1): #function is the f we want to find its root and x0 and x1 are two random starting points
x_n = x0
x_n1 = x1
while True:
x_n2 = x_n1-(function(x_n1)/((function(x_n1)-function(x_n))/(x_n1-x_n)))
if abs(x_n2 - x_n1)<0.00001 :
return x_n2
x_n=x_n1
x_n1=x_n2
def f(x):
return math.pow(x,3)-2*x-5
print(intersection(f,3,3.5))

View File

@ -0,0 +1,34 @@
import numpy
def LUDecompose (table):
#table that contains our data
#table has to be a square array so we need to check first
rows,columns=numpy.shape(table)
L=numpy.zeros((rows,columns))
U=numpy.zeros((rows,columns))
if rows!=columns:
return
for i in range (columns):
for j in range(i-1):
sum=0
for k in range (j-1):
sum+=L[i][k]*U[k][j]
L[i][j]=(table[i][j]-sum)/U[j][j]
L[i][i]=1
for j in range(i-1,columns):
sum1=0
for k in range(i-1):
sum1+=L[i][k]*U[k][j]
U[i][j]=table[i][j]-sum1
return L,U
matrix =numpy.array([[2,-2,1],[0,1,2],[5,3,1]])
L,U = LUDecompose(matrix)
print(L)
print(U)

View File

@ -0,0 +1,15 @@
def newton(function,function1,startingInt): #function is the f(x) and function1 is the f'(x)
x_n=startingInt
while True:
x_n1=x_n-function(x_n)/function1(x_n)
if abs(x_n-x_n1)<0.00001:
return x_n1
x_n=x_n1
def f(x):
return (x**3)-2*x-5
def f1(x):
return 3*(x**2)-2
print(newton(f,f1,3))

View File

@ -0,0 +1,36 @@
# Implementing Newton Raphson method in Python
# Author: Haseeb
from sympy import diff
from decimal import Decimal
def NewtonRaphson(func, a):
''' Finds root from the point 'a' onwards by Newton-Raphson method '''
while True:
c = Decimal(a) - ( Decimal(eval(func)) / Decimal(eval(str(diff(func)))) )
a = c
# This number dictates the accuracy of the answer
if abs(eval(func)) < 10**-15:
return c
# Let's Execute
if __name__ == '__main__':
# Find root of trigonometric function
# Find value of pi
print ('sin(x) = 0', NewtonRaphson('sin(x)', 2))
# Find root of polynomial
print ('x**2 - 5*x +2 = 0', NewtonRaphson('x**2 - 5*x +2', 0.4))
# Find Square Root of 5
print ('x**2 - 5 = 0', NewtonRaphson('x**2 - 5', 0.1))
# Exponential Roots
print ('exp(x) - 1 = 0', NewtonRaphson('exp(x) - 1', 0))

View File

@ -0,0 +1,116 @@
def compare_string(string1, string2):
l1 = list(string1); l2 = list(string2)
count = 0
for i in range(len(l1)):
if l1[i] != l2[i]:
count += 1
l1[i] = '_'
if count > 1:
return -1
else:
return("".join(l1))
def check(binary):
pi = []
while 1:
check1 = ['$']*len(binary)
temp = []
for i in range(len(binary)):
for j in range(i+1, len(binary)):
k=compare_string(binary[i], binary[j])
if k != -1:
check1[i] = '*'
check1[j] = '*'
temp.append(k)
for i in range(len(binary)):
if check1[i] == '$':
pi.append(binary[i])
if len(temp) == 0:
return pi
binary = list(set(temp))
def decimal_to_binary(no_of_variable, minterms):
temp = []
s = ''
for m in minterms:
for i in range(no_of_variable):
s = str(m%2) + s
m //= 2
temp.append(s)
s = ''
return temp
def is_for_table(string1, string2, count):
l1 = list(string1);l2=list(string2)
count_n = 0
for i in range(len(l1)):
if l1[i] != l2[i]:
count_n += 1
if count_n == count:
return True
else:
return False
def selection(chart, prime_implicants):
temp = []
select = [0]*len(chart)
for i in range(len(chart[0])):
count = 0
rem = -1
for j in range(len(chart)):
if chart[j][i] == 1:
count += 1
rem = j
if count == 1:
select[rem] = 1
for i in range(len(select)):
if select[i] == 1:
for j in range(len(chart[0])):
if chart[i][j] == 1:
for k in range(len(chart)):
chart[k][j] = 0
temp.append(prime_implicants[i])
while 1:
max_n = 0; rem = -1; count_n = 0
for i in range(len(chart)):
count_n = chart[i].count(1)
if count_n > max_n:
max_n = count_n
rem = i
if max_n == 0:
return temp
temp.append(prime_implicants[rem])
for i in range(len(chart[0])):
if chart[rem][i] == 1:
for j in range(len(chart)):
chart[j][i] = 0
def prime_implicant_chart(prime_implicants, binary):
chart = [[0 for x in range(len(binary))] for x in range(len(prime_implicants))]
for i in range(len(prime_implicants)):
count = prime_implicants[i].count('_')
for j in range(len(binary)):
if(is_for_table(prime_implicants[i], binary[j], count)):
chart[i][j] = 1
return chart
def main():
no_of_variable = int(raw_input("Enter the no. of variables\n"))
minterms = [int(x) for x in raw_input("Enter the decimal representation of Minterms 'Spaces Seprated'\n").split()]
binary = decimal_to_binary(no_of_variable, minterms)
prime_implicants = check(binary)
print("Prime Implicants are:")
print(prime_implicants)
chart = prime_implicant_chart(prime_implicants, binary)
essential_prime_implicants = selection(chart,prime_implicants)
print("Essential Prime Implicants are:")
print(essential_prime_implicants)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,54 @@
from __future__ import print_function
def decrypt(message):
"""
>>> decrypt('TMDETUX PMDVU')
Decryption using Key #0: TMDETUX PMDVU
Decryption using Key #1: SLCDSTW OLCUT
Decryption using Key #2: RKBCRSV NKBTS
Decryption using Key #3: QJABQRU MJASR
Decryption using Key #4: PIZAPQT LIZRQ
Decryption using Key #5: OHYZOPS KHYQP
Decryption using Key #6: NGXYNOR JGXPO
Decryption using Key #7: MFWXMNQ IFWON
Decryption using Key #8: LEVWLMP HEVNM
Decryption using Key #9: KDUVKLO GDUML
Decryption using Key #10: JCTUJKN FCTLK
Decryption using Key #11: IBSTIJM EBSKJ
Decryption using Key #12: HARSHIL DARJI
Decryption using Key #13: GZQRGHK CZQIH
Decryption using Key #14: FYPQFGJ BYPHG
Decryption using Key #15: EXOPEFI AXOGF
Decryption using Key #16: DWNODEH ZWNFE
Decryption using Key #17: CVMNCDG YVMED
Decryption using Key #18: BULMBCF XULDC
Decryption using Key #19: ATKLABE WTKCB
Decryption using Key #20: ZSJKZAD VSJBA
Decryption using Key #21: YRIJYZC URIAZ
Decryption using Key #22: XQHIXYB TQHZY
Decryption using Key #23: WPGHWXA SPGYX
Decryption using Key #24: VOFGVWZ ROFXW
Decryption using Key #25: UNEFUVY QNEWV
"""
LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
for key in range(len(LETTERS)):
translated = ""
for symbol in message:
if symbol in LETTERS:
num = LETTERS.find(symbol)
num = num - key
if num < 0:
num = num + len(LETTERS)
translated = translated + LETTERS[num]
else:
translated = translated + symbol
print("Decryption using Key #%s: %s" % (key, translated))
def main():
message = raw_input("Encrypted message: ")
message = message.upper()
decrypt(message)
if __name__ == '__main__':
import doctest
doctest.testmod()
main()

32
ciphers/onepad_cipher.py Normal file
View File

@ -0,0 +1,32 @@
from __future__ import print_function
import random
class Onepad:
def encrypt(self, text):
'''Function to encrypt text using psedo-random numbers'''
plain = [ord(i) for i in text]
key = []
cipher = []
for i in plain:
k = random.randint(1, 300)
c = (i+k)*k
cipher.append(c)
key.append(k)
return cipher, key
def decrypt(self, cipher, key):
'''Function to decrypt text using psedo-random numbers.'''
plain = []
for i in range(len(key)):
p = (cipher[i]-(key[i])**2)/key[i]
plain.append(chr(p))
plain = ''.join([i for i in plain])
return plain
if __name__ == '__main__':
c, k = Onepad().encrypt('Hello')
print(c, k)
print(Onepad().decrypt(c, k))

7193
ciphers/prehistoric_men.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,36 @@
from __future__ import print_function
import time, os, sys
import transposition_cipher as transCipher
def main():
inputFile = 'Prehistoric Men.txt'
outputFile = 'Output.txt'
key = int(raw_input('Enter key: '))
mode = raw_input('Encrypt/Decrypt [e/d]: ')
if not os.path.exists(inputFile):
print('File %s does not exist. Quitting...' % inputFile)
sys.exit()
if os.path.exists(outputFile):
print('Overwrite %s? [y/n]' % outputFile)
response = raw_input('> ')
if not response.lower().startswith('y'):
sys.exit()
startTime = time.time()
if mode.lower().startswith('e'):
content = open(inputFile).read()
translated = transCipher.encryptMessage(key, content)
elif mode.lower().startswith('d'):
content = open(outputFile).read()
translated =transCipher .decryptMessage(key, content)
outputObj = open(outputFile, 'w')
outputObj.write(translated)
outputObj.close()
totalTime = round(time.time() - startTime, 2)
print(('Done (', totalTime, 'seconds )'))
if __name__ == '__main__':
main()

209
ciphers/xor_cipher.py Normal file
View File

@ -0,0 +1,209 @@
"""
author: Christian Bender
date: 21.12.2017
class: XORCipher
This class implements the XOR-cipher algorithm and provides
some useful methods for encrypting and decrypting strings and
files.
Overview about methods
- encrypt : list of char
- decrypt : list of char
- encrypt_string : str
- decrypt_string : str
- encrypt_file : boolean
- decrypt_file : boolean
"""
class XORCipher(object):
def __init__(self, key = 0):
"""
simple constructor that receives a key or uses
default key = 0
"""
#private field
self.__key = key
def encrypt(self, content, key):
"""
input: 'content' of type string and 'key' of type int
output: encrypted string 'content' as a list of chars
if key not passed the method uses the key by the constructor.
otherwise key = 1
"""
# precondition
assert (isinstance(key,int) and isinstance(content,str))
key = key or self.__key or 1
# make sure key can be any size
while (key > 255):
key -= 255
# This will be returned
ans = []
for ch in content:
ans.append(chr(ord(ch) ^ key))
return ans
def decrypt(self,content,key):
"""
input: 'content' of type list and 'key' of type int
output: decrypted string 'content' as a list of chars
if key not passed the method uses the key by the constructor.
otherwise key = 1
"""
# precondition
assert (isinstance(key,int) and isinstance(content,list))
key = key or self.__key or 1
# make sure key can be any size
while (key > 255):
key -= 255
# This will be returned
ans = []
for ch in content:
ans.append(chr(ord(ch) ^ key))
return ans
def encrypt_string(self,content, key = 0):
"""
input: 'content' of type string and 'key' of type int
output: encrypted string 'content'
if key not passed the method uses the key by the constructor.
otherwise key = 1
"""
# precondition
assert (isinstance(key,int) and isinstance(content,str))
key = key or self.__key or 1
# make sure key can be any size
while (key > 255):
key -= 255
# This will be returned
ans = ""
for ch in content:
ans += chr(ord(ch) ^ key)
return ans
def decrypt_string(self,content,key = 0):
"""
input: 'content' of type string and 'key' of type int
output: decrypted string 'content'
if key not passed the method uses the key by the constructor.
otherwise key = 1
"""
# precondition
assert (isinstance(key,int) and isinstance(content,str))
key = key or self.__key or 1
# make sure key can be any size
while (key > 255):
key -= 255
# This will be returned
ans = ""
for ch in content:
ans += chr(ord(ch) ^ key)
return ans
def encrypt_file(self, file, key = 0):
"""
input: filename (str) and a key (int)
output: returns true if encrypt process was
successful otherwise false
if key not passed the method uses the key by the constructor.
otherwise key = 1
"""
#precondition
assert (isinstance(file,str) and isinstance(key,int))
try:
with open(file,"r") as fin:
with open("encrypt.out","w+") as fout:
# actual encrypt-process
for line in fin:
fout.write(self.encrypt_string(line,key))
except:
return False
return True
def decrypt_file(self,file, key):
"""
input: filename (str) and a key (int)
output: returns true if decrypt process was
successful otherwise false
if key not passed the method uses the key by the constructor.
otherwise key = 1
"""
#precondition
assert (isinstance(file,str) and isinstance(key,int))
try:
with open(file,"r") as fin:
with open("decrypt.out","w+") as fout:
# actual encrypt-process
for line in fin:
fout.write(self.decrypt_string(line,key))
except:
return False
return True
# Tests
# crypt = XORCipher()
# key = 67
# # test enrcypt
# print crypt.encrypt("hallo welt",key)
# # test decrypt
# print crypt.decrypt(crypt.encrypt("hallo welt",key), key)
# # test encrypt_string
# print crypt.encrypt_string("hallo welt",key)
# # test decrypt_string
# print crypt.decrypt_string(crypt.encrypt_string("hallo welt",key),key)
# if (crypt.encrypt_file("test.txt",key)):
# print "encrypt successful"
# else:
# print "encrypt unsuccessful"
# if (crypt.decrypt_file("encrypt.out",key)):
# print "decrypt successful"
# else:
# print "decrypt unsuccessful"

View File

@ -0,0 +1,3 @@
arr = [10, 20, 30, 40]
arr[1] = 30
print(arr)

181
data_structures/avl.py Normal file
View File

@ -0,0 +1,181 @@
"""
An AVL tree
"""
from __future__ import print_function
class Node:
def __init__(self, label):
self.label = label
self._parent = None
self._left = None
self._right = None
self.height = 0
@property
def right(self):
return self._right
@right.setter
def right(self, node):
if node is not None:
node._parent = self
self._right = node
@property
def left(self):
return self._left
@left.setter
def left(self, node):
if node is not None:
node._parent = self
self._left = node
@property
def parent(self):
return self._parent
@parent.setter
def parent(self, node):
if node is not None:
self._parent = node
self.height = self.parent.height + 1
else:
self.height = 0
class AVL:
def __init__(self):
self.root = None
self.size = 0
def insert(self, value):
node = Node(value)
if self.root is None:
self.root = node
self.root.height = 0
self.size = 1
else:
# Same as Binary Tree
dad_node = None
curr_node = self.root
while True:
if curr_node is not None:
dad_node = curr_node
if node.label < curr_node.label:
curr_node = curr_node.left
else:
curr_node = curr_node.right
else:
node.height = dad_node.height
dad_node.height += 1
if node.label < dad_node.label:
dad_node.left = node
else:
dad_node.right = node
self.rebalance(node)
self.size += 1
break
def rebalance(self, node):
n = node
while n is not None:
height_right = n.height
height_left = n.height
if n.right is not None:
height_right = n.right.height
if n.left is not None:
height_left = n.left.height
if abs(height_left - height_right) > 1:
if height_left > height_right:
left_child = n.left
if left_child is not None:
h_right = (left_child.right.height
if (left_child.right is not None) else 0)
h_left = (left_child.left.height
if (left_child.left is not None) else 0)
if (h_left > h_right):
self.rotate_left(n)
break
else:
self.double_rotate_right(n)
break
else:
right_child = n.right
if right_child is not None:
h_right = (right_child.right.height
if (right_child.right is not None) else 0)
h_left = (right_child.left.height
if (right_child.left is not None) else 0)
if (h_left > h_right):
self.double_rotate_left(n)
break
else:
self.rotate_right(n)
break
n = n.parent
def rotate_left(self, node):
aux = node.parent.label
node.parent.label = node.label
node.parent.right = Node(aux)
node.parent.right.height = node.parent.height + 1
node.parent.left = node.right
def rotate_right(self, node):
aux = node.parent.label
node.parent.label = node.label
node.parent.left = Node(aux)
node.parent.left.height = node.parent.height + 1
node.parent.right = node.right
def double_rotate_left(self, node):
self.rotate_right(node.getRight().getRight())
self.rotate_left(node)
def double_rotate_right(self, node):
self.rotate_left(node.getLeft().getLeft())
self.rotate_right(node)
def empty(self):
if self.root is None:
return True
return False
def preShow(self, curr_node):
if curr_node is not None:
self.preShow(curr_node.left)
print(curr_node.label, end=" ")
self.preShow(curr_node.right)
def preorder(self, curr_node):
if curr_node is not None:
self.preShow(curr_node.left)
self.preShow(curr_node.right)
print(curr_node.label, end=" ")
def getRoot(self):
return self.root
t = AVL()
t.insert(1)
t.insert(2)
t.insert(3)
# t.preShow(t.root)
# print("\n")
# t.insert(4)
# t.insert(5)
# t.preShow(t.root)
# t.preorden(t.root)

View File

@ -0,0 +1,29 @@
from __future__ import print_function
class FenwickTree:
def __init__(self, SIZE): # create fenwick tree with size SIZE
self.Size = SIZE
self.ft = [0 for i in range (0,SIZE)]
def update(self, i, val): # update data (adding) in index i in O(lg N)
while (i < self.Size):
self.ft[i] += val
i += i & (-i)
def query(self, i): # query cumulative data from index 0 to i in O(lg N)
ret = 0
while (i > 0):
ret += self.ft[i]
i -= i & (-i)
return ret
if __name__ == '__main__':
f = FenwickTree(100)
f.update(1,20)
f.update(4,4)
print (f.query(1))
print (f.query(3))
print (f.query(4))
f.update(2,-5)
print (f.query(1))
print (f.query(3))

View File

@ -0,0 +1,91 @@
from __future__ import print_function
import math
class SegmentTree:
def __init__(self, N):
self.N = N
self.st = [0 for i in range(0,4*N)] # approximate the overall size of segment tree with array N
self.lazy = [0 for i in range(0,4*N)] # create array to store lazy update
self.flag = [0 for i in range(0,4*N)] # flag for lazy update
def left(self, idx):
return idx*2
def right(self, idx):
return idx*2 + 1
def build(self, idx, l, r, A):
if l==r:
self.st[idx] = A[l-1]
else :
mid = (l+r)//2
self.build(self.left(idx),l,mid, A)
self.build(self.right(idx),mid+1,r, A)
self.st[idx] = max(self.st[self.left(idx)] , self.st[self.right(idx)])
# update with O(lg N) (Normal segment tree without lazy update will take O(Nlg N) for each update)
def update(self, idx, l, r, a, b, val): # update(1, 1, N, a, b, v) for update val v to [a,b]
if self.flag[idx] == True:
self.st[idx] = self.lazy[idx]
self.flag[idx] = False
if l!=r:
self.lazy[self.left(idx)] = self.lazy[idx]
self.lazy[self.right(idx)] = self.lazy[idx]
self.flag[self.left(idx)] = True
self.flag[self.right(idx)] = True
if r < a or l > b:
return True
if l >= a and r <= b :
self.st[idx] = val
if l!=r:
self.lazy[self.left(idx)] = val
self.lazy[self.right(idx)] = val
self.flag[self.left(idx)] = True
self.flag[self.right(idx)] = True
return True
mid = (l+r)//2
self.update(self.left(idx),l,mid,a,b,val)
self.update(self.right(idx),mid+1,r,a,b,val)
self.st[idx] = max(self.st[self.left(idx)] , self.st[self.right(idx)])
return True
# query with O(lg N)
def query(self, idx, l, r, a, b): #query(1, 1, N, a, b) for query max of [a,b]
if self.flag[idx] == True:
self.st[idx] = self.lazy[idx]
self.flag[idx] = False
if l != r:
self.lazy[self.left(idx)] = self.lazy[idx]
self.lazy[self.right(idx)] = self.lazy[idx]
self.flag[self.left(idx)] = True
self.flag[self.right(idx)] = True
if r < a or l > b:
return -math.inf
if l >= a and r <= b:
return self.st[idx]
mid = (l+r)//2
q1 = self.query(self.left(idx),l,mid,a,b)
q2 = self.query(self.right(idx),mid+1,r,a,b)
return max(q1,q2)
def showData(self):
showList = []
for i in range(1,N+1):
showList += [self.query(1, 1, self.N, i, i)]
print (showList)
if __name__ == '__main__':
A = [1,2,-4,7,3,-5,6,11,-20,9,14,15,5,2,-8]
N = 15
segt = SegmentTree(N)
segt.build(1,1,N,A)
print (segt.query(1,1,N,4,6))
print (segt.query(1,1,N,7,11))
print (segt.query(1,1,N,7,12))
segt.update(1,1,N,1,3,111)
print (segt.query(1,1,N,1,15))
segt.update(1,1,N,7,8,235)
segt.showData()

View File

@ -0,0 +1,71 @@
from __future__ import print_function
import math
class SegmentTree:
def __init__(self, A):
self.N = len(A)
self.st = [0] * (4 * self.N) # approximate the overall size of segment tree with array N
self.build(1, 0, self.N - 1)
def left(self, idx):
return idx * 2
def right(self, idx):
return idx * 2 + 1
def build(self, idx, l, r):
if l == r:
self.st[idx] = A[l]
else:
mid = (l + r) // 2
self.build(self.left(idx), l, mid)
self.build(self.right(idx), mid + 1, r)
self.st[idx] = max(self.st[self.left(idx)] , self.st[self.right(idx)])
def update(self, a, b, val):
return self.update_recursive(1, 0, self.N - 1, a - 1, b - 1, val)
def update_recursive(self, idx, l, r, a, b, val): # update(1, 1, N, a, b, v) for update val v to [a,b]
if r < a or l > b:
return True
if l == r :
self.st[idx] = val
return True
mid = (l+r)//2
self.update_recursive(self.left(idx), l, mid, a, b, val)
self.update_recursive(self.right(idx), mid+1, r, a, b, val)
self.st[idx] = max(self.st[self.left(idx)] , self.st[self.right(idx)])
return True
def query(self, a, b):
return self.query_recursive(1, 0, self.N - 1, a - 1, b - 1)
def query_recursive(self, idx, l, r, a, b): #query(1, 1, N, a, b) for query max of [a,b]
if r < a or l > b:
return -math.inf
if l >= a and r <= b:
return self.st[idx]
mid = (l+r)//2
q1 = self.query_recursive(self.left(idx), l, mid, a, b)
q2 = self.query_recursive(self.right(idx), mid + 1, r, a, b)
return max(q1, q2)
def showData(self):
showList = []
for i in range(1,N+1):
showList += [self.query(i, i)]
print (showList)
if __name__ == '__main__':
A = [1,2,-4,7,3,-5,6,11,-20,9,14,15,5,2,-8]
N = 15
segt = SegmentTree(A)
print (segt.query(4, 6))
print (segt.query(7, 11))
print (segt.query(7, 12))
segt.update(1,3,111)
print (segt.query(1, 15))
segt.update(7,8,235)
segt.showData()

View File

@ -0,0 +1,258 @@
'''
A binary search Tree
'''
from __future__ import print_function
class Node:
def __init__(self, label, parent):
self.label = label
self.left = None
self.right = None
#Added in order to delete a node easier
self.parent = parent
def getLabel(self):
return self.label
def setLabel(self, label):
self.label = label
def getLeft(self):
return self.left
def setLeft(self, left):
self.left = left
def getRight(self):
return self.right
def setRight(self, right):
self.right = right
def getParent(self):
return self.parent
def setParent(self, parent):
self.parent = parent
class BinarySearchTree:
def __init__(self):
self.root = None
def insert(self, label):
# Create a new Node
new_node = Node(label, None)
# If Tree is empty
if self.empty():
self.root = new_node
else:
#If Tree is not empty
curr_node = self.root
#While we don't get to a leaf
while curr_node is not None:
#We keep reference of the parent node
parent_node = curr_node
#If node label is less than current node
if new_node.getLabel() < curr_node.getLabel():
#We go left
curr_node = curr_node.getLeft()
else:
#Else we go right
curr_node = curr_node.getRight()
#We insert the new node in a leaf
if new_node.getLabel() < parent_node.getLabel():
parent_node.setLeft(new_node)
else:
parent_node.setRight(new_node)
#Set parent to the new node
new_node.setParent(parent_node)
def delete(self, label):
if (not self.empty()):
#Look for the node with that label
node = self.getNode(label)
#If the node exists
if(node is not None):
#If it has no children
if(node.getLeft() is None and node.getRight() is None):
self.__reassignNodes(node, None)
node = None
#Has only right children
elif(node.getLeft() is None and node.getRight() is not None):
self.__reassignNodes(node, node.getRight())
#Has only left children
elif(node.getLeft() is not None and node.getRight() is None):
self.__reassignNodes(node, node.getLeft())
#Has two children
else:
#Gets the max value of the left branch
tmpNode = self.getMax(node.getLeft())
#Deletes the tmpNode
self.delete(tmpNode.getLabel())
#Assigns the value to the node to delete and keesp tree structure
node.setLabel(tmpNode.getLabel())
def getNode(self, label):
curr_node = None
#If the tree is not empty
if(not self.empty()):
#Get tree root
curr_node = self.getRoot()
#While we don't find the node we look for
#I am using lazy evaluation here to avoid NoneType Attribute error
while curr_node is not None and curr_node.getLabel() is not label:
#If node label is less than current node
if label < curr_node.getLabel():
#We go left
curr_node = curr_node.getLeft()
else:
#Else we go right
curr_node = curr_node.getRight()
return curr_node
def getMax(self, root = None):
if(root is not None):
curr_node = root
else:
#We go deep on the right branch
curr_node = self.getRoot()
if(not self.empty()):
while(curr_node.getRight() is not None):
curr_node = curr_node.getRight()
return curr_node
def getMin(self, root = None):
if(root is not None):
curr_node = root
else:
#We go deep on the left branch
curr_node = self.getRoot()
if(not self.empty()):
curr_node = self.getRoot()
while(curr_node.getLeft() is not None):
curr_node = curr_node.getLeft()
return curr_node
def empty(self):
if self.root is None:
return True
return False
def __InOrderTraversal(self, curr_node):
nodeList = []
if curr_node is not None:
nodeList.insert(0, curr_node)
nodeList = nodeList + self.__InOrderTraversal(curr_node.getLeft())
nodeList = nodeList + self.__InOrderTraversal(curr_node.getRight())
return nodeList
def getRoot(self):
return self.root
def __isRightChildren(self, node):
if(node == node.getParent().getRight()):
return True
return False
def __reassignNodes(self, node, newChildren):
if(newChildren is not None):
newChildren.setParent(node.getParent())
if(node.getParent() is not None):
#If it is the Right Children
if(self.__isRightChildren(node)):
node.getParent().setRight(newChildren)
else:
#Else it is the left children
node.getParent().setLeft(newChildren)
#This function traversal the tree. By default it returns an
#In order traversal list. You can pass a function to traversal
#The tree as needed by client code
def traversalTree(self, traversalFunction = None, root = None):
if(traversalFunction is None):
#Returns a list of nodes in preOrder by default
return self.__InOrderTraversal(self.root)
else:
#Returns a list of nodes in the order that the users wants to
return traversalFunction(self.root)
#Returns an string of all the nodes labels in the list
#In Order Traversal
def __str__(self):
list = self.__InOrderTraversal(self.root)
str = ""
for x in list:
str = str + " " + x.getLabel().__str__()
return str
def InPreOrder(curr_node):
nodeList = []
if curr_node is not None:
nodeList = nodeList + InPreOrder(curr_node.getLeft())
nodeList.insert(0, curr_node.getLabel())
nodeList = nodeList + InPreOrder(curr_node.getRight())
return nodeList
def testBinarySearchTree():
'''
Example
8
/ \
3 10
/ \ \
1 6 14
/ \ /
4 7 13
'''
'''
Example After Deletion
7
/ \
1 4
'''
t = BinarySearchTree()
t.insert(8)
t.insert(3)
t.insert(6)
t.insert(1)
t.insert(10)
t.insert(14)
t.insert(13)
t.insert(4)
t.insert(7)
#Prints all the elements of the list in order traversal
print(t.__str__())
if(t.getNode(6) is not None):
print("The label 6 exists")
else:
print("The label 6 doesn't exist")
if(t.getNode(-1) is not None):
print("The label -1 exists")
else:
print("The label -1 doesn't exist")
if(not t.empty()):
print(("Max Value: ", t.getMax().getLabel()))
print(("Min Value: ", t.getMin().getLabel()))
t.delete(13)
t.delete(10)
t.delete(8)
t.delete(3)
t.delete(6)
t.delete(14)
#Gets all the elements of the tree In pre order
#And it prints them
list = t.traversalTree(InPreOrder, t.root)
for x in list:
print(x)
if __name__ == "__main__":
testBinarySearchTree()

View File

@ -0,0 +1,54 @@
from __future__ import print_function
def printDist(dist, V):
print("\nVertex Distance")
for i in range(V):
if dist[i] != float('inf') :
print(i,"\t",int(dist[i]),end = "\t")
else:
print(i,"\t","INF",end="\t")
print()
def BellmanFord(graph, V, E, src):
mdist=[float('inf') for i in range(V)]
mdist[src] = 0.0
for i in range(V-1):
for j in range(V):
u = graph[j]["src"]
v = graph[j]["dst"]
w = graph[j]["weight"]
if mdist[u] != float('inf') and mdist[u] + w < mdist[v]:
mdist[v] = mdist[u] + w
for j in range(V):
u = graph[j]["src"]
v = graph[j]["dst"]
w = graph[j]["weight"]
if mdist[u] != float('inf') and mdist[u] + w < mdist[v]:
print("Negative cycle found. Solution not possible.")
return
printDist(mdist, V)
#MAIN
V = int(raw_input("Enter number of vertices: "))
E = int(raw_input("Enter number of edges: "))
graph = [dict() for j in range(E)]
for i in range(V):
graph[i][i] = 0.0
for i in range(E):
print("\nEdge ",i+1)
src = int(raw_input("Enter source:"))
dst = int(raw_input("Enter destination:"))
weight = float(raw_input("Enter weight:"))
graph[i] = {"src": src,"dst": dst, "weight": weight}
gsrc = int(raw_input("\nEnter shortest path source:"))
BellmanFord(graph, V, E, gsrc)

View File

@ -0,0 +1,67 @@
#!/usr/bin/python
# encoding=utf8
""" Author: OMKAR PATHAK """
from __future__ import print_function
class Graph():
def __init__(self):
self.vertex = {}
# for printing the Graph vertexes
def printGraph(self):
for i in self.vertex.keys():
print(i,' -> ', ' -> '.join([str(j) for j in self.vertex[i]]))
# for adding the edge beween two vertexes
def addEdge(self, fromVertex, toVertex):
# check if vertex is already present,
if fromVertex in self.vertex.keys():
self.vertex[fromVertex].append(toVertex)
else:
# else make a new vertex
self.vertex[fromVertex] = [toVertex]
def BFS(self, startVertex):
# Take a list for stoting already visited vertexes
visited = [False] * len(self.vertex)
# create a list to store all the vertexes for BFS
queue = []
# mark the source node as visited and enqueue it
visited[startVertex] = True
queue.append(startVertex)
while queue:
startVertex = queue.pop(0)
print(startVertex, end = ' ')
# mark all adjacent nodes as visited and print them
for i in self.vertex[startVertex]:
if visited[i] == False:
queue.append(i)
visited[i] = True
if __name__ == '__main__':
g = Graph()
g.addEdge(0, 1)
g.addEdge(0, 2)
g.addEdge(1, 2)
g.addEdge(2, 0)
g.addEdge(2, 3)
g.addEdge(3, 3)
g.printGraph()
print('BFS:')
g.BFS(2)
# OUTPUT:
# 0  ->  1 -> 2
# 1  ->  2
# 2  ->  0 -> 3
# 3  ->  3
# BFS:
# 2 0 3 1

View File

@ -0,0 +1,66 @@
#!/usr/bin/python
# encoding=utf8
""" Author: OMKAR PATHAK """
from __future__ import print_function
class Graph():
def __init__(self):
self.vertex = {}
# for printing the Graph vertexes
def printGraph(self):
print(self.vertex)
for i in self.vertex.keys():
print(i,' -> ', ' -> '.join([str(j) for j in self.vertex[i]]))
# for adding the edge beween two vertexes
def addEdge(self, fromVertex, toVertex):
# check if vertex is already present,
if fromVertex in self.vertex.keys():
self.vertex[fromVertex].append(toVertex)
else:
# else make a new vertex
self.vertex[fromVertex] = [toVertex]
def DFS(self):
# visited array for storing already visited nodes
visited = [False] * len(self.vertex)
# call the recursive helper function
for i in range(len(self.vertex)):
if visited[i] == False:
self.DFSRec(i, visited)
def DFSRec(self, startVertex, visited):
# mark start vertex as visited
visited[startVertex] = True
print(startVertex, end = ' ')
# Recur for all the vertexes that are adjacent to this node
for i in self.vertex.keys():
if visited[i] == False:
self.DFSRec(i, visited)
if __name__ == '__main__':
g = Graph()
g.addEdge(0, 1)
g.addEdge(0, 2)
g.addEdge(1, 2)
g.addEdge(2, 0)
g.addEdge(2, 3)
g.addEdge(3, 3)
g.printGraph()
print('DFS:')
g.DFS()
# OUTPUT:
# 0  ->  1 -> 2
# 1  ->  2
# 2  ->  0 -> 3
# 3  ->  3
# DFS:
# 0 1 2 3

View File

@ -0,0 +1,57 @@
from __future__ import print_function
def printDist(dist, V):
print("\nVertex Distance")
for i in range(V):
if dist[i] != float('inf') :
print(i,"\t",int(dist[i]),end = "\t")
else:
print(i,"\t","INF",end="\t")
print()
def minDist(mdist, vset, V):
minVal = float('inf')
minInd = -1
for i in range(V):
if (not vset[i]) and mdist[i] < minVal :
minInd = i
minVal = mdist[i]
return minInd
def Dijkstra(graph, V, src):
mdist=[float('inf') for i in range(V)]
vset = [False for i in range(V)]
mdist[src] = 0.0;
for i in range(V-1):
u = minDist(mdist, vset, V)
vset[u] = True
for v in range(V):
if (not vset[v]) and graph[u][v]!=float('inf') and mdist[u] + graph[u][v] < mdist[v]:
mdist[v] = mdist[u] + graph[u][v]
printDist(mdist, V)
#MAIN
V = int(raw_input("Enter number of vertices: "))
E = int(raw_input("Enter number of edges: "))
graph = [[float('inf') for i in range(V)] for j in range(V)]
for i in range(V):
graph[i][i] = 0.0
for i in range(E):
print("\nEdge ",i+1)
src = int(raw_input("Enter source:"))
dst = int(raw_input("Enter destination:"))
weight = float(raw_input("Enter weight:"))
graph[src][dst] = weight
gsrc = int(raw_input("\nEnter shortest path source:"))
Dijkstra(graph, V, gsrc)

View File

@ -0,0 +1,212 @@
# Title: Dijkstra's Algorithm for finding single source shortest path from scratch
# Author: Shubham Malik
# References: https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
from __future__ import print_function
import math
import sys
# For storing the vertex set to retreive node with the lowest distance
class PriorityQueue:
# Based on Min Heap
def __init__(self):
self.cur_size = 0
self.array = []
self.pos = {} # To store the pos of node in array
def isEmpty(self):
return self.cur_size == 0
def min_heapify(self, idx):
lc = self.left(idx)
rc = self.right(idx)
if lc < self.cur_size and self.array(lc)[0] < self.array(idx)[0]:
smallest = lc
else:
smallest = idx
if rc < self.cur_size and self.array(rc)[0] < self.array(smallest)[0]:
smallest = rc
if smallest != idx:
self.swap(idx, smallest)
self.min_heapify(smallest)
def insert(self, tup):
# Inserts a node into the Priority Queue
self.pos[tup[1]] = self.cur_size
self.cur_size += 1
self.array.append((sys.maxsize, tup[1]))
self.decrease_key((sys.maxsize, tup[1]), tup[0])
def extract_min(self):
# Removes and returns the min element at top of priority queue
min_node = self.array[0][1]
self.array[0] = self.array[self.cur_size - 1]
self.cur_size -= 1
self.min_heapify(1)
del self.pos[min_node]
return min_node
def left(self, i):
# returns the index of left child
return 2 * i + 1
def right(self, i):
# returns the index of right child
return 2 * i + 2
def par(self, i):
# returns the index of parent
return math.floor(i / 2)
def swap(self, i, j):
# swaps array elements at indices i and j
# update the pos{}
self.pos[self.array[i][1]] = j
self.pos[self.array[j][1]] = i
temp = self.array[i]
self.array[i] = self.array[j]
self.array[j] = temp
def decrease_key(self, tup, new_d):
idx = self.pos[tup[1]]
# assuming the new_d is atmost old_d
self.array[idx] = (new_d, tup[1])
while idx > 0 and self.array[self.par(idx)][0] > self.array[idx][0]:
self.swap(idx, self.par(idx))
idx = self.par(idx)
class Graph:
def __init__(self, num):
self.adjList = {} # To store graph: u -> (v,w)
self.num_nodes = num # Number of nodes in graph
# To store the distance from source vertex
self.dist = [0] * self.num_nodes
self.par = [-1] * self.num_nodes # To store the path
def add_edge(self, u, v, w):
# Edge going from node u to v and v to u with weight w
# u (w)-> v, v (w) -> u
# Check if u already in graph
if u in self.adjList.keys():
self.adjList[u].append((v, w))
else:
self.adjList[u] = [(v, w)]
# Assuming undirected graph
if v in self.adjList.keys():
self.adjList[v].append((u, w))
else:
self.adjList[v] = [(u, w)]
def show_graph(self):
# u -> v(w)
for u in self.adjList:
print(u, '->', ' -> '.join(str("{}({})".format(v, w))
for v, w in self.adjList[u]))
def dijkstra(self, src):
# Flush old junk values in par[]
self.par = [-1] * self.num_nodes
# src is the source node
self.dist[src] = 0
Q = PriorityQueue()
Q.insert((0, src)) # (dist from src, node)
for u in self.adjList.keys():
if u != src:
self.dist[u] = sys.maxsize # Infinity
self.par[u] = -1
while not Q.isEmpty():
u = Q.extract_min() # Returns node with the min dist from source
# Update the distance of all the neighbours of u and
# if their prev dist was INFINITY then push them in Q
for v, w in self.adjList[u]:
new_dist = self.dist[u] + w
if self.dist[v] > new_dist:
if self.dist[v] == sys.maxsize:
Q.insert((new_dist, v))
else:
Q.decrease_key((self.dist[v], v), new_dist)
self.dist[v] = new_dist
self.par[v] = u
# Show the shortest distances from src
self.show_distances(src)
def show_distances(self, src):
print("Distance from node: {}".format(src))
for u in range(self.num_nodes):
print('Node {} has distance: {}'.format(u, self.dist[u]))
def show_path(self, src, dest):
# To show the shortest path from src to dest
# WARNING: Use it *after* calling dijkstra
path = []
cost = 0
temp = dest
# Backtracking from dest to src
while self.par[temp] != -1:
path.append(temp)
if temp != src:
for v, w in self.adjList[temp]:
if v == self.par[temp]:
cost += w
break
temp = self.par[temp]
path.append(src)
path.reverse()
print('----Path to reach {} from {}----'.format(dest, src))
for u in path:
print('{}'.format(u), end=' ')
if u != dest:
print('-> ', end='')
print('\nTotal cost of path: ', cost)
if __name__ == '__main__':
graph = Graph(9)
graph.add_edge(0, 1, 4)
graph.add_edge(0, 7, 8)
graph.add_edge(1, 2, 8)
graph.add_edge(1, 7, 11)
graph.add_edge(2, 3, 7)
graph.add_edge(2, 8, 2)
graph.add_edge(2, 5, 4)
graph.add_edge(3, 4, 9)
graph.add_edge(3, 5, 14)
graph.add_edge(4, 5, 10)
graph.add_edge(5, 6, 2)
graph.add_edge(6, 7, 1)
graph.add_edge(6, 8, 6)
graph.add_edge(7, 8, 7)
graph.show_graph()
graph.dijkstra(0)
graph.show_path(0, 4)
# OUTPUT
# 0 -> 1(4) -> 7(8)
# 1 -> 0(4) -> 2(8) -> 7(11)
# 7 -> 0(8) -> 1(11) -> 6(1) -> 8(7)
# 2 -> 1(8) -> 3(7) -> 8(2) -> 5(4)
# 3 -> 2(7) -> 4(9) -> 5(14)
# 8 -> 2(2) -> 6(6) -> 7(7)
# 5 -> 2(4) -> 3(14) -> 4(10) -> 6(2)
# 4 -> 3(9) -> 5(10)
# 6 -> 5(2) -> 7(1) -> 8(6)
# Distance from node: 0
# Node 0 has distance: 0
# Node 1 has distance: 4
# Node 2 has distance: 12
# Node 3 has distance: 19
# Node 4 has distance: 21
# Node 5 has distance: 11
# Node 6 has distance: 9
# Node 7 has distance: 8
# Node 8 has distance: 14
# ----Path to reach 4 from 0----
# 0 -> 7 -> 6 -> 5 -> 4
# Total cost of path: 21

View File

@ -0,0 +1,70 @@
"""
You are given a tree(a simple connected graph with no cycles). The tree has N
nodes numbered from 1 to N and is rooted at node 1.
Find the maximum number of edges you can remove from the tree to get a forest
such that each connected component of the forest contains an even number of
nodes.
Constraints
2 <= 2 <= 100
Note: The tree input will be such that it can always be decomposed into
components containing an even number of nodes.
"""
from __future__ import print_function
# pylint: disable=invalid-name
from collections import defaultdict
def dfs(start):
"""DFS traversal"""
# pylint: disable=redefined-outer-name
ret = 1
visited[start] = True
for v in tree.get(start):
if v not in visited:
ret += dfs(v)
if ret % 2 == 0:
cuts.append(start)
return ret
def even_tree():
"""
2 1
3 1
4 3
5 2
6 1
7 2
8 6
9 8
10 8
On removing edges (1,3) and (1,6), we can get the desired result 2.
"""
dfs(1)
if __name__ == '__main__':
n, m = 10, 9
tree = defaultdict(list)
visited = {}
cuts = []
count = 0
edges = [
(2, 1),
(3, 1),
(4, 3),
(5, 2),
(6, 1),
(7, 2),
(8, 6),
(9, 8),
(10, 8),
]
for u, v in edges:
tree[u].append(v)
tree[v].append(u)
even_tree()
print(len(cuts) - 1)

View File

@ -0,0 +1,48 @@
from __future__ import print_function
def printDist(dist, V):
print("\nThe shortest path matrix using Floyd Warshall algorithm\n")
for i in range(V):
for j in range(V):
if dist[i][j] != float('inf') :
print(int(dist[i][j]),end = "\t")
else:
print("INF",end="\t")
print()
def FloydWarshall(graph, V):
dist=[[float('inf') for i in range(V)] for j in range(V)]
for i in range(V):
for j in range(V):
dist[i][j] = graph[i][j]
for k in range(V):
for i in range(V):
for j in range(V):
if dist[i][k]!=float('inf') and dist[k][j]!=float('inf') and dist[i][k]+dist[k][j] < dist[i][j]:
dist[i][j] = dist[i][k] + dist[k][j]
printDist(dist, V)
#MAIN
V = int(raw_input("Enter number of vertices: "))
E = int(raw_input("Enter number of edges: "))
graph = [[float('inf') for i in range(V)] for j in range(V)]
for i in range(V):
graph[i][i] = 0.0
for i in range(E):
print("\nEdge ",i+1)
src = int(raw_input("Enter source:"))
dst = int(raw_input("Enter destination:"))
weight = float(raw_input("Enter weight:"))
graph[src][dst] = weight
FloydWarshall(graph, V)

View File

@ -0,0 +1,44 @@
#!/usr/bin/python
# encoding=utf8
from __future__ import print_function
# Author: OMKAR PATHAK
# We can use Python's dictionary for constructing the graph
class AdjacencyList(object):
def __init__(self):
self.List = {}
def addEdge(self, fromVertex, toVertex):
# check if vertex is already present
if fromVertex in self.List.keys():
self.List[fromVertex].append(toVertex)
else:
self.List[fromVertex] = [toVertex]
def printList(self):
for i in self.List:
print((i,'->',' -> '.join([str(j) for j in self.List[i]])))
if __name__ == '__main__':
al = AdjacencyList()
al.addEdge(0, 1)
al.addEdge(0, 4)
al.addEdge(4, 1)
al.addEdge(4, 3)
al.addEdge(1, 0)
al.addEdge(1, 4)
al.addEdge(1, 3)
al.addEdge(1, 2)
al.addEdge(2, 3)
al.addEdge(3, 4)
al.printList()
# OUTPUT:
# 0 -> 1 -> 4
# 1 -> 0 -> 4 -> 3 -> 2
# 2 -> 3
# 3 -> 4
# 4 -> 1 -> 3

View File

@ -0,0 +1,31 @@
from __future__ import print_function
class Graph:
def __init__(self, vertex):
self.vertex = vertex
self.graph = [[0] for i in range(vertex)]
def add_edge(self, u, v):
self.graph[u - 1].append(v - 1)
def show(self):
for i in range(self.vertex):
print('%d: '% (i + 1), end=' ')
for j in self.graph[i]:
print('%d-> '% (j + 1), end=' ')
print(' ')
g = Graph(100)
g.add_edge(1,3)
g.add_edge(2,3)
g.add_edge(3,4)
g.add_edge(3,5)
g.add_edge(4,5)
g.show()

View File

@ -0,0 +1,32 @@
from __future__ import print_function
class Graph:
def __init__(self, vertex):
self.vertex = vertex
self.graph = [[0] * vertex for i in range(vertex) ]
def add_edge(self, u, v):
self.graph[u - 1][v - 1] = 1
self.graph[v - 1][u - 1] = 1
def show(self):
for i in self.graph:
for j in i:
print(j, end=' ')
print(' ')
g = Graph(100)
g.add_edge(1,4)
g.add_edge(4,2)
g.add_edge(4,5)
g.add_edge(2,5)
g.add_edge(5,3)
g.show()

View File

@ -0,0 +1,90 @@
#!/usr/bin/python
from __future__ import print_function, division
try:
raw_input # Python 2
except NameError:
raw_input = input # Python 3
class Heap:
def __init__(self):
self.h = []
self.currsize = 0
def leftChild(self,i):
if 2*i+1 < self.currsize:
return 2*i+1
return None
def rightChild(self,i):
if 2*i+2 < self.currsize:
return 2*i+2
return None
def maxHeapify(self,node):
if node < self.currsize:
m = node
lc = self.leftChild(node)
rc = self.rightChild(node)
if lc is not None and self.h[lc] > self.h[m]:
m = lc
if rc is not None and self.h[rc] > self.h[m]:
m = rc
if m!=node:
temp = self.h[node]
self.h[node] = self.h[m]
self.h[m] = temp
self.maxHeapify(m)
def buildHeap(self,a):
self.currsize = len(a)
self.h = list(a)
for i in range(self.currsize/2,-1,-1):
self.maxHeapify(i)
def getMax(self):
if self.currsize >= 1:
me = self.h[0]
temp = self.h[0]
self.h[0] = self.h[self.currsize-1]
self.h[self.currsize-1] = temp
self.currsize -= 1
self.maxHeapify(0)
return me
return None
def heapSort(self):
size = self.currsize
while self.currsize-1 >= 0:
temp = self.h[0]
self.h[0] = self.h[self.currsize-1]
self.h[self.currsize-1] = temp
self.currsize -= 1
self.maxHeapify(0)
self.currsize = size
def insert(self,data):
self.h.append(data)
curr = self.currsize
self.currsize+=1
while self.h[curr] > self.h[curr/2]:
temp = self.h[curr/2]
self.h[curr/2] = self.h[curr]
self.h[curr] = temp
curr = curr/2
def display(self):
print(self.h)
def main():
l = list(map(int, raw_input().split()))
h = Heap()
h.buildHeap(l)
h.heapSort()
h.display()
if __name__=='__main__':
main()

View File

@ -0,0 +1,76 @@
'''
- A linked list is similar to an array, it holds values. However, links in a linked list do not have indexes.
- This is an example of a double ended, doubly linked list.
- Each link references the next link and the previous one.
'''
from __future__ import print_function
class LinkedList:
def __init__(self):
self.head = None
self.tail = None
def insertHead(self, x):
newLink = Link(x) #Create a new link with a value attached to it
if(self.isEmpty() == True): #Set the first element added to be the tail
self.tail = newLink
else:
self.head.previous = newLink # newLink <-- currenthead(head)
newLink.next = self.head # newLink <--> currenthead(head)
self.head = newLink # newLink(head) <--> oldhead
def deleteHead(self):
temp = self.head
self.head = self.head.next # oldHead <--> 2ndElement(head)
self.head.previous = None # oldHead --> 2ndElement(head) nothing pointing at it so the old head will be removed
if(self.head is None):
self.tail = None
return temp
def insertTail(self, x):
newLink = Link(x)
newLink.next = None # currentTail(tail) newLink -->
self.tail.next = newLink # currentTail(tail) --> newLink -->
newLink.previous = self.tail #currentTail(tail) <--> newLink -->
self.tail = newLink # oldTail <--> newLink(tail) -->
def deleteTail(self):
temp = self.tail
self.tail = self.tail.previous # 2ndLast(tail) <--> oldTail --> None
self.tail.next = None # 2ndlast(tail) --> None
return temp
def delete(self, x):
current = self.head
while(current.value != x): # Find the position to delete
current = current.next
if(current == self.head):
self.deleteHead()
elif(current == self.tail):
self.deleteTail()
else: #Before: 1 <--> 2(current) <--> 3
current.previous.next = current.next # 1 --> 3
current.next.previous = current.previous # 1 <--> 3
def isEmpty(self): #Will return True if the list is empty
return(self.head is None)
def display(self): #Prints contents of the list
current = self.head
while(current != None):
current.displayLink()
current = current.next
print()
class Link:
next = None #This points to the link in front of the new link
previous = None #This points to the link behind the new link
def __init__(self, x):
self.value = x
def displayLink(self):
print("{}".format(self.value), end=" ")

View File

@ -0,0 +1,22 @@
class Node:
def __init__(self, item, next):
self.item = item
self.next = next
class LinkedList:
def __init__(self):
self.head = None
def add(self, item):
self.head = Node(item, self.head)
def remove(self):
if self.is_empty():
return None
else:
item = self.head.item
self.head = self.head.next
return item
def is_empty(self):
return self.head is None

View File

@ -0,0 +1,70 @@
from __future__ import print_function
class Node: # create a Node
def __init__(self, data):
self.data = data # given data
self.next = None # given next to None
class Linked_List:
def insert_tail(Head, data):
if Head.next is None:
Head.next = Node(data)
else:
Head.next.insert_tail(data)
def insert_head(Head, data):
tamp = Head
if tamp is None:
newNod = Node() # create a new Node
newNod.data = data
newNod.next = None
Head = newNod # make new node to Head
else:
newNod = Node()
newNod.data = data
newNod.next = Head # put the Head at NewNode Next
Head = newNod # make a NewNode to Head
return Head
def printList(Head): # print every node data
tamp = Head
while tamp is not None:
print(tamp.data)
tamp = tamp.next
def delete_head(Head): # delete from head
if Head is not None:
Head = Head.next
return Head # return new Head
def delete_tail(Head): # delete from tail
if Head is not None:
tamp = Node()
tamp = Head
while tamp.next.next is not None: # find the 2nd last element
tamp = tamp.next
# delete the last element by give next None to 2nd last Element
tamp.next = None
return Head
def isEmpty(Head):
return Head is None # Return if Head is none
def reverse(Head):
prev = None
current = Head
while current:
# Store the current node's next node.
next_node = current.next
# Make the current node's next point backwards
current.next = prev
# Make the previous node be the current node
prev = current
# Make the current node the next node (to progress iteration)
current = next_node
# Return prev in order to put the head at the end
Head = prev
return Head

View File

@ -0,0 +1,40 @@
from __future__ import print_function
# Python code to demonstrate working of
# extend(), extendleft(), rotate(), reverse()
# importing "collections" for deque operations
import collections
# initializing deque
de = collections.deque([1, 2, 3,])
# using extend() to add numbers to right end
# adds 4,5,6 to right end
de.extend([4,5,6])
# printing modified deque
print ("The deque after extending deque at end is : ")
print (de)
# using extendleft() to add numbers to left end
# adds 7,8,9 to right end
de.extendleft([7,8,9])
# printing modified deque
print ("The deque after extending deque at beginning is : ")
print (de)
# using rotate() to rotate the deque
# rotates by 3 to left
de.rotate(-3)
# printing modified deque
print ("The deque after rotating deque is : ")
print (de)
# using reverse() to reverse the deque
de.reverse()
# printing modified deque
print ("The deque after reversing deque is : ")
print (de)

View File

@ -0,0 +1,45 @@
"""Queue represented by a python list"""
class Queue():
def __init__(self):
self.entries = []
self.length = 0
self.front=0
def __str__(self):
printed = '<' + str(self.entries)[1:-1] + '>'
return printed
"""Enqueues {@code item}
@param item
item to enqueue"""
def put(self, item):
self.entries.append(item)
self.length = self.length + 1
"""Dequeues {@code item}
@requirement: |self.length| > 0
@return dequeued
item that was dequeued"""
def get(self):
self.length = self.length - 1
dequeued = self.entries[self.front]
self.front-=1
self.entries = self.entries[self.front:]
return dequeued
"""Rotates the queue {@code rotation} times
@param rotation
number of times to rotate queue"""
def rotate(self, rotation):
for i in range(rotation):
self.put(self.get())
"""Enqueues {@code item}
@return item at front of self.entries"""
def front(self):
return self.entries[0]
"""Returns the length of this.entries"""
def size(self):
return self.length

View File

@ -0,0 +1,50 @@
"""Queue represented by a pseudo stack (represented by a list with pop and append)"""
class Queue():
def __init__(self):
self.stack = []
self.length = 0
def __str__(self):
printed = '<' + str(self.stack)[1:-1] + '>'
return printed
"""Enqueues {@code item}
@param item
item to enqueue"""
def put(self, item):
self.stack.append(item)
self.length = self.length + 1
"""Dequeues {@code item}
@requirement: |self.length| > 0
@return dequeued
item that was dequeued"""
def get(self):
self.rotate(1)
dequeued = self.stack[self.length-1]
self.stack = self.stack[:-1]
self.rotate(self.length-1)
self.length = self.length -1
return dequeued
"""Rotates the queue {@code rotation} times
@param rotation
number of times to rotate queue"""
def rotate(self, rotation):
for i in range(rotation):
temp = self.stack[0]
self.stack = self.stack[1:]
self.put(temp)
self.length = self.length - 1
"""Reports item at the front of self
@return item at front of self.stack"""
def front(self):
front = self.get()
self.put(front)
self.rotate(self.length-1)
return front
"""Returns the length of this.stack"""
def size(self):
return self.length

View File

View File

@ -0,0 +1,52 @@
'''
The stock span problem is a financial problem where we have a series of n daily
price quotes for a stock and we need to calculate span of stock's price for all n days.
The span Si of the stock's price on a given day i is defined as the maximum
number of consecutive days just before the given day, for which the price of the stock
on the current day is less than or equal to its price on the given day.
'''
from __future__ import print_function
def calculateSpan(price, S):
n = len(price)
# Create a stack and push index of fist element to it
st = []
st.append(0)
# Span value of first element is always 1
S[0] = 1
# Calculate span values for rest of the elements
for i in range(1, n):
# Pop elements from stack whlie stack is not
# empty and top of stack is smaller than price[i]
while( len(st) > 0 and price[st[0]] <= price[i]):
st.pop()
# If stack becomes empty, then price[i] is greater
# than all elements on left of it, i.e. price[0],
# price[1], ..price[i-1]. Else the price[i] is
# greater than elements after top of stack
S[i] = i+1 if len(st) <= 0 else (i - st[0])
# Push this element to stack
st.append(i)
# A utility function to print elements of array
def printArray(arr, n):
for i in range(0,n):
print (arr[i],end =" ")
# Driver program to test above function
price = [10, 4, 5, 90, 120, 80]
S = [0 for i in range(len(price)+1)]
# Fill the span values in array S[]
calculateSpan(price, S)
# Print the calculated span values
printArray(S, len(price))

View File

@ -0,0 +1,23 @@
class Stack:
def __init__(self):
self.stack = []
self.top = 0
def is_empty(self):
return (self.top == 0)
def push(self, item):
if self.top < len(self.stack):
self.stack[self.top] = item
else:
self.stack.append(item)
self.top += 1
def pop(self):
if self.is_empty():
return None
else:
self.top -= 1
return self.stack[self.top]

View File

@ -0,0 +1,23 @@
from __future__ import print_function
from __future__ import absolute_import
from .Stack import Stack
__author__ = 'Omkar Pathak'
def balanced_parentheses(parentheses):
""" Use a stack to check if a string of parentheses are balanced."""
stack = Stack(len(parentheses))
for parenthesis in parentheses:
if parenthesis == '(':
stack.push(parenthesis)
elif parenthesis == ')':
stack.pop()
return not stack.is_empty()
if __name__ == '__main__':
examples = ['((()))', '((())']
print('Balanced parentheses demonstration:\n')
for example in examples:
print(example + ': ' + str(balanced_parentheses(example)))

View File

@ -0,0 +1,64 @@
from __future__ import print_function
from __future__ import absolute_import
import string
from .Stack import Stack
__author__ = 'Omkar Pathak'
def is_operand(char):
return char in string.ascii_letters or char in string.digits
def precedence(char):
""" Return integer value representing an operator's precedence, or
order of operation.
https://en.wikipedia.org/wiki/Order_of_operations
"""
dictionary = {'+': 1, '-': 1,
'*': 2, '/': 2,
'^': 3}
return dictionary.get(char, -1)
def infix_to_postfix(expression):
""" Convert infix notation to postfix notation using the Shunting-yard
algorithm.
https://en.wikipedia.org/wiki/Shunting-yard_algorithm
https://en.wikipedia.org/wiki/Infix_notation
https://en.wikipedia.org/wiki/Reverse_Polish_notation
"""
stack = Stack(len(expression))
postfix = []
for char in expression:
if is_operand(char):
postfix.append(char)
elif char not in {'(', ')'}:
while (not stack.is_empty()
and precedence(char) <= precedence(stack.peek())):
postfix.append(stack.pop())
stack.push(char)
elif char == '(':
stack.push(char)
elif char == ')':
while not stack.is_empty() and stack.peek() != '(':
postfix.append(stack.pop())
# Pop '(' from stack. If there is no '(', there is a mismatched
# parentheses.
if stack.peek() != '(':
raise ValueError('Mismatched parentheses')
stack.pop()
while not stack.is_empty():
postfix.append(stack.pop())
return ' '.join(postfix)
if __name__ == '__main__':
expression = 'a+b*(c^d-e)^(f+g*h)-i'
print('Infix to Postfix Notation demonstration:\n')
print('Infix notation: ' + expression)
print('Postfix notation: ' + infix_to_postfix(expression))

View File

@ -0,0 +1,17 @@
from __future__ import print_function
# Function to print element and NGE pair for all elements of list
def printNGE(arr):
for i in range(0, len(arr), 1):
next = -1
for j in range(i+1, len(arr), 1):
if arr[i] < arr[j]:
next = arr[j]
break
print(str(arr[i]) + " -- " + str(next))
# Driver program to test above function
arr = [11,13,21,3]
printNGE(arr)

View File

@ -0,0 +1,69 @@
from __future__ import print_function
__author__ = 'Omkar Pathak'
class Stack(object):
""" A stack is an abstract data type that serves as a collection of
elements with two principal operations: push() and pop(). push() adds an
element to the top of the stack, and pop() removes an element from the top
of a stack. The order in which elements come off of a stack are
Last In, First Out (LIFO).
https://en.wikipedia.org/wiki/Stack_(abstract_data_type)
"""
def __init__(self, limit=10):
self.stack = []
self.limit = limit
def __bool__(self):
return not bool(self.stack)
def __str__(self):
return str(self.stack)
def push(self, data):
""" Push an element to the top of the stack."""
if len(self.stack) >= self.limit:
raise StackOverflowError
self.stack.append(data)
def pop(self):
""" Pop an element off of the top of the stack."""
if self.stack:
return self.stack.pop()
else:
raise IndexError('pop from an empty stack')
def peek(self):
""" Peek at the top-most element of the stack."""
if self.stack:
return self.stack[-1]
def is_empty(self):
""" Check if a stack is empty."""
return not bool(self.stack)
def size(self):
""" Return the size of the stack."""
return len(self.stack)
class StackOverflowError(BaseException):
pass
if __name__ == '__main__':
stack = Stack()
for i in range(10):
stack.push(i)
print('Stack demonstration:\n')
print('Initial stack: ' + str(stack))
print('pop(): ' + str(stack.pop()))
print('After pop(), the stack is now: ' + str(stack))
print('peek(): ' + str(stack.peek()))
stack.push(100)
print('After push(100), the stack is now: ' + str(stack))
print('is_empty(): ' + str(stack.is_empty()))
print('size(): ' + str(stack.size()))

View File

@ -0,0 +1,75 @@
"""
A Trie/Prefix Tree is a kind of search tree used to provide quick lookup
of words/patterns in a set of words. A basic Trie however has O(n^2) space complexity
making it impractical in practice. It however provides O(max(search_string, length of longest word)) lookup
time making it an optimal approach when space is not an issue.
"""
class TrieNode:
def __init__(self):
self.nodes = dict() # Mapping from char to TrieNode
self.is_leaf = False
def insert_many(self, words: [str]): # noqa: E999 This syntax is Python 3 only
"""
Inserts a list of words into the Trie
:param words: list of string words
:return: None
"""
for word in words:
self.insert(word)
def insert(self, word: str): # noqa: E999 This syntax is Python 3 only
"""
Inserts a word into the Trie
:param word: word to be inserted
:return: None
"""
curr = self
for char in word:
if char not in curr.nodes:
curr.nodes[char] = TrieNode()
curr = curr.nodes[char]
curr.is_leaf = True
def find(self, word: str) -> bool: # noqa: E999 This syntax is Python 3 only
"""
Tries to find word in a Trie
:param word: word to look for
:return: Returns True if word is found, False otherwise
"""
curr = self
for char in word:
if char not in curr.nodes:
return False
curr = curr.nodes[char]
return curr.is_leaf
def print_words(node: TrieNode, word: str): # noqa: E999 This syntax is Python 3 only
"""
Prints all the words in a Trie
:param node: root node of Trie
:param word: Word variable should be empty at start
:return: None
"""
if node.is_leaf:
print(word, end=' ')
for key, value in node.nodes.items():
print_words(value, word + key)
def test():
words = ['banana', 'bananas', 'bandana', 'band', 'apple', 'all', 'beast']
root = TrieNode()
root.insert_many(words)
# print_words(root, '')
assert root.find('banana')
assert not root.find('bandanas')
assert not root.find('apps')
assert root.find('apple')
test()

View File

View File

@ -0,0 +1,78 @@
from __future__ import absolute_import
from .union_find import UnionFind
import unittest
class TestUnionFind(unittest.TestCase):
def test_init_with_valid_size(self):
uf = UnionFind(5)
self.assertEqual(uf.size, 5)
def test_init_with_invalid_size(self):
with self.assertRaises(ValueError):
uf = UnionFind(0)
with self.assertRaises(ValueError):
uf = UnionFind(-5)
def test_union_with_valid_values(self):
uf = UnionFind(10)
for i in range(11):
for j in range(11):
uf.union(i, j)
def test_union_with_invalid_values(self):
uf = UnionFind(10)
with self.assertRaises(ValueError):
uf.union(-1, 1)
with self.assertRaises(ValueError):
uf.union(11, 1)
def test_same_set_with_valid_values(self):
uf = UnionFind(10)
for i in range(11):
for j in range(11):
if i == j:
self.assertTrue(uf.same_set(i, j))
else:
self.assertFalse(uf.same_set(i, j))
uf.union(1, 2)
self.assertTrue(uf.same_set(1, 2))
uf.union(3, 4)
self.assertTrue(uf.same_set(3, 4))
self.assertFalse(uf.same_set(1, 3))
self.assertFalse(uf.same_set(1, 4))
self.assertFalse(uf.same_set(2, 3))
self.assertFalse(uf.same_set(2, 4))
uf.union(1, 3)
self.assertTrue(uf.same_set(1, 3))
self.assertTrue(uf.same_set(1, 4))
self.assertTrue(uf.same_set(2, 3))
self.assertTrue(uf.same_set(2, 4))
uf.union(4, 10)
self.assertTrue(uf.same_set(1, 10))
self.assertTrue(uf.same_set(2, 10))
self.assertTrue(uf.same_set(3, 10))
self.assertTrue(uf.same_set(4, 10))
def test_same_set_with_invalid_values(self):
uf = UnionFind(10)
with self.assertRaises(ValueError):
uf.same_set(-1, 1)
with self.assertRaises(ValueError):
uf.same_set(11, 0)
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1,87 @@
class UnionFind():
"""
https://en.wikipedia.org/wiki/Disjoint-set_data_structure
The union-find is a disjoint-set data structure
You can merge two sets and tell if one set belongs to
another one.
It's used on the Kruskal Algorithm
(https://en.wikipedia.org/wiki/Kruskal%27s_algorithm)
The elements are in range [0, size]
"""
def __init__(self, size):
if size <= 0:
raise ValueError("size should be greater than 0")
self.size = size
# The below plus 1 is because we are using elements
# in range [0, size]. It makes more sense.
# Every set begins with only itself
self.root = [i for i in range(size+1)]
# This is used for heuristic union by rank
self.weight = [0 for i in range(size+1)]
def union(self, u, v):
"""
Union of the sets u and v.
Complexity: log(n).
Amortized complexity: < 5 (it's very fast).
"""
self._validate_element_range(u, "u")
self._validate_element_range(v, "v")
if u == v:
return
# Using union by rank will guarantee the
# log(n) complexity
rootu = self._root(u)
rootv = self._root(v)
weight_u = self.weight[rootu]
weight_v = self.weight[rootv]
if weight_u >= weight_v:
self.root[rootv] = rootu
if weight_u == weight_v:
self.weight[rootu] += 1
else:
self.root[rootu] = rootv
def same_set(self, u, v):
"""
Return true if the elements u and v belongs to
the same set
"""
self._validate_element_range(u, "u")
self._validate_element_range(v, "v")
return self._root(u) == self._root(v)
def _root(self, u):
"""
Get the element set root.
This uses the heuristic path compression
See wikipedia article for more details.
"""
if u != self.root[u]:
self.root[u] = self._root(self.root[u])
return self.root[u]
def _validate_element_range(self, u, element_name):
"""
Raises ValueError if element is not in range
"""
if u < 0 or u > self.size:
msg = ("element {0} with value {1} "
"should be in range [0~{2}]")\
.format(element_name, u, self.size)
raise ValueError(msg)

View File

@ -0,0 +1,37 @@
import math
class Graph:
def __init__(self, N = 0): # a graph with Node 0,1,...,N-1
self.N = N
self.W = [[math.inf for j in range(0,N)] for i in range(0,N)] # adjacency matrix for weight
self.dp = [[math.inf for j in range(0,N)] for i in range(0,N)] # dp[i][j] stores minimum distance from i to j
def addEdge(self, u, v, w):
self.dp[u][v] = w
def floyd_warshall(self):
for k in range(0,self.N):
for i in range(0,self.N):
for j in range(0,self.N):
self.dp[i][j] = min(self.dp[i][j], self.dp[i][k] + self.dp[k][j])
def showMin(self, u, v):
return self.dp[u][v]
if __name__ == '__main__':
graph = Graph(5)
graph.addEdge(0,2,9)
graph.addEdge(0,4,10)
graph.addEdge(1,3,5)
graph.addEdge(2,3,7)
graph.addEdge(3,0,10)
graph.addEdge(3,1,2)
graph.addEdge(3,2,1)
graph.addEdge(3,4,6)
graph.addEdge(4,1,3)
graph.addEdge(4,2,4)
graph.addEdge(4,3,9)
graph.floyd_warshall()
graph.showMin(1,4)
graph.showMin(0,3)

View File

@ -0,0 +1,58 @@
# server
import socket # Import socket module
port = 60000 # Reserve a port for your service.
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
s.bind((host, port)) # Bind to the port
s.listen(5) # Now wait for client connection.
print('Server listening....')
while True:
conn, addr = s.accept() # Establish connection with client.
print('Got connection from', addr)
data = conn.recv(1024)
print('Server received', repr(data))
filename = 'mytext.txt'
f = open(filename, 'rb')
in_data = f.read(1024)
while (in_data):
conn.send(in_data)
print('Sent ', repr(in_data))
in_data = f.read(1024)
f.close()
print('Done sending')
conn.send('Thank you for connecting')
conn.close()
# client side server
import socket # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 60000 # Reserve a port for your service.
s.connect((host, port))
s.send("Hello server!")
with open('received_file', 'wb') as f:
print('file opened')
while True:
print('receiving data...')
data = s.recv(1024)
print('data=%s', (data))
if not data:
break
# write data to a file
f.write(data)
f.close()
print('Successfully get the file')
s.close()
print('connection closed')

View File

@ -0,0 +1,36 @@
"""
File transfer protocol used to send and receive files using FTP server.
Use credentials to provide access to the FTP client
Note: Do not use root username & password for security reasons
Create a seperate user and provide access to a home directory of the user
Use login id and password of the user created
cwd here stands for current working directory
"""
from ftplib import FTP
ftp = FTP('xxx.xxx.x.x') # Enter the ip address or the domain name here
ftp.login(user='username', passwd='password')
ftp.cwd('/Enter the directory here/')
"""
The file which will be received via the FTP server
Enter the location of the file where the file is received
"""
def ReceiveFile():
FileName = 'example.txt' """ Enter the location of the file """
LocalFile = open(FileName, 'wb')
ftp.retrbinary('RETR ' + FileName, LocalFile.write, 1024)
ftp.quit()
LocalFile.close()
"""
The file which will be sent via the FTP server
The file send will be send to the current working directory
"""
def SendFile():
FileName = 'example.txt' """ Enter the name of the file """
ftp.storbinary('STOR ' + FileName, open(FileName, 'rb'))
ftp.quit()

View File

@ -0,0 +1,44 @@
# Finding Articulation Points in Undirected Graph
def computeAP(l):
n = len(l)
outEdgeCount = 0
low = [0] * n
visited = [False] * n
isArt = [False] * n
def dfs(root, at, parent, outEdgeCount):
if parent == root:
outEdgeCount += 1
visited[at] = True
low[at] = at
for to in l[at]:
if to == parent:
pass
elif not visited[to]:
outEdgeCount = dfs(root, to, at, outEdgeCount)
low[at] = min(low[at], low[to])
# AP found via bridge
if at < low[to]:
isArt[at] = True
# AP found via cycle
if at == low[to]:
isArt[at] = True
else:
low[at] = min(low[at], to)
return outEdgeCount
for i in range(n):
if not visited[i]:
outEdgeCount = 0
outEdgeCount = dfs(i, i, -1, outEdgeCount)
isArt[i] = (outEdgeCount > 1)
for x in range(len(isArt)):
if isArt[x] == True:
print(x)
# Adjacency list of graph
l = {0:[1,2], 1:[0,2], 2:[0,1,3,5], 3:[2,4], 4:[3], 5:[2,6,8], 6:[5,7], 7:[6,8], 8:[5,7]}
computeAP(l)

View File

@ -0,0 +1,43 @@
# Check whether Graph is Bipartite or Not using BFS
# A Bipartite Graph is a graph whose vertices can be divided into two independent sets,
# U and V such that every edge (u, v) either connects a vertex from U to V or a vertex
# from V to U. In other words, for every edge (u, v), either u belongs to U and v to V,
# or u belongs to V and v to U. We can also say that there is no edge that connects
# vertices of same set.
def checkBipartite(l):
queue = []
visited = [False] * len(l)
color = [-1] * len(l)
def bfs():
while(queue):
u = queue.pop(0)
visited[u] = True
for neighbour in l[u]:
if neighbour == u:
return False
if color[neighbour] == -1:
color[neighbour] = 1 - color[u]
queue.append(neighbour)
elif color[neighbour] == color[u]:
return False
return True
for i in range(len(l)):
if not visited[i]:
queue.append(i)
color[i] = 0
if bfs() == False:
return False
return True
# Adjacency List of graph
l = {0:[1,3], 1:[0,2], 2:[1,3], 3:[0,2]}
print(checkBipartite(l))

31
graphs/FindingBridges.py Normal file
View File

@ -0,0 +1,31 @@
# Finding Bridges in Undirected Graph
def computeBridges(l):
id = 0
n = len(l) # No of vertices in graph
low = [0] * n
visited = [False] * n
def dfs(at, parent, bridges, id):
visited[at] = True
low[at] = id
id += 1
for to in l[at]:
if to == parent:
pass
elif not visited[to]:
dfs(to, at, bridges, id)
low[at] = min(low[at], low[to])
if at < low[to]:
bridges.append([at, to])
else:
# This edge is a back edge and cannot be a bridge
low[at] = min(low[at], to)
bridges = []
for i in range(n):
if (not visited[i]):
dfs(i, -1, bridges, id)
print(bridges)
l = {0:[1,2], 1:[0,2], 2:[0,1,3,5], 3:[2,4], 4:[3], 5:[2,6,8], 6:[5,7], 7:[6,8], 8:[5,7]}
computeBridges(l)

View File

@ -0,0 +1,30 @@
# Finding longest distance in Directed Acyclic Graph using KahnsAlgorithm
def longestDistance(l):
indegree = [0] * len(l)
queue = []
longDist = [1] * len(l)
for key, values in l.items():
for i in values:
indegree[i] += 1
for i in range(len(indegree)):
if indegree[i] == 0:
queue.append(i)
while(queue):
vertex = queue.pop(0)
for x in l[vertex]:
indegree[x] -= 1
if longDist[vertex] + 1 > longDist[x]:
longDist[x] = longDist[vertex] + 1
if indegree[x] == 0:
queue.append(x)
print(max(longDist))
# Adjacency list of Graph
l = {0:[2,3,4], 1:[2,7], 2:[5], 3:[5,7], 4:[7], 5:[6], 6:[7], 7:[]}
longestDistance(l)

View File

@ -0,0 +1,32 @@
# Kahn's Algorithm is used to find Topological ordering of Directed Acyclic Graph using BFS
def topologicalSort(l):
indegree = [0] * len(l)
queue = []
topo = []
cnt = 0
for key, values in l.items():
for i in values:
indegree[i] += 1
for i in range(len(indegree)):
if indegree[i] == 0:
queue.append(i)
while(queue):
vertex = queue.pop(0)
cnt += 1
topo.append(vertex)
for x in l[vertex]:
indegree[x] -= 1
if indegree[x] == 0:
queue.append(x)
if cnt != len(l):
print("Cycle exists")
else:
print(topo)
# Adjacency List of Graph
l = {0:[1,2], 1:[3], 2:[3], 3:[4,5], 4:[], 5:[]}
topologicalSort(l)

View File

@ -0,0 +1,111 @@
import sys
from collections import defaultdict
def PrimsAlgorithm(l):
nodePosition = []
def getPosition(vertex):
return nodePosition[vertex]
def setPosition(vertex, pos):
nodePosition[vertex] = pos
def topToBottom(heap, start, size, positions):
if start > size // 2 - 1:
return
else:
if 2 * start + 2 >= size:
m = 2 * start + 1
else:
if heap[2 * start + 1] < heap[2 * start + 2]:
m = 2 * start + 1
else:
m = 2 * start + 2
if heap[m] < heap[start]:
temp, temp1 = heap[m], positions[m]
heap[m], positions[m] = heap[start], positions[start]
heap[start], positions[start] = temp, temp1
temp = getPosition(positions[m])
setPosition(positions[m], getPosition(positions[start]))
setPosition(positions[start], temp)
topToBottom(heap, m, size, positions)
# Update function if value of any node in min-heap decreases
def bottomToTop(val, index, heap, position):
temp = position[index]
while(index != 0):
if index % 2 == 0:
parent = int( (index-2) / 2 )
else:
parent = int( (index-1) / 2 )
if val < heap[parent]:
heap[index] = heap[parent]
position[index] = position[parent]
setPosition(position[parent], index)
else:
heap[index] = val
position[index] = temp
setPosition(temp, index)
break
index = parent
else:
heap[0] = val
position[0] = temp
setPosition(temp, 0)
def heapify(heap, positions):
start = len(heap) // 2 - 1
for i in range(start, -1, -1):
topToBottom(heap, i, len(heap), positions)
def deleteMinimum(heap, positions):
temp = positions[0]
heap[0] = sys.maxsize
topToBottom(heap, 0, len(heap), positions)
return temp
visited = [0 for i in range(len(l))]
Nbr_TV = [-1 for i in range(len(l))] # Neighboring Tree Vertex of selected vertex
# Minimum Distance of explored vertex with neighboring vertex of partial tree formed in graph
Distance_TV = [] # Heap of Distance of vertices from their neighboring vertex
Positions = []
for x in range(len(l)):
p = sys.maxsize
Distance_TV.append(p)
Positions.append(x)
nodePosition.append(x)
TreeEdges = []
visited[0] = 1
Distance_TV[0] = sys.maxsize
for x in l[0]:
Nbr_TV[ x[0] ] = 0
Distance_TV[ x[0] ] = x[1]
heapify(Distance_TV, Positions)
for i in range(1, len(l)):
vertex = deleteMinimum(Distance_TV, Positions)
if visited[vertex] == 0:
TreeEdges.append((Nbr_TV[vertex], vertex))
visited[vertex] = 1
for v in l[vertex]:
if visited[v[0]] == 0 and v[1] < Distance_TV[ getPosition(v[0]) ]:
Distance_TV[ getPosition(v[0]) ] = v[1]
bottomToTop(v[1], getPosition(v[0]), Distance_TV, Positions)
Nbr_TV[ v[0] ] = vertex
return TreeEdges
# < --------- Prims Algorithm --------- >
n = int(raw_input("Enter number of vertices: "))
e = int(raw_input("Enter number of edges: "))
adjlist = defaultdict(list)
for x in range(e):
l = [int(x) for x in input().split()]
adjlist[l[0]].append([ l[1], l[2] ])
adjlist[l[1]].append([ l[0], l[2] ])
print(PrimsAlgorithm(adjlist))

View File

@ -0,0 +1,266 @@
from __future__ import print_function
import heapq
import numpy as np
try:
xrange # Python 2
except NameError:
xrange = range # Python 3
class PriorityQueue:
def __init__(self):
self.elements = []
self.set = set()
def minkey(self):
if not self.empty():
return self.elements[0][0]
else:
return float('inf')
def empty(self):
return len(self.elements) == 0
def put(self, item, priority):
if item not in self.set:
heapq.heappush(self.elements, (priority, item))
self.set.add(item)
else:
# update
# print("update", item)
temp = []
(pri, x) = heapq.heappop(self.elements)
while x != item:
temp.append((pri, x))
(pri, x) = heapq.heappop(self.elements)
temp.append((priority, item))
for (pro, xxx) in temp:
heapq.heappush(self.elements, (pro, xxx))
def remove_element(self, item):
if item in self.set:
self.set.remove(item)
temp = []
(pro, x) = heapq.heappop(self.elements)
while x != item:
temp.append((pro, x))
(pro, x) = heapq.heappop(self.elements)
for (prito, yyy) in temp:
heapq.heappush(self.elements, (prito, yyy))
def top_show(self):
return self.elements[0][1]
def get(self):
(priority, item) = heapq.heappop(self.elements)
self.set.remove(item)
return (priority, item)
def consistent_hueristic(P, goal):
# euclidean distance
a = np.array(P)
b = np.array(goal)
return np.linalg.norm(a - b)
def hueristic_2(P, goal):
# integer division by time variable
return consistent_hueristic(P, goal) // t
def hueristic_1(P, goal):
# manhattan distance
return abs(P[0] - goal[0]) + abs(P[1] - goal[1])
def key(start, i, goal, g_function):
ans = g_function[start] + W1 * hueristics[i](start, goal)
return ans
def do_something(back_pointer, goal, start):
grid = np.chararray((n, n))
for i in range(n):
for j in range(n):
grid[i][j] = '*'
for i in range(n):
for j in range(n):
if (j, (n-1)-i) in blocks:
grid[i][j] = "#"
grid[0][(n-1)] = "-"
x = back_pointer[goal]
while x != start:
(x_c, y_c) = x
# print(x)
grid[(n-1)-y_c][x_c] = "-"
x = back_pointer[x]
grid[(n-1)][0] = "-"
for i in xrange(n):
for j in range(n):
if (i, j) == (0, n-1):
print(grid[i][j], end=' ')
print("<-- End position", end=' ')
else:
print(grid[i][j], end=' ')
print()
print("^")
print("Start position")
print()
print("# is an obstacle")
print("- is the path taken by algorithm")
print("PATH TAKEN BY THE ALGORITHM IS:-")
x = back_pointer[goal]
while x != start:
print(x, end=' ')
x = back_pointer[x]
print(x)
quit()
def valid(p):
if p[0] < 0 or p[0] > n-1:
return False
if p[1] < 0 or p[1] > n-1:
return False
return True
def expand_state(s, j, visited, g_function, close_list_anchor, close_list_inad, open_list, back_pointer):
for itera in range(n_hueristic):
open_list[itera].remove_element(s)
# print("s", s)
# print("j", j)
(x, y) = s
left = (x-1, y)
right = (x+1, y)
up = (x, y+1)
down = (x, y-1)
for neighbours in [left, right, up, down]:
if neighbours not in blocks:
if valid(neighbours) and neighbours not in visited:
# print("neighbour", neighbours)
visited.add(neighbours)
back_pointer[neighbours] = -1
g_function[neighbours] = float('inf')
if valid(neighbours) and g_function[neighbours] > g_function[s] + 1:
g_function[neighbours] = g_function[s] + 1
back_pointer[neighbours] = s
if neighbours not in close_list_anchor:
open_list[0].put(neighbours, key(neighbours, 0, goal, g_function))
if neighbours not in close_list_inad:
for var in range(1,n_hueristic):
if key(neighbours, var, goal, g_function) <= W2 * key(neighbours, 0, goal, g_function):
# print("why not plssssssssss")
open_list[j].put(neighbours, key(neighbours, var, goal, g_function))
# print
def make_common_ground():
some_list = []
# block 1
for x in range(1, 5):
for y in range(1, 6):
some_list.append((x, y))
# line
for x in range(15, 20):
some_list.append((x, 17))
# block 2 big
for x in range(10, 19):
for y in range(1, 15):
some_list.append((x, y))
# L block
for x in range(1, 4):
for y in range(12, 19):
some_list.append((x, y))
for x in range(3, 13):
for y in range(16, 19):
some_list.append((x, y))
return some_list
hueristics = {0: consistent_hueristic, 1: hueristic_1, 2: hueristic_2}
blocks_blk = [(0, 1),(1, 1),(2, 1),(3, 1),(4, 1),(5, 1),(6, 1),(7, 1),(8, 1),(9, 1),(10, 1),(11, 1),(12, 1),(13, 1),(14, 1),(15, 1),(16, 1),(17, 1),(18, 1), (19, 1)]
blocks_no = []
blocks_all = make_common_ground()
blocks = blocks_blk
# hyper parameters
W1 = 1
W2 = 1
n = 20
n_hueristic = 3 # one consistent and two other inconsistent
# start and end destination
start = (0, 0)
goal = (n-1, n-1)
t = 1
def multi_a_star(start, goal, n_hueristic):
g_function = {start: 0, goal: float('inf')}
back_pointer = {start:-1, goal:-1}
open_list = []
visited = set()
for i in range(n_hueristic):
open_list.append(PriorityQueue())
open_list[i].put(start, key(start, i, goal, g_function))
close_list_anchor = []
close_list_inad = []
while open_list[0].minkey() < float('inf'):
for i in range(1, n_hueristic):
# print("i", i)
# print(open_list[0].minkey(), open_list[i].minkey())
if open_list[i].minkey() <= W2 * open_list[0].minkey():
global t
t += 1
# print("less prio")
if g_function[goal] <= open_list[i].minkey():
if g_function[goal] < float('inf'):
do_something(back_pointer, goal, start)
else:
_, get_s = open_list[i].top_show()
visited.add(get_s)
expand_state(get_s, i, visited, g_function, close_list_anchor, close_list_inad, open_list, back_pointer)
close_list_inad.append(get_s)
else:
# print("more prio")
if g_function[goal] <= open_list[0].minkey():
if g_function[goal] < float('inf'):
do_something(back_pointer, goal, start)
else:
# print("hoolla")
get_s = open_list[0].top_show()
visited.add(get_s)
expand_state(get_s, 0, visited, g_function, close_list_anchor, close_list_inad, open_list, back_pointer)
close_list_anchor.append(get_s)
print("No path found to goal")
print()
for i in range(n-1,-1, -1):
for j in range(n):
if (j, i) in blocks:
print('#', end=' ')
elif (j, i) in back_pointer:
if (j, i) == (n-1, n-1):
print('*', end=' ')
else:
print('-', end=' ')
else:
print('*', end=' ')
if (j, i) == (n-1, n-1):
print('<-- End position', end=' ')
print()
print("^")
print("Start position")
print()
print("# is an obstacle")
print("- is the path taken by algorithm")
multi_a_star(start, goal, n_hueristic)

102
graphs/a_star.py Normal file
View File

@ -0,0 +1,102 @@
from __future__ import print_function
grid = [[0, 1, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0],#0 are free path whereas 1's are obstacles
[0, 1, 0, 0, 0, 0],
[0, 1, 0, 0, 1, 0],
[0, 0, 0, 0, 1, 0]]
'''
heuristic = [[9, 8, 7, 6, 5, 4],
[8, 7, 6, 5, 4, 3],
[7, 6, 5, 4, 3, 2],
[6, 5, 4, 3, 2, 1],
[5, 4, 3, 2, 1, 0]]'''
init = [0, 0]
goal = [len(grid)-1, len(grid[0])-1] #all coordinates are given in format [y,x]
cost = 1
#the cost map which pushes the path closer to the goal
heuristic = [[0 for row in range(len(grid[0]))] for col in range(len(grid))]
for i in range(len(grid)):
for j in range(len(grid[0])):
heuristic[i][j] = abs(i - goal[0]) + abs(j - goal[1])
if grid[i][j] == 1:
heuristic[i][j] = 99 #added extra penalty in the heuristic map
#the actions we can take
delta = [[-1, 0 ], # go up
[ 0, -1], # go left
[ 1, 0 ], # go down
[ 0, 1 ]] # go right
#function to search the path
def search(grid,init,goal,cost,heuristic):
closed = [[0 for col in range(len(grid[0]))] for row in range(len(grid))]# the referrence grid
closed[init[0]][init[1]] = 1
action = [[0 for col in range(len(grid[0]))] for row in range(len(grid))]#the action grid
x = init[0]
y = init[1]
g = 0
f = g + heuristic[init[0]][init[0]]
cell = [[f, g, x, y]]
found = False # flag that is set when search is complete
resign = False # flag set if we can't find expand
while not found and not resign:
if len(cell) == 0:
resign = True
return "FAIL"
else:
cell.sort()#to choose the least costliest action so as to move closer to the goal
cell.reverse()
next = cell.pop()
x = next[2]
y = next[3]
g = next[1]
f = next[0]
if x == goal[0] and y == goal[1]:
found = True
else:
for i in range(len(delta)):#to try out different valid actions
x2 = x + delta[i][0]
y2 = y + delta[i][1]
if x2 >= 0 and x2 < len(grid) and y2 >=0 and y2 < len(grid[0]):
if closed[x2][y2] == 0 and grid[x2][y2] == 0:
g2 = g + cost
f2 = g2 + heuristic[x2][y2]
cell.append([f2, g2, x2, y2])
closed[x2][y2] = 1
action[x2][y2] = i
invpath = []
x = goal[0]
y = goal[1]
invpath.append([x, y])#we get the reverse path from here
while x != init[0] or y != init[1]:
x2 = x - delta[action[x][y]][0]
y2 = y - delta[action[x][y]][1]
x = x2
y = y2
invpath.append([x, y])
path = []
for i in range(len(invpath)):
path.append(invpath[len(invpath) - 1 - i])
print("ACTION MAP")
for i in range(len(action)):
print(action[i])
return path
a = search(grid,init,goal,cost,heuristic)
for i in range(len(a)):
print(a[i])

281
graphs/basic-graphs.py Normal file
View File

@ -0,0 +1,281 @@
from __future__ import print_function
try:
raw_input # Python 2
except NameError:
raw_input = input # Python 3
try:
xrange # Python 2
except NameError:
xrange = range # Python 3
# Accept No. of Nodes and edges
n, m = map(int, raw_input().split(" "))
# Initialising Dictionary of edges
g = {}
for i in xrange(n):
g[i + 1] = []
"""
--------------------------------------------------------------------------------
Accepting edges of Unweighted Directed Graphs
--------------------------------------------------------------------------------
"""
for _ in xrange(m):
x, y = map(int, raw_input().split(" "))
g[x].append(y)
"""
--------------------------------------------------------------------------------
Accepting edges of Unweighted Undirected Graphs
--------------------------------------------------------------------------------
"""
for _ in xrange(m):
x, y = map(int, raw_input().split(" "))
g[x].append(y)
g[y].append(x)
"""
--------------------------------------------------------------------------------
Accepting edges of Weighted Undirected Graphs
--------------------------------------------------------------------------------
"""
for _ in xrange(m):
x, y, r = map(int, raw_input().split(" "))
g[x].append([y, r])
g[y].append([x, r])
"""
--------------------------------------------------------------------------------
Depth First Search.
Args : G - Dictionary of edges
s - Starting Node
Vars : vis - Set of visited nodes
S - Traversal Stack
--------------------------------------------------------------------------------
"""
def dfs(G, s):
vis, S = set([s]), [s]
print(s)
while S:
flag = 0
for i in G[S[-1]]:
if i not in vis:
S.append(i)
vis.add(i)
flag = 1
print(i)
break
if not flag:
S.pop()
"""
--------------------------------------------------------------------------------
Breadth First Search.
Args : G - Dictionary of edges
s - Starting Node
Vars : vis - Set of visited nodes
Q - Traveral Stack
--------------------------------------------------------------------------------
"""
from collections import deque
def bfs(G, s):
vis, Q = set([s]), deque([s])
print(s)
while Q:
u = Q.popleft()
for v in G[u]:
if v not in vis:
vis.add(v)
Q.append(v)
print(v)
"""
--------------------------------------------------------------------------------
Dijkstra's shortest path Algorithm
Args : G - Dictionary of edges
s - Starting Node
Vars : dist - Dictionary storing shortest distance from s to every other node
known - Set of knows nodes
path - Preceding node in path
--------------------------------------------------------------------------------
"""
def dijk(G, s):
dist, known, path = {s: 0}, set(), {s: 0}
while True:
if len(known) == len(G) - 1:
break
mini = 100000
for i in dist:
if i not in known and dist[i] < mini:
mini = dist[i]
u = i
known.add(u)
for v in G[u]:
if v[0] not in known:
if dist[u] + v[1] < dist.get(v[0], 100000):
dist[v[0]] = dist[u] + v[1]
path[v[0]] = u
for i in dist:
if i != s:
print(dist[i])
"""
--------------------------------------------------------------------------------
Topological Sort
--------------------------------------------------------------------------------
"""
from collections import deque
def topo(G, ind=None, Q=[1]):
if ind is None:
ind = [0] * (len(G) + 1) # SInce oth Index is ignored
for u in G:
for v in G[u]:
ind[v] += 1
Q = deque()
for i in G:
if ind[i] == 0:
Q.append(i)
if len(Q) == 0:
return
v = Q.popleft()
print(v)
for w in G[v]:
ind[w] -= 1
if ind[w] == 0:
Q.append(w)
topo(G, ind, Q)
"""
--------------------------------------------------------------------------------
Reading an Adjacency matrix
--------------------------------------------------------------------------------
"""
def adjm():
n, a = raw_input(), []
for i in xrange(n):
a.append(map(int, raw_input().split()))
return a, n
"""
--------------------------------------------------------------------------------
Floyd Warshall's algorithm
Args : G - Dictionary of edges
s - Starting Node
Vars : dist - Dictionary storing shortest distance from s to every other node
known - Set of knows nodes
path - Preceding node in path
--------------------------------------------------------------------------------
"""
def floy(A_and_n):
(A, n) = A_and_n
dist = list(A)
path = [[0] * n for i in xrange(n)]
for k in xrange(n):
for i in xrange(n):
for j in xrange(n):
if dist[i][j] > dist[i][k] + dist[k][j]:
dist[i][j] = dist[i][k] + dist[k][j]
path[i][k] = k
print(dist)
"""
--------------------------------------------------------------------------------
Prim's MST Algorithm
Args : G - Dictionary of edges
s - Starting Node
Vars : dist - Dictionary storing shortest distance from s to nearest node
known - Set of knows nodes
path - Preceding node in path
--------------------------------------------------------------------------------
"""
def prim(G, s):
dist, known, path = {s: 0}, set(), {s: 0}
while True:
if len(known) == len(G) - 1:
break
mini = 100000
for i in dist:
if i not in known and dist[i] < mini:
mini = dist[i]
u = i
known.add(u)
for v in G[u]:
if v[0] not in known:
if v[1] < dist.get(v[0], 100000):
dist[v[0]] = v[1]
path[v[0]] = u
"""
--------------------------------------------------------------------------------
Accepting Edge list
Vars : n - Number of nodes
m - Number of edges
Returns : l - Edge list
n - Number of Nodes
--------------------------------------------------------------------------------
"""
def edglist():
n, m = map(int, raw_input().split(" "))
l = []
for i in xrange(m):
l.append(map(int, raw_input().split(' ')))
return l, n
"""
--------------------------------------------------------------------------------
Kruskal's MST Algorithm
Args : E - Edge list
n - Number of Nodes
Vars : s - Set of all nodes as unique disjoint sets (initially)
--------------------------------------------------------------------------------
"""
def krusk(E_and_n):
# Sort edges on the basis of distance
(E, n) = E_and_n
E.sort(reverse=True, key=lambda x: x[2])
s = [set([i]) for i in range(1, n + 1)]
while True:
if len(s) == 1:
break
print(s)
x = E.pop()
for i in xrange(len(s)):
if x[0] in s[i]:
break
for j in xrange(len(s)):
if x[1] in s[j]:
if i == j:
break
s[j].update(s[i])
s.pop(i)
break

View File

@ -0,0 +1,32 @@
from __future__ import print_function
num_nodes, num_edges = list(map(int,raw_input().split()))
edges = []
for i in range(num_edges):
node1, node2, cost = list(map(int,raw_input().split()))
edges.append((i,node1,node2,cost))
edges = sorted(edges, key=lambda edge: edge[3])
parent = [i for i in range(num_nodes)]
def find_parent(i):
if(i != parent[i]):
parent[i] = find_parent(parent[i])
return parent[i]
minimum_spanning_tree_cost = 0
minimum_spanning_tree = []
for edge in edges:
parent_a = find_parent(edge[1])
parent_b = find_parent(edge[2])
if(parent_a != parent_b):
minimum_spanning_tree_cost += edge[3]
minimum_spanning_tree.append(edge)
parent[parent_a] = parent_b
print(minimum_spanning_tree_cost)
for edge in minimum_spanning_tree:
print(edge)

46
graphs/scc_kosaraju.py Normal file
View File

@ -0,0 +1,46 @@
from __future__ import print_function
# n - no of nodes, m - no of edges
n, m = list(map(int,raw_input().split()))
g = [[] for i in range(n)] #graph
r = [[] for i in range(n)] #reversed graph
# input graph data (edges)
for i in range(m):
u, v = list(map(int,raw_input().split()))
g[u].append(v)
r[v].append(u)
stack = []
visit = [False]*n
scc = []
component = []
def dfs(u):
global g, r, scc, component, visit, stack
if visit[u]: return
visit[u] = True
for v in g[u]:
dfs(v)
stack.append(u)
def dfs2(u):
global g, r, scc, component, visit, stack
if visit[u]: return
visit[u] = True
component.append(u)
for v in r[u]:
dfs2(v)
def kosaraju():
global g, r, scc, component, visit, stack
for i in range(n):
dfs(i)
visit = [False]*n
for i in stack[::-1]:
if visit[i]: continue
component = []
dfs2(i)
scc.append(component)
return scc
print(kosaraju())

78
graphs/tarjans_scc.py Normal file
View File

@ -0,0 +1,78 @@
from collections import deque
def tarjan(g):
"""
Tarjan's algo for finding strongly connected components in a directed graph
Uses two main attributes of each node to track reachability, the index of that node within a component(index),
and the lowest index reachable from that node(lowlink).
We then perform a dfs of the each component making sure to update these parameters for each node and saving the
nodes we visit on the way.
If ever we find that the lowest reachable node from a current node is equal to the index of the current node then it
must be the root of a strongly connected component and so we save it and it's equireachable vertices as a strongly
connected component.
Complexity: strong_connect() is called at most once for each node and has a complexity of O(|E|) as it is DFS.
Therefore this has complexity O(|V| + |E|) for a graph G = (V, E)
"""
n = len(g)
stack = deque()
on_stack = [False for _ in range(n)]
index_of = [-1 for _ in range(n)]
lowlink_of = index_of[:]
def strong_connect(v, index, components):
index_of[v] = index # the number when this node is seen
lowlink_of[v] = index # lowest rank node reachable from here
index += 1
stack.append(v)
on_stack[v] = True
for w in g[v]:
if index_of[w] == -1:
index = strong_connect(w, index, components)
lowlink_of[v] = lowlink_of[w] if lowlink_of[w] < lowlink_of[v] else lowlink_of[v]
elif on_stack[w]:
lowlink_of[v] = lowlink_of[w] if lowlink_of[w] < lowlink_of[v] else lowlink_of[v]
if lowlink_of[v] == index_of[v]:
component = []
w = stack.pop()
on_stack[w] = False
component.append(w)
while w != v:
w = stack.pop()
on_stack[w] = False
component.append(w)
components.append(component)
return index
components = []
for v in range(n):
if index_of[v] == -1:
strong_connect(v, 0, components)
return components
def create_graph(n, edges):
g = [[] for _ in range(n)]
for u, v in edges:
g[u].append(v)
return g
if __name__ == '__main__':
# Test
n_vertices = 7
source = [0, 0, 1, 2, 3, 3, 4, 4, 6]
target = [1, 3, 2, 0, 1, 4, 5, 6, 5]
edges = [(u, v) for u, v in zip(source, target)]
g = create_graph(n_vertices, edges)
assert [[5], [6], [4], [3, 2, 1, 0]] == tarjan(g)

View File

@ -0,0 +1,74 @@
# Linear algebra library for Python
This module contains some useful classes and functions for dealing with linear algebra in python 2.
---
## Overview
- class Vector
- This class represents a vector of arbitray size and operations on it.
**Overview about the methods:**
- constructor(components : list) : init the vector
- set(components : list) : changes the vector components.
- __str__() : toString method
- component(i : int): gets the i-th component (start by 0)
- size() : gets the size of the vector (number of components)
- euclidLength() : returns the eulidean length of the vector.
- operator + : vector addition
- operator - : vector subtraction
- operator * : scalar multiplication and dot product
- copy() : copies this vector and returns it.
- changeComponent(pos,value) : changes the specified component.
- function zeroVector(dimension)
- returns a zero vector of 'dimension'
- function unitBasisVector(dimension,pos)
- returns a unit basis vector with a One at index 'pos' (indexing at 0)
- function axpy(scalar,vector1,vector2)
- computes the axpy operation
- function randomVector(N,a,b)
- returns a random vector of size N, with random integer components between 'a' and 'b'.
- class Matrix
- This class represents a matrix of arbitrary size and operations on it.
**Overview about the methods:**
- __str__() : returns a string representation
- operator * : implements the matrix vector multiplication
implements the matrix-scalar multiplication.
- changeComponent(x,y,value) : changes the specified component.
- component(x,y) : returns the specified component.
- width() : returns the width of the matrix
- height() : returns the height of the matrix
- operator + : implements the matrix-addition.
- operator - _ implements the matrix-subtraction
- function squareZeroMatrix(N)
- returns a square zero-matrix of dimension NxN
- function randomMatrix(W,H,a,b)
- returns a random matrix WxH with integer components between 'a' and 'b'
---
## Documentation
The module is well documented. You can use the python in-built ```help(...)``` function.
For instance: ```help(Vector)``` gives you all information about the Vector-class.
Or ```help(unitBasisVector)``` gives you all information you needed about the
global function ```unitBasisVector(...)```. If you need informations about a certain
method you type ```help(CLASSNAME.METHODNAME)```.
---
## Usage
You will find the module in the **src** directory its called ```lib.py```. You need to
import this module in your project. Alternative you can also use the file ```lib.pyc``` in python-bytecode.
---
## Tests
In the **src** directory you also find the test-suite, its called ```tests.py```.
The test-suite uses the built-in python-test-framework **unittest**.

View File

@ -0,0 +1,364 @@
# -*- coding: utf-8 -*-
"""
Created on Mon Feb 26 14:29:11 2018
@author: Christian Bender
@license: MIT-license
This module contains some useful classes and functions for dealing
with linear algebra in python.
Overview:
- class Vector
- function zeroVector(dimension)
- function unitBasisVector(dimension,pos)
- function axpy(scalar,vector1,vector2)
- function randomVector(N,a,b)
- class Matrix
- function squareZeroMatrix(N)
- function randomMatrix(W,H,a,b)
"""
import math
import random
class Vector(object):
"""
This class represents a vector of arbitray size.
You need to give the vector components.
Overview about the methods:
constructor(components : list) : init the vector
set(components : list) : changes the vector components.
__str__() : toString method
component(i : int): gets the i-th component (start by 0)
size() : gets the size of the vector (number of components)
euclidLength() : returns the eulidean length of the vector.
operator + : vector addition
operator - : vector subtraction
operator * : scalar multiplication and dot product
copy() : copies this vector and returns it.
changeComponent(pos,value) : changes the specified component.
TODO: compare-operator
"""
def __init__(self,components):
"""
input: components or nothing
simple constructor for init the vector
"""
self.__components = components
def set(self,components):
"""
input: new components
changes the components of the vector.
replace the components with newer one.
"""
if len(components) > 0:
self.__components = components
else:
raise Exception("please give any vector")
def __str__(self):
"""
returns a string representation of the vector
"""
ans = "("
length = len(self.__components)
for i in range(length):
if i != length-1:
ans += str(self.__components[i]) + ","
else:
ans += str(self.__components[i]) + ")"
if len(ans) == 1:
ans += ")"
return ans
def component(self,i):
"""
input: index (start at 0)
output: the i-th component of the vector.
"""
if i < len(self.__components) and i >= 0:
return self.__components[i]
else:
raise Exception("index out of range")
def size(self):
"""
returns the size of the vector
"""
return len(self.__components)
def eulidLength(self):
"""
returns the eulidean length of the vector
"""
summe = 0
for c in self.__components:
summe += c**2
return math.sqrt(summe)
def __add__(self,other):
"""
input: other vector
assumes: other vector has the same size
returns a new vector that represents the sum.
"""
size = self.size()
result = []
if size == other.size():
for i in range(size):
result.append(self.__components[i] + other.component(i))
else:
raise Exception("must have the same size")
return Vector(result)
def __sub__(self,other):
"""
input: other vector
assumes: other vector has the same size
returns a new vector that represents the differenz.
"""
size = self.size()
result = []
if size == other.size():
for i in range(size):
result.append(self.__components[i] - other.component(i))
else: # error case
raise Exception("must have the same size")
return Vector(result)
def __mul__(self,other):
"""
mul implements the scalar multiplication
and the dot-product
"""
ans = []
if isinstance(other,float) or isinstance(other,int):
for c in self.__components:
ans.append(c*other)
elif (isinstance(other,Vector) and (self.size() == other.size())):
size = self.size()
summe = 0
for i in range(size):
summe += self.__components[i] * other.component(i)
return summe
else: # error case
raise Exception("invalide operand!")
return Vector(ans)
def copy(self):
"""
copies this vector and returns it.
"""
components = [x for x in self.__components]
return Vector(components)
def changeComponent(self,pos,value):
"""
input: an index (pos) and a value
changes the specified component (pos) with the
'value'
"""
#precondition
assert (pos >= 0 and pos < len(self.__components))
self.__components[pos] = value
def zeroVector(dimension):
"""
returns a zero-vector of size 'dimension'
"""
#precondition
assert(isinstance(dimension,int))
ans = []
for i in range(dimension):
ans.append(0)
return Vector(ans)
def unitBasisVector(dimension,pos):
"""
returns a unit basis vector with a One
at index 'pos' (indexing at 0)
"""
#precondition
assert(isinstance(dimension,int) and (isinstance(pos,int)))
ans = []
for i in range(dimension):
if i != pos:
ans.append(0)
else:
ans.append(1)
return Vector(ans)
def axpy(scalar,x,y):
"""
input: a 'scalar' and two vectors 'x' and 'y'
output: a vector
computes the axpy operation
"""
# precondition
assert(isinstance(x,Vector) and (isinstance(y,Vector)) \
and (isinstance(scalar,int) or isinstance(scalar,float)))
return (x*scalar + y)
def randomVector(N,a,b):
"""
input: size (N) of the vector.
random range (a,b)
output: returns a random vector of size N, with
random integer components between 'a' and 'b'.
"""
ans = zeroVector(N)
random.seed(None)
for i in range(N):
ans.changeComponent(i,random.randint(a,b))
return ans
class Matrix(object):
"""
class: Matrix
This class represents a arbitrary matrix.
Overview about the methods:
__str__() : returns a string representation
operator * : implements the matrix vector multiplication
implements the matrix-scalar multiplication.
changeComponent(x,y,value) : changes the specified component.
component(x,y) : returns the specified component.
width() : returns the width of the matrix
height() : returns the height of the matrix
operator + : implements the matrix-addition.
operator - _ implements the matrix-subtraction
"""
def __init__(self,matrix,w,h):
"""
simple constructor for initialzes
the matrix with components.
"""
self.__matrix = matrix
self.__width = w
self.__height = h
def __str__(self):
"""
returns a string representation of this
matrix.
"""
ans = ""
for i in range(self.__height):
ans += "|"
for j in range(self.__width):
if j < self.__width -1:
ans += str(self.__matrix[i][j]) + ","
else:
ans += str(self.__matrix[i][j]) + "|\n"
return ans
def changeComponent(self,x,y, value):
"""
changes the x-y component of this matrix
"""
if x >= 0 and x < self.__height and y >= 0 and y < self.__width:
self.__matrix[x][y] = value
else:
raise Exception ("changeComponent: indices out of bounds")
def component(self,x,y):
"""
returns the specified (x,y) component
"""
if x >= 0 and x < self.__height and y >= 0 and y < self.__width:
return self.__matrix[x][y]
else:
raise Exception ("changeComponent: indices out of bounds")
def width(self):
"""
getter for the width
"""
return self.__width
def height(self):
"""
getter for the height
"""
return self.__height
def __mul__(self,other):
"""
implements the matrix-vector multiplication.
implements the matrix-scalar multiplication
"""
if isinstance(other, Vector): # vector-matrix
if (other.size() == self.__width):
ans = zeroVector(self.__height)
for i in range(self.__height):
summe = 0
for j in range(self.__width):
summe += other.component(j) * self.__matrix[i][j]
ans.changeComponent(i,summe)
summe = 0
return ans
else:
raise Exception("vector must have the same size as the "
+ "number of columns of the matrix!")
elif isinstance(other,int) or isinstance(other,float): # matrix-scalar
matrix = []
for i in range(self.__height):
row = []
for j in range(self.__width):
row.append(self.__matrix[i][j] * other)
matrix.append(row)
return Matrix(matrix,self.__width,self.__height)
def __add__(self,other):
"""
implements the matrix-addition.
"""
if (self.__width == other.width() and self.__height == other.height()):
matrix = []
for i in range(self.__height):
row = []
for j in range(self.__width):
row.append(self.__matrix[i][j] + other.component(i,j))
matrix.append(row)
return Matrix(matrix,self.__width,self.__height)
else:
raise Exception("matrix must have the same dimension!")
def __sub__(self,other):
"""
implements the matrix-subtraction.
"""
if (self.__width == other.width() and self.__height == other.height()):
matrix = []
for i in range(self.__height):
row = []
for j in range(self.__width):
row.append(self.__matrix[i][j] - other.component(i,j))
matrix.append(row)
return Matrix(matrix,self.__width,self.__height)
else:
raise Exception("matrix must have the same dimension!")
def squareZeroMatrix(N):
"""
returns a square zero-matrix of dimension NxN
"""
ans = []
for i in range(N):
row = []
for j in range(N):
row.append(0)
ans.append(row)
return Matrix(ans,N,N)
def randomMatrix(W,H,a,b):
"""
returns a random matrix WxH with integer components
between 'a' and 'b'
"""
matrix = []
random.seed(None)
for i in range(H):
row = []
for j in range(W):
row.append(random.randint(a,b))
matrix.append(row)
return Matrix(matrix,W,H)

View File

@ -0,0 +1,133 @@
# -*- coding: utf-8 -*-
"""
Created on Mon Feb 26 15:40:07 2018
@author: Christian Bender
@license: MIT-license
This file contains the test-suite for the linear algebra library.
"""
import unittest
from lib import *
class Test(unittest.TestCase):
def test_component(self):
"""
test for method component
"""
x = Vector([1,2,3])
self.assertEqual(x.component(0),1)
self.assertEqual(x.component(2),3)
try:
y = Vector()
self.assertTrue(False)
except:
self.assertTrue(True)
def test_str(self):
"""
test for toString() method
"""
x = Vector([0,0,0,0,0,1])
self.assertEqual(x.__str__(),"(0,0,0,0,0,1)")
def test_size(self):
"""
test for size()-method
"""
x = Vector([1,2,3,4])
self.assertEqual(x.size(),4)
def test_euclidLength(self):
"""
test for the eulidean length
"""
x = Vector([1,2])
self.assertAlmostEqual(x.eulidLength(),2.236,3)
def test_add(self):
"""
test for + operator
"""
x = Vector([1,2,3])
y = Vector([1,1,1])
self.assertEqual((x+y).component(0),2)
self.assertEqual((x+y).component(1),3)
self.assertEqual((x+y).component(2),4)
def test_sub(self):
"""
test for - operator
"""
x = Vector([1,2,3])
y = Vector([1,1,1])
self.assertEqual((x-y).component(0),0)
self.assertEqual((x-y).component(1),1)
self.assertEqual((x-y).component(2),2)
def test_mul(self):
"""
test for * operator
"""
x = Vector([1,2,3])
a = Vector([2,-1,4]) # for test of dot-product
b = Vector([1,-2,-1])
self.assertEqual((x*3.0).__str__(),"(3.0,6.0,9.0)")
self.assertEqual((a*b),0)
def test_zeroVector(self):
"""
test for the global function zeroVector(...)
"""
self.assertTrue(zeroVector(10).__str__().count("0") == 10)
def test_unitBasisVector(self):
"""
test for the global function unitBasisVector(...)
"""
self.assertEqual(unitBasisVector(3,1).__str__(),"(0,1,0)")
def test_axpy(self):
"""
test for the global function axpy(...) (operation)
"""
x = Vector([1,2,3])
y = Vector([1,0,1])
self.assertEqual(axpy(2,x,y).__str__(),"(3,4,7)")
def test_copy(self):
"""
test for the copy()-method
"""
x = Vector([1,0,0,0,0,0])
y = x.copy()
self.assertEqual(x.__str__(),y.__str__())
def test_changeComponent(self):
"""
test for the changeComponent(...)-method
"""
x = Vector([1,0,0])
x.changeComponent(0,0)
x.changeComponent(1,1)
self.assertEqual(x.__str__(),"(0,1,0)")
def test_str_matrix(self):
A = Matrix([[1,2,3],[2,4,5],[6,7,8]],3,3)
self.assertEqual("|1,2,3|\n|2,4,5|\n|6,7,8|\n",A.__str__())
def test__mul__matrix(self):
A = Matrix([[1,2,3],[4,5,6],[7,8,9]],3,3)
x = Vector([1,2,3])
self.assertEqual("(14,32,50)",(A*x).__str__())
self.assertEqual("|2,4,6|\n|8,10,12|\n|14,16,18|\n",(A*2).__str__())
def test_changeComponent_matrix(self):
A = Matrix([[1,2,3],[2,4,5],[6,7,8]],3,3)
A.changeComponent(0,2,5)
self.assertEqual("|1,2,5|\n|2,4,5|\n|6,7,8|\n",A.__str__())
def test_component_matrix(self):
A = Matrix([[1,2,3],[2,4,5],[6,7,8]],3,3)
self.assertEqual(7,A.component(2,1),0.01)
def test__add__matrix(self):
A = Matrix([[1,2,3],[2,4,5],[6,7,8]],3,3)
B = Matrix([[1,2,7],[2,4,5],[6,7,10]],3,3)
self.assertEqual("|2,4,10|\n|4,8,10|\n|12,14,18|\n",(A+B).__str__())
def test__sub__matrix(self):
A = Matrix([[1,2,3],[2,4,5],[6,7,8]],3,3)
B = Matrix([[1,2,7],[2,4,5],[6,7,10]],3,3)
self.assertEqual("|0,0,-4|\n|0,0,0|\n|0,0,-2|\n",(A-B).__str__())
def test_squareZeroMatrix(self):
self.assertEqual('|0,0,0,0,0|\n|0,0,0,0,0|\n|0,0,0,0,0|\n|0,0,0,0,0|'
+'\n|0,0,0,0,0|\n',squareZeroMatrix(5).__str__())
if __name__ == "__main__":
unittest.main()

74
maths/BasicMaths.py Normal file
View File

@ -0,0 +1,74 @@
import math
def primeFactors(n):
pf = []
while n % 2 == 0:
pf.append(2)
n = int(n / 2)
for i in range(3, int(math.sqrt(n))+1, 2):
while n % i == 0:
pf.append(i)
n = int(n / i)
if n > 2:
pf.append(n)
return pf
def numberOfDivisors(n):
div = 1
temp = 1
while n % 2 == 0:
temp += 1
n = int(n / 2)
div = div * (temp)
for i in range(3, int(math.sqrt(n))+1, 2):
temp = 1
while n % i == 0:
temp += 1
n = int(n / i)
div = div * (temp)
return div
def sumOfDivisors(n):
s = 1
temp = 1
while n % 2 == 0:
temp += 1
n = int(n / 2)
if temp > 1:
s *= (2**temp - 1) / (2 - 1)
for i in range(3, int(math.sqrt(n))+1, 2):
temp = 1
while n % i == 0:
temp += 1
n = int(n / i)
if temp > 1:
s *= (i**temp - 1) / (i - 1)
return s
def eulerPhi(n):
l = primeFactors(n)
l = set(l)
s = n
for x in l:
s *= (x - 1)/x
return s
def main():
print(primeFactors(100))
print(numberOfDivisors(100))
print(sumOfDivisors(100))
print(eulerPhi(100))
if __name__ == '__main__':
main()

View File

@ -0,0 +1,18 @@
# Fibonacci Sequence Using Recursion
def recur_fibo(n):
return n if n <= 1 else (recur_fibo(n-1) + recur_fibo(n-2))
def isPositiveInteger(limit):
return limit >= 0
def main():
limit = int(input("How many terms to include in fibonacci series: "))
if isPositiveInteger(limit):
print("The first {limit} terms of the fibonacci series are as follows:")
print([recur_fibo(n) for n in range(limit)])
else:
print("Please enter a positive integer: ")
if __name__ == '__main__':
main()

View File

@ -0,0 +1,15 @@
# Greater Common Divisor - https://en.wikipedia.org/wiki/Greatest_common_divisor
def gcd(a, b):
return b if a == 0 else gcd(b % a, a)
def main():
try:
nums = input("Enter two Integers separated by comma (,): ").split(',')
num1 = int(nums[0]); num2 = int(nums[1])
except (IndexError, UnboundLocalError, ValueError):
print("Wrong Input")
print(f"gcd({num1}, {num2}) = {gcd(num1, num2)}")
if __name__ == '__main__':
main()

View File

@ -0,0 +1,20 @@
def modularExponential(base, power, mod):
if power < 0:
return -1
base %= mod
result = 1
while power > 0:
if power & 1:
result = (result * base) % mod
power = power >> 1
base = (base * base) % mod
return result
def main():
print(modularExponential(3, 200, 13))
if __name__ == '__main__':
main()

46
maths/SegmentedSieve.py Normal file
View File

@ -0,0 +1,46 @@
import math
def sieve(n):
in_prime = []
start = 2
end = int(math.sqrt(n)) # Size of every segment
temp = [True] * (end + 1)
prime = []
while(start <= end):
if temp[start] == True:
in_prime.append(start)
for i in range(start*start, end+1, start):
if temp[i] == True:
temp[i] = False
start += 1
prime += in_prime
low = end + 1
high = low + end - 1
if high > n:
high = n
while(low <= n):
temp = [True] * (high-low+1)
for each in in_prime:
t = math.floor(low / each) * each
if t < low:
t += each
for j in range(t, high+1, each):
temp[j - low] = False
for j in range(len(temp)):
if temp[j] == True:
prime.append(j+low)
low = high + 1
high = low + end - 1
if high > n:
high = n
return prime
print(sieve(10**6))

View File

@ -0,0 +1,24 @@
import math
n = int(raw_input("Enter n: "))
def sieve(n):
l = [True] * (n+1)
prime = []
start = 2
end = int(math.sqrt(n))
while(start <= end):
if l[start] == True:
prime.append(start)
for i in range(start*start, n+1, start):
if l[i] == True:
l[i] = False
start += 1
for j in range(end+1,n+1):
if l[j] == True:
prime.append(j)
return prime
print(sieve(n))

49
maths/SimpsonRule.py Normal file
View File

@ -0,0 +1,49 @@
'''
Numerical integration or quadrature for a smooth function f with known values at x_i
This method is the classical approch of suming 'Equally Spaced Abscissas'
method 2:
"Simpson Rule"
'''
from __future__ import print_function
def method_2(boundary, steps):
# "Simpson Rule"
# int(f) = delta_x/2 * (b-a)/3*(f1 + 4f2 + 2f_3 + ... + fn)
h = (boundary[1] - boundary[0]) / steps
a = boundary[0]
b = boundary[1]
x_i = makePoints(a,b,h)
y = 0.0
y += (h/3.0)*f(a)
cnt = 2
for i in x_i:
y += (h/3)*(4-2*(cnt%2))*f(i)
cnt += 1
y += (h/3.0)*f(b)
return y
def makePoints(a,b,h):
x = a + h
while x < (b-h):
yield x
x = x + h
def f(x): #enter your function here
y = (x-0)*(x-0)
return y
def main():
a = 0.0 #Lower bound of integration
b = 1.0 #Upper bound of integration
steps = 10.0 #define number of steps or resolution
boundary = [a, b] #define boundary of integration
y = method_2(boundary, steps)
print('y = {0}'.format(y))
if __name__ == '__main__':
main()

46
maths/TrapezoidalRule.py Normal file
View File

@ -0,0 +1,46 @@
'''
Numerical integration or quadrature for a smooth function f with known values at x_i
This method is the classical approch of suming 'Equally Spaced Abscissas'
method 1:
"extended trapezoidal rule"
'''
from __future__ import print_function
def method_1(boundary, steps):
# "extended trapezoidal rule"
# int(f) = dx/2 * (f1 + 2f2 + ... + fn)
h = (boundary[1] - boundary[0]) / steps
a = boundary[0]
b = boundary[1]
x_i = makePoints(a,b,h)
y = 0.0
y += (h/2.0)*f(a)
for i in x_i:
#print(i)
y += h*f(i)
y += (h/2.0)*f(b)
return y
def makePoints(a,b,h):
x = a + h
while x < (b-h):
yield x
x = x + h
def f(x): #enter your function here
y = (x-0)*(x-0)
return y
def main():
a = 0.0 #Lower bound of integration
b = 1.0 #Upper bound of integration
steps = 10.0 #define number of steps or resolution
boundary = [a, b] #define boundary of integration
y = method_1(boundary, steps)
print('y = {0}'.format(y))
if __name__ == '__main__':
main()

327
neural_network/FCN.ipynb Normal file

File diff suppressed because one or more lines are too long

193
neural_network/bpnn.py Normal file
View File

@ -0,0 +1,193 @@
#!/usr/bin/python
# encoding=utf8
'''
A Framework of Back Propagation Neural NetworkBP model
Easy to use:
* add many layers as you want
* clearly see how the loss decreasing
Easy to expand:
* more activation functions
* more loss functions
* more optimization method
Author: Stephen Lee
Github : https://github.com/RiptideBo
Date: 2017.11.23
'''
import numpy as np
import matplotlib.pyplot as plt
def sigmoid(x):
return 1 / (1 + np.exp(-1 * x))
class DenseLayer():
'''
Layers of BP neural network
'''
def __init__(self,units,activation=None,learning_rate=None,is_input_layer=False):
'''
common connected layer of bp network
:param units: numbers of neural units
:param activation: activation function
:param learning_rate: learning rate for paras
:param is_input_layer: whether it is input layer or not
'''
self.units = units
self.weight = None
self.bias = None
self.activation = activation
if learning_rate is None:
learning_rate = 0.3
self.learn_rate = learning_rate
self.is_input_layer = is_input_layer
def initializer(self,back_units):
self.weight = np.asmatrix(np.random.normal(0,0.5,(self.units,back_units)))
self.bias = np.asmatrix(np.random.normal(0,0.5,self.units)).T
if self.activation is None:
self.activation = sigmoid
def cal_gradient(self):
if self.activation == sigmoid:
gradient_mat = np.dot(self.output ,(1- self.output).T)
gradient_activation = np.diag(np.diag(gradient_mat))
else:
gradient_activation = 1
return gradient_activation
def forward_propagation(self,xdata):
self.xdata = xdata
if self.is_input_layer:
# input layer
self.wx_plus_b = xdata
self.output = xdata
return xdata
else:
self.wx_plus_b = np.dot(self.weight,self.xdata) - self.bias
self.output = self.activation(self.wx_plus_b)
return self.output
def back_propagation(self,gradient):
gradient_activation = self.cal_gradient() # i * i 维
gradient = np.asmatrix(np.dot(gradient.T,gradient_activation))
self._gradient_weight = np.asmatrix(self.xdata)
self._gradient_bias = -1
self._gradient_x = self.weight
self.gradient_weight = np.dot(gradient.T,self._gradient_weight.T)
self.gradient_bias = gradient * self._gradient_bias
self.gradient = np.dot(gradient,self._gradient_x).T
# ----------------------upgrade
# -----------the Negative gradient direction --------
self.weight = self.weight - self.learn_rate * self.gradient_weight
self.bias = self.bias - self.learn_rate * self.gradient_bias.T
return self.gradient
class BPNN():
'''
Back Propagation Neural Network model
'''
def __init__(self):
self.layers = []
self.train_mse = []
self.fig_loss = plt.figure()
self.ax_loss = self.fig_loss.add_subplot(1,1,1)
def add_layer(self,layer):
self.layers.append(layer)
def build(self):
for i,layer in enumerate(self.layers[:]):
if i < 1:
layer.is_input_layer = True
else:
layer.initializer(self.layers[i-1].units)
def summary(self):
for i,layer in enumerate(self.layers[:]):
print('------- layer %d -------'%i)
print('weight.shape ',np.shape(layer.weight))
print('bias.shape ',np.shape(layer.bias))
def train(self,xdata,ydata,train_round,accuracy):
self.train_round = train_round
self.accuracy = accuracy
self.ax_loss.hlines(self.accuracy, 0, self.train_round * 1.1)
x_shape = np.shape(xdata)
for round_i in range(train_round):
all_loss = 0
for row in range(x_shape[0]):
_xdata = np.asmatrix(xdata[row,:]).T
_ydata = np.asmatrix(ydata[row,:]).T
# forward propagation
for layer in self.layers:
_xdata = layer.forward_propagation(_xdata)
loss, gradient = self.cal_loss(_ydata, _xdata)
all_loss = all_loss + loss
# back propagation
# the input_layer does not upgrade
for layer in self.layers[:0:-1]:
gradient = layer.back_propagation(gradient)
mse = all_loss/x_shape[0]
self.train_mse.append(mse)
self.plot_loss()
if mse < self.accuracy:
print('----达到精度----')
return mse
def cal_loss(self,ydata,ydata_):
self.loss = np.sum(np.power((ydata - ydata_),2))
self.loss_gradient = 2 * (ydata_ - ydata)
# vector (shape is the same as _ydata.shape)
return self.loss,self.loss_gradient
def plot_loss(self):
if self.ax_loss.lines:
self.ax_loss.lines.remove(self.ax_loss.lines[0])
self.ax_loss.plot(self.train_mse, 'r-')
plt.ion()
plt.show()
plt.pause(0.1)
def example():
x = np.random.randn(10,10)
y = np.asarray([[0.8,0.4],[0.4,0.3],[0.34,0.45],[0.67,0.32],
[0.88,0.67],[0.78,0.77],[0.55,0.66],[0.55,0.43],[0.54,0.1],
[0.1,0.5]])
model = BPNN()
model.add_layer(DenseLayer(10))
model.add_layer(DenseLayer(20))
model.add_layer(DenseLayer(30))
model.add_layer(DenseLayer(2))
model.build()
model.summary()
model.train(xdata=x,ydata=y,train_round=100,accuracy=0.01)
if __name__ == '__main__':
example()

View File

@ -0,0 +1,306 @@
#-*- coding: utf-8 -*-
'''
- - - - - -- - - - - - - - - - - - - - - - - - - - - - -
Name - - CNN - Convolution Neural Network For Photo Recognizing
Goal - - Recognize Handing Writting Word Photo
DetailTotal 5 layers neural network
* Convolution layer
* Pooling layer
* Input layer layer of BP
* Hiden layer of BP
* Output layer of BP
Author: Stephen Lee
Github: 245885195@qq.com
Date: 2017.9.20
- - - - - -- - - - - - - - - - - - - - - - - - - - - - -
'''
from __future__ import print_function
import numpy as np
import matplotlib.pyplot as plt
class CNN():
def __init__(self,conv1_get,size_p1,bp_num1,bp_num2,bp_num3,rate_w=0.2,rate_t=0.2):
'''
:param conv1_get: [a,c,d]size, number, step of convolution kernel
:param size_p1: pooling size
:param bp_num1: units number of flatten layer
:param bp_num2: units number of hidden layer
:param bp_num3: units number of output layer
:param rate_w: rate of weight learning
:param rate_t: rate of threshold learning
'''
self.num_bp1 = bp_num1
self.num_bp2 = bp_num2
self.num_bp3 = bp_num3
self.conv1 = conv1_get[:2]
self.step_conv1 = conv1_get[2]
self.size_pooling1 = size_p1
self.rate_weight = rate_w
self.rate_thre = rate_t
self.w_conv1 = [np.mat(-1*np.random.rand(self.conv1[0],self.conv1[0])+0.5) for i in range(self.conv1[1])]
self.wkj = np.mat(-1 * np.random.rand(self.num_bp3, self.num_bp2) + 0.5)
self.vji = np.mat(-1*np.random.rand(self.num_bp2, self.num_bp1)+0.5)
self.thre_conv1 = -2*np.random.rand(self.conv1[1])+1
self.thre_bp2 = -2*np.random.rand(self.num_bp2)+1
self.thre_bp3 = -2*np.random.rand(self.num_bp3)+1
def save_model(self,save_path):
#save model dict with pickle
import pickle
model_dic = {'num_bp1':self.num_bp1,
'num_bp2':self.num_bp2,
'num_bp3':self.num_bp3,
'conv1':self.conv1,
'step_conv1':self.step_conv1,
'size_pooling1':self.size_pooling1,
'rate_weight':self.rate_weight,
'rate_thre':self.rate_thre,
'w_conv1':self.w_conv1,
'wkj':self.wkj,
'vji':self.vji,
'thre_conv1':self.thre_conv1,
'thre_bp2':self.thre_bp2,
'thre_bp3':self.thre_bp3}
with open(save_path, 'wb') as f:
pickle.dump(model_dic, f)
print('Model saved %s'% save_path)
@classmethod
def ReadModel(cls,model_path):
#read saved model
import pickle
with open(model_path, 'rb') as f:
model_dic = pickle.load(f)
conv_get= model_dic.get('conv1')
conv_get.append(model_dic.get('step_conv1'))
size_p1 = model_dic.get('size_pooling1')
bp1 = model_dic.get('num_bp1')
bp2 = model_dic.get('num_bp2')
bp3 = model_dic.get('num_bp3')
r_w = model_dic.get('rate_weight')
r_t = model_dic.get('rate_thre')
#create model instance
conv_ins = CNN(conv_get,size_p1,bp1,bp2,bp3,r_w,r_t)
#modify model parameter
conv_ins.w_conv1 = model_dic.get('w_conv1')
conv_ins.wkj = model_dic.get('wkj')
conv_ins.vji = model_dic.get('vji')
conv_ins.thre_conv1 = model_dic.get('thre_conv1')
conv_ins.thre_bp2 = model_dic.get('thre_bp2')
conv_ins.thre_bp3 = model_dic.get('thre_bp3')
return conv_ins
def sig(self,x):
return 1 / (1 + np.exp(-1*x))
def do_round(self,x):
return round(x, 3)
def convolute(self,data,convs,w_convs,thre_convs,conv_step):
#convolution process
size_conv = convs[0]
num_conv =convs[1]
size_data = np.shape(data)[0]
#get the data slice of original image data, data_focus
data_focus = []
for i_focus in range(0, size_data - size_conv + 1, conv_step):
for j_focus in range(0, size_data - size_conv + 1, conv_step):
focus = data[i_focus:i_focus + size_conv, j_focus:j_focus + size_conv]
data_focus.append(focus)
#caculate the feature map of every single kernel, and saved as list of matrix
data_featuremap = []
Size_FeatureMap = int((size_data - size_conv) / conv_step + 1)
for i_map in range(num_conv):
featuremap = []
for i_focus in range(len(data_focus)):
net_focus = np.sum(np.multiply(data_focus[i_focus], w_convs[i_map])) - thre_convs[i_map]
featuremap.append(self.sig(net_focus))
featuremap = np.asmatrix(featuremap).reshape(Size_FeatureMap, Size_FeatureMap)
data_featuremap.append(featuremap)
#expanding the data slice to One dimenssion
focus1_list = []
for each_focus in data_focus:
focus1_list.extend(self.Expand_Mat(each_focus))
focus_list = np.asarray(focus1_list)
return focus_list,data_featuremap
def pooling(self,featuremaps,size_pooling,type='average_pool'):
#pooling process
size_map = len(featuremaps[0])
size_pooled = int(size_map/size_pooling)
featuremap_pooled = []
for i_map in range(len(featuremaps)):
map = featuremaps[i_map]
map_pooled = []
for i_focus in range(0,size_map,size_pooling):
for j_focus in range(0, size_map, size_pooling):
focus = map[i_focus:i_focus + size_pooling, j_focus:j_focus + size_pooling]
if type == 'average_pool':
#average pooling
map_pooled.append(np.average(focus))
elif type == 'max_pooling':
#max pooling
map_pooled.append(np.max(focus))
map_pooled = np.asmatrix(map_pooled).reshape(size_pooled,size_pooled)
featuremap_pooled.append(map_pooled)
return featuremap_pooled
def _expand(self,datas):
#expanding three dimension data to one dimension list
data_expanded = []
for i in range(len(datas)):
shapes = np.shape(datas[i])
data_listed = datas[i].reshape(1,shapes[0]*shapes[1])
data_listed = data_listed.getA().tolist()[0]
data_expanded.extend(data_listed)
data_expanded = np.asarray(data_expanded)
return data_expanded
def _expand_mat(self,data_mat):
#expanding matrix to one dimension list
data_mat = np.asarray(data_mat)
shapes = np.shape(data_mat)
data_expanded = data_mat.reshape(1,shapes[0]*shapes[1])
return data_expanded
def _calculate_gradient_from_pool(self,out_map,pd_pool,num_map,size_map,size_pooling):
'''
calcluate the gradient from the data slice of pool layer
pd_pool: list of matrix
out_map: the shape of data slice(size_map*size_map)
return: pd_all: list of matrix, [num, size_map, size_map]
'''
pd_all = []
i_pool = 0
for i_map in range(num_map):
pd_conv1 = np.ones((size_map, size_map))
for i in range(0, size_map, size_pooling):
for j in range(0, size_map, size_pooling):
pd_conv1[i:i + size_pooling, j:j + size_pooling] = pd_pool[i_pool]
i_pool = i_pool + 1
pd_conv2 = np.multiply(pd_conv1,np.multiply(out_map[i_map],(1-out_map[i_map])))
pd_all.append(pd_conv2)
return pd_all
def trian(self,patterns,datas_train, datas_teach, n_repeat, error_accuracy,draw_e = bool):
#model traning
print('----------------------Start Training-------------------------')
print((' - - Shape: Train_Data ',np.shape(datas_train)))
print((' - - Shape: Teach_Data ',np.shape(datas_teach)))
rp = 0
all_mse = []
mse = 10000
while rp < n_repeat and mse >= error_accuracy:
alle = 0
print('-------------Learning Time %d--------------'%rp)
for p in range(len(datas_train)):
#print('------------Learning Image: %d--------------'%p)
data_train = np.asmatrix(datas_train[p])
data_teach = np.asarray(datas_teach[p])
data_focus1,data_conved1 = self.convolute(data_train,self.conv1,self.w_conv1,
self.thre_conv1,conv_step=self.step_conv1)
data_pooled1 = self.pooling(data_conved1,self.size_pooling1)
shape_featuremap1 = np.shape(data_conved1)
'''
print(' -----original shape ', np.shape(data_train))
print(' ---- after convolution ',np.shape(data_conv1))
print(' -----after pooling ',np.shape(data_pooled1))
'''
data_bp_input = self._expand(data_pooled1)
bp_out1 = data_bp_input
bp_net_j = np.dot(bp_out1,self.vji.T) - self.thre_bp2
bp_out2 = self.sig(bp_net_j)
bp_net_k = np.dot(bp_out2 ,self.wkj.T) - self.thre_bp3
bp_out3 = self.sig(bp_net_k)
#--------------Model Leaning ------------------------
# calcluate error and gradient---------------
pd_k_all = np.multiply((data_teach - bp_out3), np.multiply(bp_out3, (1 - bp_out3)))
pd_j_all = np.multiply(np.dot(pd_k_all,self.wkj), np.multiply(bp_out2, (1 - bp_out2)))
pd_i_all = np.dot(pd_j_all,self.vji)
pd_conv1_pooled = pd_i_all / (self.size_pooling1*self.size_pooling1)
pd_conv1_pooled = pd_conv1_pooled.T.getA().tolist()
pd_conv1_all = self._calculate_gradient_from_pool(data_conved1,pd_conv1_pooled,shape_featuremap1[0],
shape_featuremap1[1],self.size_pooling1)
#weight and threshold learning process---------
#convolution layer
for k_conv in range(self.conv1[1]):
pd_conv_list = self._expand_mat(pd_conv1_all[k_conv])
delta_w = self.rate_weight * np.dot(pd_conv_list,data_focus1)
self.w_conv1[k_conv] = self.w_conv1[k_conv] + delta_w.reshape((self.conv1[0],self.conv1[0]))
self.thre_conv1[k_conv] = self.thre_conv1[k_conv] - np.sum(pd_conv1_all[k_conv]) * self.rate_thre
#all connected layer
self.wkj = self.wkj + pd_k_all.T * bp_out2 * self.rate_weight
self.vji = self.vji + pd_j_all.T * bp_out1 * self.rate_weight
self.thre_bp3 = self.thre_bp3 - pd_k_all * self.rate_thre
self.thre_bp2 = self.thre_bp2 - pd_j_all * self.rate_thre
# calculate the sum error of all single image
errors = np.sum(abs((data_teach - bp_out3)))
alle = alle + errors
#print(' ----Teach ',data_teach)
#print(' ----BP_output ',bp_out3)
rp = rp + 1
mse = alle/patterns
all_mse.append(mse)
def draw_error():
yplot = [error_accuracy for i in range(int(n_repeat * 1.2))]
plt.plot(all_mse, '+-')
plt.plot(yplot, 'r--')
plt.xlabel('Learning Times')
plt.ylabel('All_mse')
plt.grid(True, alpha=0.5)
plt.show()
print('------------------Training Complished---------------------')
print((' - - Training epoch: ', rp, ' - - Mse: %.6f' % mse))
if draw_e:
draw_error()
return mse
def predict(self,datas_test):
#model predict
produce_out = []
print('-------------------Start Testing-------------------------')
print((' - - Shape: Test_Data ',np.shape(datas_test)))
for p in range(len(datas_test)):
data_test = np.asmatrix(datas_test[p])
data_focus1, data_conved1 = self.convolute(data_test, self.conv1, self.w_conv1,
self.thre_conv1, conv_step=self.step_conv1)
data_pooled1 = self.pooling(data_conved1, self.size_pooling1)
data_bp_input = self._expand(data_pooled1)
bp_out1 = data_bp_input
bp_net_j = bp_out1 * self.vji.T - self.thre_bp2
bp_out2 = self.sig(bp_net_j)
bp_net_k = bp_out2 * self.wkj.T - self.thre_bp3
bp_out3 = self.sig(bp_net_k)
produce_out.extend(bp_out3.getA().tolist())
res = [list(map(self.do_round,each)) for each in produce_out]
return np.asarray(res)
def convolution(self,data):
#return the data of image after convoluting process so we can check it out
data_test = np.asmatrix(data)
data_focus1, data_conved1 = self.convolute(data_test, self.conv1, self.w_conv1,
self.thre_conv1, conv_step=self.step_conv1)
data_pooled1 = self.pooling(data_conved1, self.size_pooling1)
return data_conved1,data_pooled1
if __name__ == '__main__':
pass
'''
I will put the example on other file
'''

View File

@ -0,0 +1,124 @@
'''
Perceptron
w = w + N * (d(k) - y) * x(k)
Using perceptron network for oil analysis,
with Measuring of 3 parameters that represent chemical characteristics we can classify the oil, in p1 or p2
p1 = -1
p2 = 1
'''
from __future__ import print_function
import random
class Perceptron:
def __init__(self, sample, exit, learn_rate=0.01, epoch_number=1000, bias=-1):
self.sample = sample
self.exit = exit
self.learn_rate = learn_rate
self.epoch_number = epoch_number
self.bias = bias
self.number_sample = len(sample)
self.col_sample = len(sample[0])
self.weight = []
def training(self):
for sample in self.sample:
sample.insert(0, self.bias)
for i in range(self.col_sample):
self.weight.append(random.random())
self.weight.insert(0, self.bias)
epoch_count = 0
while True:
erro = False
for i in range(self.number_sample):
u = 0
for j in range(self.col_sample + 1):
u = u + self.weight[j] * self.sample[i][j]
y = self.sign(u)
if y != self.exit[i]:
for j in range(self.col_sample + 1):
self.weight[j] = self.weight[j] + self.learn_rate * (self.exit[i] - y) * self.sample[i][j]
erro = True
#print('Epoch: \n',epoch_count)
epoch_count = epoch_count + 1
# if you want controle the epoch or just by erro
if erro == False:
print(('\nEpoch:\n',epoch_count))
print('------------------------\n')
#if epoch_count > self.epoch_number or not erro:
break
def sort(self, sample):
sample.insert(0, self.bias)
u = 0
for i in range(self.col_sample + 1):
u = u + self.weight[i] * sample[i]
y = self.sign(u)
if y == -1:
print(('Sample: ', sample))
print('classification: P1')
else:
print(('Sample: ', sample))
print('classification: P2')
def sign(self, u):
return 1 if u >= 0 else -1
samples = [
[-0.6508, 0.1097, 4.0009],
[-1.4492, 0.8896, 4.4005],
[2.0850, 0.6876, 12.0710],
[0.2626, 1.1476, 7.7985],
[0.6418, 1.0234, 7.0427],
[0.2569, 0.6730, 8.3265],
[1.1155, 0.6043, 7.4446],
[0.0914, 0.3399, 7.0677],
[0.0121, 0.5256, 4.6316],
[-0.0429, 0.4660, 5.4323],
[0.4340, 0.6870, 8.2287],
[0.2735, 1.0287, 7.1934],
[0.4839, 0.4851, 7.4850],
[0.4089, -0.1267, 5.5019],
[1.4391, 0.1614, 8.5843],
[-0.9115, -0.1973, 2.1962],
[0.3654, 1.0475, 7.4858],
[0.2144, 0.7515, 7.1699],
[0.2013, 1.0014, 6.5489],
[0.6483, 0.2183, 5.8991],
[-0.1147, 0.2242, 7.2435],
[-0.7970, 0.8795, 3.8762],
[-1.0625, 0.6366, 2.4707],
[0.5307, 0.1285, 5.6883],
[-1.2200, 0.7777, 1.7252],
[0.3957, 0.1076, 5.6623],
[-0.1013, 0.5989, 7.1812],
[2.4482, 0.9455, 11.2095],
[2.0149, 0.6192, 10.9263],
[0.2012, 0.2611, 5.4631]
]
exit = [-1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1]
network = Perceptron(sample=samples, exit = exit, learn_rate=0.01, epoch_number=1000, bias=-1)
network.trannig()
while True:
sample = []
for i in range(3):
sample.insert(i, float(raw_input('value: ')))
network.sort(sample)

View File

@ -0,0 +1,17 @@
'''
Problem Statement:
If we list all the natural numbers below 10 that are multiples of 3 or 5,
we get 3,5,6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below N.
'''
from __future__ import print_function
try:
raw_input # Python 2
except NameError:
raw_input = input # Python 3
n = int(raw_input().strip())
sum=0
for a in range(3,n):
if(a%3==0 or a%5==0):
sum+=a
print(sum)

View File

@ -0,0 +1,20 @@
'''
Problem Statement:
If we list all the natural numbers below 10 that are multiples of 3 or 5,
we get 3,5,6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below N.
'''
from __future__ import print_function
try:
raw_input # Python 2
except NameError:
raw_input = input # Python 3
n = int(raw_input().strip())
sum = 0
terms = (n-1)//3
sum+= ((terms)*(6+(terms-1)*3))//2 #sum of an A.P.
terms = (n-1)//5
sum+= ((terms)*(10+(terms-1)*5))//2
terms = (n-1)//15
sum-= ((terms)*(30+(terms-1)*15))//2
print(sum)

View File

@ -0,0 +1,50 @@
from __future__ import print_function
'''
Problem Statement:
If we list all the natural numbers below 10 that are multiples of 3 or 5,
we get 3,5,6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below N.
'''
'''
This solution is based on the pattern that the successive numbers in the series follow: 0+3,+2,+1,+3,+1,+2,+3.
'''
try:
raw_input # Python 2
except NameError:
raw_input = input # Python 3
n = int(raw_input().strip())
sum=0
num=0
while(1):
num+=3
if(num>=n):
break
sum+=num
num+=2
if(num>=n):
break
sum+=num
num+=1
if(num>=n):
break
sum+=num
num+=3
if(num>=n):
break
sum+=num
num+=1
if(num>=n):
break
sum+=num
num+=2
if(num>=n):
break
sum+=num
num+=3
if(num>=n):
break
sum+=num
print(sum);

View File

@ -0,0 +1,30 @@
def mulitples(limit):
xmulti = []
zmulti = []
z = 3
x = 5
temp = 1
while True:
result = z * temp
if (result < limit):
zmulti.append(result)
temp += 1
else:
temp = 1
break
while True:
result = x * temp
if (result < limit):
xmulti.append(result)
temp += 1
else:
break
collection = list(set(xmulti+zmulti))
return (sum(collection))
print (mulitples(1000))

View File

@ -0,0 +1,26 @@
'''
Problem:
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2,
the first 10 terms will be:
1,2,3,5,8,13,21,34,55,89,..
By considering the terms in the Fibonacci sequence whose values do not exceed n, find the sum of the even-valued terms.
e.g. for n=10, we have {2,8}, sum is 10.
'''
from __future__ import print_function
try:
raw_input # Python 2
except NameError:
raw_input = input # Python 3
n = int(raw_input().strip())
i=1
j=2
sum=0
while(j<=n):
if((j&1)==0): #can also use (j%2==0)
sum+=j
temp=i
i=j
j=temp+i
print(sum)

View File

@ -0,0 +1,12 @@
def fib(n):
a, b, s = 0, 1, 0
while b < n:
if b % 2 == 0 and b < n: s += b
a, b = b, a+b
ls.append(s)
T = int(input().strip())
ls = []
for _ in range(T):
fib(int(input().strip()))
print(ls, sep = '\n')

View File

@ -0,0 +1,20 @@
'''
Problem:
Each new term in the Fibonacci sequence is generated by adding the previous two terms.
0,1,1,2,3,5,8,13,21,34,55,89,..
Every third term from 0 is even So using this I have written a simple code
By considering the terms in the Fibonacci sequence whose values do not exceed n, find the sum of the even-valued terms.
e.g. for n=10, we have {2,8}, sum is 10.
'''
"""Python 3"""
n = int(raw_input())
a=0
b=2
count=0
while 4*b+a<n:
c=4*b+a
a=b
b=c
count=count+a
print(count+b)

View File

@ -0,0 +1,39 @@
'''
Problem:
The prime factors of 13195 are 5,7,13 and 29. What is the largest prime factor of a given number N?
e.g. for 10, largest prime factor = 5. For 17, largest prime factor = 17.
'''
from __future__ import print_function, division
import math
def isprime(no):
if(no==2):
return True
elif (no%2==0):
return False
sq = int(math.sqrt(no))+1
for i in range(3,sq,2):
if(no%i==0):
return False
return True
maxNumber = 0
n=int(raw_input())
if(isprime(n)):
print(n)
else:
while (n%2==0):
n=n/2
if(isprime(n)):
print(n)
else:
n1 = int(math.sqrt(n))+1
for i in range(3,n1,2):
if(n%i==0):
if(isprime(n/i)):
maxNumber = n/i
break
elif(isprime(i)):
maxNumber = i
print(maxNumber)

View File

@ -0,0 +1,17 @@
'''
Problem:
The prime factors of 13195 are 5,7,13 and 29. What is the largest prime factor of a given number N?
e.g. for 10, largest prime factor = 5. For 17, largest prime factor = 17.
'''
from __future__ import print_function
n=int(raw_input())
prime=1
i=2
while(i*i<=n):
while(n%i==0):
prime=i
n/=i
i+=1
if(n>1):
prime=n
print(prime)

View File

@ -0,0 +1,29 @@
'''
Problem:
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 x 99.
Find the largest palindrome made from the product of two 3-digit numbers which is less than N.
'''
from __future__ import print_function
limit = int(raw_input("limit? "))
# fetchs the next number
for number in range(limit-1,10000,-1):
# converts number into string.
strNumber = str(number)
# checks whether 'strNumber' is a palindrome.
if(strNumber == strNumber[::-1]):
divisor = 999
# if 'number' is a product of two 3-digit numbers
# then number is the answer otherwise fetch next number.
while(divisor != 99):
if((number % divisor == 0) and (len(str(number / divisor)) == 3)):
print(number)
exit(0)
divisor -=1

View File

@ -0,0 +1,19 @@
'''
Problem:
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 x 99.
Find the largest palindrome made from the product of two 3-digit numbers which is less than N.
'''
from __future__ import print_function
arr = []
for i in range(999,100,-1):
for j in range(999,100,-1):
t = str(i*j)
if t == t[::-1]:
arr.append(i*j)
arr.sort()
n=int(raw_input())
for i in arr[::-1]:
if(i<n):
print(i)
exit(0)

View File

@ -0,0 +1,21 @@
'''
Problem:
2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest positive number that is evenly divisible(divisible with no remainder) by all of the numbers from 1 to N?
'''
from __future__ import print_function
n = int(raw_input())
i = 0
while 1:
i+=n*(n-1)
nfound=0
for j in range(2,n):
if (i%j != 0):
nfound=1
break
if(nfound==0):
if(i==0):
i=1
print(i)
break

View File

@ -0,0 +1,20 @@
#!/bin/python3
'''
Problem:
2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest positive number that is evenly divisible(divisible with no remainder) by all of the numbers from 1 to N?
'''
""" Euclidean GCD Algorithm """
def gcd(x,y):
return x if y==0 else gcd(y,x%y)
""" Using the property lcm*gcd of two numbers = product of them """
def lcm(x,y):
return (x*y)//gcd(x,y)
n = int(raw_input())
g=1
for i in range(1,n+1):
g=lcm(g,i)
print(g)

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
'''
Problem:
The sum of the squares of the first ten natural numbers is,
1^2 + 2^2 + ... + 10^2 = 385
The square of the sum of the first ten natural numbers is,
(1 + 2 + ... + 10)^2 = 552 = 3025
Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 385 = 2640.
Find the difference between the sum of the squares of the first N natural numbers and the square of the sum.
'''
from __future__ import print_function
suma = 0
sumb = 0
n = int(raw_input())
for i in range(1,n+1):
suma += i**2
sumb += i
sum = sumb**2 - suma
print(sum)

View File

@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
'''
Problem:
The sum of the squares of the first ten natural numbers is,
1^2 + 2^2 + ... + 10^2 = 385
The square of the sum of the first ten natural numbers is,
(1 + 2 + ... + 10)^2 = 552 = 3025
Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 385 = 2640.
Find the difference between the sum of the squares of the first N natural numbers and the square of the sum.
'''
from __future__ import print_function
n = int(raw_input())
suma = n*(n+1)/2
suma **= 2
sumb = n*(n+1)*(2*n+1)/6
print(suma-sumb)

View File

@ -0,0 +1,30 @@
'''
By listing the first six prime numbers:
2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13.
What is the Nth prime number?
'''
from __future__ import print_function
from math import sqrt
def isprime(n):
if (n==2):
return True
elif (n%2==0):
return False
else:
sq = int(sqrt(n))+1
for i in range(3,sq,2):
if(n%i==0):
return False
return True
n = int(raw_input())
i=0
j=1
while(i!=n and j<3):
j+=1
if (isprime(j)):
i+=1
while(i!=n):
j+=2
if(isprime(j)):
i+=1
print(j)

View File

@ -0,0 +1,16 @@
# By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13. What is the Nth prime number?
def isprime(number):
for i in range(2,int(number**0.5)+1):
if number%i==0:
return False
return True
n = int(raw_input('Enter The N\'th Prime Number You Want To Get: ')) # Ask For The N'th Prime Number Wanted
primes = []
num = 2
while len(primes) < n:
if isprime(num):
primes.append(num)
num += 1
else:
num += 1
print(primes[len(primes) - 1])

View File

@ -0,0 +1,15 @@
import sys
def main():
LargestProduct = -sys.maxsize-1
number=raw_input().strip()
for i in range(len(number)-13):
product=1
for j in range(13):
product *= int(number[i+j])
if product > LargestProduct:
LargestProduct = product
print(LargestProduct)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,15 @@
from __future__ import print_function
# Program to find the product of a,b,c which are Pythagorean Triplet that satisfice the following:
# 1. a < b < c
# 2. a**2 + b**2 = c**2
# 3. a + b + c = 1000
print("Please Wait...")
for a in range(300):
for b in range(400):
for c in range(500):
if(a < b < c):
if((a**2) + (b**2) == (c**2)):
if((a+b+c) == 1000):
print(("Product of",a,"*",b,"*",c,"=",(a*b*c)))
break

View File

@ -0,0 +1,18 @@
"""A Pythagorean triplet is a set of three natural numbers, for which,
a^2+b^2=c^2
Given N, Check if there exists any Pythagorean triplet for which a+b+c=N
Find maximum possible value of product of a,b,c among all such Pythagorean triplets, If there is no such Pythagorean triplet print -1."""
#!/bin/python3
product=-1
d=0
N = int(raw_input())
for a in range(1,N//3):
"""Solving the two equations a**2+b**2=c**2 and a+b+c=N eliminating c """
b=(N*N-2*a*N)//(2*N-2*a)
c=N-a-b
if c*c==(a*a+b*b):
d=(a*b*c)
if d>=product:
product=d
print(product)

View File

@ -0,0 +1,38 @@
from __future__ import print_function
from math import sqrt
try:
xrange #Python 2
except NameError:
xrange = range #Python 3
def is_prime(n):
for i in xrange(2, int(sqrt(n))+1):
if n%i == 0:
return False
return True
def sum_of_primes(n):
if n > 2:
sumOfPrimes = 2
else:
return 0
for i in xrange(3, n, 2):
if is_prime(i):
sumOfPrimes += i
return sumOfPrimes
if __name__ == '__main__':
import sys
if len(sys.argv) == 1:
print(sum_of_primes(2000000))
else:
try:
n = int(sys.argv[1])
print(sum_of_primes(n))
except ValueError:
print('Invalid entry - please enter a number.')

Some files were not shown because too many files have changed in this diff Show More