mirror of
https://github.com/TheAlgorithms/Python.git
synced 2025-01-18 08:17:01 +00:00
increment 1
This commit is contained in:
parent
718b99ae39
commit
564179a0ec
38
analysis/Compression_Analysis/PSNR.py
Normal file
38
analysis/Compression_Analysis/PSNR.py
Normal 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()
|
||||
|
BIN
analysis/Compression_Analysis/compressed_image.png
Normal file
BIN
analysis/Compression_Analysis/compressed_image.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
BIN
analysis/Compression_Analysis/example_image.jpg
Normal file
BIN
analysis/Compression_Analysis/example_image.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
BIN
analysis/Compression_Analysis/orignal_image.png
Normal file
BIN
analysis/Compression_Analysis/orignal_image.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 82 KiB |
33
arithmetic_analysis/bisection.py
Normal file
33
arithmetic_analysis/bisection.py
Normal 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))
|
16
arithmetic_analysis/intersection.py
Normal file
16
arithmetic_analysis/intersection.py
Normal 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))
|
34
arithmetic_analysis/lu_decomposition.py
Normal file
34
arithmetic_analysis/lu_decomposition.py
Normal 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)
|
15
arithmetic_analysis/newton_method.py
Normal file
15
arithmetic_analysis/newton_method.py
Normal 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))
|
36
arithmetic_analysis/newton_raphson_method.py
Normal file
36
arithmetic_analysis/newton_raphson_method.py
Normal 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))
|
||||
|
||||
|
||||
|
||||
|
116
boolean_algebra/quine_mc_cluskey.py
Normal file
116
boolean_algebra/quine_mc_cluskey.py
Normal 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()
|
54
ciphers/brute_force_caesar_cipher.py
Normal file
54
ciphers/brute_force_caesar_cipher.py
Normal 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
32
ciphers/onepad_cipher.py
Normal 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
7193
ciphers/prehistoric_men.txt
Normal file
File diff suppressed because it is too large
Load Diff
36
ciphers/transposition_cipher_encrypt_decrypt_file.py
Normal file
36
ciphers/transposition_cipher_encrypt_decrypt_file.py
Normal 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
209
ciphers/xor_cipher.py
Normal 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"
|
3
data_structures/arrays.py
Normal file
3
data_structures/arrays.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
arr = [10, 20, 30, 40]
|
||||
arr[1] = 30
|
||||
print(arr)
|
181
data_structures/avl.py
Normal file
181
data_structures/avl.py
Normal 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)
|
29
data_structures/binary tree/FenwickTree.py
Normal file
29
data_structures/binary tree/FenwickTree.py
Normal 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))
|
91
data_structures/binary tree/LazySegmentTree.py
Normal file
91
data_structures/binary tree/LazySegmentTree.py
Normal 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()
|
71
data_structures/binary tree/SegmentTree.py
Normal file
71
data_structures/binary tree/SegmentTree.py
Normal 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()
|
258
data_structures/binary tree/binary_search_tree.py
Normal file
258
data_structures/binary tree/binary_search_tree.py
Normal 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()
|
54
data_structures/graph/bellman_ford.py
Normal file
54
data_structures/graph/bellman_ford.py
Normal 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)
|
67
data_structures/graph/breadth_first_search.py
Normal file
67
data_structures/graph/breadth_first_search.py
Normal 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
|
66
data_structures/graph/depth_first_search.py
Normal file
66
data_structures/graph/depth_first_search.py
Normal 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
|
57
data_structures/graph/dijkstra.py
Normal file
57
data_structures/graph/dijkstra.py
Normal 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)
|
212
data_structures/graph/dijkstra_algorithm.py
Normal file
212
data_structures/graph/dijkstra_algorithm.py
Normal 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
|
70
data_structures/graph/even_tree.py
Normal file
70
data_structures/graph/even_tree.py
Normal 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)
|
48
data_structures/graph/floyd_warshall.py
Normal file
48
data_structures/graph/floyd_warshall.py
Normal 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)
|
44
data_structures/graph/graph.py
Normal file
44
data_structures/graph/graph.py
Normal 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
|
31
data_structures/graph/graph_list.py
Normal file
31
data_structures/graph/graph_list.py
Normal 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()
|
||||
|
32
data_structures/graph/graph_matrix.py
Normal file
32
data_structures/graph/graph_matrix.py
Normal 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()
|
||||
|
90
data_structures/heap/heap.py
Normal file
90
data_structures/heap/heap.py
Normal 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()
|
||||
|
||||
|
76
data_structures/linked_list/DoublyLinkedList.py
Normal file
76
data_structures/linked_list/DoublyLinkedList.py
Normal 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=" ")
|
22
data_structures/linked_list/__init__.py
Normal file
22
data_structures/linked_list/__init__.py
Normal 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
|
70
data_structures/linked_list/singly_LinkedList.py
Normal file
70
data_structures/linked_list/singly_LinkedList.py
Normal 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
|
40
data_structures/queue/DeQueue.py
Normal file
40
data_structures/queue/DeQueue.py
Normal 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)
|
45
data_structures/queue/QueueOnList.py
Normal file
45
data_structures/queue/QueueOnList.py
Normal 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
|
50
data_structures/queue/QueueOnPseudoStack.py
Normal file
50
data_structures/queue/QueueOnPseudoStack.py
Normal 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
|
0
data_structures/queue/__init__.py
Normal file
0
data_structures/queue/__init__.py
Normal file
52
data_structures/stacks/Stock-Span-Problem.py
Normal file
52
data_structures/stacks/Stock-Span-Problem.py
Normal 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))
|
23
data_structures/stacks/__init__.py
Normal file
23
data_structures/stacks/__init__.py
Normal 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]
|
23
data_structures/stacks/balanced_parentheses.py
Normal file
23
data_structures/stacks/balanced_parentheses.py
Normal 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)))
|
64
data_structures/stacks/infix_to_postfix_conversion.py
Normal file
64
data_structures/stacks/infix_to_postfix_conversion.py
Normal 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))
|
17
data_structures/stacks/next.py
Normal file
17
data_structures/stacks/next.py
Normal 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)
|
69
data_structures/stacks/stack.py
Normal file
69
data_structures/stacks/stack.py
Normal 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()))
|
75
data_structures/trie/Trie.py
Normal file
75
data_structures/trie/Trie.py
Normal 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()
|
0
data_structures/union_find/__init__.py
Normal file
0
data_structures/union_find/__init__.py
Normal file
78
data_structures/union_find/tests_union_find.py
Normal file
78
data_structures/union_find/tests_union_find.py
Normal 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()
|
87
data_structures/union_find/union_find.py
Normal file
87
data_structures/union_find/union_find.py
Normal 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)
|
37
dynamic_programming/floyd_warshall.py
Normal file
37
dynamic_programming/floyd_warshall.py
Normal 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)
|
58
file_transfer_protocol/ftp_client_server.py
Normal file
58
file_transfer_protocol/ftp_client_server.py
Normal 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')
|
36
file_transfer_protocol/ftp_send_receive.py
Normal file
36
file_transfer_protocol/ftp_send_receive.py
Normal 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()
|
44
graphs/ArticulationPoints.py
Normal file
44
graphs/ArticulationPoints.py
Normal 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)
|
43
graphs/CheckBipartiteGraph_BFS.py
Normal file
43
graphs/CheckBipartiteGraph_BFS.py
Normal 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
31
graphs/FindingBridges.py
Normal 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)
|
30
graphs/KahnsAlgorithm_long.py
Normal file
30
graphs/KahnsAlgorithm_long.py
Normal 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)
|
32
graphs/KahnsAlgorithm_topo.py
Normal file
32
graphs/KahnsAlgorithm_topo.py
Normal 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)
|
111
graphs/MinimumSpanningTree_Prims.py
Normal file
111
graphs/MinimumSpanningTree_Prims.py
Normal 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))
|
266
graphs/Multi_Hueristic_Astar.py
Normal file
266
graphs/Multi_Hueristic_Astar.py
Normal 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
102
graphs/a_star.py
Normal 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
281
graphs/basic-graphs.py
Normal 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
|
32
graphs/minimum_spanning_tree_kruskal.py
Normal file
32
graphs/minimum_spanning_tree_kruskal.py
Normal 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
46
graphs/scc_kosaraju.py
Normal 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
78
graphs/tarjans_scc.py
Normal 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)
|
74
linear_algebra_python/README.md
Normal file
74
linear_algebra_python/README.md
Normal 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**.
|
364
linear_algebra_python/src/lib.py
Normal file
364
linear_algebra_python/src/lib.py
Normal 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)
|
||||
|
||||
|
133
linear_algebra_python/src/tests.py
Normal file
133
linear_algebra_python/src/tests.py
Normal 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
74
maths/BasicMaths.py
Normal 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()
|
||||
|
||||
|
18
maths/FibonacciSequenceRecursion.py
Normal file
18
maths/FibonacciSequenceRecursion.py
Normal 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()
|
15
maths/GreaterCommonDivisor.py
Normal file
15
maths/GreaterCommonDivisor.py
Normal 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()
|
||||
|
20
maths/ModularExponential.py
Normal file
20
maths/ModularExponential.py
Normal 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
46
maths/SegmentedSieve.py
Normal 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))
|
24
maths/SieveOfEratosthenes.py
Normal file
24
maths/SieveOfEratosthenes.py
Normal 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
49
maths/SimpsonRule.py
Normal 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
46
maths/TrapezoidalRule.py
Normal 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
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
193
neural_network/bpnn.py
Normal file
|
@ -0,0 +1,193 @@
|
|||
#!/usr/bin/python
|
||||
# encoding=utf8
|
||||
|
||||
'''
|
||||
|
||||
A Framework of Back Propagation Neural Network(BP) 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()
|
306
neural_network/convolution_neural_network.py
Normal file
306
neural_network/convolution_neural_network.py
Normal file
|
@ -0,0 +1,306 @@
|
|||
#-*- coding: utf-8 -*-
|
||||
|
||||
'''
|
||||
- - - - - -- - - - - - - - - - - - - - - - - - - - - - -
|
||||
Name - - CNN - Convolution Neural Network For Photo Recognizing
|
||||
Goal - - Recognize Handing Writting Word Photo
|
||||
Detail:Total 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
|
||||
'''
|
124
neural_network/perceptron.py
Normal file
124
neural_network/perceptron.py
Normal 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)
|
17
project_euler/Problem 01/sol1.py
Normal file
17
project_euler/Problem 01/sol1.py
Normal 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)
|
20
project_euler/Problem 01/sol2.py
Normal file
20
project_euler/Problem 01/sol2.py
Normal 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)
|
50
project_euler/Problem 01/sol3.py
Normal file
50
project_euler/Problem 01/sol3.py
Normal 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);
|
30
project_euler/Problem 01/sol4.py
Normal file
30
project_euler/Problem 01/sol4.py
Normal 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))
|
26
project_euler/Problem 02/sol1.py
Normal file
26
project_euler/Problem 02/sol1.py
Normal 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)
|
12
project_euler/Problem 02/sol2.py
Normal file
12
project_euler/Problem 02/sol2.py
Normal 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')
|
20
project_euler/Problem 02/sol3.py
Normal file
20
project_euler/Problem 02/sol3.py
Normal 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)
|
||||
|
39
project_euler/Problem 03/sol1.py
Normal file
39
project_euler/Problem 03/sol1.py
Normal 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)
|
17
project_euler/Problem 03/sol2.py
Normal file
17
project_euler/Problem 03/sol2.py
Normal 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)
|
29
project_euler/Problem 04/sol1.py
Normal file
29
project_euler/Problem 04/sol1.py
Normal 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
|
19
project_euler/Problem 04/sol2.py
Normal file
19
project_euler/Problem 04/sol2.py
Normal 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)
|
21
project_euler/Problem 05/sol1.py
Normal file
21
project_euler/Problem 05/sol1.py
Normal 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
|
20
project_euler/Problem 05/sol2.py
Normal file
20
project_euler/Problem 05/sol2.py
Normal 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)
|
20
project_euler/Problem 06/sol1.py
Normal file
20
project_euler/Problem 06/sol1.py
Normal 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)
|
16
project_euler/Problem 06/sol2.py
Normal file
16
project_euler/Problem 06/sol2.py
Normal 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)
|
30
project_euler/Problem 07/sol1.py
Normal file
30
project_euler/Problem 07/sol1.py
Normal 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)
|
16
project_euler/Problem 07/sol2.py
Normal file
16
project_euler/Problem 07/sol2.py
Normal 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])
|
15
project_euler/Problem 08/sol1.py
Normal file
15
project_euler/Problem 08/sol1.py
Normal 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()
|
15
project_euler/Problem 09/sol1.py
Normal file
15
project_euler/Problem 09/sol1.py
Normal 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
|
18
project_euler/Problem 09/sol2.py
Normal file
18
project_euler/Problem 09/sol2.py
Normal 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)
|
38
project_euler/Problem 10/sol1.py
Normal file
38
project_euler/Problem 10/sol1.py
Normal 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
Loading…
Reference in New Issue
Block a user