├── .gitignore ├── .idea ├── .gitignore ├── algoritmi.iml ├── inspectionProfiles │ └── profiles_settings.xml ├── misc.xml ├── modules.xml ├── other.xml └── vcs.xml ├── alberi ├── __init__.py ├── abr.py ├── alberibinari.py ├── eccezioni.py ├── test.py └── utility.py ├── backtracking ├── __init__.py ├── backtracking.py ├── cricca.py └── subsetsum.py ├── esempigreedy ├── __init__.py └── knapsackfrazionario.py ├── grafi ├── __init__.py ├── algosugrafi.py ├── algosugrafipesati.py ├── grafi.py ├── grafino.py ├── grafinopesati.py ├── grafipesati.py ├── scheduleratt.py ├── test.py └── unionfind.py ├── heap ├── __init__.py ├── eccezioni.py ├── heap.py ├── heapmodificabile.py └── test.py ├── main.py ├── programmazionedinamica ├── __init__.py ├── editdistance.py ├── knapsack01.py └── lcs.py └── semplici ├── __init__.py ├── codeprioritafissata.py ├── mergesort.py ├── quicksort.py ├── simple.py └── test.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Project exclude paths 2 | /env/ -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Datasource local storage ignored files 5 | /../../../../../../:\Users\sfles\PycharmProjects\algoritmi\.idea/dataSources/ 6 | /dataSources.local.xml 7 | # Editor-based HTTP Client requests 8 | /httpRequests/ 9 | -------------------------------------------------------------------------------- /.idea/algoritmi.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/other.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /alberi/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sflesca/EsempiAlgoritmiPython/780dd2e398382bd42eb1c0ea081964a7aef0a259/alberi/__init__.py -------------------------------------------------------------------------------- /alberi/abr.py: -------------------------------------------------------------------------------- 1 | from alberi.alberibinari import AlberoBin 2 | 3 | 4 | class ABR: 5 | def __init__(self): 6 | self.valori: AlberoBin = None 7 | 8 | def search(self, val): 9 | x = self.__search__(self.valori, val) 10 | if x is None: 11 | return False 12 | if x.val == val: 13 | return True 14 | return False 15 | 16 | def __search__(self, curr, 17 | val) -> AlberoBin: # restituisce il nodo in cui è contenuto il valore cercato oppure il padre del nodo in cui sarebbe contenuto il valore cercato se non presente 18 | if curr is None: 19 | return curr 20 | if curr.val == val: 21 | return curr 22 | elif curr.val > val: 23 | if curr.sin is not None: 24 | return self.__search__(curr.sin, val) 25 | else: 26 | return curr 27 | else: 28 | if curr.des is not None: 29 | return self.__search__(curr.des, val) 30 | else: 31 | return curr 32 | 33 | def min(self): 34 | if self.valori is None: 35 | return None 36 | curr = self.valori 37 | while curr.sin is not None: 38 | curr = curr.sin 39 | return curr.val 40 | 41 | def max(self): 42 | if self.valori is None: 43 | return None 44 | curr = self.valori 45 | while curr.des is not None: 46 | curr = curr.des 47 | return curr.val 48 | 49 | def insert(self, val): 50 | n = self.__search__(self.valori, val) 51 | if n is None: # Inserimento sulla radice 52 | self.valori = AlberoBin(val) 53 | else: 54 | if n.val != val: # Inserimento generale 55 | nuovo = AlberoBin(val) 56 | if n.val > val: 57 | n.setfigliosin(nuovo) 58 | else: 59 | n.setfigliodes(nuovo) 60 | 61 | def delete(self, val): 62 | if self.valori is None: 63 | return 64 | n = self.__search__(self.valori, val) 65 | if n.val != val: 66 | return 67 | if (n.sin is not None) and (n.des is not None): 68 | tt = n.des 69 | while tt.sin is not None: 70 | tt = tt.sin 71 | n.val = tt.val 72 | n = tt 73 | padre = n.parent 74 | if padre is None: 75 | if n.sin is not None: 76 | self.valori = n.sin 77 | n.sin.pota() 78 | else: 79 | self.valori = n.des 80 | n.des.pota() 81 | else: 82 | if n.sin is not None: 83 | xx = n.sin 84 | else 85 | xx = n.des 86 | xx.pota() 87 | if padre.sin == n: 88 | n.pota() 89 | padre.sin = xx 90 | else: 91 | n.pota() 92 | padre.des = xx 93 | -------------------------------------------------------------------------------- /alberi/alberibinari.py: -------------------------------------------------------------------------------- 1 | from re import match 2 | 3 | from alberi.eccezioni import ValoriScorretti 4 | 5 | 6 | class AlberoBin: 7 | def __init__(self, val): 8 | self.val = val 9 | self.sin: AlberoBin = None 10 | self.des: AlberoBin = None 11 | self.parent: AlberoBin = None 12 | 13 | def setfigliosin(self, sin): 14 | # complessità: indichiamo com n il numero di nodi già memorizzati nell'albero 15 | # theta(1) 16 | if not isinstance(sin, AlberoBin): 17 | raise ValoriScorretti("tipo figlio non consentito") 18 | if sin is None: 19 | return 20 | if sin.parent is not None: 21 | raise ValoriScorretti("Il figlio passato ha già un padre") 22 | if self.sin is not None: 23 | self.sin.pota() # staccare il figlio esistente 24 | sin.parent = self 25 | self.sin = sin 26 | 27 | def setfigliodes(self, des): 28 | # complessità: indichiamo com n il numero di nodi già memorizzati nell'albero 29 | # theta(1) 30 | if not isinstance(des, AlberoBin): 31 | raise ValoriScorretti("tipo figlio non consentito") 32 | if self.des is not None: 33 | self.des.pota() 34 | if des.parent is not None: 35 | raise ValoriScorretti("Il figlio passato ha già un padre") 36 | des.parent = self 37 | self.des = des 38 | 39 | def pota(self): 40 | # complessità: indichiamo com n il numero di nodi già memorizzati nell'albero 41 | # theta(1) 42 | if self.parent is None: 43 | return 44 | if self.parent.sin == self: 45 | self.parent.sin = None 46 | if self.parent.des == self: 47 | self.parent.des = None 48 | self.parent = None 49 | 50 | def __iter__(self): 51 | self.cur = self 52 | self.hasnext = True 53 | while self.cur.sin is not None: 54 | self.cur = self.cur.sin 55 | return self 56 | 57 | def __next__(self): 58 | if not self.hasnext: 59 | raise StopIteration 60 | tmp = self.cur.val 61 | self.__avanza__() 62 | return tmp 63 | 64 | def __avanza__(self): 65 | direzione = "des" 66 | while direzione != "stop": 67 | match direzione: 68 | case "sin": 69 | if self.cur.sin is None: 70 | direzione = "stop" 71 | else: 72 | self.cur = self.cur.sin 73 | direzione = "sin" 74 | case "des": 75 | if self.cur.des is None: 76 | direzione = "su" 77 | else: 78 | self.cur = self.cur.des 79 | direzione = "sin" 80 | case "su": 81 | if self.cur.parent is None: 82 | self.hasnext = False 83 | direzione = "stop" 84 | else: 85 | if self.cur.parent.sin == self.cur: 86 | self.cur = self.cur.parent 87 | direzione = "stop" 88 | else: 89 | self.cur = self.cur.parent 90 | direzione = "su" 91 | 92 | def visitainfissa(self, l): 93 | if self.sin is not None: 94 | self.sin.visitainfissa(l) 95 | l.append(self.val) 96 | if self.des is not None: 97 | self.des.visitainfissa(l) 98 | 99 | def visitaanticipata(self, l): 100 | l.append(self.val) 101 | if self.sin is not None: 102 | self.sin.visitaanticipata(l) 103 | if self.des is not None: 104 | self.des.visitaanticipata(l) 105 | 106 | def visitaposticipata(self, l): 107 | if self.sin is not None: 108 | self.sin.visitaposticipata(l) 109 | if self.des is not None: 110 | self.des.visitaposticipata(l) 111 | l.append(self.val) 112 | 113 | def visitalivelli(self, l): 114 | coda = [self] 115 | while len(coda) != 0: 116 | curr = coda.pop(0) 117 | l.append(curr.val) 118 | if curr.sin is not None: 119 | coda.append(curr.sin) 120 | if curr.des is not None: 121 | coda.append(curr.des) 122 | return l 123 | 124 | 125 | def tonestedlist(a): 126 | if a is None: 127 | return None 128 | return [a.val, tonestedlist(a.sin), tonestedlist(a.des)] 129 | 130 | 131 | def fromnestedlist(l): 132 | if l is None: 133 | return None 134 | x = AlberoBin(l[0]) 135 | s = fromnestedlist(l[1]) 136 | if s is not None: 137 | x.setfigliosin(s) 138 | d = fromnestedlist(l[2]) 139 | if d is not None: 140 | x.setfigliodes(d) 141 | return x 142 | -------------------------------------------------------------------------------- /alberi/eccezioni.py: -------------------------------------------------------------------------------- 1 | class ValoriScorretti(Exception): 2 | def __init__(self, message): 3 | self.message = message -------------------------------------------------------------------------------- /alberi/test.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from alberi.alberibinari import AlberoBin, tonestedlist, fromnestedlist 4 | 5 | a = AlberoBin(0) 6 | b = AlberoBin(1) 7 | c = AlberoBin(2) 8 | d = AlberoBin(3) 9 | e = AlberoBin(4) 10 | f = AlberoBin(5) 11 | a.setfigliosin(b) 12 | a.setfigliodes(c) 13 | b.setfigliosin(d) 14 | b.setfigliodes(e) 15 | c.setfigliosin(f) 16 | # for x in a: 17 | # print(x) 18 | 19 | l = [] 20 | a.visitainfissa(l) 21 | print(l) 22 | 23 | l = [] 24 | a.visitaanticipata(l) 25 | print(l) 26 | 27 | l = [] 28 | a.visitaposticipata(l) 29 | print(l) 30 | 31 | l = [] 32 | a.visitalivelli(l) 33 | print(l) 34 | 35 | 36 | def vI1(a): 37 | l = [] 38 | vI(a, l) 39 | return l 40 | 41 | 42 | def vI(a, l): 43 | if a is None: 44 | return 45 | vI(a.sin, l) 46 | l.append(a.val) 47 | vI(a.des, l) 48 | 49 | 50 | def somma(a: AlberoBin)->int: 51 | if a is None: 52 | return 0 53 | return a.val+somma(a.sin)+somma(a.des) 54 | 55 | 56 | def verifica(a: AlberoBin) -> bool: 57 | if a is None: 58 | return False 59 | if a.sin is None and a.des is None: 60 | return False 61 | return verifica(a.sin) or verifica(a.des) or (a.val == somma(a.sin) + somma(a.des)) 62 | 63 | def mini(a:AlberoBin)->int: 64 | if(a is None): 65 | return -sys.maxint 66 | minimo = a.val 67 | if(a.sin is not None): 68 | minimo = min(minimo, mini(a.sin)) 69 | if(a.des is not None): 70 | minimo = min(minimo,mini(a.des)) 71 | return minimo 72 | 73 | def maxi(a:AlberoBin)->int: 74 | if(a is None): 75 | return sys.maxint 76 | massimo = a.val 77 | if(a.sin is not None): 78 | massimo = max(massimo, maxi(a.sin)) 79 | if(a.des is not None): 80 | massimo = max(massimo,maxi(a.des)) 81 | return massimo 82 | 83 | def ediricercaminmax(a:AlberoBin,mini:int,maxi:int)->bool: 84 | if a is None: 85 | return True 86 | return (mini<=a.val and a.val <= maxi) and \ 87 | ediricercaminmax(a.sin,mini, a.val-1) and ediricercaminmax(a.des,a.val+1,maxi) 88 | 89 | 90 | def ediricerca(a:AlberoBin)->bool: 91 | if a is None: 92 | return True 93 | return ediricercaminmax(a,mini(a),maxi(a)) 94 | 95 | def sonosimmetrici(a:AlberoBin,b:AlberoBin)->bool: 96 | if a is None and b is None: 97 | return True 98 | if (a is not None and b is None) or (a is None and b is not None): 99 | return False 100 | return a.val==b.val and sonosimmetrici(a.sin,b.des) and sonosimmetrici(a.des, b.sin) 101 | 102 | def esimmetrico(a:AlberoBin)->bool: 103 | return sonosimmetrici(a,a) 104 | 105 | 106 | 107 | lalb = tonestedlist(a) 108 | print(lalb) 109 | 110 | alb = fromnestedlist([0, [1, [3, None, None], [4, None, None]], [1, [5, None, None], None]]) 111 | print(tonestedlist(alb)) 112 | print(esimmetrico(alb)) 113 | 114 | alb = fromnestedlist([0, [1, [3, None, None], [4, None, None]], [1, [4, None, None], [3, None, None]]]) 115 | print(tonestedlist(alb)) 116 | print(esimmetrico(alb)) 117 | 118 | alb.ciccio = "ciao" 119 | print(alb.ciccio) 120 | -------------------------------------------------------------------------------- /alberi/utility.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from platform import android_ver 3 | 4 | from alberi.abr import ABR 5 | from alberi.alberibinari import AlberoBin 6 | 7 | 8 | def altezza(a: AlberoBin) ->int: 9 | if a is None: 10 | return 0 11 | return 1 + max(altezza(a.sin),altezza(a.des)) 12 | 13 | def _xor(a:int, b: int)-> int: 14 | return a+b if a+b<=2 else 2 15 | 16 | 17 | def verifica(a: AlberoBin) ->int: 18 | if a is None: 19 | return 0 20 | if not a.sin and not a.des: 21 | return 1 if a.val == 0 else 0 22 | return _xor(verifica(a.sin), verifica(a.des)) 23 | 24 | def verificacorretta(a: AlberoBin) ->bool: 25 | return verifica(a)==1 26 | 27 | menoinfinito = -sys.maxsize 28 | 29 | def massimo(a: AlberoBin)->int: 30 | if a is None: 31 | return menoinfinito 32 | return max(a.val,massimo(a.sin),massimo(a.des)) 33 | 34 | def verifica1(a: AlberoBin)->bool: 35 | if a is None or (a.sin is None and a.des is None): 36 | return True 37 | return massimo(a.sin)bool: 41 | if a is None: 42 | return False 43 | if not a.sin and not a.des: 44 | return a.val == val 45 | return almenounafoglia(a.sin, val) or almenounafoglia(a.des, val) 46 | 47 | 48 | def tuttiminori(a:AlberoBin, val)->bool: 49 | if a is None: 50 | return True 51 | return a.valbool: 55 | if a is None: 56 | return True 57 | return a.val>=val and tuttimaggiori(a.sin, val) and tuttimaggiori(a.des, val) 58 | 59 | 60 | def diricerca(a: AlberoBin)->bool: 61 | if a is None: 62 | return True 63 | return (tuttiminori(a.sin, a.val) and tuttimaggiori(a.des, a.val) 64 | and diricerca(a.sin) and diricerca(a.des)) 65 | 66 | 67 | def diricercasbagliato(a: AlberoBin)->bool: 68 | if a is None: 69 | return True 70 | if (a.sin is not None): 71 | if a.sin.val >= val: 72 | return False 73 | if (a.des is not None): 74 | if a.des.val >= val: 75 | return False 76 | return diricercasbagliato(a.sin) and diricercasbagliato(a.des) 77 | 78 | def costruisciABRdavettoreordinato(abr:ABR, l:list, inizio: int, fine:int): 79 | if finebool: 6 | liv: int = 0 7 | rivedi: bool = False 8 | if not self.primaScelta(liv): 9 | return False 10 | while liv >= 0: 11 | if self.verificaVincoli(liv): 12 | if self.solCompleta(liv): 13 | self.costruisciSoluzione(liv) 14 | return True 15 | liv += 1 16 | if not self.primaScelta(liv): 17 | rivedi = True 18 | else: 19 | if not self.successivaScelta(liv): 20 | rivedi = True 21 | while rivedi and liv >= 0: 22 | liv -= 1 23 | if liv >= 0 and self.successivaScelta(liv): 24 | rivedi = False 25 | return False 26 | 27 | def primaScelta(self, liv: int)->bool: 28 | pass 29 | 30 | def successivaScelta(self, liv: int)->bool: 31 | pass 32 | 33 | def solCompleta(self, liv: int)->bool: 34 | pass 35 | 36 | def verificaVincoli(self, liv: int)->bool: 37 | pass 38 | 39 | def costruisciSoluzione(self, liv: int): 40 | pass 41 | -------------------------------------------------------------------------------- /backtracking/cricca.py: -------------------------------------------------------------------------------- 1 | from backtracking import ProblemaBack 2 | from grafi.grafino import GrafoNO, GrafoMANO 3 | 4 | 5 | class Cricca(ProblemaBack): 6 | def __init__(self, g: GrafoNO, k: int): 7 | self.g: Grafo = g 8 | self.nodes: list[int] = [-1 for i in range(k)] 9 | self.sol: list[int] = [] 10 | 11 | def primaScelta(self, liv: int) -> bool: 12 | if liv == 0: 13 | self.nodes[liv] = 0 14 | return True 15 | if self.nodes[liv - 1] >= self.g.n - 1: 16 | return False 17 | self.nodes[liv] = self.nodes[liv - 1] + 1 18 | return True 19 | 20 | def successivaScelta(self, liv: int) -> bool: 21 | if self.nodes[liv] >= self.g.n - 1: 22 | return False 23 | self.nodes[liv] = self.nodes[liv] + 1 24 | return True 25 | 26 | def solCompleta(self, liv: int) -> bool: 27 | return liv == len(self.nodes) - 1 28 | 29 | def verificaVincoli(self, liv: int) -> bool: 30 | for i in range(liv - 1): 31 | if not self.g.arco(self.nodes[i], self.nodes[liv]): 32 | return False 33 | return True 34 | 35 | def costruisciSoluzione(self, liv: int): 36 | for x in self.nodes: 37 | self.sol.append(x) 38 | 39 | 40 | g: GrafoNO = GrafoMANO(6) 41 | g.aggiungiarco(0,1) 42 | g.aggiungiarco(1,4) 43 | g.aggiungiarco(0,4) 44 | g.aggiungiarco(2,1) 45 | g.aggiungiarco(1,5) 46 | g.aggiungiarco(3,4) 47 | g.stampa() 48 | 49 | c:Cricca = Cricca(g,3) 50 | if c.risolvi(): 51 | print("Cricca(g,3)") 52 | print(c.sol) 53 | else: 54 | print("Cricca(g,3): no sol") 55 | 56 | c:Cricca = Cricca(g,4) 57 | if c.risolvi(): 58 | print("Cricca(g,4)") 59 | print(c.sol) 60 | else: 61 | print("Cricca(g,4): no sol") 62 | -------------------------------------------------------------------------------- /backtracking/subsetsum.py: -------------------------------------------------------------------------------- 1 | from backtracking import ProblemaBack 2 | 3 | 4 | class SubsetSum(ProblemaBack): 5 | def __init__(self, s: list[int], v: int): 6 | super().__init__() 7 | self.s = s 8 | self.v = v 9 | self.sol = [True for i in range(len(s))] 10 | self.soluzione = [] 11 | 12 | def primaScelta(self, liv: int)->bool: 13 | if liv == len(self.s): 14 | return False 15 | else: 16 | self.sol[liv] = True 17 | return True 18 | 19 | def successivaScelta(self, liv: int)->bool: 20 | if self.sol[liv]: 21 | self.sol[liv] = False 22 | return True 23 | else: 24 | return False 25 | 26 | def solCompleta(self, liv: int)->bool: 27 | somma =0 28 | for i in range(liv+1): 29 | if self.sol[i]: 30 | somma += self.s[i] 31 | return somma == self.v 32 | 33 | def verificaVincoli(self, liv: int)->bool: 34 | somma = 0 35 | for i in range(liv + 1): 36 | if self.sol[i]: 37 | somma += self.s[i] 38 | return somma <= self.v 39 | 40 | def costruisciSoluzione(self, liv: int): 41 | for i in range(liv + 1): 42 | if self.sol[i]: 43 | self.soluzione.append(self.s[i]) 44 | s = [1,21,3,40,13,15,7,8,9,10] 45 | v = 180 46 | p:SubsetSum = SubsetSum(s, v) 47 | if p.risolvi(): 48 | print(f"SubsetSum({s}, {v})") 49 | print(f"{p.soluzione} - {sum(p.soluzione)}") 50 | else: 51 | print("SubsetSum(s,v): no sol") 52 | -------------------------------------------------------------------------------- /esempigreedy/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sflesca/EsempiAlgoritmiPython/780dd2e398382bd42eb1c0ea081964a7aef0a259/esempigreedy/__init__.py -------------------------------------------------------------------------------- /esempigreedy/knapsackfrazionario.py: -------------------------------------------------------------------------------- 1 | # Python3 program to solve fractional 2 | # Knapsack Problem 3 | 4 | 5 | class ItemValue: 6 | """Item Value DataClass""" 7 | 8 | def __init__(self, wt, val, ind): 9 | self.wt = wt 10 | self.val = val 11 | self.ind = ind 12 | self.cost = val // wt 13 | 14 | def __lt__(self, other): 15 | return self.cost < other.cost 16 | 17 | 18 | # Greedy Approach 19 | class FractionalKnapSack: 20 | """Time Complexity O(n log n)""" 21 | 22 | @staticmethod 23 | def getmaxvalue(wt, val, capacity): 24 | """function to get maximum value """ 25 | iVal = [] 26 | for i in range(len(wt)): 27 | iVal.append(ItemValue(wt[i], val[i], i)) 28 | 29 | # sorting items by value 30 | iVal.sort(reverse=True) 31 | 32 | totalValue = 0 33 | for i in iVal: 34 | curWt = int(i.wt) 35 | curVal = int(i.val) 36 | if capacity - curWt >= 0: 37 | capacity -= curWt 38 | totalValue += curVal 39 | else: 40 | fraction = capacity / curWt 41 | totalValue += curVal * fraction 42 | capacity = int(capacity - (curWt * fraction)) 43 | break 44 | return totalValue 45 | 46 | 47 | # Driver Code 48 | if __name__ == "__main__": 49 | wt = [10, 40, 20, 30] 50 | val = [60, 40, 100, 120] 51 | capacity = 50 52 | 53 | # Function call 54 | maxValue = FractionalKnapSack.getmaxvalue(wt, val, capacity) 55 | print("Maximum value in Knapsack =", maxValue) 56 | 57 | # This code is contributed by vibhu4agarwal 58 | -------------------------------------------------------------------------------- /grafi/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sflesca/EsempiAlgoritmiPython/780dd2e398382bd42eb1c0ea081964a7aef0a259/grafi/__init__.py -------------------------------------------------------------------------------- /grafi/algosugrafi.py: -------------------------------------------------------------------------------- 1 | from grafi import Grafo, GrafoLA, GrafoMA 2 | from grafino import GrafoNO, GrafoLANO, GrafoMANO 3 | 4 | 5 | def __visitaprofonditaRic__(g: Grafo, nodo: int, visitati: list[bool], risultato: list[int]): 6 | if not visitati[nodo]: 7 | visitati[nodo] = True 8 | risultato.append(nodo) 9 | for ad in g.adiacenti(nodo): 10 | __visitaprofonditaRic__(g, ad, visitati, risultato) 11 | 12 | 13 | def visitaprofonditaRic(g: Grafo, nodo: int) -> list[int]: 14 | risultato: list[int] = [] 15 | __visitaprofonditaRic__(g, nodo, [False for i in range(g.n)], risultato) 16 | return risultato 17 | 18 | 19 | def visitaprofondita(g: Grafo, nodo: int) -> list[int]: # MA theta(n^2) LA theta(m) spaziale theta(n) 20 | risultato: list[int] = [] 21 | pila: list[int] = [] 22 | visitati: list[bool] = [False for i in range(g.n)] 23 | pila.append(nodo) 24 | while pila: 25 | curr: int = pila.pop() 26 | if not visitati[curr]: 27 | visitati[curr] = True 28 | risultato.append(curr) 29 | for ad in reversed(list(g.adiacenti(curr))): 30 | pila.append(ad) 31 | return risultato 32 | 33 | 34 | def visitaampiezza(g: Grafo, nodo: int) -> list[int]: # MA theta(n^2) LA theta(m) spaziale theta(n) 35 | risultato: list[int] = [] 36 | coda: list[int] = [] 37 | visitati: list[bool] = [False for i in range(g.n)] 38 | coda.append(nodo) 39 | while coda: 40 | curr: int = coda.pop(0) # theta(n) 41 | if not visitati[curr]: 42 | visitati[curr] = True # theta(n) 43 | risultato.append(curr) # theta(n) 44 | for ad in g.adiacenti(curr): # LA theta(m) MA theta(n^2) 45 | if not visitati[ad]: # theta(m) 46 | coda.append(ad) # theta(m) 47 | return risultato 48 | 49 | 50 | def econnesso(g: GrafoNO) -> bool: 51 | result = visitaampiezza(g, 0) 52 | if len(result) == g.n: 53 | return True 54 | return False 55 | 56 | 57 | def ealbero(g: GrafoNO) -> bool: # MA theta(n^2) LA theta(n) 58 | return g.n == g.m + 1 and econnesso(g) 59 | 60 | 61 | def numcompconnesse(g: GrafoNO) -> int: 62 | visitati: list[bool] = [False for i in range(g.n)] 63 | comp: int = 0 64 | for i in range(g.n): 65 | if not visitati[i]: 66 | comp += 1 67 | __visitaprofonditaRic__(g, i, visitati, []) 68 | return comp 69 | 70 | 71 | def eaciclico(g: GrafoNO) -> bool: 72 | return g.n == g.m + numcompconnesse(g) 73 | 74 | 75 | def trovazero(gradi: list[int], rimossi) -> int: 76 | for i in range(len(gradi)): 77 | if gradi[i] == 0 and not rimossi[i]: 78 | return i 79 | return -1 80 | 81 | 82 | def tuttizero(gradi: list[int]) -> bool: 83 | for x in gradi: 84 | if x != 0: 85 | return False 86 | return True 87 | 88 | 89 | def eaciclicoOR(g: Grafo) -> bool: #theta(n^2) 90 | gradi: list[int] = [0 for i in range(g.n)] #theta(n) 91 | rimossi: list[bool] = [False for i in range(g.n)] #theta(n) 92 | for x, y in g.archi(): #MA theta(n^2) LA theta(m) 93 | gradi[y] += 1 94 | curr = trovazero(gradi, rimossi) #theta(n) 95 | while curr != -1: #per ogni nodo che rimuovo (nel caso peggiore per ogni nodo) theta(n^2) 96 | rimossi[curr] = True 97 | for ad in g.adiacenti(curr): #MA theta(n) LA theta(grado_i(curr)) 98 | gradi[ad] -= 1 99 | curr = trovazero(gradi, rimossi) #theta(n) 100 | return tuttizero(gradi) #theta(n) 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /grafi/algosugrafipesati.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from grafipesati import GrafoP, GrafoLAP 4 | from grafinopesati import GrafoNOP, GrafoNOLAP 5 | from heap.heapmodificabile import HeapModificabile 6 | from unionfind import UnionFind 7 | 8 | 9 | def _peso(elem): 10 | return elem[2] 11 | 12 | 13 | class Pair: 14 | def __init__(self, x, p): 15 | self.x = x 16 | self.p = p 17 | 18 | def __lt__(self, other): 19 | return self.p < other.p 20 | 21 | def __eq__(self, other): 22 | return self.x == other.x 23 | 24 | def __hash__(self): 25 | return self.x 26 | 27 | def print(self): 28 | print("(" + str(self.x) + ", " + str(self.p) + ")") 29 | 30 | def __str__(self): 31 | return "(" + str(self.x) + ", " + str(self.p) + ")" 32 | 33 | def __repr__(self): 34 | return "(" + str(self.x) + ", " + str(self.p) + ")" 35 | 36 | 37 | def kruskal(g: GrafoNOP): 38 | archiordinati = sorted(g.archi(), key=_peso) 39 | forest: UnionFind = UnionFind(g.n) 40 | result = [] 41 | count = 0 42 | for x, y, p in archiordinati: 43 | if forest.find(x) != forest.find(y): 44 | result.append((x, y, p)) 45 | forest.union(forest.find(x), forest.find(y)) 46 | count += 1 47 | if count == g.n - 1: 48 | return result 49 | return [] 50 | 51 | 52 | def prim(g: GrafoNOP): 53 | padri: list[int] = [-1 for i in range(g.n)] 54 | pesi: list[int] = [sys.maxsize for i in range(g.n)] 55 | preso: list[bool] = [False for i in range(g.n)] 56 | curr: int = 0 57 | padri[0] = 0 58 | preso[0] = True 59 | count = 1 60 | result = [] 61 | mioheap: HeapModificabile = HeapModificabile(g.n) 62 | for a in g.adiacenti(curr): 63 | mioheap.ins(Pair(a.y, a.peso)) 64 | padri[a.y] = curr 65 | pesi[a.y] = a.peso 66 | while not mioheap.evuoto(): 67 | count += 1 68 | cp: Pair = mioheap.out() 69 | preso[cp.x] = True 70 | result.append((padri[cp.x], cp.x, cp.p)) 71 | for a in g.adiacenti(cp.x): 72 | if not preso[a.y]: 73 | if padri[a.y] == -1: 74 | mioheap.ins(Pair(a.y, a.peso)) 75 | padri[a.y] = cp.x 76 | pesi[a.y] = a.peso 77 | elif pesi[a.y] > a.peso: 78 | mioheap.update(Pair(a.y, a.peso)) 79 | padri[a.y] = cp.x 80 | pesi[a.y] = a.peso 81 | if count == g.n: 82 | return result 83 | else: 84 | return [] 85 | 86 | 87 | def Dijkstra(g: GrafoP, source: int): 88 | padri: list[int] = [-1 for i in range(g.n)] 89 | pesi: list[int] = [sys.maxsize for i in range(g.n)] 90 | preso: list[bool] = [False for i in range(g.n)] 91 | curr: int = source 92 | padri[curr] = curr 93 | preso[curr] = True 94 | count = 1 95 | result = [] 96 | mioheap: HeapModificabile = HeapModificabile(g.n) 97 | for a in g.adiacenti(curr): 98 | mioheap.ins(Pair(a.y, a.peso)) 99 | padri[a.y] = curr 100 | pesi[a.y] = a.peso 101 | while not mioheap.evuoto(): 102 | count += 1 103 | cp: Pair = mioheap.out() 104 | preso[cp.x] = True 105 | result.append((padri[cp.x], cp.x, cp.p)) 106 | for a in g.adiacenti(cp.x): 107 | if not preso[a.y]: 108 | if padri[a.y] == -1: 109 | mioheap.ins(Pair(a.y, a.peso + pesi[cp.x])) 110 | padri[a.y] = cp.x 111 | pesi[a.y] = a.peso 112 | elif pesi[a.y] > a.peso + pesi[cp.x]: 113 | mioheap.update(Pair(a.y, a.peso + pesi[cp.x])) 114 | padri[a.y] = cp.x 115 | pesi[a.y] = a.peso 116 | return result 117 | 118 | 119 | def floyd(g: GrafoP): 120 | M = [[sys.maxsize for i in range(g.n)] for j in range(g.n)] # Calcola matrice di adiacenza 121 | for i in range(g.n): 122 | M[i][i] = 0 123 | for x, y, p in g.archi(): 124 | M[x][y] = p 125 | for x in range(len(M)): 126 | for u in range(len(M)): 127 | for v in range(len(M)): 128 | if M[u][v] > M[u][x] + M[x][v]: 129 | M[u][v] = M[u][x] + M[x][v] 130 | return M 131 | 132 | 133 | g = GrafoLAP(5) 134 | g.aggiungiarco(0, 1, 2.1) 135 | g.aggiungiarco(0, 2, 1.1) 136 | g.aggiungiarco(1, 2, 1) 137 | g.aggiungiarco(3, 0, 1) 138 | g.aggiungiarco(3, 4, 1.2) 139 | g.aggiungiarco(0, 4, 2.2) 140 | g.stampa() 141 | 142 | # print(kruskal(g)) 143 | # print(prim(g)) 144 | 145 | print(floyd(g)) 146 | -------------------------------------------------------------------------------- /grafi/grafi.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | 4 | class Grafo: 5 | def __init__(self, n: int): 6 | self.n: int = n 7 | self.m: int = 0 8 | 9 | def aggiungiarco(self, x, y): 10 | pass 11 | 12 | def rimuoviarco(self, x, y): 13 | pass 14 | 15 | def arco(self, x, y): 16 | pass 17 | 18 | def adiacenti(self, x): 19 | pass 20 | 21 | def archi(self): 22 | pass 23 | 24 | def stampa(self): 25 | pass 26 | 27 | 28 | class GrafoMA(Grafo): 29 | def __init__(self, n): # crea un grafo con numero di nodi nodes 30 | super().__init__(n) 31 | self.mat = np.zeros((n, n), np.bool_) 32 | 33 | def aggiungiarco(self, x: int, y: int): #theta(1) 34 | if not self.mat[x][y]: 35 | self.mat[x][y] = True 36 | self.m += 1 37 | 38 | def rimuoviarco(self, x: int, y: int): #theta(1) 39 | if self.mat[x][y]: 40 | self.mat[x][y] = False 41 | self.m -= 1 42 | 43 | def arco(self, x: int, y: int) -> bool: #theta(1) 44 | return self.mat[x][y] 45 | 46 | def adiacenti(self, x): #La complessita di scorrere tutto l'iterable è theta(n) 47 | return IterArcoMAAdiacenti(self, x) 48 | 49 | def archi(self): #La complessita di scorrere tutto l'iterable è theta(n^2) 50 | return IterArcoMA(self) 51 | 52 | def stampa(self): 53 | for x in range(self.mat.shape[0]): 54 | for y in range(self.mat.shape[1]): 55 | if self.mat[x][y]: 56 | print("(" + str(x) + ", " + str(y) + ")") 57 | 58 | 59 | class IterArcoMAAdiacenti: 60 | def __init__(self, g, x): 61 | self.g = g 62 | self.x = x 63 | 64 | def __iter__(self): 65 | self.y = 0 66 | while self.y < self.g.mat.shape[1] and not self.g.mat[self.x][self.y]: 67 | self.y += 1 68 | if self.y < self.g.mat.shape[1]: 69 | self.hasnext = True 70 | else: 71 | self.hasnext = False 72 | return self 73 | 74 | def __next__(self): 75 | if not self.hasnext: 76 | raise StopIteration 77 | tmp = self.y 78 | self.y += 1 79 | while self.y < self.g.mat.shape[1] and not self.g.mat[self.x][self.y]: 80 | self.y += 1 81 | if self.y < self.g.mat.shape[1]: 82 | self.hasnext = True 83 | else: 84 | self.hasnext = False 85 | return tmp 86 | 87 | 88 | class IterArcoMA: 89 | def __init__(self, g): 90 | self.g = g 91 | 92 | def __iter__(self): 93 | self.x = 0 94 | self.it = iter(self.g.adiacenti(self.x)) 95 | return self 96 | 97 | def __next__(self): 98 | trovato = False 99 | while not trovato: 100 | try: 101 | y = next(self.it) 102 | trovato = True 103 | except StopIteration: 104 | if self.x < self.g.n - 1: 105 | self.x += 1 106 | self.it = iter(self.g.adiacenti(self.x)) 107 | else: 108 | raise StopIteration 109 | return self.x, y 110 | 111 | 112 | class GrafoLA(Grafo): 113 | def __init__(self, n): # crea un grafo con numero di nodi nodes 114 | super().__init__(n) 115 | self.mat = [[] for i in range(n)] 116 | 117 | def aggiungiarco(self, x, y): #theta(grado_u(x)) 118 | if y not in self.mat[x]: 119 | self.mat[x].append(y) 120 | self.m += 1 121 | 122 | def rimuoviarco(self, x, y): 123 | try: 124 | self.mat[x].remove(y) #theta(grado_u(x)) 125 | self.m -= 1 126 | except ValueError: 127 | pass 128 | 129 | def arco(self, x, y): #theta(grado_u(x)) 130 | return y in self.mat[x] 131 | 132 | def adiacenti(self, x): #La complessita di scorrere tutto l'iterable è theta(grado_u(x)) 133 | return self.mat[x] 134 | 135 | def archi(self): #La complessita di scorrere tutto l'iterable è theta(m) 136 | return IterArcoLA(self) 137 | 138 | def stampa(self): 139 | for x in range(len(self.mat)): 140 | for y in self.mat[x]: 141 | print("(" + str(x) + ", " + str(y) + ")") 142 | 143 | 144 | class IterArcoLA: 145 | def __init__(self, g): 146 | self.g: GrafoLA = g 147 | 148 | def __iter__(self): 149 | self.x = 0 150 | self.it = iter(self.g.adiacenti(self.x)) 151 | return self 152 | 153 | def __next__(self): 154 | trovato = False 155 | while not trovato: 156 | try: 157 | y = next(self.it) 158 | trovato = True 159 | except StopIteration: 160 | if self.x < self.g.n - 1: 161 | self.x += 1 162 | self.it = iter(self.g.adiacenti(self.x)) 163 | else: 164 | raise StopIteration 165 | return self.x, y 166 | -------------------------------------------------------------------------------- /grafi/grafino.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | class GrafoNO: 4 | def __init__(self,n:int): 5 | self.n = n 6 | self.m = 0 7 | 8 | def aggiungiarco(self, x, y): 9 | pass 10 | 11 | def rimuoviarco(self, x, y): 12 | pass 13 | 14 | def arco(self, x, y): 15 | pass 16 | 17 | def adiacenti(self, x): 18 | pass 19 | 20 | def archi(self): 21 | pass 22 | 23 | def stampa(self): 24 | pass 25 | 26 | 27 | class GrafoMANO(GrafoNO): 28 | def __init__(self, n): # crea un grafo con numero di nodi nodes 29 | super().__init__(n) 30 | self.mat = np.zeros((n, n), np.bool_) 31 | 32 | 33 | def aggiungiarco(self, x, y): 34 | if not self.mat[x][y]: 35 | self.mat[x][y] = True 36 | self.mat[y][x] = True 37 | self.m += 1 38 | 39 | def rimuoviarco(self, x, y): 40 | if self.mat[x][y]: 41 | self.mat[x][y] = False 42 | self.mat[y][x] = False 43 | self.m -= 1 44 | 45 | def arco(self, x, y): 46 | return self.mat[x][y] 47 | 48 | def adiacenti(self, x): 49 | return IterArcoMAAdiacenti(self, x) 50 | 51 | def archi(self): 52 | return IterArcoMA(self) 53 | 54 | def stampa(self): 55 | for x in range(self.mat.shape[0]): 56 | for y in range(self.mat.shape[1]): 57 | if self.mat[x][y]: 58 | print("(" + str(x) + ", " + str(y) + ")") 59 | 60 | 61 | class IterArcoMAAdiacenti: 62 | def __init__(self, g, x): 63 | self.g = g 64 | self.x = x 65 | 66 | def __iter__(self): 67 | self.y = 0 68 | while self.y < self.g.mat.shape[1] and not self.g.mat[self.x][self.y]: 69 | self.y += 1 70 | if self.y < self.g.mat.shape[1]: 71 | self.hasnext = True 72 | else: 73 | self.hasnext = False 74 | return self 75 | 76 | def __next__(self): 77 | if not self.hasnext: 78 | raise StopIteration 79 | tmp = self.y 80 | self.y += 1 81 | while self.y < self.g.mat.shape[1] and not self.g.mat[self.x][self.y]: 82 | self.y += 1 83 | if self.y < self.g.mat.shape[1]: 84 | self.hasnext = True 85 | else: 86 | self.hasnext = False 87 | return tmp 88 | 89 | 90 | class IterArcoMA: 91 | def __init__(self, g): 92 | self.g = g 93 | 94 | def __iter__(self): 95 | self.x = 0 96 | self.it = iter(self.g.adiacenti(self.x)) 97 | return self 98 | 99 | def __next__(self): 100 | trovato = False 101 | while not trovato: 102 | try: 103 | y = next(self.it) 104 | if y >= self.x: 105 | trovato = True 106 | except StopIteration: 107 | if self.x < self.g.n-1: 108 | self.x += 1 109 | self.it = iter(self.g.adiacenti(self.x)) 110 | else: 111 | raise StopIteration 112 | return self.x, y 113 | 114 | 115 | class GrafoLANO(GrafoNO): 116 | def __init__(self, n): # crea un grafo con numero di nodi nodes 117 | super().__init__(n) 118 | self.mat = [[] for i in range(n)] 119 | 120 | def aggiungiarco(self, x, y): 121 | if y not in self.mat[x]: 122 | self.mat[x].append(y) 123 | self.mat[y].append(x) 124 | self.m += 1 125 | 126 | def rimuoviarco(self, x, y): 127 | if self.arco(x,y): 128 | self.mat[x].remove(y) 129 | self.mat[y].remove(x) 130 | self.m -=1 131 | 132 | def arco(self, x, y): 133 | return y in self.mat[x] 134 | 135 | def adiacenti(self, x): 136 | return self.mat[x] 137 | 138 | def archi(self): 139 | return IterArcoLA(self) 140 | 141 | def stampa(self): 142 | for x in range(len(self.mat)): 143 | for y in self.mat[x]: 144 | print("(" + str(x) + ", " + str(y) + ")") 145 | 146 | class IterArcoLA: 147 | def __init__(self, g): 148 | self.g:GrafoLA = g 149 | 150 | def __iter__(self): 151 | self.x = 0 152 | self.it = iter(self.g.adiacenti(self.x)) 153 | return self 154 | 155 | def __next__(self): 156 | trovato = False 157 | while not trovato: 158 | try: 159 | y = next(self.it) 160 | if y >= self.x: 161 | trovato = True 162 | except StopIteration: 163 | if self.x < self.g.n-1: 164 | self.x += 1 165 | self.it = iter(self.g.adiacenti(self.x)) 166 | else: 167 | raise StopIteration 168 | return self.x, y 169 | 170 | -------------------------------------------------------------------------------- /grafi/grafinopesati.py: -------------------------------------------------------------------------------- 1 | class GrafoNOP: 2 | def __init__(self, n: int): 3 | self.n = n 4 | self.m = 0 5 | 6 | def aggiungiarco(self, x: int, y: int, peso: float): 7 | pass 8 | 9 | def rimuoviarco(self, x: int, y: int): 10 | pass 11 | 12 | def arco(self, x: int, y: int) -> float: 13 | pass 14 | 15 | def adiacenti(self, x: int): 16 | pass 17 | 18 | def archi(self): 19 | pass 20 | 21 | def stampa(self): 22 | pass 23 | 24 | 25 | class CoppiaP: 26 | def __init__(self, y:int, peso:float): 27 | self.y=y 28 | self.peso=peso 29 | 30 | def __eq__(self, other): 31 | if isinstance(other, self.__class__): 32 | return self.y==other.y 33 | return False 34 | 35 | def __ne__(self, other): 36 | return not self.__eq__(other) 37 | 38 | def __repr__(self): 39 | return "(" + str(self.y) + ", " + str(self.peso) + ")" 40 | 41 | 42 | class GrafoNOLAP(GrafoNOP): 43 | def __init__(self, n): # crea un grafo con numero di nodi nodes 44 | super().__init__(n) 45 | self.mat = [[] for i in range(n)] 46 | 47 | def aggiungiarco(self, x: int, y: int, peso: float): 48 | if y not in self.mat[x]: 49 | self.mat[x].append(CoppiaP(y, peso)) 50 | self.mat[y].append(CoppiaP(x, peso)) 51 | self.m += 1 52 | 53 | def rimuoviarco(self, x, y): 54 | try: 55 | self.mat[x].remove(CoppiaP(y,0)) 56 | self.mat[y].remove(CoppiaP(x, 0)) 57 | self.m -= 1 58 | except ValueError: 59 | pass 60 | 61 | def arco(self, x, y): 62 | c = self.mat[x][self.mat[x].index(CoppiaP(y,0))] 63 | return x, c.y, c.peso 64 | 65 | def adiacenti(self, x): 66 | return self.mat[x] 67 | 68 | def archi(self): 69 | return IterArcoLA(self) 70 | 71 | def stampa(self): 72 | for x in range(len(self.mat)): 73 | for c in self.mat[x]: 74 | print("(" + str(x) + ", " + str(c.y) + ", "+ str(c.peso) + ")") 75 | 76 | 77 | class IterArcoLA: 78 | def __init__(self, g): 79 | self.g: GrafoLA = g 80 | 81 | def __iter__(self): 82 | self.x = 0 83 | self.it = iter(self.g.adiacenti(self.x)) 84 | return self 85 | 86 | def __next__(self): 87 | trovato = False 88 | while not trovato: 89 | try: 90 | c = next(self.it) 91 | trovato = True 92 | except StopIteration: 93 | if self.x < self.g.n - 1: 94 | self.x += 1 95 | self.it = iter(self.g.adiacenti(self.x)) 96 | else: 97 | raise StopIteration 98 | return self.x, c.y, c.peso 99 | 100 | 101 | 102 | 103 | 104 | 105 | g = GrafoNOLAP(4) 106 | g.aggiungiarco(0, 1, 2.1) 107 | g.aggiungiarco(0, 2, 1.1) 108 | g.aggiungiarco(1, 2, 1) 109 | g.aggiungiarco(2, 0, 1) 110 | g.aggiungiarco(3, 0, 1) 111 | g.stampa() 112 | 113 | print("\n") 114 | g.rimuoviarco(0,3) 115 | g.stampa() 116 | print("\n") 117 | print(g.arco(0,1)) 118 | 119 | print("\n") 120 | for c in g.archi(): 121 | print(c) -------------------------------------------------------------------------------- /grafi/grafipesati.py: -------------------------------------------------------------------------------- 1 | class GrafoP: 2 | def __init__(self, n: int): 3 | self.n = n 4 | self.m = 0 5 | 6 | def aggiungiarco(self, x: int, y: int, peso: float): 7 | pass 8 | 9 | def rimuoviarco(self, x: int, y: int): 10 | pass 11 | 12 | def arco(self, x: int, y: int) -> float: 13 | pass 14 | 15 | def adiacenti(self, x: int): 16 | pass 17 | 18 | def archi(self): 19 | pass 20 | 21 | def stampa(self): 22 | pass 23 | 24 | 25 | class CoppiaP: 26 | def __init__(self, y:int, peso:float): 27 | self.y=y 28 | self.peso=peso 29 | 30 | def __eq__(self, other): 31 | if isinstance(other, self.__class__): 32 | return self.y==other.y 33 | return False 34 | 35 | def __ne__(self, other): 36 | return not self.__eq__(other) 37 | 38 | def __repr__(self): 39 | return "(" + str(self.y) + ", " + str(self.peso) + ")" 40 | 41 | 42 | class GrafoLAP(GrafoP): 43 | def __init__(self, n): # crea un grafo con numero di nodi nodes 44 | super().__init__(n) 45 | self.mat = [[] for i in range(n)] 46 | 47 | def aggiungiarco(self, x: int, y: int, peso: float): 48 | if y not in self.mat[x]: 49 | self.mat[x].append(CoppiaP(y, peso)) 50 | self.m += 1 51 | 52 | def rimuoviarco(self, x, y): 53 | try: 54 | self.mat[x].remove(CoppiaP(y,0)) 55 | self.m -= 1 56 | except ValueError: 57 | pass 58 | 59 | def arco(self, x, y): 60 | c = self.mat[x][self.mat[x].index(CoppiaP(y,0))] 61 | return x, c.y, c.peso 62 | 63 | def adiacenti(self, x): 64 | return self.mat[x] 65 | 66 | def archi(self): 67 | return IterArcoLA(self) 68 | 69 | def stampa(self): 70 | for x in range(len(self.mat)): 71 | for c in self.mat[x]: 72 | print("(" + str(x) + ", " + str(c.y) + ", "+ str(c.peso) + ")") 73 | 74 | 75 | class IterArcoLA: 76 | def __init__(self, g): 77 | self.g: GrafoLA = g 78 | 79 | def __iter__(self): 80 | self.x = 0 81 | self.it = iter(self.g.adiacenti(self.x)) 82 | return self 83 | 84 | def __next__(self): 85 | trovato = False 86 | while not trovato: 87 | try: 88 | c = next(self.it) 89 | trovato = True 90 | except StopIteration: 91 | if self.x < self.g.n - 1: 92 | self.x += 1 93 | self.it = iter(self.g.adiacenti(self.x)) 94 | else: 95 | raise StopIteration 96 | return self.x, c.y, c.peso 97 | 98 | 99 | 100 | 101 | 102 | 103 | g = GrafoLAP(4) 104 | g.aggiungiarco(0, 1, 2.1) 105 | g.aggiungiarco(0, 2, 1.1) 106 | g.aggiungiarco(1, 2, 1) 107 | g.aggiungiarco(2, 0, 1) 108 | g.aggiungiarco(3, 0, 1) 109 | g.stampa() 110 | 111 | print("\n") 112 | g.rimuoviarco(0,3) 113 | g.stampa() 114 | print("\n") 115 | print(g.arco(0,1)) 116 | 117 | print("\n") 118 | for c in g.archi(): 119 | print(c) -------------------------------------------------------------------------------- /grafi/scheduleratt.py: -------------------------------------------------------------------------------- 1 | from grafi import GrafoLA 2 | from algosugrafi import trovazero, tuttizero 3 | 4 | 5 | class AttivitaNonSchedulabili(Exception): 6 | pass 7 | 8 | 9 | class Attivita: 10 | def __init__(self, nome: str, durata: int): 11 | self.nome: str = nome 12 | self.durata: int = durata 13 | self.start: int = 0 14 | 15 | def __str__(self): 16 | return "("+self.nome+","+self.durata+","+self.start+")" 17 | 18 | def __repr__(self): 19 | return "("+self.nome+","+str(self.durata)+","+str(self.start)+")" 20 | 21 | 22 | class Propedeuticita: 23 | def __init__(self, fromatt: int, toatt: int): 24 | self.fromatt: int = fromatt 25 | self.toatt: int = toatt 26 | 27 | 28 | 29 | class Scheduler: 30 | def __init__(self, listaattivita: list[Attivita], prop: list[Propedeuticita]): 31 | self.atts: list(Attivita) = listaattivita 32 | self.grafo = GrafoLA(len(self.atts)) 33 | for p in prop: 34 | self.grafo.aggiungiarco(p.fromatt, p.toatt) 35 | 36 | def addpropedeuticita(self, afrom: int, ato: int): 37 | self.grafo.aggiungiarco(afrom, ato) 38 | 39 | def schedule(self) -> list[Attivita]: 40 | gradi: list[int] = [0 for i in range(self.grafo.n)] 41 | rimossi: list[bool] = [False for i in range(self.grafo.n)] 42 | for x, y in self.grafo.archi(): 43 | gradi[y] += 1 44 | curr = trovazero(gradi, rimossi) 45 | while curr != -1: 46 | rimossi[curr] = True 47 | for ad in self.grafo.adiacenti(curr): 48 | gradi[ad] -= 1 49 | if self.atts[ad].start < self.atts[curr].start + self.atts[curr].durata: 50 | self.atts[ad].start = self.atts[curr].start + self.atts[curr].durata 51 | curr = trovazero(gradi, rimossi) 52 | if tuttizero(gradi): 53 | return self.atts 54 | else: 55 | raise AttivitaNonSchedulabili("propedeuticità cicliche") 56 | -------------------------------------------------------------------------------- /grafi/test.py: -------------------------------------------------------------------------------- 1 | from grafi import GrafoMA 2 | from grafi import GrafoLA, Grafo 3 | from algosugrafi import visitaprofonditaRic, visitaprofondita, visitaampiezza, eaciclicoOR 4 | from grafino import GrafoLANO, GrafoMANO 5 | from unionfind import UnionFind 6 | from scheduleratt import Scheduler, Attivita, Propedeuticita 7 | 8 | g = GrafoMANO(4) 9 | g.aggiungiarco(0, 1) 10 | g.aggiungiarco(0, 2) 11 | g.aggiungiarco(1, 2) 12 | g.aggiungiarco(2, 0) 13 | g.aggiungiarco(3, 0) 14 | g.stampa() 15 | 16 | print("adiacenti di 0") 17 | it = g.adiacenti(0) 18 | for a in it: 19 | print(a) 20 | 21 | print("tutti") 22 | it = g.archi() 23 | for a in it: 24 | print(a) 25 | 26 | 27 | UF = UnionFind(5) 28 | print('UF') 29 | print(UF) 30 | UF.union(UF.find(0), UF.find(1)) 31 | print('DOPO UNION Set(0) e Set(1)') 32 | print(UF) 33 | UF.union(UF.find(2), UF.find(1)) 34 | print('DOPO UNION Set(2) e Set(1)') 35 | print(UF) 36 | 37 | 38 | g: Grafo = GrafoLA(7) 39 | g.aggiungiarco(0, 1) 40 | g.aggiungiarco(0, 2) 41 | g.aggiungiarco(1, 3) 42 | # g.aggiungiarco(2, 3) 43 | g.aggiungiarco(3, 4) 44 | g.aggiungiarco(5, 6) 45 | g.stampa() 46 | 47 | print(visitaprofonditaRic(g, 0)) 48 | print(visitaprofondita(g, 0)) 49 | print(visitaampiezza(g, 0)) 50 | # print("E' connesso:"+str(econnesso(g))) 51 | # print("E' albero:"+str(ealbero(g))) 52 | # print("Num componenti connesse:"+str(numcompconnesse(g))) 53 | # print("E' aciclico:"+str(eaciclico(g))) 54 | print("E' aciclico:" + str(eaciclicoOR(g))) 55 | 56 | 57 | listatt = [Attivita(str(i), i+1) for i in range(g.n)] 58 | listprop = [Propedeuticita(x,y) for x,y in g.archi()] 59 | schedulatore: Scheduler = Scheduler(listatt,listprop) 60 | listatt = schedulatore.schedule() 61 | print(listatt) -------------------------------------------------------------------------------- /grafi/unionfind.py: -------------------------------------------------------------------------------- 1 | class MySet: 2 | def __init__(self, elem: int): 3 | self.elementlist: list[int] = [elem] 4 | self.name: int = elem 5 | self.pos: int = self.name 6 | self.size: int = 1 7 | 8 | def __repr__(self): 9 | return "("+str(self.name)+", "+str(self.size)+", "+str(self.pos)+", "+str(self.elementlist) +")" 10 | 11 | 12 | class UnionFind: 13 | def __init__(self, n: int): 14 | self.sets: list = [MySet(i) for i in range(n)] 15 | self.elements: list = [i for i in range(n)] 16 | 17 | def find(self, elem: int) -> MySet: 18 | return self.sets[self.elements[elem]] 19 | 20 | def union(self, a: MySet, b: MySet): 21 | if a.size < b.size: 22 | print('Eseguo '+ str(len(a.elementlist))+' spostamenti') 23 | for el in a.elementlist: 24 | self.elements[el] = b.pos 25 | b.elementlist.append(el) 26 | b.size += a.size 27 | b.name = a.name 28 | a.size = 0 29 | a.elementlist = [] 30 | else: 31 | print('Eseguo ' + str(len(b.elementlist)) + ' spostamenti') 32 | for el in b.elementlist: 33 | self.elements[el] = a.pos 34 | a.elementlist.append(el) 35 | a.size += b.size 36 | b.size = 0 37 | b.elementlist = [] 38 | 39 | 40 | def unionSenzaBilanciamento(self, a: MySet, b: MySet): 41 | for el in b.elementlist: 42 | self.elements[el] = a.pos 43 | a.elementlist.append(el) 44 | a.size += b.size 45 | b.size = 0 46 | b.elementlist = [] 47 | 48 | def __repr__(self): 49 | return str(self.sets)+"\n"+str(self.elements) 50 | -------------------------------------------------------------------------------- /heap/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sflesca/EsempiAlgoritmiPython/780dd2e398382bd42eb1c0ea081964a7aef0a259/heap/__init__.py -------------------------------------------------------------------------------- /heap/eccezioni.py: -------------------------------------------------------------------------------- 1 | class HeapFullError(Exception): 2 | def __init__(self, message="Heap pieno"): 3 | self.message = message -------------------------------------------------------------------------------- /heap/heap.py: -------------------------------------------------------------------------------- 1 | from heap.eccezioni import HeapFullError 2 | 3 | 4 | class Heap: 5 | def __init__(self, dim: int): 6 | self.dim = dim 7 | self.actualdim = 0 8 | self.values = [0 for x in range(dim)] 9 | 10 | 11 | 12 | def ins(self, val): 13 | if self.actualdim < self.dim: 14 | self.values[self.actualdim] = val 15 | curr = self.actualdim 16 | self.actualdim += 1 17 | while curr > 0 and self.values[curr] < self.values[(curr + 1) // 2 - 1]: 18 | tmp = self.values[(curr + 1) // 2 - 1] 19 | self.values[(curr + 1) // 2 - 1] = self.values[curr] 20 | self.values[curr] = tmp 21 | curr = (curr + 1) // 2 - 1 22 | else: 23 | raise HeapFullError() 24 | 25 | def top(self): 26 | if self.actualdim <= 0: 27 | raise HeapEmptyError() 28 | return self.values[0] 29 | 30 | def out(self): 31 | x = self.top() 32 | self.values[0] = self.values[self.actualdim - 1] 33 | self.actualdim -= 1 34 | curr = 0 35 | while (curr + 1) * 2 - 1 < self.actualdim: 36 | if (curr + 1) * 2 < self.actualdim: 37 | if self.values[curr] > min(self.values[(curr + 1) * 2 - 1], self.values[(curr + 1) * 2]): 38 | if self.values[(curr + 1) * 2 - 1] < self.values[(curr + 1) * 2]: 39 | tmp = self.values[curr] 40 | self.values[curr] = self.values[(curr + 1) * 2 - 1] 41 | self.values[(curr + 1) * 2 - 1] = tmp 42 | curr = (curr + 1) * 2 - 1 43 | else: 44 | tmp = self.values[curr] 45 | self.values[curr] = self.values[(curr + 1) * 2] 46 | self.values[(curr + 1) * 2] = tmp 47 | curr = (curr + 1) * 2 48 | else: 49 | break 50 | if self.values[curr] > self.values[(curr + 1) * 2 - 1]: 51 | tmp = self.values[curr] 52 | self.values[curr] = self.values[(curr + 1) * 2 - 1] 53 | self.values[(curr + 1) * 2 - 1] = tmp 54 | curr = (curr + 1) * 2 - 1 55 | else: 56 | break 57 | return x 58 | 59 | def print(self): 60 | print("Numero elementi:" + str(self.actualdim)) 61 | print("Dimensione max:" + str(self.dim)) 62 | print("Elenco Valori") 63 | print(str(self.values[:self.actualdim])) 64 | -------------------------------------------------------------------------------- /heap/heapmodificabile.py: -------------------------------------------------------------------------------- 1 | from heap.heap import Heap 2 | 3 | 4 | class HeapModificabile(Heap): 5 | 6 | def __init__(self, dim): 7 | super().__init__(dim) 8 | self.positions = {} 9 | 10 | def ins(self, val): 11 | if self.actualdim < self.dim: 12 | self.values[self.actualdim] = val 13 | curr = self.actualdim 14 | self.positions[val]=curr 15 | self.actualdim +=1 16 | while curr > 0 and self.values[curr] min(self.values[(curr+1) * 2 - 1], self.values[(curr+1) * 2]): 35 | if self.values[(curr+1) * 2 - 1] < self.values[(curr+1) * 2]: 36 | tmp = self.values[curr] 37 | self.values[curr] = self.values[(curr+1) * 2 - 1] 38 | self.values[(curr+1) * 2 - 1] = tmp 39 | self.positions[self.values[curr]] = curr 40 | self.positions[self.values[(curr+1) * 2 - 1]] = (curr+1) * 2 - 1 41 | curr = (curr+1) * 2 - 1 42 | else: 43 | tmp = self.values[curr] 44 | self.values[curr] = self.values[(curr+1) * 2] 45 | self.values[(curr+1) * 2] = tmp 46 | self.positions[self.values[curr]] = curr 47 | self.positions[self.values[(curr+1) * 2]] = (curr+1) * 2 48 | curr = (curr+1) * 2 49 | else: 50 | break 51 | elif self.values[curr] > self.values[(curr + 1) * 2 - 1]: 52 | tmp = self.values[curr] 53 | self.values[curr] = self.values[(curr + 1) * 2 - 1] 54 | self.values[(curr + 1) * 2 - 1] = tmp 55 | self.positions[self.values[curr]] = curr 56 | self.positions[self.values[(curr + 1) * 2 - 1]] = (curr + 1) * 2 - 1 57 | curr = (curr + 1) * 2 - 1 58 | else: 59 | break 60 | del self.positions[x] 61 | return x 62 | 63 | def update(self, val): 64 | if not val in self.positions: #implementazione inefficiente sarebbe necessario un accesso diretto 65 | self.ins(val) 66 | else: 67 | curr = self.positions[val] 68 | if val < self.values[curr]: 69 | self.values[curr] = val 70 | del self.positions[val] 71 | self.positions[val] = curr 72 | while curr > 0 and self.values[curr] < self.values[(curr + 1) // 2 - 1]: 73 | tmp = self.values[(curr + 1) // 2 - 1] 74 | self.values[(curr + 1) // 2 - 1] = self.values[curr] 75 | self.values[curr] = tmp 76 | self.positions[self.values[(curr + 1) // 2 - 1]] = (curr + 1) // 2 - 1 77 | self.positions[self.values[curr]] = curr 78 | curr = (curr + 1) // 2 - 1 79 | else: 80 | self.values[curr] = val 81 | del self.positions[val] 82 | self.positions[val] = curr 83 | while (curr + 1) * 2 - 1 < self.actualdim: 84 | if (curr + 1) * 2 < self.actualdim: 85 | if self.values[curr] > min(self.values[(curr + 1) * 2 - 1], self.values[(curr + 1) * 2]): 86 | if self.values[(curr + 1) * 2 - 1] < self.values[(curr + 1) * 2]: 87 | tmp = self.values[curr] 88 | self.values[curr] = self.values[(curr + 1) * 2 - 1] 89 | self.values[(curr + 1) * 2 - 1] = tmp 90 | self.positions[self.values[curr]] = curr 91 | self.positions[self.values[(curr + 1) * 2 - 1]] = (curr + 1) * 2 - 1 92 | curr = (curr + 1) * 2 - 1 93 | else: 94 | tmp = self.values[curr] 95 | self.values[curr] = self.values[(curr + 1) * 2] 96 | self.values[(curr + 1) * 2] = tmp 97 | self.positions[self.values[curr]] = curr 98 | self.positions[self.values[(curr + 1) * 2]] = (curr + 1) * 2 99 | curr = (curr + 1) * 2 100 | else: 101 | break 102 | if self.values[curr] > self.values[(curr + 1) * 2 - 1]: 103 | tmp = self.values[curr] 104 | self.values[curr] = self.values[(curr + 1) * 2 - 1] 105 | self.values[(curr + 1) * 2 - 1] = tmp 106 | self.positions[self.values[curr]] = curr 107 | self.positions[self.values[(curr + 1) * 2 - 1]] = (curr + 1) * 2 - 1 108 | curr = (curr + 1) * 2 - 1 109 | else: 110 | break 111 | 112 | def evuoto(self): 113 | return self.actualdim==0 114 | 115 | def print(self): 116 | super().print() 117 | print(self.positions) 118 | -------------------------------------------------------------------------------- /heap/test.py: -------------------------------------------------------------------------------- 1 | from heap import Heap 2 | from heapmodificabile import HeapModificabile 3 | 4 | class Pair: 5 | def __init__(self, x, p): 6 | self.x = x 7 | self.p = p 8 | 9 | def __lt__(self, other): 10 | return self.p< other.p 11 | 12 | def __eq__(self, other): 13 | return self.x == other.x 14 | 15 | def __hash__(self): 16 | return self.x 17 | 18 | def print(self): 19 | print("("+str(self.x)+", "+str(self.p)+")") 20 | 21 | def __str__(self): 22 | return "("+str(self.x)+", "+str(self.p)+")" 23 | 24 | def __repr__(self): 25 | return "(" + str(self.x) + ", " + str(self.p) + ")" 26 | 27 | h = HeapModificabile(10) 28 | h.ins(Pair(0,5)) 29 | h.ins(Pair(1,9)) 30 | h.ins(Pair(2,3)) 31 | h.ins(Pair(3,6)) 32 | h.ins(Pair(4,4)) 33 | h.print() 34 | 35 | print(h.top()) 36 | print(h.out()) 37 | h.print() 38 | 39 | h.update(Pair(4,2)) 40 | h.print() 41 | h.update(Pair(1,1)) 42 | h.print() 43 | 44 | h.update(Pair(1,9)) 45 | h.print() -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | for i in range(0,99): 2 | if i%2==1 and i%3==2 and i%4==3 and i%5==4 and i%6==5: 3 | print(i) -------------------------------------------------------------------------------- /programmazionedinamica/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sflesca/EsempiAlgoritmiPython/780dd2e398382bd42eb1c0ea081964a7aef0a259/programmazionedinamica/__init__.py -------------------------------------------------------------------------------- /programmazionedinamica/editdistance.py: -------------------------------------------------------------------------------- 1 | # A Dynamic Programming based Python program for edit 2 | # distance problem 3 | 4 | 5 | def editdistance(str1, str2, m, n): 6 | # Create a table to store results of subproblems 7 | dp = [[0 for x in range(n + 1)] for x in range(m + 1)] 8 | 9 | # Fill d[][] in bottom up manner 10 | for i in range(m + 1): 11 | for j in range(n + 1): 12 | 13 | # If first string is empty, only option is to 14 | # insert all characters of second string 15 | if i == 0: 16 | dp[i][j] = j # Min. operations = j 17 | 18 | # If second string is empty, only option is to 19 | # remove all characters of second string 20 | elif j == 0: 21 | dp[i][j] = i # Min. operations = i 22 | 23 | # If last characters are same, ignore last char 24 | # and recur for remaining string 25 | elif str1[i - 1] == str2[j - 1]: 26 | dp[i][j] = dp[i - 1][j - 1] 27 | 28 | # If last character are different, consider all 29 | # possibilities and find minimum 30 | else: 31 | dp[i][j] = 1 + min(dp[i][j - 1], # Insert 32 | dp[i - 1][j], # Remove 33 | dp[i - 1][j - 1]) # Replace 34 | 35 | return dp[m][n] 36 | 37 | 38 | # Driver code 39 | str1 = "sunday" 40 | str2 = "saturday" 41 | 42 | print(editdistance(str1, str2, len(str1), len(str2))) 43 | # This code is contributed by Bhavya Jain 44 | -------------------------------------------------------------------------------- /programmazionedinamica/knapsack01.py: -------------------------------------------------------------------------------- 1 | # A Dynamic Programming based Python 2 | # Program for 0-1 Knapsack problem 3 | # Returns the maximum value that can 4 | # be put in a knapsack of capacity W 5 | 6 | 7 | def knapsack(W, wt, val, n): 8 | K = [[0 for x in range(W + 1)] for x in range(n + 1)] 9 | 10 | # Build table K[][] in bottom up manner 11 | for i in range(n + 1): 12 | for w in range(W + 1): 13 | if i == 0 or w == 0: 14 | K[i][w] = 0 15 | elif wt[i-1] <= w: 16 | K[i][w] = max(val[i-1] + K[i-1][w-wt[i-1]], K[i-1][w]) 17 | else: 18 | K[i][w] = K[i-1][w] 19 | return K[n][W] 20 | 21 | 22 | # Driver code 23 | val = [60, 100, 120] 24 | wt = [10, 20, 30] 25 | W = 50 26 | n = len(val) 27 | print(knapsack(W, wt, val, n)) 28 | 29 | # This code is contributed by Bhavya Jain 30 | -------------------------------------------------------------------------------- /programmazionedinamica/lcs.py: -------------------------------------------------------------------------------- 1 | # Dynamic Programming implementation of LCS problem 2 | 3 | def lcs(X, Y): 4 | # find the length of the strings 5 | m = len(X) 6 | n = len(Y) 7 | 8 | # declaring the array for storing the dp values 9 | L = [[None] * (n + 1) for i in range(m + 1)] 10 | 11 | # Following steps build L[m+1][n+1] in bottom up fashion 12 | # Note: L[i][j] contains length of LCS of X[0..i-1] 13 | # and Y[0..j-1] 14 | for i in range(m + 1): 15 | for j in range(n + 1): 16 | if i == 0 or j == 0: 17 | L[i][j] = 0 18 | elif X[i - 1] == Y[j - 1]: 19 | L[i][j] = L[i - 1][j - 1] + 1 20 | else: 21 | L[i][j] = max(L[i - 1][j], L[i][j - 1]) 22 | 23 | # L[m][n] contains the length of LCS of X[0..n-1] & Y[0..m-1] 24 | return L[m][n] 25 | 26 | 27 | # end of function lcs 28 | 29 | 30 | # Driver program to test the above function 31 | X = "AGGTAB" 32 | Y = "GXTXAYB" 33 | print("Length of LCS is ", lcs(X, Y)) 34 | -------------------------------------------------------------------------------- /semplici/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sflesca/EsempiAlgoritmiPython/780dd2e398382bd42eb1c0ea081964a7aef0a259/semplici/__init__.py -------------------------------------------------------------------------------- /semplici/codeprioritafissata.py: -------------------------------------------------------------------------------- 1 | class CodaPFIX: 2 | def __init__(self, maxp: int): 3 | self.code: list = [[] for x in range(maxp)] 4 | self.maxp: int = maxp 5 | self.size: int = 0 6 | 7 | def insert(self, val, p: int): 8 | if p < self.maxp: 9 | self.code[p].append(val) 10 | self.size += 1 11 | 12 | def pop(self): 13 | if self.size == 0: 14 | return None 15 | for i in range(maxp): 16 | if len(self.code[i]) > 0: 17 | self.size -= 1 18 | return self.code[i].pop(0) 19 | 20 | def top(self): 21 | if self.size == 0: 22 | return None 23 | for i in range(maxp): 24 | if len(self.code[i]) > 0: 25 | return self.code[i][0] 26 | -------------------------------------------------------------------------------- /semplici/mergesort.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | def merge_sort(arr: List[int]) -> List[int]: 5 | if len(arr) > 1: 6 | mid = len(arr) // 2 # Trova il punto medio dell'array 7 | left_half: List[int] = arr[:mid] # Dividi la parte sinistra 8 | right_half: List[int] = arr[mid:] # Dividi la parte destra 9 | 10 | merge_sort(left_half) # Ricorsivamente ordina la parte sinistra 11 | merge_sort(right_half) # Ricorsivamente ordina la parte destra 12 | 13 | merge(arr, left_half, right_half) 14 | 15 | return arr 16 | 17 | 18 | def merge(arr: List[int], left_half: List[int], right_half: List[int]) -> None: 19 | i = j = k = 0 20 | 21 | # Unisci le due metà ordinate 22 | while i < len(left_half) and j < len(right_half): 23 | if left_half[i] < right_half[j]: 24 | arr[k] = left_half[i] 25 | i += 1 26 | else: 27 | arr[k] = right_half[j] 28 | j += 1 29 | k += 1 30 | 31 | # Controlla se ci sono elementi rimasti 32 | while i < len(left_half): 33 | arr[k] = left_half[i] 34 | i += 1 35 | k += 1 36 | 37 | while j < len(right_half): 38 | arr[k] = right_half[j] 39 | j += 1 40 | k += 1 41 | 42 | 43 | # Esempio di utilizzo 44 | arr = [38, 27, 43, 3, 9, 82, 10] 45 | print("Array originale:", arr) 46 | print("Array ordinato:", merge_sort(arr)) -------------------------------------------------------------------------------- /semplici/quicksort.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | import random 3 | 4 | def quick_sort(arr: List[int]) -> List[int]: 5 | if len(arr) <= 1: 6 | return arr 7 | else: 8 | pivot = random.choice(arr) # Scelta randomizzata del pivot 9 | left = [x for x in arr if x < pivot] 10 | middle = [x for x in arr if x == pivot] 11 | right = [x for x in arr if x > pivot] 12 | return quick_sort(left) + middle + quick_sort(right) 13 | 14 | # Esempio di utilizzo 15 | arr = [38, 27, 43, 3, 9, 82, 10] 16 | print("Array originale:", arr) 17 | print("Array ordinato:", quick_sort(arr)) -------------------------------------------------------------------------------- /semplici/simple.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | 4 | def sommamatrici(a, b): 5 | c = np.zeros(a.shape) 6 | for i in range(c.shape[0]): 7 | for j in range(c.shape[1]): 8 | c[i][j] = a[i][j] + b[i][j] 9 | return c 10 | 11 | 12 | def moltiplicazionematrici(a, b): 13 | c = np.zeros((a.shape[0], b.shape[1])) 14 | for i in range(len(c)): 15 | for j in range(len(c[i])): 16 | for k in range(len(a[i])): 17 | c[i][j] += a[i][k] * b[k][j] 18 | return c 19 | 20 | 21 | def fatt(n): 22 | if n > 1: 23 | return fatt(n - 1) * n 24 | else: 25 | return 1 26 | 27 | 28 | def fatit(n): 29 | ft = 1 30 | for i in range(1, n + 1): 31 | ft *= i 32 | return ft 33 | 34 | 35 | def fib(n): 36 | if n <= 2: 37 | return 1 38 | else: 39 | return 40 | 41 | 42 | def fibc(n): 43 | if n <= 1: 44 | return 1, 1 45 | else: 46 | x, y = fibc(n - 1) 47 | return x + y, x 48 | 49 | def fib1(n): 50 | x, y = fibc(n) 51 | return x 52 | 53 | 54 | def search(vett, x): 55 | for v in vett: 56 | if v == x: 57 | return True 58 | return False 59 | 60 | 61 | def somma(vett): 62 | x = 0 63 | for v in vett: 64 | x += v 65 | return x 66 | 67 | 68 | def sommainefficiente(vett): 69 | x = [0 for i in range(len(vett) + 1)] 70 | for i in range(len(vett)): 71 | x[i + 1] = vett[i] + x[i] 72 | return x[len(vett)] 73 | 74 | 75 | def ordinamentoABolle(vett): 76 | for i in range(len(vett) - 1): 77 | scambiati = False 78 | for j in range(1, len(vett) - i): 79 | if vett[j - 1] > vett[j]: 80 | tmp = vett[j - 1] 81 | vett[j - 1] = vett[j] 82 | vett[j] = tmp 83 | scambiati = True 84 | if not scambiati: 85 | return 0 86 | return 1 87 | 88 | 89 | def merge(A, B): 90 | n = len(A) 91 | m = len(B) 92 | C = [] 93 | i = 0 94 | j = 0 95 | while i < n and j < m: 96 | if A[i] <= B[j]: 97 | C.append(A[i]) 98 | i = i + 1 99 | else: 100 | C.append(B[j]) 101 | j = j + 1 102 | while i < n: 103 | C.append(A[i]) 104 | i = i + 1 105 | while j < m: 106 | C.append(B[j]) 107 | j = j + 1 108 | return C 109 | 110 | 111 | def quasifib(n): 112 | if n <= 2: 113 | return 1 114 | else: 115 | return quasifib(n - 1) + quasifib(n - 1) 116 | -------------------------------------------------------------------------------- /semplici/test.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import time 3 | 4 | from semplici.simple import moltiplicazionematrici, sommamatrici, fatt, fatit, search, somma, sommainefficiente, \ 5 | ordinamentoABolle, merge, fib, quasifib 6 | 7 | # m1 = np.array([[0, 1], [2, 3]]) 8 | # m2 = np.array([[0, 2, 3], [1, 4, 5]]) 9 | # m3 = sommamatrici(m1,m2) 10 | # print(m3) 11 | # m3 = moltiplicazionematrici(m1,m2) 12 | # print(m3) 13 | # 14 | # print("fatt(6)=" + str(fatt(6))) 15 | # print("fatt(6)=" + str(fatit(6))) 16 | # 17 | # trovato = search([1,2,3,4,8,5], 14) 18 | # print(trovato) 19 | 20 | 21 | v1 = np.random.randint(0, 9, 100000000) 22 | x = 15 23 | ts = time.time() 24 | trovato = search(v1, x) 25 | te = time.time() - ts 26 | if trovato: 27 | print(str(x)+" è presente") 28 | else: 29 | print(str(x) + " non è presente") 30 | print("Tempo ricerca = " + str(te)+" secondi") 31 | 32 | 33 | # v1 = np.random.randint(0, 4, 100000000) 34 | # ts = time.time() 35 | # s = somma(v1) 36 | # te = time.time() - ts 37 | # print(str(s)+"è la somma") 38 | # print("Tempo ricerca = " + str(te)+" secondi") 39 | 40 | # v1 = [1, 2,3, 6, 28, 2] 41 | # print(somma(v1)) 42 | # print(sommainefficiente(v1)) 43 | 44 | # v = [0,3,12,24,1,2] 45 | # v1 = [12,5, 17, 34,1] 46 | # ordinamentoABolle(v) 47 | # ordinamentoABolle(v1) 48 | # print(v) 49 | # print(v1) 50 | # v2 = merge(v,v1) 51 | # print(v2) 52 | 53 | # for i in range(1,21): 54 | # print("fib "+str(i)+"="+str(fib(i))) 55 | 56 | print(quasifib(3)) --------------------------------------------------------------------------------